Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

OK, I think we're on the same page regarding our meta-discussion =)

Yes, I absolutely find

  customers.map(&:name)
a win over

  customers.map { |c| c.name }
My reasoning is that the former is less code overall, is fundamentally 'simpler' (passing a parameter to a method rather than calling with a block), and the code it replaces has redundancy (the block parameter is there only to be immediately referenced for the sole purpose of getting at one of the object's attributes). With #try, there's similarly less code overall and it removes redundancy.

I agree that brevity alone is not enough to prefer one idiom over another. Expressiveness is a big part. I like these idioms, so I'm actually in the camp that they do make the code more precise and communicative.

In my book, though, #returning is simply an exception. A simple assignment and return are already so fundamentally expressive on their own, that — to me — replacing them with a method invocation and block doesn't get you more expressiveness, and instead it actually makes things less readable.

To me, it would be like writing an abstraction layer to replace the use of variables in the language, where you have to invoke a special-purpose lookup table class to set and retrieve values. Why would you prefer

  Variable.set(:foo, 'bar')
  puts(Variable.get(:foo))
over

  foo = 'bar'
  puts(foo)
Why not just use variables?


Funny you mention that. If you had your own implementation of variables, you could probably override the behaviour of parameters in the #returning method to get the behavior in the OP without rewriting code.

Naturally the syntax looks a little ugly to the ALGOL-shaped eye, but imagine such a thing written into the language. It would be trivial to permit the ALOGOL-like syntax in the code but also allow you to override the #get and #set methods when you want to.

IIRC, this is exactly what Generalized Variables are in Common Lisp. Variables where you override the meaning of setting and getting their value.

Ruby sorta kinda allows this in a very limited case. While you cannot override the meaning of:

    foo = "foo"
You can create setter method such as:

    class MyStack
      
      # ...

      def top
        @array[-1]
      end

      def top=(value)
        @array[-1] = value
      end

    end
Thus, stack.top and stack.top = "foo" can do whatever you want.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: