Reply to topic  [ 4 posts ] 
Function w/ only 1 optional parameter fails unless specified 
Author Message
Yorick Padawan

Joined: Tue Jun 07, 2011 1:46 pm
Posts: 32
Location: UNH
Post Function w/ only 1 optional parameter fails unless specified
For instance,

Code:
func testbug(optvar=)
{
   default, optvar, 0;
   if (optvar > 20)
      optvar = 30;
   return optvar;
}

It seems like a bug because I cannot called the function by using
Code:
> a = testbug();
ERROR (*main*) too many actual parameters in function call
WARNING source code unavailable (try dbdis function)
now at pc= 1 (of 12), failed at pc= 4
To enter debug mode, type <RETURN> now (then dbexit to get out)

but this works
Code:
> a = testbug(optvar=);

and this
Code:
> a = testbug(optvar=1);


:?:


Tue Aug 23, 2011 9:38 am
Profile
Yorick Master

Joined: Wed Jun 01, 2005 11:34 am
Posts: 112
Post Re: Function w/ only 1 optional parameter fails unless speci
This has come up before and is apparently a feature, not a bug. Calling a function as testbug() is equivalent to calling it as testbug([]). In other words, it's impossible to call a function with no positional parameters. See this post: viewtopic.php?p=907#p907

You'll want to provide a dummy positional argument that you then ignore:

Code:
func testbug(void, optvar=)
{
   default, optvar, 0;
   if (optvar > 20)
      optvar = 30;
   return optvar;
}


(However I'm surprised that it lets you call it as "testbug(optvar=1)", I would have expected that to provoke an error.)


Wed Aug 24, 2011 7:26 am
Profile
Yorick Padawan

Joined: Tue Jun 07, 2011 1:46 pm
Posts: 32
Location: UNH
Post Re: Function w/ only 1 optional parameter fails unless speci
Interesting. Thanks for the tip, I suppose I'll just use the dummy var or understand wrap_args.


Wed Aug 24, 2011 12:12 pm
Profile
Yorick Master

Joined: Mon Nov 22, 2004 9:43 am
Posts: 354
Location: Livermore, CA, USA
Post Re: Function w/ only 1 optional parameter fails unless speci
I would call this a misfeature rather than a feature. It's a side effect of how yorick syntax treats missing arguments.

I could make the parser recognize f() as a special case, treated completely differently than f(x). If I made f() call f with zero arguments, rather than with one nil argument, then potentially f([]) could act differently than f(), which I judged as a worse syntactic evil. To be consistent, any number of trailing blank arguments would have to be eliminated by the parser: Consider the sequence of expressions f(), f(,), f(,,), f(,,,), ... Should all of these invoke f with zero arguments, or only the first? Should the number of arguments be the number of commas or one greater than the number of commas? And what about f(x,)? Should that be parsed exactly the same as f(x), namely as a call to f with one argument, or does it mean f(x,[])?. And what about f(,x,)? Did you mean f([],x) or f([],x,[])? The strangeness goes on and on with this stance, even though I admit that all these higher order considerations are progressively more obscure and less likely to be confusing. Anyway, I went for f() not being a special case unto itself, even though that means every function which you intend to invoke as a function (as opposed to as a subroutine) must be declared with at least one positional argument, as dnagle points out. I usually call it "void", which makes it look like a C declaration of a function with no arguments. (Incidentally, there is a slight performance hit for this, since the local variable "void" actually is initialized to [] at run time. But this discussion is not about performance.)

Incidentally, the treatment of keyword arguments is entirely consistent: f(key=x) calls f with zero positional arguments and one keyword argument, just as f(key=x,) calls it with one keyword and one positional -- a keyword argument "eats" a comma or parenthesis just like a positional argument. You should still declare f with a single positional argument "void", as dnagle says, unless it is your intention to force the caller to supply at least one keyword argument.

Also, wrap_args will not give you any means to cope with the issue. That will only give you a means for making f(x) behave differently from f(x,); there is no way you can ever distinguish f() from f([]), as you can check with the disassemble function.

In the end, the rule is: If you will use the return value of a function, you must declare it with at least one positional parameter. Functions with zero positional parameters can be invoked only as subroutines.

The real problem here is that yorick looks a lot like C, and C does parse f() as a special case -- other than this one case, it doesn't permit blank arguments at all (and of course it doesn't have keyword arguments). I've always regarded this misfeature as a part of the yorick subroutine calling syntax, which also disagrees with the C subroutine syntax. That subroutine syntax disagreement actually causes more problems for yorick beginners or casual programmers than the relatively rare case of a function producing an output with no inputs.


Mon Sep 05, 2011 8:24 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 4 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.