

... because Ruby isn't terse enough yet - mdemare
http://weblog.raganwald.com/2007/10/stringtoproc.html

======
mnemonicsloth
What is a "point-free holomorphism" ?

I study math, hack Scheme, and find myself totally confused by terminology.

Maybe it's a riddle or something -- "What does complex-smoothness have to do
with lambda calculus?"

~~~
raganwald
It was actually a typo. Fixed, thank you.

~~~
mnemonicsloth
No, thank you.

I've just been forced to learn about a new language proposal, a new (to me)
set of morphisms, and a nonstandard approach to proving stuff in topology.
That's a rich link.

------
mdemare
In Paul Graham's Accumulator Generator comparison
(<http://www.paulgraham.com/accgen.html>) Ruby is now terser than any language
except Arc.

    
    
        foo = 'n -> x -> n += x'.to_proc
    
        f = foo[4]
        f[2] # => 6
        f[2] # => 8
    

(This would be even terser:

    
    
        foo = &'n -> x -> n += x'
    

but the ampersand syntax is only allowed after a method call.)

~~~
dfranke
I think Haskell is overall terser than Ruby. The trouble with the accgen test
is that it's imperative, and Haskell isn't meant to be. Here's the Haskell
implementation that I would submit:

    
    
      putStrLn "Don't do that, you nimwit!"

~~~
yariv
The Erlang version is unnecessarily verbose (and also semantically different)
because it uses 2 processes. It can be rewritten as

Foo = fun(N) -> put(var, N), fun(X) -> V = get(var) + X, put(var, V), V end
end.

It's not as concise as Ruby or Arc, but it's a one liner. However, similar to
Haskell, this style of programming is discouraged in Erlang.

------
jsnx
This is cute but first-class functions would be better. I've had to switch to
Python to find them.

------
mynameishere
The Perl Golf anti-pattern.

~~~
mechanical_fish
I tend to agree with you. It's obvious to me that the following code evaluates
to 6:

    
    
      r = 2
      foo = lambda {|x| x * r}
      foo.call(3)
    

And it's obvious to me that the following code raises an ArgumentError:

    
    
      foo = lambda {|x,r| x * r}
      foo.call(3)
      

But what does this do?

    
    
      r = 2
      bar = 'x*r'.to_proc
      bar(3)
    

Do I get the 6, or do I get the ArgumentError?

UPDATE: I presume the answer is "ArgumentError" (because the alternative
appears to be positively _evil_ ), and that what I really need to do is this:

    
    
      r = 2
      bar = 'x -> x*r'.to_proc
      bar(3)
    
    

Why is this such an improvement over lambda? Couldn't these folks just _fix_
lambda (e.g. to remove the need for that annoying .call method every time I
use the result) rather than deciding that every Ruby programmer needs to learn
yet another argument syntax?

~~~
raganwald
"these folks"

There are at least two kinds of folks: those who are "fixing" Ruby the
language, such as the Rubinius team, and those who are "using" the language.

I am in the latter camp. So sometimes I complain about what is
broken--[http://weblog.raganwald.com/2007/02/why-ruby-is-not-
acceptab...](http://weblog.raganwald.com/2007/02/why-ruby-is-not-
acceptable.html--and) sometimes I hack around it. But no, I am in no position
to change the language. If I was, I would actually implement the point-free
and underscore conventions natively.

If you want to use closures, you want to use lambda, not String#to_proc. If
you dislike using .call, Ruby also allows [] syntax, so:

    
    
        r = 2
        foo = lambda {|x| x * r}
        foo.[3]
    

May be a little less objectionable.

~~~
mechanical_fish
I cannot get foo.[3] to work:

    
    
      syntax error, unexpected '['
    

But please don't spend too much time explaining what I'm doing wrong, because
I'm afraid I don't like foo.[3] anyway. :)

Let me demonstrate my problem by taking a simulated tour through my brain as
it encounters foo.[3] for the first time:

"WTF?

"Did someone mistype foo[3]?

"No, wait, surely it's supposed to be foo(3). I'm pretty sure that foo is a
function. Didn't we set it equal to a lambda expression three lines ago?

"Maybe I need glasses. Let's adjust my monitor. No, those are square brackets,
all right. And that really is a period between "foo" and the brackets.

"Maybe Google can help. But I'm not sure how to google '.[]'

"Oh, no -- is this one of those mysterious edge cases of the Ruby syntax? Do I
hear _Why laughing at me? Does foo.[] magically target the eigenclass, or the
metaclass, or the zetaclass, or something? Or did one of the libraries
secretly redefine the core language behind my back?

"omigod, I should have learned Python.

"No, wait! The dot means that we're calling a method. And I know that [] is a
method -- we redefine it all the time. So foo.[3] is just an obscure-ass way
of calling foo[3] .

"Which makes no sense, because I thought foo was a function. So I must be
wrong.

"WTF?"

[ten minutes later]

"Aargh! I went through _ten minutes of confusion_ just to save _three
characters_?"

I may have exaggerated this a little. And, yet, I really did have _no idea_
that .[] works, and I still have no idea _how_ it works. (Of course, in my
version of Ruby, it apparently _doesn't_ work, which makes it hard to
investigate.)

Now, don't get me wrong -- Ruby is my favorite programming language. Quite
often, after the tortured syntax, the monkey-patched class, or the strange new
DSL stops you dead in your tracks, you'll struggle through the learning curve
and discover that you have _a powerful new technique_. This starts on day zero
of Ruby, when you see your first block. It looks like nothing on Earth, but it
turns out to be _insanely great_.

Symbol#to_proc is a borderline case. I like the idea, but I hate the syntax.
The &: doesn't bother me as much as the lack of curly brackets. To me,
idiomatic Ruby is about blocks -- I expect map() and inject() and delete_if()
to take blocks, not arguments. I would really prefer this:

    
    
      my_array.map {_.get_funky}
    

Reading this makes me happy. There's a map() call, so I expect a block, and
look -- there are the curly brackets. And because it's a block, the stuff
inside it must be a method call. And, in fact, the underscore and the dot mean
that we're invoking a method on a placeholder. All is well with the world, and
no higher brain functions need to be engaged.

But, you know, life isn't perfect. Language is about communication, and
ultimately the language you speak is determined by what other people are
speaking. Symbol#to_proc is powerful enough to become popular, and popular
enough to be idiomatic, so we all have to learn it. Perhaps I'll even start
using it.

But I'm afraid String#to_proc, like foo.[x], is past the point of diminishing
returns. Do I really need a version of lambda that is not only utterly unlike
Ruby's usual lambda, but is even _less_ like Scheme's lambda? And are my
colleagues really going to forgive me for asking them to learn Haskell syntax
in order to read something as trivial as lambda {|x,y| x+y} ? I'm not even
sure if I could forgive myself!

~~~
raganwald
"I cannot get foo.[3] to work"

Hey, neither can I. Quite possibly because foo.[3] actually doesn't work, it's
foo[3] that works and I made a typo.

Sorry about that, and especially too bad considering how your first reaction
was to consider the possibility that your version of Ruby was at fault instead
of the possibility that I made a careless error. I appreciate the implied vote
of confidence, but I'm aghast at the consequences.

I appreciate your taking the time to share your reaction. I'm mulling over
exactly what I prefer about the point-free syntax, and the prod to think
thinks over may help me understand my own views in more depth.

~~~
mechanical_fish
So, part of me is tempted to use this as an example of the reason why
languages benefit from a certain amount of redundancy and consistency. :)

The other part of me is quite embarrassed, because I thought I had _tried_
foo[3] and failed. I guess that's why everyone in the Ruby community prefers
automated testing!

Of course, if I thought that applying an array reference to a Proc made any
sort of intuitive sense, I might have tried it more carefully. :) I still wish
that I could just say foo(x).

Anyway, I'm glad you appreciated my report from the field. And of _course_ you
prefer the point-free syntax -- you know Haskell, you know Lisp, you seem to
know a certain amount of mathematics. It all makes perfect sense to you, just
as I can only dimly remember the time when vector calculus didn't make perfect
sense to me.

But I shouldn't indulge my love for German by randomly German syntax into my
English prose inserting. Unless I have a very good reason: perhaps I want to
borrow the uniquely compact German word _shadenfreude_ , or perhaps essential
it is the alien character of Yoda to establish. When you break the rules in
Ruby code that you intend to show to someone else (and is there really any
other kind of code?) you need to convince the reader that you had a very good
reason, because you're making him or her work harder to understand you.

Keep playing with the syntax for a while. You may find that it's so elegant
that it is worth defending against the inevitable skeptics. And, if not, at
least golf is a very pleasant way to pass the time!

~~~
raganwald
"golf is a very pleasant way to pass the time!"

Golf is a good walk spoiled => Golf is good code spoiled.

------
donna
hmm, i dunno... self-modifying code can lead to insanity... :)

