38 comments

[ 2.6 ms ] story [ 86.5 ms ] thread
A better example IMO is...

Before:

  result = case value
    when 5
      ...
    when 4
      ...
    end
After:

  case value
  when 5
    ...
  when 4
    ...
  end => result
The latter allows for some nicer formatting I think.
At the expense of increasing the complexity to read code.
How is the complexity increased?
As you read through code you can come across a huge switch and not know why until you look to the end. Now you’re reading bottom-up, which is just as unnatural as right-to-left for english speakers.

Not necessarily more complex, but not less complex either IMO. I often say complexity can’t be eliminated, only spread around differently; I think we’re seeing that here.

I think it would be possible to think of this in terms of complexity theory, for N case statements to you would possibly have to check 2N locations for assignment. I wonder if you could do parallel assignment: var1 = case = var2
Because now there are 2 ways to do the same thing with little obvious benefit other than syntactic bikeshedding.

2 ways to do something is more complex than 1.

But it's more than just the syntax of the code. It now means new lint rules, new coding standards in projects (some will allow => assignment, some will encourage conformity to legacy code, and others will disallow it entirely). There will be new Rubocop rules and other editor configs to update for proper syntax highlighting.

Syntactic changes like this with little obvious benefit need to be looked at skeptically. Just because something can be done, doesn't mean it should be.

It's actually very simple to illustrate. Say this 5 => x in english. (three words or less)

Or this one

cat => person.pet

I’m a fan.

In my limited experience, leftward assignment breaks the “flow” explaining a program to a novice.

(comment deleted)
The problem is.. most popular languages use leftward assignment. Teaching a noob this would make other languages harder to read. I can switch from Java, to c++ to ruby.. My 9 year old figured out the leftward assignment. It feels like a change for change sake.
To me this seems like a clear loss. The syntax is (as far as I can tell) strictly more verbose than the existing assignment syntax. Ruby is already plagued by a million-and-one ways to do everything, but at least in other cases simplicity (à la zen of Python) trades off for brevity.
I don't even care about the verbosity - it's just ugly syntax. If I'm skimming a file that uses that syntax, I could easily get confused and think there's a comparison going on. One of Ruby's big draws (to me, at least) is code that is incredibly expressive and code that is aesthetically pleasing to look at. I feel this is serving the expressiveness at huge cost to aesthetics, and honestly there's not much gain to expressiveness in my opinion.

EDIT: I also completely forgot about the existing hashrocket syntax for maps.

I don't particularly like the idea of rightward assignment (although the syntax itself seems fine to me), but the "million-and-one ways to do everything" is the biggest reason I strongly prefer the language over more "constrained/limited" languages like Python. In those terms, this seems like a definite win for the language (and those who choose to use it) for me.
For simple one-line expressions, this doesn't seem to offer much. However, looking at multiline statements with FP-style or conditional logic, this can definitely improve the flow and visual rhythm of the code.
Rightward assignment with a hash rocket?

I've been using ruby for a decade and I don't get why this is necessary (or even good).

I’d rather have changes to type safety, performance, or even a compiled binary. Or a merger between crystal and interpreted mode
Does sort of make a hash in Ruby more confusing to the untrained eye (unless the hash rocket is totally dead, I haven't written Ruby since like the 2.3 days):

{ "age" => age, "name" => name }

I like the idea a lot. It'd probably allow for some nice functional looking code, but that's also the problem... it'd only look functional. And I think without VM/compiler/runtime support of functional programming it's pretty much a big waste of time.

I can use piece shit for a shoehorn; doesn't mean I should.

No, the hash rocket still exists. However, if you use symbols as keys, you can replace ":foo => bar" with "foo: bar". Many people, of course, use hashes with symbols as keys, but whenever you don't, you still need to use the hashrocket syntax.
I get why you'd want it, but I'm not sure they should be reusing => for it, since that already means something in Ruby.
Yeah, I also start getting confused by reusing of the syntax. Now there's also a proposal to use { 1, 2, 3 } to represent sets - but {} is already used for blocks of code and for maps, so now that will be essentially a 3rd use case for curly braces.

On the other hand Ruby has already such a extensive syntax that it's hard to come up with something else that would not already be taken. -> represents lambda, >> is a valid method name, etc.

Could this be an initial step towards elixir-like chaining?

"foobar" => upcase() => x

Doesn't this introduce an ambiguity?

    def foo(*arg, **kwarg)
      puts "#{arg}/#{kwarg}"
    end
    b = 'meh'
    foo(:a => b)
Now this produces

    []/{:a=>"meh"}
But with right-assign

    [:a]/{}

?
Oh. The bugs that this would produce. And spotting it visually would be killer
Is there a place we can voice our concerns over this move.

I was just teaching Ruby to someone learning to code. I have to admit because all popular languages use leftward assignment it was one less thing to teach.

=> is pretty loaded as it is

Agreed. And it doesn't really improve anything. The argument that it makes code easier to read is bogus. Perhaps for people who only work in ruby. I suspect rubo-cop would have a rule against this a week after it was added.
Why do most languages use right-to-left assignments? Is it purely a matter of path dependence? I guess also that binding a value to a name usually indicates that you'll use the name later on, and having the name on the LHS makes for a better UI for looking up the value the name is bound to.

On an unrelated side note, I've always thought "=" was a huge mistake in language design, confusing countless people who are coming into programming who reasonably mistake it for equality. I don't know why it won over ALGOL-style ":=".

> On an unrelated side note, I've always thought "=" was a huge mistake in language design, confusing countless people who are coming into programming who reasonably mistake it for equality. I don't know why it won over ALGOL-style ":=".

Probably because adding a colon to an equality sign doesn’t clarify the meaning at all.

Had Algol (as some less widely influential for other reasons languages have) adopted something that more clearly represented movement into the variable being assigned like:

  a <- 25
Maybe it would have won out over “=" for assignment.
I considered such an assignment operator for a little language I was developing, but there was an ambiguity between this:

  a <- 25
and this:

  a < -25
Since everything was an expression in the language, the latter would evaluate to a boolean. In the end I just went with "=" for assignment, and "==" for equality.
"=" is still equality. It's not an operator that compares two values. It's an operator that defines the left hand to be equal to the right hand. I feel like "=" for assignment is fine. For boolean comparison something like "=?" seems most clear, like asking a question whether the left and right hand side are equal.
In imperative languages, assignment has a side effect of making the LHS equal to the RHS. But it's still different from equality, since variables can be reassigned

E.g.

    a = 2
    a = 3
    2 = 3 //what???
Assignment is fundamentally part of the language execution model, which is entirely apart from anything related to mathematical equality. Even in languages where you can't rebind a variable name, it's still weird to use = as assignment, since it would have such different behavior than seemingly analogous operators like > and <.
This is so ugly. Already we have things like AND vs && or tailing if's that don't quite work like three line if's or how scoping do..end vs {} is ever so slightly different.

I'd wonder how the right assignment would work differently. What small gotcha would it create.

I also wonder how my co-workers would take it, if I started using it.. Or if I figured out how it was different and used it for the once case that it worked.

For me. having a million ways to do something leads to slower dev time. More context I'd need to load.

why is this even needed? why introduce something to fix something that isn't a problem?