var answer = if number == 42
The language looks shockingly pleasant in a number of ways, but everything being an expression seems odd. Would somebody mind helping me understand the value (semantic, performance, etc.) of such a choice? var answer = if number == 42
The language looks shockingly pleasant in a number of ways, but everything being an expression seems odd. Would somebody mind helping me understand the value (semantic, performance, etc.) of such a choice? doSomeThing() unless person.present
For me that utterly destroys readability - in my mind, when I see a (), that function is being called there and then. The fact that you can invalidate that later in the line confuses me deeply - and it doesn't really provide any benefits above an if statement anyway.The rest of CoffeeScript is great though, don't get me wrong. (though ES6 JavaScript has taken the best features anyway)
something() if False else y
The `something` function is never called.It fits the style of Ruby to try and cut down on syntax noise where it's not needed. Contrast:
save! if !record.persisted? && !record.invalid?
save! unless record.persisted? || record.invalid?
Though I do appreciate it's a bit unusual compared with most other languages – CoffeeScript does owe a lot to Ruby's syntax. if !record.persisted? && !record.invalid?
save!
or: unless record.persisted? || record.invalid?
save!Another way to look at it is why do you think the conditional should come before like you've shown? Because C or even older languages started with that? If you didn't have prior experience with that form, would you still think it's inherently better, or would the trade-offs between the two forms seem slightly more balanced?
The same applies to while/until loops, which can lead to quite succinct code.
I've been using it for a long time, so I don't find it confusing at all – but I agree it's pretty rare to find, so I'm not surprised to find out some people would rather not see that!
For example, they work really well in loop control statements:
for my $i (1 .. 100) {
next if $i == 10;
next if skippable($i);
last if is_what_we_want($i);
# Do stuff here
}
Or more complex param validation sub foo( $arg1, $arg2 ) {
return unless $arg1 > 10;
die "Invalid argument arg2!" unless defined $arg2 and $arg2 =~ /^(?:CAT|DOG|GERBIL)$/;
# Do something
}
That said, I don't like it for assignment of in that manner (at least where the assigned value comes out of the if), because the main justification for allowing it (it's a natural extension of how we think) doesn't follow. A ternary operator is better in that instance, IMHO.A major semantic benefit of expression-oriented programming is minimizing state while maximizing composition (e.g. compare and contrast a switch statement to pattern matching).
It's aligned with a general approach of reducing syntax noise, and it can result in some really nice, clean code. It leads to a whole class of syntax possibilities, like implicit returns.
There are probably some performance arguments against this in the case of Coffeescript, especially wrt constructing expensive return values that are immediately discarded. The consistency is nice, however.
$v = 1 if $v < 1;
return unless defined $param;
die "died!" unless $param > 10;
But you cannot: $v = if $v;
You also cannot use else on postconditionals (if it's that complex, you need a traditional if statement). x = (:false if true)
=> :false
x = (:false if false)
=> nil
Any other if statement does appear to be treated as a value: x = if true then 5 else 10 end
=> 5 my $x = 1;
$x = 10 if $x > 1;
say $x; # 1
Personally I find the assignment of the if/else statement's return value distasteful, as it's both complex to read and mixes a portion of a natural pattern of thinking while later abandoning it, making it unintuitive. At that level, I prefer a ternary operator.EDIT: of course, there's Smalltalk, where postfix conditionals and loops are the only form available. Maybe Ruby got inspired by those.