Charles Oliver Nutter wrote:
> On Sat, Jan 29, 2011 at 12:37 AM, Eric Christopherson
> <echristopherson / gmail.com> wrote:
>> Specifically, MacRuby has an extension to the usual hash parameters
>> that seems pretty complicated to me, but allows it to interact fairly
>> painlessly with Objective-C*. It basically allows you to define a
>> method with named parameters. It's bewildering because a method
>> invocation like "person.setFirstName('Gloria', { :lastName=>'Alvarez'
>> })" actually calls a *different* method from
>> "person.setFirstName('Gloria', lastName: 'Alvarez')" (the former is
>> the regular Ruby hash argument type; the latter uses the
>> MacRuby-specific keyed arguments. If no keyed-argument version of a
>> method exists, it will just translate it into a hash-argument form.)
> Laurent can correct me if I'm wrong, but I don't think ObjC's syntax
> qualifies as true named arguments.

Yes. Objective-C inherits its syntax from Smalltalk, which just has
plain old boring standard positional arguments like every other
language, like C, like Ruby minus optional and splat arguments.

The only peculiarity is that the arguments get written between the
subroutine name instead of at the end. So, if you have a method named
foo:bar:baz: which takes three arguments, the way you would call it in
pretty much every other language is

    foo:bar:baz:(1, 2, 3)

whereas in Smalltalk it's

    foo: 1 bar: 2 baz: 3

This allows you to achieve some nice readability with clever method
naming, i.e. instead of

    dictionary.add(1, 2) # which one's the key and which is the value?

you get

    dictionary at: 1 put: 2.

But fundamentally, these are still positional arguments. I could, for
example, do this in Ruby:

    dictionary.at_first_put_second(1, 2)

> In MacRuby/ObjC, a method call like
> 
> foo(bar:1, baz:2)
> 
> Is just a way of saying something like
> 
> foo_with_bar_with_baz(1, 2)

More precisely, your example (roughly) translates to the following
snippet of Smalltalk:

    temp := Dictionary new.
    temp at: #bar put: 1.   'No dictionary literals in Smalltalk'

    foo: temp baz: 2.

i.e. in Ruby:

    send(:'foo:baz:', { :bar => 1 }, 2)

A better example would be

    foo(1, bar: 2, baz: 3)

which translates to

    foo: 1 bar: 2 baz: 3.

or

    send(:'foo:bar:baz:', 1, 2, 3)

> The method name and the argument names actually resolve to different
> method bodies internally. In addition, the order is absolutely
> crucial. The following two calls are not the same and will not end up
> in the same target method:
> 
> foo(bar: 1, baz: 2)
> foo(baz: 2, bar: 1)

Correct.

The only reason why you can say

    condition ifTrue: [doThis] ifFalse: [doThat].
    condition ifFalse: [doThat] ifTrue: [doThis].
    condition ifTrue: [doThis]; ifFalse: [doThat].

is because TrueClass and FalseClass define four methods

    ifTrue:ifFalse:
    ifFalse:ifTrue:
    ifTrue:
    ifFalse:

With named arguments (and optional arguments), you would have just one
method:

    def if(then=->{}, else=->{})

jwm