Matz is on the Plane, Weighing Dots and Arrows #
Dots or arrows? Dots or arrows? See, he said he was leaving for RubyConf and on the way he’d figure out this whole dots and arrows business. Currently, arrows are winning, since they’re checked into 1.9.
Nobu gives some examples in ruby-talk:160170:
>> 1.times -> (foo="bar") { puts foo } => 0 >> def y >> yield >> end >> y -> (foo="bar") { puts foo }
The two dotted suggestions (err.. one one-dotted and one two-dotted!) come from Christophe Grandsire, who suggests a colon, and Eric Mahurin, who offers a period (which semantically jives with method calling):
collection.each:(foo="bar){puts foo} collection.each.(foo="bar){puts foo}
I don’t envy the Yacc’ry ahead for Nobu and Matz. But it’s fun to see everyone’s ears go up when the syntactical frosting comes out. Even when it’s only a couple sprinkles.
Robby Russell
ARTIST : Harry Nilsson
TITLE : Me and My Arrow
The Point
Me and my arrow Straighter than narrow Wherever we go, everyone knows It’s me and my arrow
Me and my arrow Taking the high road Wherever we go, everyone knows It’s me and my arrow
And in the morning when I wake up She may be gone, I don’t know And if we make up just to break up I’ll carry on, oh yes I will
Me and my arrow, Do-do-loo-do, do-do do-do do do Straighter than narrow Wherever we go, everyone knows It’s me and my arrow
Me and my arrow (5X)
\->
Even though \ has been thrown out because of problems with some encodings (turns up as a yen symbol sometimes), I still think it should be considered. Possibly one of two ways to do it?
I guess I’ve grown too fond of
in Haskell.
<|:{
OK, what was the problem we were trying to solve with this new syntax again?
Oh, yeah, it’s so we can give default values to block params. Something I don’t think I’ve ever really needed…. (something I have needed, though, is to be able to give a block-scoped variable an initial value so that… oh, forget about that)
I’m hoping this doesn’t mean that the old ’|var|’ thing isn’t going away… So would this still be valid: collection.each {|item| puts item } ?
If not, I’m really going to miss it. And I’m really not going to be happy. I really hope this is being proposed as an alternative syntax, not a replacement for the current one. I really, really hope… What’s Matz’s number so I can call him on the plane?
MenTaLguY
I vote arrow, myself.
rynok
Or maybe I’m just so accustomed to it…
MenTaLguY
And yes, I would be truly sad to see the demise of goalposts, if it came to that.
JB
I agree mostly with <|:{. I really like the current “collection.each {|item| puts item }” style. Along with the ”|var| do” blocks.
Of the three new styles mentioned here, I think I prefer the colon approach. It is probably me overreacting, but → is a bit awkward and speed robbing.
Dan
Wow, matz wasn’t kidding when he said he wants to maximize breakage before 2.0. This affects every thing in ruby I’ve ever done. Unless I am reading this the wrong way, and we are keeping—
object.method { |item| ... }
Which I think is the case here…
<|:{
If the goalposts are going, I can see the headlines now: REVOLT at RUBYCONF !
Save the goalposts! Default block params just aren’t worth it.
{|..|}
Please Help! I’m endangered!
<|:{
Now that a syntactic face has been put on this impending tragedy ‘{|..|}’ maybe Matz will have mercy. How could he eliminate this cute little fellow:
{|..|}
Now we just need to give him a name.
Dan
Oh god, just fix the parser instead of tearing up the syntax, please!
Danno
DEATH TO DOTS AND ARROWS !
GOALPOSTS FOR LIFE !
grammarian
I trust Matz will duly take into account the potential havoc his decision might wreak on the Poignant Guide.
To wit:
<|:{
The beauty of that passage from the PoignantGuide would be mared by dots and arrows. Perhaps it would have to be changed to read something like:
No, that just doesn’t work. The arrow operator is just too violent and reminicent of that barbaric language C.
Trejkaz
What’s the point of this? To make it easier for the computer to parse and harder for the human to parse? I could have sworn that the readability was half the point of using Ruby in the first place.
MenTaLguY
{|..|}
looks rather like the Prince from Katamari Damacy, minus antenna.forever {|..|}
Aha! I found the “reason.”
Albert
Perhaps this is extreme but why not get rid of bitwise or. I don’t think it’s used often enough to justify its own symbol, and we could just use
bitor
(or something equivalent) to do the same thing.Trejkaz
Or, why not just make the parser say that the first
|
is the end of the block parameters, period… if you want to use bitwise or inside a default parameter (which is pretty bloody unlikely, IMO ) you can put it in(
..)
.<|:{
Albert: No, we should not get rid of bitwise OR. I would suggest that this whole idea of needing to create a mechanism for default arguments to blocks is a solution in search of a problem. I think the whole idea should be dropped because it is of such limited use. Sure it might come in handy in some very special cases that might crop up less than 1% of the of the time – why mess up Ruby’s syntax just for such a small gain? In my five years of Ruby programming I can think of one time where I said, “Gee, it would be nice to have default arguments to blocks” – and then I worked around it (not very hard to do). Better to have some inconvenience for that very special case than to make this kind of change that inconveniences a lot of people and totally breaks current code.
<|:{
This seems like the ‘correct’ syntax for default block arguments. It looks great. But yacc doesn’t like it apparently. Should yacc dictate our language design? I say NO!
If we can’t have something nice and intuitive like:
then we should either: 1) wait for a better yacc that could handle it (probably not possible) 2)find another parser generator for Ruby (ANTLR?) or perhaps even have the Ruby parser written in Ruby (that would have lots of advantages – though a disadvantage could be slowness.)
Actually, come to think of it, why can’t yacc handle:?
We all know Matz is brilliant, but maybe yacc isn’t his thing. Any yacc experts out there who can help us out? I’d hate to see Ruby’s syntax get messed up because of yacc limitations (or perceived limitations)... come to think of it, it probably isn’t possible in yacc because of the bitwise OR thing. Would it be too require that bitwise OR not be allowed between the goalposts? They aren’t allowed now, so what’s the big deal? Or, we could say that you have to use ‘or’ not ’|’. Or if you insist on using a bitwise OR between the goalposts you’ve gotta enclose the whole experession in ‘(..)’. Doesn’t seem like much to ask.
Or what if an alternate syntax were allowed:
...Ah, but now they’ve got me playing their game. I say we just say NO.
Trejkaz
To explain why they’re looking at default parameters in blocks, suppose you want to dynamically define a method (such as what all that metaprogramming jazz does.) A nice, sensible way to do that is to pass the method logic as a block.
Now, what do suppose you would do if the method you wanted to define had default values for some parameters?
But I agree that if YACC is really the problem here, then off with its head. Isn’t the Perl parser/lexer written in Perl? Maybe that was an urban legend… ;-)
Andrew
IMO , lambda { |foo = bar| puts foo } is by far the best.
If yacc truly can’t handle it, than maybe an alternative to yacc needs to be found.
crzwdjk
The arrows they’re just stealing from perl. And in perl they do like kind of nice:
or
or even
From the perspective of someone who doesn’t live and breathe ruby, the arrow visually puts the parameter list between the block-caller and the block, which is where it belongs semantically. Plus this way blocks looks visually more like functions.
Ezra
There was a big duscussion about this stuff on ruby-talk back in August. Matz said the {|..|} would never go away. And I quote:
|I think one of the first things that attracted me to ruby is the {| |x|...} syntax. So please leave my happy little blocks alone. Or at |least leave them as an option.
Don’t worry. The block syntax will not be changed. Never.
_why cult follower
I say we all learn Python. Just to see how hell really looks like.
Tsela
So if we are going to have a new syntax for blocks with default argument values (and we are going to, despite what the opponents might have liked), let’s have a nice one at least. It may not be used often (thank God!), but at least one’s eyes won’t jump out of their sockets if they come across code using it. And the current syntax stays, so nobody has to change their habits if they don’t want to.
BTW , I am Christophe Grandsire, the one that proposed the colon syntax. I just want to make clear that I have no big attachment to this subject. I just want every feature of Ruby’s syntax to fit in the whole, even if this is a controversial one. And that arrow just jumps out and bites your nose. At least there are precedents in Ruby for the use of the colon, so it doesn’t hurt as much.
Anyway, the important thing at least is this: Do not worry: {|..|} is not going away! The new syntax is just an alternative syntax (with one additional feature), not a replacement of the current one.
->(i){i.love.arrows}
Hug and Kisses lads. Me thinks, I’ve been struck by Cupids Arrow.
I love arrows.
zimbatm
Thomas
Why not just use := for assignment of defaults in blocks, eg
lambda { |foo := ‘bar’| puts foo }
It reminds me of good ol’ Pascal.
hgs
I really don’t want \ because escaping things is already done with \ so it crops up everywhere in the regexp %Q(world). [Without looking it up, what’s the gsub expression for substituting \\ for \ again?] Even !^ would be better: a kit of parts to make a lambda.
Maybe if block, lambda and proc are so subtle in their difference we should just have a block keyword and do:
Dan
Can anyone give a good example of when a block needs a default value? The example given in the article,
1.times -> (foo="bar") { puts foo }
, is not that great (just doputs "bar"
!. Same with #each—when the hell would “bar” be printed?Tsela
{|foo:=(a|b)| puts foo}
possible. Yacc doesn’t seem to be able to handle that.Dan: when you want to create a method with
define_method
and a block, the block arguments become the method arguments. What if you want to create a method with default argument values? You can’t right now. Another possibility I can think of (but it may be a bit contrived) is a hash where some values arenil
, and you want to loop through it with allnil
’s replaced by some valid value. And then there’s registering callbacks, where it may be of some use (I’m out on a limb here, having just begun to toy with Ruby-Gnome :) ).sporkmonger
Groovy had this exact same problem. This is what they used:
If we’re going to insist on default parameters within blocks, I think everything should stay within the braces.
sporkmonger
A question:
Would yacc complain if we demanded that all default parameters within block be surrounded by parens?
For example:
and
JES
“Should yacc dictate our language design? I say NO!”
Couldn’t agree more. Computers are slaves – we are masters. That being said, we still live in the real world. Is YACC patchable?
xml-blog.com
Not that I’m qualified as a language designer, but how about:
{|foo ~ bar| puts foo}
jvoorhis
Now that I’ve seen that Groovy example, I’m wondering why the chute was ever necessary. A wall would have worked fine.
{ x, y | x * y }
Not that it much matters at this point :)
brasilian_guy
riffraff
people may ignore this, but yacc already dictated our language. the reason Why ruby does not have if a > b > c meaning if(b <a>c) is that yacc is not able to parse it. Come one ANTLR guys, let’s remove the ugly parse.y!
riffraff
batkins
It seems like part of the rationale behind this is that default values for block variables would let define_method do everything a def can.
def x( a, b = 332332, * c )
would be identical to
define_method :x do |a, b = 332332, *c |
That said, I think the arrow syntax is way ugly, and is a lose.
But is it really YACC ’s fault that bitwise-OR’s inside goalposts cause problems? That seems like a difficult situation to resolve no matter what parsing software you’re using.
And, whoa, ANTLR is not the answer. Why make the entire muckiness of Java a requirement for building Ruby?
<|:{
Oh, yeah, ANTLR is written in Java now instead of C++.
jvoorhis
brasilian_guy:
The point wasn’t to attack the problem, it was just a thought I had on the block syntax. Also, what I was thinking was that the pipe character would only be there if there were parameters, otherwise no pipes.
I’ve never played with YACC although I would like to. Maybe RACC would be a fun place to start.
tt
Parsers can also be written in OCaml (cf. cil.sf.net or nekovm.org).
Deirdre
“Drop-kick me Jesus through the goalposts of life, end over end through them righteous uprights.”
I envy anyone with serious YACC -fu, but I am not among them.
I’m with JB. I like the current syntax. Of the alternates, I dislike them nearly equally, but have a slight preference for the arrow and the colon (in that order).
meig
How about adding a colon to the last pipe symbol? lineofcode = ‘a.each {|c=(b|d)|: puts c}’; puts m = (/(?:[ |\{])(\|.*?\|:)/).match(lineofcode)
joesb
It’s pity that, while the groups of developer can solve all the problem in implementing Ruby, e.g., Thread, Continuation, Porting ruby to many platform , uses of YAML ; we just can’t get the syntax we want simply because Yacc doesn’t allow it.
kim
If someone wants to check out a LexerInRuby go to www.rubygarden.org/ruby?RubyOnlineCookbook. Another text scanning tool is www.rubyhacker.com/code/scanf/ (a C tool which may be optimized by cil.sf.net).
sporkmonger
Incidentally, jvoorhis, Groovy used to have just the single goalpost before they discovered the bitwise-or problem. Identical syntax to what you were just saying.
Curious, how would Matz’s current syntax plan look with do..end blocks?
If so, that just made me hate the idea even more I think.
meig
Another option to get the parser reach the last pipe symbol would be to add a colon to bitwise-or: ”|:” (instead of adding a colon to the last pipe symbol). Each of the two enclosing ”|” must then be followed by a [^:] in the regexp.
lisp_guy
John McCarthy figured out the solution back in 1958: get rid of syntax completely.
Lisp forever!
Ben
Isn’t there a formal BNF for Ruby anywhere? If so, then switching to ANTLER shouldn’t be too difficult.
If not, then I suggest making one before starting to hack like this. I think this problem can be solved by making a BNF : (note: I don;t know BNF very well so this is probably not correct!!)
Hopefully this is valid…I think the problem with the ’->’ vs ’:’ vs ’.’ syntaxes is they don’t give you any context about what they are supposed to do. Why not use proc or function or def instead?
Cheers, Ben
Comments are closed for this entry.