[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: call/cc



> -----Original Message-----
> From: owner-ll1-discuss@ai.mit.edu
[mailto:owner-ll1-discuss@ai.mit.edu]
> On Behalf Of Kragen Sitaker
> Sent: Friday, December 14, 2001 2:20 PM
> To: jmarshall@mak.com
> Cc: alk@pobox.com; ll1-discuss@ai.mit.edu
> Subject: Re: call/cc
...snip...
> 
> Here's a little bit of interlingual comparison --- what does it take
> to construct a new anonymous function that adds its two arguments and
> apply it to two numbers?
> 
> Perl: sub { $_[0] + $_[1] }->(3, 5)      18 tokens ($_ and -> are 1
token
> each)
> JavaScript: function(x, y){return x + y}(3, 5)
>                                          17 tokens
> Lisp: ((lambda (x y) (+ x y)) 3 5)       16 tokens
> Smalltalk: [:x :y | x + y] valueWithArguments: #(3 5)
>                                          15 tokens
> Python: (lambda x, y: x + y)(3, 5)       15 tokens
> OCaml: (fun x y -> x + y) 3 5            10 tokens
> Haskell: (\x y -> x + y) 3 5             10 tokens (\x is 2 tokens, ->
is
> 1)
> FORTH: marker foo  3 5 :noname + ; execute  foo
>                                          9 tokens (explicit cleanup)
> FORTH: 3 5 :noname + ; execute           6 tokens (cheating because no
GC)
> PostScript: 3 5 {add} exec               6 tokens
> dc: 3 5 [+] x                            6 tokens
> 
> 6 tokens is probably the minimal a reasonable language can hope to do
> here (although none of the languages I think of as reasonable made it
> there.)

I'm not clear on the criteria. For example, why is postscript listed as
taking only 6 tokens. How is that (actually expressively) different from
writing the equivalent in a language like Smalltalk:

    [3+5] value

Would I write (in postscript):

     3 5 7 {add} 

Would this be the same (where 'exec' and 'value' mean invoke it)?

    [3+5+7] 

What if I presume that I can define a #add fn of the form:

    |add| := [:v| |s| v do: [:n|s:+=n]. s].

Then write (in SmallScript):

    add({3,5,7})

Or (classic smalltalk w/{...} dyn-lists):

    Add value: {3,5,7}

You need to separate the anon-fn from the invocation of that anon-fn
with some set of values. 

For classic Smalltalk I think your example form would be:
    
     fn := [:x:y| x+y]

     fn value: 3 value: 5.

Ignoring the 2 assignment elements (provided for clarity/illustration)
we could have written it:

     [:x:y|x+y] value: 3 value: 5.

We have 6 elements in the declaration
    block, var-decl, var-decl, var, msg, var

And (3) 4 elements in the invocation
    var, msg, arg1, arg2

SmallScript additionally allows us to write:

    [:x:y|x+y](3,5)

Or for &rest style variable argument processing we ought to be able to
generate a form for writing something equivalent to:
    
    [|a:=&...| a inject: 0 into: [:s:n|s+n]](...)

Or for a general Smalltalk style #inject:into: operation:

    [:op||a:=&...| a inject: 0 into: [:s:n|s.perform(op,n)]](...)

As in:

    [:op||a:=&...| a inject: 0 into: [:s:n|s.perform(op,n)]](#+,3,5)

For operating on arbitrary numbers of elements.

Which we could even specialize to define #inject(<>) for something like:
    [|a:=&...| a.inject([:s:n|s+n])](3,5,7,9)

Or if we wanted to use basic services, then:

    [|s. a:=&...| a do: [:n|s:+=n]. s](3,5,7,9)

Alternately written (without keyword messages) as:

    [|s. a:=&...| a.do([:n|s:+=n]). s](3,5,7,9)

Or if you don't like square brackets, then:

    {|s. a:=&...| a.do({:n|s:+=n}). s}(3,5,7,9)

So, what is the point of this discussion again?   

-- Dave S. [www.smallscript.org]