Re: [stack] Point free (pointless) programming in ruby? (fwd)

John Nowak <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
On Jan 15, 2009, at 5:37 PM, John Carter wrote:

> On Tue, 13 Jan 2009, John Nowak wrote:
>
>> Languages like ML and Haskell work better because they have curried
>> functions.
>
> Actually Currying works quite well in Ruby...
>
> two_arg = lambda{|a,b| somefunc(a,b)}
>
> b="Some concrete value"
> one_arg = lambda{|a| two_arg.call(a,b)}

That is not currying. Unfortunately, this is something of a common  
misunderstanding. A curried function is one that emulates taking more  
than one argument by using many functions that take a single argument.  
For example, here's a function in Haskell that adds three numbers:

    foo = \x y z -> x + y + z

And here's *the exact same function* with a different name:

    bar = \x -> (\y -> (\z -> x + y + z))

When you write the former, you're really doing the later. Both can be  
called identically as they're exactly the same thing:

    foo (1, 2, 3)  -- 6
    bar (1, 2, 3)  -- 6

Because 'foo' and 'bar' are curried, we can do this to mean the *exact  
same thing* once again; this is called partial application:

    ((foo 1) 2) 3  -- 6
    ((bar 1) 2) 3  -- 6

Additionally, Haskell offers a function for currying a function:

    curry (\(x, y) -> x + y)  ==  \x y -> x + y

And uncurrying:

    uncurry (\x y -> x + y)  ==  \(x, y) -> x + y

Now, you *can* write a curried function in Ruby like so:

    baz = lambda{|a| lambda{|b| lambda{|c| a + b + c}}}

And call it as such:

    baz.call(1).call(2).call(3)  # 6

Unfortunately, it's quite painful.

I'm not sure where the confusion with respect to "curry" started.  
Factor is an example of a language that unfortunately misuses the term.

>> Keep in mind that all existing concatenative languages make heavy use
>> of stacks. Related languages like FP and FL make heavy use of lists.
>> Trying to do pointfree programming in languages that don't do such
>> things (Ruby, Python, Haskell, Scheme, etc) is going to be quite
>> painful. For example, here's the Haskell example above in Joy:
>
> Well, actually Ruby has Array's that behave (or can be made to behave)
> in almost all respects like lists.

Yes, you could write all new functions that operate on stacks instead  
of using normal parameters. Ruby performance being what it is though,  
I can't imagine this being useful for much of anything. Languages like  
Factor do analysis to eliminate constant reading from and writing to a  
stack which improves performance dramatically. Having to update an  
array's contents, make bounds checks, update an array's length, and so  
on just to add two numbers doesn't sound like fun.

> ie. Ruby is a superset of concatenative languages.
> ie. If one restricts ones activities to a suitable concatenative
> subset, the same interesting properties emerge.

Yes, if you rewrite every function to work on stacks and use none of  
Ruby's features, you will have a very poor concatenative language with  
awful syntax. Of course, one can implement Ruby's features in a  
concatenative language too. It's therefore a bit silly to claim one is  
a superset of the other.

- John
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.