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

Apples and oranges. Ruby is very, very expressive compared to Go. Go's legibility comes from the simplicity of its syntax, Ruby's legibility comes from its expressive syntax.


Can you give either an example or explanation of what you mean by expressive syntax? People talk about it but I don't really know what they mean.


Ruby was one of my first languages and for awhile I described it as 'programming in english' especially Rails with the ActiveSupport gem. I often just fired up IRB (the repl) and guessed what function names I could use on a given object and it worked. I think this is why a lot of DSLs ended up in Ruby (chef, etc) plus the method_missing idiom allowed for a lot of this sort of expressivity at the expense of sometimes being thoroughly confused as to where a method was defined.

Overall I ended up writing more performance oriented applications and ruby (at least at the time) wasn't worth the 'it's pleasant to read and write' vs 'this ruby script that used to take a day now takes 15mins written in a language more suited for the task'. The other language I'd consider less expressive just in a less optimized-for-the-human-while-writing kind of way.

Crystal seemed nice in the respect that it might be the best of both worlds, but like mentioned elsewhere here it's still fairly niche.


I looked at the activesupport gem and I think maybe the things we call general purpose languages are actually just really broad domain specific languages. From the gem description "Rich support for multibyte strings, internationalization, time zones, and testing.". I do testing, and occasionally I have a string, but mostly I only do numeric programming, I don't think of that as a niche. Fortran was/is for numeric programming I think of numeric programming as the default normal sort of programming. That probably isn't so much the case anymore, but we probably all think of our domain as the normal one. So expressiveness is probably highly relative to the domain. Julia seems very expressive to me. So do rust and modern c++. But I don't do much string handling, and I don't really even know what internationalization means.


Ruby's extreme expressiveness comes from a few things. First, everything is an object. Second, Ruby has lots of functional features that make it exceptionally concise to express certain things.

Here's a simple example I'll do in JavaScript first since most people can read it. You have an array of the numbers 1 through 10 and want to get a new array with only the odd numbers.

  arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  arr.filter(num => num % 2)

  > [1, 3, 5, 7, 9]
In Ruby you could express this the same way:

  arr.filter { |num| num % 2 }
  
  => [1, 3, 5, 7, 9]
But there's a better way. Since everything is an object, including integers, you can just ask the numbers if they are odd instead of using the mod operator.

  arr.filter { |num| num.odd? }
  
  => [1, 3, 5, 7, 9]
(Yes, method names can end in a question mark (?). By convention, methods that end in a question mark are predicate methods that return a boolean. Methods can also end in an exclamation point/bang (!). By convention, these bang methods are "dangerous" – they might do something destructive like mutate an object in-place instead of returning a new copy.)

We can make this even more concise though.

  arr.filter(&:odd?) 

  => [1, 3, 5, 7, 9]
There's a bit to unpack here.

:odd? is a Symbol

The & operator calls the #to_proc method on the symbol :odd? then converts the result into a block, which is passed to the filter method. In other words, the #odd? method is called on each element in the array no different than the previous example.

Here's another way to express the exact same thing:

  arr.reject(&:even?) 

  => [1, 3, 5, 7, 9]
This is just one simple example. Ruby can express many things on one line that would take several lines in other languages. This is what makes it expressive – it's the density and readability of operations.

Another one of my favorite language features is that parentheses on method calls are optional, so a lot of syntax that looks like it would be language-level operators are actually just regular method calls to objects in Ruby. An example of this is ==, which is an operator in many other languages. In Ruby it is a method call. Consider this expression:

  true == false
This is calling the #== instance method on the object `true` (which is an instance of TrueClass), passing `false` as the first argument. Written identically:

  true.==(false)
This is wild if you're coming from another language where things like this are operators, but it is completely natural in Ruby. It is extremely powerful.


Clojure says “hold my beer”.




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

Search: