
Moving from Ruby to Rust - steveklabnik
http://deliveroo.engineering/2019/02/14/moving-from-ruby-to-rust.html
======
StavrosK
I've been wanting to learn Rust for a long time, but I'm hit by the curse of
Python being the second best at everything. Every time I try to write
something in Rust, I think "okay, I can either spend a week learning Rust and
writing this, by which point I might lose motivation, or I can have it done in
Python in an hour".

Unfortunately, Python always wins, and it's also never not an option, since it
runs on everything I care to develop on :(

~~~
ilovecaching
Is it second best though? I can write an app in Go in the same amount of time
it would take me in Python and it would be an order of magnitude faster,
multithreaded, and type checked. Python is really quite slow and error prone
if you think about it.

~~~
smogcutter
You're missing the point, he could've said brainfuck instead of python and the
content would be the same: it's hard to motivate yourself to learn something
new when you're already productive in another language and want to get work
done.

~~~
WrtCdEvrydy
I wonder if that will be the next abstraction layer.

A programming language that compiles down into target programming languages.

Reminds me of Haxe.

~~~
bluejekyll
In some senses, this is what all the JVM languages are, or the WASM languages,
or C FFI. You can build compatible layers between any languages, but at the
end of the day, most people want to be able to read the libraries and other
source code they’re working with.

Scala, Kotlin, and Java can all interop with each other, but at the end of the
day much of the libraries get rewritten between the languages.

------
mooreds
And this is the reason you shouldn't worry about jamming out your MVP in
rails.

Because at the beginning you want to optimize for developer productivity and
then when (if!) you get to a certain size, you can easily move to a solution
that emphasizes machine productivity (aka performance).

~~~
carlmr
I find that Rust is good on developer time, too, however it costs you all the
developer time up front. In Ruby, Python or whatever you spend less time
developing, but so much time debugging those little runtime errors that would
have been compile time errors in other languages that I still think it only
feels faster, it isn't really faster.

When you get to maintenance mode this effect becomes even more pronounced.
Because it's much easier to not break something in a nicely typed codebase.

There's some languages that kind of bridge this gap between having a lot of
compile time safety and still being easy to write. I'm thinking of F#, OCaml
that have a lot of the same type safety, and barely need more type annotations
than Python. They're not as fast as Rust, but also they don't necessitate
thinking on the extra layer of ownership (which can cost you time).

People always think of the hours it takes to develop some feature and forget
the days it takes to debug it.

------
virtualritz
Maybe Deliveroo should consider about removing their IP ban for this
subdomain. Not everyone has a VPN readily availiable.

I'm traveling in Uruguay. I get:

Error 1009 Ray ID: 4a945b112e23c577 • 2019-02-15 02:31:00 UTC Access denied
What happened? The owner of this website (deliveroo.engineering) has banned
the country or region your IP address is in (UY) from accessing this website.

~~~
GrayShade
Cloudflare, most likely.

------
xiphias2
I just moved some math heavy code from Ruby to Julia and was surprised how
easy it was. By far the biggest difference was the 1-based indexing. Moving to
Rust would taken me much more time, though in Julia it's harder for me to
optimize the low level details.

~~~
pageandrew
1 based indexing? is there any particular reason Julia uses 1 based indexing?
seems like a pointless thing to differentiate from other languages

~~~
ZeroCool2u
Personally, I find it annoying considering it's just based on convention from
other math software. Otherwise, an amazing language.

~~~
Certhas
When I started Julia I was annoyed by it.

Then I realized that 90% of my mental gymnastics with indices got simplified.
Explaining indexing to newbies is now immediate where before it took a slide,
several examples, and a clever picture. Slicing is also more natural:

"1:3 picks out index 1, 2 and 3, which are the first, second and third element
of the array."

Instead of the python version of

"0:4 picks out index 0, 1 and 2, which are the first, second and third element
of the array."

~~~
saghm
> "0:4 picks out index 0, 1 and 2, which are the first, second and third
> element of the array."

I don't think that's right? It should pick out four things, not three.

Of course, you could argue that getting that wrong proves your point! I
personally still prefer 0-indexing, but I definitely agree with you that
having an exclusive upper bound is confusing.

~~~
Certhas
You're right of course. Not intentional.

0:3 picks out index 0, 1, 2.

So 1:3 picks out the second and third element, which are indexed by 1 and 2
respectively.

My guess is that what one prefers probably depends entirely on the data
structures one works with most....

~~~
shele
I like how you got it wrong, proving your point.

------
Corrado
That was a nice article but I would have liked to have seen how they
compile/deployed the code. Was it in Gem form or a system lib or something
else? Was it a separate package altogether or did it build in their CI? How
hard was it to integrate into their deployments?

I guess I'm looking at it from a DevOps standpoint but those types of
questions can (should!) inform the decisions you make about your code. Mixing
in multiple languages (most likely) increases the footprint of your
infrastructure and shouldn't be ignored. This is the same whether you use
Rust, or NodeJS, or Python.

------
aboutruby
They just moved a computationally intensive task to a much faster language.
Not as large scale as moving everything from Rails to Scala in the case of
Twitter for instance, but pretty standard is any large Rails application to
use faster languages for performance sensitive tasks.

~~~
outworlder
There are no 'fast languages'. Just fast implementations.

This distinction is important.

~~~
marcosdumay
You won't get anything near the performance of a usual Rust code by optimizing
some CPython code. It doesn't matter how much you try.

~~~
icebraining
Who said anything about CPython? Pypy can get close to C speed, so I doubt it
can't get anywhere near Rust.

~~~
dagw
PyPy will get you a 10-time speed up over pure Python in real-world code on a
good day. While that is nice, it's not close to C.

------
joemccall86
I'm curious if Crystal was considered given its speed and similarity to Ruby.

~~~
hamandcheese
I really like Crystal, but the lack of any large corporate sponsors or large
production systems using it (that I’m aware of) means I would probably never
choose it for anything besides toy projects.

~~~
dtn
Apparently Yahoo jp have used it in one of their internal tools

[https://twitter.com/taichiro_dev/status/1047803131986292736](https://twitter.com/taichiro_dev/status/1047803131986292736)

------
htfy96
Just curious: why there are so many articles putting two things that varies a
lot in their market positions in juxtaposition? e.g., Go or Rust/Ruby to
rust/Wasm over JavaScript/NoSQL to MySQL

~~~
jaimex2
It's a common scenario. You build something with tools that allow rapid
development, then if you become successful need to find a path forward to
scale.

There are many paths to do this - each with trade offs.

~~~
htfy96
That's true, but according to my experience, it's usually better to perform
gradual migrations like from Ruby to Crystal, if it can't solve the problem,
try some other GC-based languages like Go. Things like Rust should be the last
resort, especially when there is no Rust expert in your team.

EDIT: as some people explained below, this is certainly another trade-off. My
experience is based on a case where the team was made of non-talented
engineers and many of them stick to the same language in their whole career
path.

~~~
james_s_tayler
Crystal isn't exactly something I'd run in production.

Besides it's crippled as a language due to never allowing anything to be null,
so there isn't any powerful metaprogramming you can do with it. That is a big
turn off for me. Otherwise Crystal would be such a nice sweet spot IMO .

~~~
realusername
Not allowing NULL & having weak metaprogramming options sounds like advantages
to me. you still have metaprogramming using language templates & scope
shadowing, that's not at runtime but it's clearly good enough.

The problem with Crystal is more with the small community than the concept
itself which is pretty good IMO.

~~~
james_s_tayler
I'm not feeling it. Compile time only metaprogramming just doesn't feel
powerful enough. Just a personal thing.

I'm definitely a fan of Crystal of though as a project and would really like
to see a bigger community and more libraries etc.

~~~
realusername
They don't do it because runtime metaprogramming has a lot of disadvantages,
it's difficult to optimize so it runs poorly, it throws away the static typing
out of the window and it's difficult to debug. I spent hours debugging Rails
code in the past because of the layers of monkey patching.

~~~
james_s_tayler
It also has a lot of advantages. It's as powerful as it is dangerous.

The real reason they don't do it is because they can't. It's inherently
unsafe. In order to always be sure something is never null you have to be
aware of what all it's inputs are so you can reason about it. That's not
possible with runtime metaprogramming techniques.

I dunno I guess I just think it's an odd choice. Don't get me wrong, it's a
neat experiment and I value it. I'm just slightly miffed that that particular
experiment had to mixed in with what amounts to a statically typed language
with the beauty and simplicity of Ruby but the friendliness and
discoverability of static typing.

------
Twirrim
I'm curious if JRuby came up for consideration at all. It seems to get some
really notable speed-ups on straight ruby code.

~~~
hit8run
I once also solved an algorithm speed problem by porting our Rails App to
jRuby. Worked like a charm!!!

------
thom
This sounds very cool, and will be very useful when the whole Deliveroo
service stops grinding to a halt every Friday night (yes, yes, I have an
exciting life).

~~~
dom96
Yeah... It was amazingly bad last weekend. These guys need to work on their
reliability.

------
jaequery
anyone know of a language that is just like Ruby, minus the symbols?

or javascript, that is procedural first rather than asynchronous?

it really bugs me that there isn't one quite like it, i'm just dying for
something like that.

~~~
chrisseaton
> anyone know of a language that is just like Ruby, minus the symbols?

What’s your issue with symbols in particular? They seem pretty harmless to me.

~~~
jaequery
Harmless yes, but is it useful? Probably not. I have been teaching people Ruby
and till this day, I have a hard time answering whenever a student asks me
what the benefit of using Symbols over Strings is.

I know it was in place early on for memory / performance reasons but as of
Ruby 2.2, there are zero-performance gains using symbols over strings.
Unfortunately it's too late to deprecate them since it's a widely adopted
practice.

When I teach Ruby, I try to evangelize how simple Ruby is but always hits the
breaks whenever I have to explain Symbols.

And ultimately, no matter how much I try to ignore, I just can't stand how
this looks:

opts = { adapter: :mysql}

It looks like a double wall of some sort which is fine for those who are used
to it but not for those beginning. (Especially those coming from other
languages like Python, PHP, and JS)

Symbols also cause occasional havoc when using 3rd-party libraries because
they all have different preference of when to use it and when not to.

So IMO, there are no benefit of Symbols and it just creates confusion more
than anything. And that is really the point I am making. I have a hard time
reasoning with those PHP/Python folks why Symbol exists and it shouldn't
really be that way.

~~~
chrisseaton
> as of Ruby 2.2, there are zero-performance gains using symbols over strings

As others have pointed out - this is demonstrably false.

    
    
        # frozen_string_literal: true
    
        a = ('fo' + 'o').to_sym
        :foo == a
    
        b = ('fo' + 'o').freeze
        'foo' == b
    

The second comparison is a 1.5x slower than the former. This is because if a
string comparison fails on identity, it then has to check characters. Symbols
are always interned so can always stop as the identity comparison.

But I actually just like them as they convey intent - a symbol is a string I
know about as the programmer. A string is a string that is runtime data.

~~~
jaequery
I too like it as you. But I find when dealing with a lot of JSON data
(decoding/encoding) the symbols become a hindrance.

------
superconformist
Then: Ruby is trendy, deliveroo picks Ruby.

Now: Rust is trendy, deliveroo picks Rust.

------
ospider
The owner of this website (deliveroo.engineering) has banned the country or
region your IP address is in (CN) from accessing this website.

huh

------
Dowwie
This article was published before the Deliveroo team made full use of Rust.
They acknowledged in the article that the project was a port of their
logistics algorithms. They didn't refactor to idiomatic Rust nor have they
made full use of concurrency, yet.

If the gains presented in the article are alluring, this is only the tip of
the iceberg.

------
rammy1234
"It was clear that Ruby was a bottleneck here and we started looking at the
alternatives." , how did you arrive at Ruby being the bottleneck ? not
questioning your work here but curious to understand what part of Ruby was
causing the performance issues.

Question is How a programming language becomes a bottleneck ? Also my
understanding ( correct me if i am wrong here) Rust is more of a systems
programming with low level access. Just trying to be curious with performance
issues pointed out to a programming language ?

~~~
casper345
tl;dr important to know the engine behind the languages

This might not be the reason for the author, but for me I understood Ruby
limitation with ruby global interpreter lock. For smaller applications I knew
this wouldnt be an issue, but when my applications began slowing down I would
check the processes and understand that my Rails application are operating
only on one single thread. Then I access if I should keep try optimizing or if
something like Elixir is a better solution. Same process with JS

~~~
rammy1234
so in which case, is it safe to say some languages( in this case Ruby) are not
cut out for high performance at their root. And in which case we should not
opt for such languages when we know we have to scale at some point. Is this
right way to think about this ? moving to another language at the point when
you have to scale is a costly affair to rewrite , isn't it ?

------
hit8run
Did you try the Ruby 2.6 JIT Compiler?

~~~
rajangdavis
Not sure why this comment is downvoted, this seems like a legitimate question
as the JIT has some serious performance benefits
([https://medium.com/@k0kubun/ruby-2-6-jit-progress-and-
future...](https://medium.com/@k0kubun/ruby-2-6-jit-progress-and-
future-84e0a830ecbf)).

~~~
aboutruby
Even if the goal of getting Ruby 3 to be 3x faster than Ruby 2 on a typical
Rails app is reached, it would be far from the 17x speedup they got by moving
to Rust.

~~~
ksec
I guess it depends. TruffleRuby could be 200x faster in some benchmarks. So it
is not that 17x speedup is an impossible task. It just needs some testing to
be sure.

------
ricardobeat
Surprised there is no mention of alternatives like Crystal or mRuby.

------
ertucetin
I would suggest Clojure; REPL driven development (fast feedbacks), fun to
code, cool community, multi-threaded etc.

Also, lots of Ruby developers are coming to Clojure world.

------
evsasse
Can`t access it from Brazil... ``` The owner of this website
(deliveroo.engineering) has banned the country or region your IP address is in
(BR) from accessing this website. ```
[https://i.imgur.com/TyDkmzc.png?1](https://i.imgur.com/TyDkmzc.png?1)

~~~
baroffoos
Here is an archive version [http://archive.is/XcMJ1](http://archive.is/XcMJ1)

~~~
mrspeaker
I'm holding off giving them a click (or any attention via the archive link /
other copy) until I find out WHY they'd do that. Is there a valid reason?

~~~
baroffoos
I think its somewhat common to block countries that have a high spam/abuse
rate. Kinda shitty.

------
cfv
You smartasses banned the entire country of Uruguay, where I reside, from
reading this. [http://imgur.com/sdd6Mlv](http://imgur.com/sdd6Mlv) If
anything, this is a huge red flag indicating that I shouldn't care about
anything Deliveroo does.

Don't be an asshole, don't geofence people for no real clear reason

~~~
czbond
I intentionally geofence most countries for certain initiatives where the high
probability audience is in my country, U.S. (for cybersecurity reasons).
Choosing a "deny" rule keeps out a lot of the crap one otherwise has to deal
with (probes, scans, connections, DDOS, etc.

~~~
bilkow
I think that's a terrible thing to do... There are real people which might
have to find workarounds just to know what your initiative is about.

I'm also curious about the type of your initiatives, are they really local?
Programming stuff isn't limited to the US[1].

[1]
[https://insights.stackoverflow.com/survey/2018/#methodology](https://insights.stackoverflow.com/survey/2018/#methodology)
(only 25% of the stack overflow 2018 survey responses were from North America
in general)

~~~
czbond
I see your point, but it isn't as bad as it may seem. Specifically I deal with
B2B companies whose sales audience and customer base are solely the US (due to
operational "boots on the ground" type of work)

