ruby picture

RCR 300: Blocks syntax sugar based on indented code blocks

Submitted by marian (Sun Apr 03 21:04:52 UTC 2005)

Abstract

Closures are widely used in functional languages and Smalltalk. I propose new syntax sugar for blocks creation based on the lambda-calculus syntax, mixed with indented code blocks.

Problem

Ruby syntax is quite clear. However, you may have to type too many "end of block". Example:

f { |x|

     g { |y|
           h { |z| 
                    ... 
              }                  |
         }                       |  <-- 3 lines to indicate end of block
  }                              |

Proposal

I propose adding optional syntax sugar for blocks to ruby. The new syntax is based on the widely known lambda-calculus (all functional languages like LISP, Scheme and Haskell are based on it and the advantage is that every functional programmer knows what a lambda-expression is). The lambda letter is written '\'. Parameters are placed after it. The block of code to execute comes afterwards. Example:

Current syntax:

                {|x, y| 
                      x = x + 1
                      y = x + 3
                }

Proposed syntax (see the "Indented code blocks" RCR to know what the ':' means and the Analysis section for another example): \x y:

   x = x + 1
        y = x + 3

Note that '\' binds to the right so i.e. \x: \y: \z: z means (x:(\y:(\z:z))).

Analysis

Most of the current programs may remain untouched since we are just adding new syntax sugar. Compatibility is assured. I think syntax gets clearer as in the following example taken from the YAML Ruby library:

Example (taken from the YAML Ruby library): def to_yaml( opts = {} )

            YAML::quick_emit( self.object_id, opts ) { |out|
                out.seq( "!omap" ) { |seq|
                    self.each { |v|
                        seq.add( Hash[ *v ] )
                    }
                }
            }
        end

The new look: def to_yaml( opts = {} )

            YAML::quick_emit( self.object_id, opts ) \out:
                out.seq( "!omap" ) \seq:
                    self.each \v:
                        seq.add( Hash[ *v ] )

Python uses the lambda x: ... construction, but permits only a single expression after the parameter. We don't restrict the number of sentences after the parameters. Besides, writing '\' is shorter than writing 'lambda'.

Any programmer who has ever seen the functional language Haskell will know what the '\' means and will immediately understand the code.

Implementation

It's a change to the lexer and parser (waiting for responses to try an implementation).
ruby picture
Comments Current voting
I don't want indentation to become significant in Ruby; it's not consistent with the way that Ruby works. If indentation ever does become significant in Ruby, I will either fork or find a different language. Ruby Is Not Python. (Thankfully.) --Austin Ziegler


It is OK if you don't like indentation rules, but "changing Ruby sintax" doesn't mean "converting Ruby into Python". On the other hand, I think It's good borrowing nice features from other languages (in this case we are talking about Python and Haskell). In my opinion this is a good feature, just look to all those redundant "end" or "}". It's the same if they are there or not as in general the code is well indented. --marian


This is *not* a good feature -- it makes indentation syntactically signficant, which reduces the readability and pastability of Ruby overall. This is not a feature worth borrowing in the least. Further, there's no redundancy to the "end" or "}" characters -- they are each syntactically significant and meaningful. The only change that I *might* like toward this end is to add *optional* alternative tagends, e.g., do ... enddo; if ... endif, etc.

Right now, it's easy to do:

  people.select { |person| person.salary < 10000 }.raise(10000)

With the proposed "feature," this will not be possible and will reduce the overall readability of Ruby. This is not something worth implementing in the least.


If I understand this correctly, the assertion is that Ruby should be more like Haskell. But Ruby is not Haskell, and this suggested syntax looks and feels alien.

If the extra lines taken by closed braces are too extravagant, feel free to compress them onto one line: }}}. It would still be better than this kind of xenotransplant.

Syntax sugar? More like ground glass. I like my Ruby just the way it is, thanks.


As long as I can still use braces as well in situations where they are better, I think this is a nice enhancment. It will make code more readable, and easier to debug. I'm not sure I like the \ for arguments tho.


Note that you can always layout your code lisp style if you like:

YAML::quick_emit( self.object_id, opts ) { |out|

    out.seq( "!omap" ) { |seq|
        self.each { |v|
            seq.add( Hash[ *v ] )}}}


Strongly opposed 13
Opposed 4
Neutral 0
In favor 1
Strongly advocate 1
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .