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

I'd also add that rubys confusion about what a function is is the thing that's been annoying me the most lately. You have procs, lambdas, blocks, and all with subtle differences (http://awaxman11.github.io/blog/2013/08/05/what-is-the-diffe...), and all I want are simple funcs as first class citizens that have consistent behavior. (TCO as a default would also be nice).

"And finally, pie in the sky, can we solve packaging apps up into distributable binaries, please? Rust and Go are making us look bad."

As a ruby programmer the lack of any reasonable - i.e. not hacky - way to build binaries is annoying. Unless you're building a server side app, you can pretty much forget using ruby because of this. Maybe that's all ruby cares about, its certainly its niche but I like ruby and would like to be able to use it for cli programs, etc. Personally, I don't want end users of my code to have to install ruby, learn about ruby gems and boot the ruby vm before having to run a cli program.



Without some difference between functions and blocks, patterns like

  foo.each do |x|
    return if x == 3
  end
Don't "return" out of the enclosing function.


That seems okay to me. JavaScript works well enough with that behavior.



Works well meaning don't use functional calls at all if you want to escape from them.


I've just never encountered that use case in Ruby code, and to me it feels like really bad style. You can use .find to find the first element that matches a block, then return that item (if one exists).


It doesn't look like fantastic Ruby code, you're right. I just wouldn't agree that JS "works well" when it comes to their somewhat afterthought functional iterators.


What doesn't work well? The only thing I can think of, which comes up on occasion, is that you can't manually stop iteration in forEach without ugly tricks like throwing and catching an exception. I actually wanted that behavior for the first time recently, so I just used JQuery's each which lets you stop iteration by returning false. I'm assuming other JS utility libraries like underscore provide something similar.


Javascript iteration primitive isn't block-based.


Ruby iteration primitive isn’t block based, either.


Of course it is. `for a in b` desugars to `b#each`, not the other way around.


How do “while” and “until” desugar? Kernel#loop?


Those are two rare exceptions and you're right they don't desugar.


Those are not “exceptions” to Ruby’s primitives, those are Ruby’s primitives. Things that desugar to methods aren’t primitives.

The thing is, they’re rare in practice for cultural reasons.


RE binaries, compilability seems difficult due to how dynamic method calls are, but Rubymotion seems to have solved that to some extent, though it's a shame it requires a subscription to even develop on which doesnt appeal.

What are the "hacky" methods currently used for packaging you mentioned? The only methods I'm aware of no longer work or still require a separate runtime.


Producing a self-sufficient binary doesn't have to mean compiling the code; py2exe is a good example.


I know this is in the vein of hacky solutions, but I tend to use jruby for the purpose of packaging up ruby applications.


This is a good solution. I've used this approach as well for server daemons.


Do you still require the JVM installed in the same way you would the Ruby's VM?


JRuby's ruby VM runs on top of whatever JVM you choose. You just have to make sure you have the JVM in your path.


Ruby's proc block mess really irritates me too, especially when I flip from JS back to Ruby. I just cannot understand why the notion of a block as a distinct entity needs to exist, other than some weird syntactic side effects of Ruby's paren-less method calling.


Here's the reason, it's because of how iteration works in Ruby with "everything is an expression" semantics: http://lucumr.pocoo.org/2012/10/18/such-a-little-thing/

In Ruby iteration is implemented by letting something call a block repeatedly until the end of the iteration. The interpreter provides jump points in order to implement skipping or breaking the iteration. A continue is implemented as a form of jumping to the end of the block, a break is implemented by jumping past the call to the iterator function. Without the return it would be very awkward to return something from the function.Imagine a function that returns the first even item from a list:

    >> def find_even iterable
    >>  iterable.each { |x| return x if x % 2 == 0 }
    >> end
    => nil
    >> find_even [1, 3, 5, 6]
    => 6
Imagine the non-local return was not available, you would have to rewrite it like this:

    >> def find_even iterable
    >>  done = false
    >>  rv = nil
    >>  iterable.each { |x|
    >>   if x % 2 == 0
    >>    done = true
    >>    rv = x
    >>    break
    >>   end
    >>  }
    >>  rv
    >> end
*


Because it is so convenient to be able to return from the outer scope.


I can't recall any occasional where I have done that.


I wish Ruby had better support for functions, passing it to a method incurs a 400% performance penalty: https://www.omniref.com/ruby/2.2.0/symbols/Proc/yield#annota...


Completely agree on the distributable binaries! You couldn't express it better. This is holding Ruby much behind of where it could be!


For first class citizen functions, you want lambdas. Lambdas are a type of Proc but trap the return statement.

Blocks are pretty much an iteration construct.

It's really not that confusing.




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

Search: