From: Kevin Ballard Date: 2005-10-21T23:57:00+09:00 Subject: Re: A comparison by example of keyword argument styles I'd quote stuff, but I'd be pulling from too many messages that it would take forever ;) Anyway, here are my thoughts on the subject: I really would like to see keyword arguments done right. Sydney's style of all arguments are implicit keyword arguments I think is terrible. The points above about being able to rename your args without worrying about calling code is good, but also I believe that implicit keyword arguments can make for inconsistent calling conventions. Basically, keyword arguments should be explicitly defined. This is akin to defining the name of the method - you're making a conscious API decision. Implicit keywords makes every single argument an API decision when it's simply not necessary. In terms of syntax, I was perfectly happy with the m_f1(1, 2, a:3, b:4) syntax until it was pointed out that this looks really terrible when you pass symbols, as in m_f1(1, 2, a: :foo, b: :bar) As was also mentioned above, I believe the best syntax is to borrow the current implicit hash syntax, as in m_f1(1, 2, a=>:foo, b=>:bar) This has several advantages. First off, it's a syntax that everybody is familiar with. Secondly, if we add a backwards-compatibility feature of treating m_f1(1, 2, :a => :foo, :b => :bar) the same as the keyword version (i.e. with "a" and "b" isntead of ":a" and ":b"), then it lends itself really well to making existing code use keyword arguments. Any code that currently uses the implicit hash to mock keywords can have the method redefined to use explicit keyword arguments and the calling code will remain untouched, so the API will remain the same. This I think is a huge plus. In terms of specifics for this syntax, I think that methods without defined keyword arguments should continue to use the implicit hash behaviour, and methods with defined keyword arguments should no longer accept the implicit hash, but rather if you want dynamic keyword arguments you should specify the **args argument to grab all unknown keyword arguments. This way existing code will work as-is, and can be slowly converted to use keyword arguments wherever appropriate. This will also help with methods that take mock keyword arguments because as soon as they're changed to use explicit keyword arguments, then they automatically will get argument checking on the keyword names, which can help people trying to call that code (i.e. it will tell you if you typoed when calling the method [unless, of course, the method takes arbitrary keywords as well via **args]). The only thing I'm not sure about right now is the proper syntax for defining them. I don't mind the look of def m_f1(foo, bar, a:, b:) except that it no longer makes sense once you're using => instead of : in the calling conventions. Maybe we could do something like def m_f1(foo, bar, :a, :b) or grab another symbol and use that, like def m_f1(foo, bar, %a, %b) I personally prefer the look of the first (:a, :b).