keyword arguments?

php.internals

Daniel Crookston

22 years ago
It looks like the last time this was discussed was October of 2003, over the course of about five emails. I don't see anything in the archives about it since then. Here's what I'd like to suggest. some_function($a, 'B', :check TRUE) function some_function($first, $second, :check $key1 = FALSE, :foo $key2) { if ($key1) { lala; } elseif ($key2 > 0) { blabla; } } Sticking a : in front of the variable name, either in the calling code or the function declaration, makes it a keyword argument. Keyword arguments are always optional, and [could|should] default to something handy like FALSE or 0. (Maybe make their defaults settable in php.ini?) I would implement this myself, but even after reading George Schlossnagle's fantastic book, I'm still not wizardly enough to do so. If someone could point me in the right direction, though... Thanks for listening, Daniel

Christian Schneider

22 years ago
Daniel Crookston wrote:
> some_function($a, 'B', :check TRUE) > > function some_function($first, $second, :check $key1 = FALSE, :foo $key2)
First of all: I guess it is too early to start the discussion about named parameters again. As much as I think named parameters are an interesting concept I don't like this solution for its syntax and static semantics. If you are still interested in what solution we chose here then read below the line, otherwise please ignore the rest and don't flame me ;-) --------------------------------------------------------------------- I'm still in favor of an approach we are using here where you can pass associative arrays without array(): some_function($a, "B", 'check' => true); [ equivalent to some_function($a, "B", array('check' => true)); ] and use function some_function($first, $second, $param) { if ($param['check']) ... } [ or extract($more) inside some_function if you prefer that ]. Patches for php4 and php5 can be found at http://cschneid.com/php/php4/function_call_named_parameters.patch and http://cschneid.com/php/php5/function_call_named_parameters.patch respectively There is also a tool called convertsyntax.php at http://cschneid.com/php/ which converts between old and new syntax. Have fun, - Chris

Daniel Crookston

22 years ago
Actually, that would be acceptable, since you lose the bulk of array(). The only thing that remains a problem is that if you add another (non-named) parameter, you still need to worry about the relative positions in all of your functions. Now that I think about it, that's actually a bigger complaint for me than having to use array(). Thoughts? Comments? Flames? Daniel P.S. Thank you for the link to the patches :)
> --------------------------------------------------------------------- > > I'm still in favor of an approach we are using here where you can pass > associative arrays without array():
<snip all else>

Johannes Schlueter

22 years ago
Hi Daniel, named paramters should only be followed by named paramters - like with default values. So one can first "fill" the unnamed once and then some (or all) of the named once. But remembering the last discussion on this idea I don't think this will be added... johannes Daniel Crookston wrote:

Daniel Convissor

22 years ago
On Wed, Jun 23, 2004 at 03:04:43PM +0000, Daniel Crookston wrote:
> > function some_function($first, $second, :check $key1 = FALSE, :foo $key2)
PHP 5 supports type hints when writing interfaces for classes. http://www.zend.com/php5/articles/engine2-php5-changes.php#Heading6 --Dan
-- T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y data intensive web and database programming http://www.AnalysisAndSolutions.com/ 4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409

Bert Slagter

22 years ago
Even after reading your message twice, I can't think of an example where this would be useful. Obviously, I don't understand your intention. Could you give an example of a construction that is made possible by this feature (and thus would otherwise be impossible)? Bert Daniel Crookston wrote:

Michael Walter

22 years ago
Bert Slagter wrote:
> Even after reading your message twice, I can't think of an example where > this would be useful. Obviously, I don't understand your intention.
The original poster wants to add syntax for keyword arguments. Keyword arguments can be found in quite some languages (Python, Common Lisp, ...), they allow you to bind a parameter by name instead of by position (similar to using an array vs. a hash).
> Could you give an example of a construction that is made possible by > this feature (and thus would otherwise be impossible)?
Surely we aren't dealing with Turing completeness here, are we? Consider the following constructor: class Window: def __init__(title, x=USE_DEFAULT, y=USE_DEFAULT, width=USE_DEFAULT, height=USE_DEFAULT, parent=None): pass And contrast: window = Window(title='Hello World', width=640, height=480) with: window = Window('Hello World', USE_DEFAULT, USE_DEFEAULT, 640, 480) Cheers, Michael

Daniel Crookston

22 years ago
The major benefit of keyword arguments doesn't occur when you're writing functions, it occurs when you're re-writing them. I can't count the number of times where I've thought "My xyz function already does something almost exactly like what I need... if I just passed it an extra parameter, I could rewrite xyz to do what I need and save a lot of time." So I add another parameter, making it optional. This is fine, all the calls to xyz that are lacking the final parameter still work (since it's optional.) But do this once or twice, and pretty soon you have function calls that look like this: xyz('a', 2, $foo, '', '', '', '', '', '', $bar); That's ugly and unnecessary, and leaves lots of room for bugs when you're writing functions that use the nth optional parameter in your function (since you have to count the number of blank spaces you need to leave.) Additionally, what happens when all of your original, three-argument (a, 2, $foo) calls to xyz need to start passing an additional argument because of a change you couldn't predict when you first wrote your function? Keyword arguments solve these problems. They're always optional - not just optional in that you can stick a '' or NULL in the spot where you would put a value in the function call. They're optional in that you can leave them out entirely. Because they're named, they can also be passed in any order. And, finally, you can add new keyword arguments at any time, and none of your current function calls will break. If there's a way to do this in PHP (short of having the last argument be a hash) that I've missed, please let me know about it. Daniel Cr On Wed, 23 Jun 2004, Bert Slagter wrote:

Jochem Maas

22 years ago
Daniel Crookston wrote:
> The major benefit of keyword arguments doesn't occur when you're > writing functions, it occurs when you're re-writing them. I can't > count the number of times where I've thought "My xyz function already > does something almost exactly like what I need... if I just passed it > an extra parameter, I could rewrite xyz to do what I need and save a > lot of time." So I add another parameter, making it optional. > > This is fine, all the calls to xyz that are lacking the final > parameter still work (since it's optional.) But do this once or > twice, and pretty soon you have function calls that look like this: > > xyz('a', 2, $foo, '', '', '', '', '', '', $bar); > > That's ugly and unnecessary, and leaves lots of room for bugs when > you're writing functions that use the nth optional parameter in your > function (since you have to count the number of blank spaces you need > to leave.) > > Additionally, what happens when all of your original, three-argument > (a, 2, $foo) calls to xyz need to start passing an additional argument > because of a change you couldn't predict when you first wrote your > function?
all that can be offset by write a complementary set of wrapper functions like: function xyzSuperSpecialFooBar($a, $b, $foo, $bar) { /* using the 7th optional arg - first 3 args required (or whatever) */ return xyz($a, $b, $foo, '', '', '', '', '', '', $bar); } which also gives you some nice sugar to help you remember exactly what that variation of params is supposed to do.
> > Keyword arguments solve these problems. They're always optional - not > just optional in that you can stick a '' or NULL in the spot where you > would put a value in the function call. They're optional in that you > can leave them out entirely. Because they're named, they can also be > passed in any order. And,
you function is still going to have to do some checking for all these optional args is it not? whats the great benefit of the optional named args in any order vs. passing an array ala: $arr = array( 'arg1' => 1, 'arg2' => 2, 'arg3' => 4, ); $rtnV = mySwissArmyKnife($arr); ---- where : function mySwissArmyKnife($arr = array()) { extract($arr); ... do the checking... ... calc something ... return $x; }
> finally, you can add new keyword arguments at any time, and none of > your current function calls will break. > > If there's a way to do this in PHP (short of having the last argument > be a hash) that I've missed, please let me know about it.
how about look at the problem in a different way - is the function xyz() (I assume that you have some realworld situation where this kind of thing would handy right now) possibly a candidate for spliting up into a class? with regard to the 'swiss army knife' function.. have you ever tried to do any serious construction work with a swiss army knife ;-) seriously tho, from what I gather there is a icecubes chance is hell that this will be implemented.

Richard Mann

22 years ago
>pretty soon you have function calls that look like this: > >xyz('a', 2, $foo, '', '', '', '', '', '', $bar);
I agree with this. I am working on a project where by the flexibility required of the object being written has spawned a massive collection of parameters. Many of these parameters are only required in certain situations and it is indeed the case that when I need to add one additional parameter to accommodate some new capability, I suddenly find myself with the task of either putting all the empty parameters in before it every time it is used or rewriting all instances of the function to place it towards the beginning. I can except that this can be avoided in many cases with better forward-planning, but it is defiantly desirable sometimes to simply have these flexible constructs available.
>all that can be offset by write a complementary set of wrapper functions >like: > >function xyzSuperSpecialFooBar($a, $b, $foo, $bar) { > /* using the 7th optional arg - first 3 args required (or whatever) */ > return xyz($a, $b, $foo, '', '', '', '', '', '', $bar); >}
Not always ideal though. Having about 6 different aliases for essentially one function can get confusing for the developer to remember. My example is a HTML Form generator, whereby the actually generation of the form elements is alike enough to be handled by one algorithm, but requires some set-up, which includes various layout settings. I could do this with a different alias for each element, but this is more difficult to automate then simply passing a 'type' variable which can easily be programmed. Having said my peace in favour of named keywords (which I do think would be extremely handy), I must say that I am not convinced by any of the syntax put forward for using them yet. :-( Maybe something like: function a($a, $b=true, $c=>false) { ... } $c would be your named parameter. Sorry for dragging up old stuff. ;-) Subject: Re: [PHP-DEV] Re: keyword arguments? The major benefit of keyword arguments doesn't occur when you're writing functions, it occurs when you're re-writing them. I can't count the number of times where I've thought "My xyz function already does something almost exactly like what I need... if I just passed it an extra parameter, I could rewrite xyz to do what I need and save a lot of time." So I add another parameter, making it optional. This is fine, all the calls to xyz that are lacking the final parameter still work (since it's optional.) But do this once or twice, and pretty soon you have function calls that look like this: xyz('a', 2, $foo, '', '', '', '', '', '', $bar); That's ugly and unnecessary, and leaves lots of room for bugs when you're writing functions that use the nth optional parameter in your function (since you have to count the number of blank spaces you need to leave.) Additionally, what happens when all of your original, three-argument (a, 2, $foo) calls to xyz need to start passing an additional argument because of a change you couldn't predict when you first wrote your function? Keyword arguments solve these problems. They're always optional - not just optional in that you can stick a '' or NULL in the spot where you would put a value in the function call. They're optional in that you can leave them out entirely. Because they're named, they can also be passed in any order. And, finally, you can add new keyword arguments at any time, and none of your current function calls will break. If there's a way to do this in PHP (short of having the last argument be a hash) that I've missed, please let me know about it. Daniel Cr

Jevon Wright

22 years ago
Wouldn't a good (not necessarily better) idea in your case be to use an object? Instead of function foo(named $a, named $b, named $c, named $d, ..., named $z) echo foo(a := $a, c := $c, e := $e, ...); you'd have class Foo { ... } $f = new Foo(); $f->setA($a); $f->setC($c); $f->setE($e); ... echo $f->doit(); This is clearer; all arguments are optional (unless you want to put required arguments in a constructor); and it basically does the same thing. And yes, it's about as much work as having a hash. Visual Basic supports named arguments (I used its style above). I've used it once in a function, but it had like 10 arguments - and it was a nightmare to try and code. I don't think the solution to extending functionality is to just add more arguments! Then again, I am still trying to instruct myself to the OO paradigm. What happens if you want to remove an argument from a function with named arguments? Either you'll have to remove it and search through all code and amend the calls (tiresome, error-prone), or you'd label the parameter "unused"/"deprecated". What happens if your function kept on changing? Before long you'll have 100 arguments with only 10 of them used at any one point... Just some thoughts... Jevon ----- Original Message ----- From: "Richard Mann" <richard.mann@gg.com> To: "Daniel Crookston" <daniel@hyperion-data.net>; "Bert Slagter" <bert@procurios.nl> Cc: <internals@lists.php.net> Sent: Thursday, June 24, 2004 8:53 PM Subject: RE: [PHP-DEV] Re: keyword arguments?
> >pretty soon you have function calls that look like this: > > > >xyz('a', 2, $foo, '', '', '', '', '', '', $bar); > > I agree with this. I am working on a project where by the flexibility > required of the object being written has spawned a massive collection of > parameters. Many of these parameters are only required in certain
situations
> and it is indeed the case that when I need to add one additional parameter > to accommodate some new capability, I suddenly find myself with the task
of
> either putting all the empty parameters in before it every time it is used > or rewriting all instances of the function to place it towards the > beginning. > > I can except that this can be avoided in many cases with better > forward-planning, but it is defiantly desirable sometimes to simply have > these flexible constructs available. > > >all that can be offset by write a complementary set of wrapper functions > >like: > > > >function xyzSuperSpecialFooBar($a, $b, $foo, $bar) { > > /* using the 7th optional arg - first 3 args required (or whatever)
*/
> > return xyz($a, $b, $foo, '', '', '', '', '', '', $bar); > >} > > Not always ideal though. Having about 6 different aliases for essentially > one function can get confusing for the developer to remember. My example
is
> a HTML Form generator, whereby the actually generation of the form
elements
> is alike enough to be handled by one algorithm, but requires some set-up, > which includes various layout settings. I could do this with a different > alias for each element, but this is more difficult to automate then simply > passing a 'type' variable which can easily be programmed. > > Having said my peace in favour of named keywords (which I do think would
be

Richard Mann

22 years ago
>Instead of > function foo(named $a, named $b, named $c, named $d, ..., named $z) > echo foo(a := $a, c := $c, e := $e, ...); > >you'd have > class Foo { ... } > $f = new Foo(); > $f->setA($a); > $f->setC($c); > $f->setE($e); > ... > echo $f->doit();
This could be done, (the code I speak of is actually already an object) but where setting-up a big HTML Form (referring to my Form generator example), it's far easier to copy, past and modify a single line function call then to use the far bulkier fashion of setting all the properties individually. This is the best way to do it some times, and all the properties being set are Object Properties, but the function acts as an interface for these properties.
>What happens if you want to remove an argument from a function with named >arguments?
Is it not the same removing any type of argument from a function? There are always different ways of doing things, sometimes others are clearly better then some. I don't think the named parameter system should be implemented to be used instead of many of the perfectly good ways of doing things, but just to assist where appropriately required. -----Original Message----- From: Jevon Wright [mailto:jevon@jevon.org] Sent: 24 June 2004 10:42 To: Richard Mann; internals@lists.php.net Subject: Re: [PHP-DEV] Re: keyword arguments? Wouldn't a good (not necessarily better) idea in your case be to use an object? Instead of function foo(named $a, named $b, named $c, named $d, ..., named $z) echo foo(a := $a, c := $c, e := $e, ...); you'd have class Foo { ... } $f = new Foo(); $f->setA($a); $f->setC($c); $f->setE($e); ... echo $f->doit(); This is clearer; all arguments are optional (unless you want to put required arguments in a constructor); and it basically does the same thing. And yes, it's about as much work as having a hash. Visual Basic supports named arguments (I used its style above). I've used it once in a function, but it had like 10 arguments - and it was a nightmare to try and code. I don't think the solution to extending functionality is to just add more arguments! Then again, I am still trying to instruct myself to the OO paradigm. What happens if you want to remove an argument from a function with named arguments? Either you'll have to remove it and search through all code and amend the calls (tiresome, error-prone), or you'd label the parameter "unused"/"deprecated". What happens if your function kept on changing? Before long you'll have 100 arguments with only 10 of them used at any one point... Just some thoughts... Jevon ----- Original Message ----- From: "Richard Mann" <richard.mann@gg.com> To: "Daniel Crookston" <daniel@hyperion-data.net>; "Bert Slagter" <bert@procurios.nl> Cc: <internals@lists.php.net> Sent: Thursday, June 24, 2004 8:53 PM Subject: RE: [PHP-DEV] Re: keyword arguments?
> >pretty soon you have function calls that look like this: > > > >xyz('a', 2, $foo, '', '', '', '', '', '', $bar); > > I agree with this. I am working on a project where by the flexibility > required of the object being written has spawned a massive collection of > parameters. Many of these parameters are only required in certain
situations
> and it is indeed the case that when I need to add one additional parameter > to accommodate some new capability, I suddenly find myself with the task
of
> either putting all the empty parameters in before it every time it is used > or rewriting all instances of the function to place it towards the > beginning. > > I can except that this can be avoided in many cases with better > forward-planning, but it is defiantly desirable sometimes to simply have > these flexible constructs available. > > >all that can be offset by write a complementary set of wrapper functions > >like: > > > >function xyzSuperSpecialFooBar($a, $b, $foo, $bar) { > > /* using the 7th optional arg - first 3 args required (or whatever)
*/
> > return xyz($a, $b, $foo, '', '', '', '', '', '', $bar); > >} > > Not always ideal though. Having about 6 different aliases for essentially > one function can get confusing for the developer to remember. My example
is
> a HTML Form generator, whereby the actually generation of the form
elements
> is alike enough to be handled by one algorithm, but requires some set-up, > which includes various layout settings. I could do this with a different > alias for each element, but this is more difficult to automate then simply > passing a 'type' variable which can easily be programmed. > > Having said my peace in favour of named keywords (which I do think would
be
> extremely handy), I must say that I am not convinced by any of the syntax > put forward for using them yet. :-( Maybe something like: > > function a($a, $b=true, $c=>false) { > ... > } > > $c would be your named parameter. > > Sorry for dragging up old stuff. ;-) > > > Subject: Re: [PHP-DEV] Re: keyword arguments? > > > The major benefit of keyword arguments doesn't occur when you're writing > functions, it occurs when you're re-writing them. I can't count the > number of times where I've thought "My xyz function already does something > almost exactly like what I need... if I just passed it an extra parameter, > I could rewrite xyz to do what I need and save a lot of time." So I add > another parameter, making it optional. > > This is fine, all the calls to xyz that are lacking the final parameter > still work (since it's optional.) But do this once or twice, and pretty > soon you have function calls that look like this: > > xyz('a', 2, $foo, '', '', '', '', '', '', $bar); > > That's ugly and unnecessary, and leaves lots of room for bugs when you're > writing functions that use the nth optional parameter in your function > (since you have to count the number of blank spaces you need to leave.) > > Additionally, what happens when all of your original, three-argument (a, > 2, $foo) calls to xyz need to start passing an additional argument because > of a change you couldn't predict when you first wrote your function? > > Keyword arguments solve these problems. They're always optional - not > just optional in that you can stick a '' or NULL in the spot where you > would put a value in the function call. They're optional in that you can > leave them out entirely. Because they're named, they can also be passed > in any order. And, finally, you can add new keyword arguments at any > time, and none of your current function calls will break. > > If there's a way to do this in PHP (short of having the last argument be a > hash) that I've missed, please let me know about it. > > Daniel Cr > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php --- Incoming mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.564 / Virus Database: 356 - Release Date: 19/01/2004

Daniel Crookston

22 years ago
Okay, so keyword arguments probably won't be implemented. "Ice cube's chance in hell" is the phrase I recall being thrown around. I have two questions: 1. Why not? 2. Where do I start with my own copy of PHP to put it in? (The reason I asked about it initially is that I thought it'd be a fun first "Let's modify PHP" project. And, finally - our messages are logged, aren't they? Why don't we trim quoted emails? No need to log all those old things. Dan

Derick Rethans

22 years ago
On Thu, 24 Jun 2004, Daniel Crookston wrote:
> Okay, so keyword arguments probably won't be implemented. "Ice cube's > chance in hell" is the phrase I recall being thrown around. I have two > questions: > > 1. Why not?
Because you can already do something similar with using a PHP array with associative elements. And, for other reasons have a look in the archive.
> 2. Where do I start with my own copy of PHP to put it in? (The reason I > asked about it initially is that I thought it'd be a fun first "Let's > modify PHP" project.
Just copy the source and rename it to something not including PHP in the name. But you should really know what you are attempting here. A fork for something like this sounds quite silly.
> And, finally - our messages are logged, aren't they? Why don't we trim > quoted emails? No need to log all those old things.
What do you mean? Most people strip useles things from emails they reply to. regards, Derick

Daniel Crookston

22 years ago
I was actually asking which part of the PHP code I'd want to modify. I haven't been able to find an overview of what all the different files are for - possibly I'm just not looking in the right place. Does such an overview exist that I could read over? Secondly, I'm not suggesting a fork - I just want to write a patch and make it available in case anyone who is as stubborn as me wants to use it. I agree that forking the project over this would be dumb. Dan

Derick Rethans

22 years ago
On Fri, 25 Jun 2004, Daniel Crookston wrote:
> I was actually asking which part of the PHP code I'd want to modify. I > haven't been able to find an overview of what all the different files are > for - possibly I'm just not looking in the right place. Does such an > overview exist that I could read over?
No, there is no such thing at all. There is some very limited and outdated information in the manual and the places you most likely need to change for this are in Zend/: zend_language_parser.y and zend_language_scanner.l and ofcourse the zend_compile.c and zend_execute.c files. regards, Derick

Jason Garber

22 years ago
Hello, I've been following this thread since it started... In my years of PHP programming, I never had a problem with passing an array to a function and using it's keys. If this is about not typing array(), then I must say I strongly disagree with the proposal. Shoot, with arrays, it's simple to define default parameters. function foo($aArgs) { $aArgs += array('SomeID' => 0, 'DoThat' => TRUE); } Required keys can even be checked for with a quick array_diff(). For the amount of times that it would *probably* be used, I don't think it's worth adding new syntax for. Sincerely, Jason Garber At 6/24/2004 10:55 PM +0000, Daniel Crookston wrote:

Andi Gutmans

22 years ago
I think the disadvantages of named arguments outweigh the advantages. It adds to the languages complexity with a construct which will probably not be used that often, and which is likely to impact parameter binding performance. I do think that in these kind of cases, where you really do require the ability to continue to extend and extend a function prototype, a hash as the last argument isn't that bad. It would look something like this: func(1, 2 , array("protocol" => "http", "version" => "1.1", "compression" = "on")); Not too bad IMO. Just as another interesting point, if you'd use ->set()'s like Jevon describes you could also reach the following kind of code thanks to PHP 5. $f->setA($a)->setB($b)->setC($c); Of course this would require all set?() methods to return $this and it's questionable if this is nice style (I probably prefer the few lines over one such line) but just some food for thought :) Andi At 09:41 PM 6/24/2004 +1200, Jevon Wright wrote: