From: Stefan Kaes Date: 2005-11-22T14:37:21+09:00 Subject: Re: semenatics of if/unless/while statement modifiers Yukihiro Matsumoto wrote: >Hi, > >In message "Re: semenatics of if/unless/while statement modifiers" > on Tue, 22 Nov 2005 09:54:46 +0900, Stefan Kaes writes: > >|So this behaviour is caused by intermingling parsing with semantic >|analysis. Much like forward procedure declarations were required for old >|Pascal compilers. > >I believe it's a strict application of the "local variables should be >assigned first" rule. Not a compromise for the compiler. > > It is definitely a compiler issue. Just like the recent discussion of the syntax for block parameters is only a compiler issue. In both forms, the v=expr gets evaluated first. So during evaluation, the assignment v=expr is always seen first, which means to me, a local variable gets created and assigned in the current binding. Any decent formal semantics writer would like to treat both forms identically too, simply by stating that "expr1 if expr2" is equivalent to "if expr2 then expr1" end. If the resolution of local variable assignment vs. function call were implemented as a second pass on the abstract syntax tree or using some form of back patching, there would be no difference between the 2 forms to begin with. Ruby is not the only language with implicit declaration of variables through local variable bindings. If you're looking at modern functional languages, you will find 2 different constructs for introducing variable bindings: LET v = expr IN expr and expr WHERE v = expr Of course, both have exactly the same meaning. If you maintain that reading direction dominates semantics issues, you'd need to rule out the second version. Tell that to some mathematician. I would like to hear about his reaction ;-) >|I hope this will be changed for Ruby 2.0, as it's an ugly wart on an >|otherwise very clean lanuage. > >I think it's not, where "not" means "not ugly". > When I read a statement, I usually think of its semantics, not its syntax. So at least for me, it's very unnatural that both forms differ. I find it rather inelegant to be forced into writing if x = options[:x] f(x) end or even f(options[:x]) if options[:x] instead of f(x) if x=options[:x] The Rails source code is literally messed up with the second variant, which is potentially slower too. I definitely would like to get this behavior changed for 2.0 -- stefan PS: I know the implementation is a little more difficult than the current one. But it can be done, so clearly, it is a compiler issue.