Log in

View Full Version : Result of NOP()


Gavino
12th November 2008, 11:26
The function NOP() currently returns a value of 0 (implemented as C++ NULL).

Would it not be better to return an 'undefined' value, ie a value for which Defined() returns false?
That way, it would be different from any other value and guaranteed to produce an error if you try to use it in an operation.

If it's indistinguishable from zero, its utility is debatable - you might just as well write "0".

stickboy
12th November 2008, 21:25
That's an interesting idea. I like it. It might break existing scripts though, but those scripts would have been using NOP() improperly anyway, and it'd be nice to catch those errors.

It'd make my Undefined() function less magical though. Oh well. ;)

Gavino
12th November 2008, 23:13
It'd make my Undefined() function less magical though. Oh well. ;)
Thanks for your support, stickboy.
Despite being a big fan of your functions, I didn't realise that Undefined() existed - found it now in jdl-util.avsi.

I suppose that weakens the case for changing NOP(), but it would be nice to have this in the core. As I said, zero seems like a poor substitute.

Gavino
20th November 2008, 13:42
Maybe only a few people are interested in this issue, but for the record, I resolved it by defining this function in an avsi file in my plugins folder:
# Redefine NOP() to give 'undefined' value
function NOP() {}

@stickboy - perhaps you could change your Undefined function to use this method. Because of the issue in this thread, the code
x = Undefined
gives error "Undefined: Cannot be called with any arguments." if 'last' is defined at this point.

IanB
20th November 2008, 21:38
For better or worse NOP() is the way it is. Changing it now would violate our do no harm concept.

Your idea is an interesting one and indicates it might be useful to add a new function whose return value is in the undefined state, but as you have shown, it is trivial to roll your own with a simple function declaration.

stickboy
21st November 2008, 05:05
Maybe only a few people are interested in this issue, but for the record, I resolved it by defining this function in an avsi file in my plugins folder:
# Redefine NOP() to give 'undefined' value
function NOP() {}Is that behavior defined to return the "undefined" value and not garbage?
@stickboy - perhaps you could change your Undefined function to use this method. Because of the issue in this thread, the code
x = Undefined
gives error "Undefined: Cannot be called with any arguments." if 'last' is defined at this point.Hmm... yeah, that's a problem. I always explicitly use parentheses when calling functions though.

Gavino
21st November 2008, 20:10
Is that behavior defined to return the "undefined" value and not garbage?
I discovered it by accident - I had left a function as a placeholder and forgot to fill in its body. Surprised to find it did not give a syntax error, I experimented further and found it did indeed give an 'undefined' value.

I can't find anything in the docs that specifies what it should do one way or the other, but rooting around in the source code, I see the parser (ScriptParser::ParseBlock) treats the result as a fresh AVSValue.
return result ? result : PExpression(new ExpConstant(AVSValue()));
Since the AVSValue() constructor gives a proper 'undefined' value, it can be relied on not to be garbage.

stickboy
22nd November 2008, 07:53
Well, if Wilbert or someone is willing to formalize it in the docs and to guarantee that behavior won't change, okay.

I suppose I also could do:
function UndefinedHelper(val "dummyArg") { return dummyArg }
function Undefined() { return UndefinedHelper() }

Gavino
22nd November 2008, 15:17
@stickboy

If you don't like the empty function, how about
function Undefined() { dummy=0 }
which also works, though the docs are silent on this one too.

[Indeed, the concept of the 'undefined' value, although well-defined at the API level, is essentially missing from the language-level documentation and is only hinted at with the explanation of Defined().]

Hopefully, the 'implicit last' problem will be recognised as a bug (and fixed), making your original definition work in all cases.

Wilbert
22nd November 2008, 17:17
[Indeed, the concept of the 'undefined' value, although well-defined at the API level, is essentially missing from the language-level documentation and is only hinted at with the explanation of Defined().]
I'm still not sure how this 'undefined' stuff works. Gavino, could you add about this to the online docs? (You probably can explain it better than me :))

Gavino
22nd November 2008, 20:17
Gavino, could you add about this to the online docs?
OK, I'll have a go and report back here when done.

IanB
22nd November 2008, 22:36
@Gavino,function Undefined() { dummy=0 }andfunction Undefined() { }are the same. They both rely on the same boundary case code in the parser for the final return value, which is currently without formal definition.

At the script level the undefined state has been really only intended for unsupplied optional arguments to user defined function.

Stickboys two function solution is about only using nailed down features to get the desired result, i.e. not risking boundary case code and tempting fate.

I don't really see a problem nailing down the current behaviour and documenting it so it can be formally used. One should do a pass through the code and make sure everything is consistent.

Gavino
23rd November 2008, 01:38
I don't really see a problem nailing down the current behaviour and documenting it so it can be formally used. One should do a pass through the code and make sure everything is consistent.
OK, thanks - that sets my mind at rest.

I understand what was behind stickboy's concerns. It wasn't clear to me either how much of the current implementation could be considered 'nailed down', but I thought it unlikely the parser would change. And I wasn't sure whether the omission of certain details in the docs was deliberate or an oversight.

I was already planning to verify my writeup with actual test cases and a cross-check with the code.

Gavino
26th November 2008, 15:15
I have now updated the wiki to cover 'undefined' values and tie down the rules for return values.

I have tried to make the documentation accurate and complete without being too pedantic or including unnecessary details. With things like this it can be tricky to get the right balance, so I hope I've achieved it.

I have made changes to the following pages:
Grammar (http://avisynth.org/mediawiki/Grammar)
Script variables (http://avisynth.org/mediawiki/Script_variables)
Boolean functions (http://avisynth.org/mediawiki/Internal_functions/Boolean_functions) (for Defined())
User defined script functions (http://avisynth.org/mediawiki/User_defined_script_functions)
The full AviSynth grammar (http://avisynth.org/mediawiki/The_full_AviSynth_grammar)

I have also taken the opportunity to correct any errors I spotted on those pages.

You can use the history/diff facility to see what's changed.
(Note that in some cases, the changes span more than one iteration.)

Wilbert
26th November 2008, 21:58
Great thanks! I will look at it and copy it over to the offline docs.

IanB
4th January 2010, 04:32
I have added a new script function "Undefined()" to CVS, it returns an AVSValue() i.e. the undefined state.

Gavino
4th January 2010, 12:11
Thanks, Ian (and Happy New Year :)).