
From Ruby to Crystal: A Quick Look - sdogruyol
https://spin.atomicobject.com/2017/03/24/ruby-to-crystal-test/
======
deedubaya
Crystal could be a really powerful tool for enhancing existing Ruby code.

Imagine a world where you write your code in Ruby, but farm out the expensive
operations to a Ruby-like Crystal extension (similar to what is commonly done
with C or Rust). I think this is possible already (just after a quick Google
search[1]), just not friendly for the average Ruby dev to implement.

[1] [https://www.slideshare.net/AnnaKazakova/how-to-write-ruby-
ex...](https://www.slideshare.net/AnnaKazakova/how-to-write-ruby-extensions-
with-crystal)

~~~
prh8
This is definitely possible-- I've done even more than basic PoC (Anna's slide
deck was one of my starting points in fact).

[https://github.com/phoffer/crystalized_ruby](https://github.com/phoffer/crystalized_ruby)

~~~
deedubaya
This is great, thanks. It seems that it is incomplete, though. What can the
community do to support further development?

------
neovintage
Outside of speed benefits as compared to ruby, one of the main things going
for crystal is it's ability to use all of the robust tooling that already
exists. This post mentions it in passing but Crystal gets the benefit of all
the existing tooling without having to build it as part of delivering the
language to developers. I think that's a huge win. I also think this is one
reason why Crystal has grown fairly quickly. This could largely but due to the
fact that it's built upon LLVM. Regardless, the community and documentation is
pretty awesome. I can't wait to see what happens for the 1.0 release.

~~~
xtracto
Can you be more specific on what you mean about "existing tooling"?. I work in
a Ruby shop and am very curious to try Crystal.

------
nurettin
Great writeup for the folks who are curious but lack the time to test Crystal.

------
mnarayan01
My biggest takeaway from reading this is that Crystal is _much_ more divergent
from Ruby than I expected.

~~~
vidarh
I'm confused by why there's so many small things that appears to be pointless
differences. E.g. "property" vs "atter_accessor". It'd seem that ease of
converting Ruby code is the major selling point, and especially with things
like TruffleRuby + Substrate, it seems like it's about to face more serious
competition that _doesn 't_ depend on rewriting your code nearly as much.

~~~
RX14
The idea behind crystal is not to make a faster ruby, but to make a rethought
ruby for the modern age: compiled, statically typed and removed of warts.

Crystal should feel familiar to ruby developers in it's syntax and stdlib, but
we have absolutely no problems with throwing away ruby's ideas when they are
deemed substandard.

Crystal doesn't aim to draw in as many ruby developers as possible, it aims to
create the best programming language possible. It just happens to have ruby as
a conceptual starting point.

~~~
cookiecaper
It seems like Ruby is a bit of a small community to target with this type of
thing. Wouldn't Ruby developers be better served by moving on to one of the
several other idealistic languages in widespread usage right now? TypeScript
is getting good reviews and Python is great.

I know it seems harsh, but when I hear people talk about the "beauty" or
"elegance" of Ruby, I just think of someone who started coding in the
2005-2009 era and started out with RoR, which was frequently presented as "the
Mac of programming languages" around that time (and this description alone
should give serious people pause).

These people got into the scene too late to remember trying to hack Perl,
Ruby's own spiritual predecessor, and the pseudo-joke that it was a "write-
only language". The two relics that remain from widespread Perl usage are
regular expressions and Ruby.

Meanwhile, several other languages that are similar to Ruby in age and/or
style have active communities and enjoy an increasing trend of innovation and
market penetration. Even languages like Groovy, which have failed to gain a
large independent following, continue to benefit from both technical and
communal innovation on their underlying runtime platforms.

I don't think I've met many people who looked at Ruby in a time when the hype
train wasn't going full steam ahead and came away with the evaluation that it
was "elegant" or "beautiful". In fact, many reformed "Rubyists" whom I know
are switching to other platforms, and RoR jobs are getting increasingly scarce
(supplanted by the next large-scale server-side fad, node.js). Not many people
seem to be using Ruby for new projects anymore.

Could you elaborate on why you chose Ruby as a reference point?

~~~
vidarh
> I know it seems harsh, but when I hear people talk about the "beauty" or
> "elegance" of Ruby, I just think of someone who started coding in the
> 2005-2009 era and started out with RoR

I started programming in 1981, I detest Rails, and I picked Ruby for its
beauty and elegance. I'm a language geek first and foremost; the syntax and
presentation of a language is extremely important for my happiness when
working with it, and nothing has so far gotten close to Ruby in that respect,
and I've worked in more languages than most developers can name.

TypeScript and Python both looks awful to me. Neither are languages I'll work
in given a choice. I don't think you'll find many Rubyists who'd consider them
viable alternatives - those who have evaluated both and come down on the Ruby
side tends to have strong opinions on the matter in my experience.

> In fact, many reformed "Rubyists" whom I know are switching to other
> platforms, and RoR jobs are getting increasingly scarce (supplanted by the
> next large-scale server-side fad, node.js). Not many people seem to be using
> Ruby for new projects anymore.

My experience is the exact opposite. It's easier than ever for me to find work
doing Ruby _even while avoiding Rails_. I'm too expensive to do Rails even I
liked it. Yet I regularly find devops consulting gigs and the like where
people are happy to find someone with Ruby skills.

If RoR jobs are indeed getting scarce, I suspect that's more an effect of the
number of Ruby developers reaching the kind of saturation that PHP developers
did years ago.

But these things are also highly dependent on _where you look_. I rarely come
across people asking for node.js for example. Presumably because my network is
tilted towards Rubyists.

~~~
cookiecaper
Can you discuss some of the linguistic edges that you find in Ruby?
Personally, I don't understand the attraction. It would help if you could
articulate. I've always struggled to see the real merit that Ruby brought to
the table.

Usually such explanations are things like "Look at all the esoteric symbols I
can pack together to accomplish something on two lines, instead of the
readable way that would've used six lines!" IMO, it's better to use a few
extra bytes for line breaks, or for explicit wrapping of things like method
arguments, and have your code more accessible.

Unless you're engaging in the above-referenced symbolic soup, Python and Ruby
code usually end up looking pretty similar. I don't know how you can say that
one "looks awful" v. the other.

~~~
vidarh
> Can you discuss some of the linguistic edges that you find in Ruby?

Ruby is close to Smalltalk, but with an Algol-family syntax that goes to
painstaking lengths to make visual clutter optional while being familiar.

There's nothing really new in Ruby in terms of semantics. What Ruby did was
fuse a number of language concepts into something that _reads well_. _Syntax_
is the primary linguistic edge of Ruby.

We get the dynamism of Smalltak, in a more familiar packaging, that then goes
to extremes to try to let you strip out ceremony.

This to me contributes to compact but _readable_ code. Outside of golfing, the
Ruby community values readability very highly, and syntax is a big part of
that.

A typical example is the block sytax, which seems trivial on the surface,
given that it is just a very thin veneer over the lambda syntax. To give a
(very) contrived example:

Ruby's "full length" lambda syntax:

    
    
        def foo l
          print "Hello "
          l.call
        end
    
        foo ->{puts "World"}
    

The block syntax:

    
    
        def bar
          print "Hello "
          yield
        end
    
        bar { puts "World" }
    

The first thing to note is that the full length syntax has become very compact
too, and the difference on the surface looks rather pointless (though it used
to be bigger), but reducing the visual clutter makes the block syntax
acceptable in a lot of circumstances where lambdas would otherwise "look
ugly". E.g. in Ruby there is "timeout", which is a method that takes a number
of seconds, and a block, letting you write "timeout 5 { call_something }". You
could do implement one with lambda's too, but you'd end up with "timeout 5,->
{ call_something }" at the bare minimum, and in instances where () around the
argument list becomes necessary, you end up with even more clutter, while the
block syntax avoids it.

This probably seems very minor, and in a way it is, but in my experience when
visual clutter disappears people think about code differently and use
constructs more or less sparingly. E.g. you _can_ do most of the semi-
functional stuff you do casually in Ruby in C++ too, but the extra ceremony
and clutter quickly puts people off. Cutting down on the clutter matters.

Another example is the DSL functionality which in Ruby is often done by
defining context classes with methods, or by injecting methods in the meta-
class of the class you're defining.

In particularly defining methods on the meta-class to be executed _during_ the
definition of a class. E.g. as a example from Sequel:

    
    
        class Movie < Sequel::Model
          plugin :validation_helpers
    
          ...
        end
    

"plugin" here is a method on the meta-class of Sequel::Model that pulls in the
relevant methods of the specified plugin by running this code while defining
the class. Being able to basically define a DSL to mutate the class while it
is being defined leads to code where boilerplate very quickly ends up
extracted into libraries in ways that tends to produce a lot of extra clutter
in other languages.

> Unless you're engaging in the above-referenced symbolic soup, Python and
> Ruby code usually end up looking pretty similar. I don't know how you can
> say that one "looks awful" v. the other.

I agree it looks relatively similar, which is exactly why I believe most of
those of us who have chosen Ruby tends to have very strong opinions about why
Ruby works for us. For me the most immediate one is that I refuse to work with
languages where significant indentation levels is a big thing. I both really
want the visual indication, and really hate working with significant
indentation (including things like YAML)

Part of the reason why I feel comfortable making that choice is exactly that
the benefit of picking Python over Ruby to me is slim enough that I can afford
to make that decision over issues that otherwise would be marginal, but that
matters to me.

------
ajamesm
70x faster? If Crystal gets its own port of Ruby on Rails, oh boy.

~~~
vidarh
70x faster, with the caveat that the way that Ruby code is written really does
not lend itself to speed.

E.g. using method calls inside the class instead of accessing instance
variables instantly springs to mind, as does the "unsorted priority queue"
which is basically a horrible abuse of Array but wrapped in a class that makes
it even slower by adding additional method calls for every operation.

That's not to diminish the speedup Crystal gets, because it does illustrate
how slow MRI's method calls are, but it'd be interesting in seeing a
comparison with an astar implementation that was actually written to be fast
in Ruby.

Also would be very interesting to see a comparison with jRuby+Truffle, of
course.

~~~
shawn42
Author of the article here. This implementation of A* was me playing around.
It is definitely not optimized for either Ruby or Crystal It was merely a
chunk of Ruby code that I had lying around. You are right about the unsorted
queue being a hack around Array, but it was part of another experiment of
using a "Fast Stack"[1] for the A* algorithm. It allowed me to swap in other
Queue implementations easily.

The point of the article was merely "How much work does it take to port Ruby
to Crystal" The performance differences were just fun to see, not the intent.

If I get time, maybe I'll run this through jRuby+Truffle as a comparison, that
would be interesting to see.

[1]
[https://github.com/SteveRabin/JPSPlusWithGoalBounding](https://github.com/SteveRabin/JPSPlusWithGoalBounding)

~~~
nurettin
That would definitely be interesting if you run it on the same hardware.

