63 comments

[ 3.3 ms ] story [ 132 ms ] thread
This is really sad that they choose Go over Crystal.
Whenever I see Go I think of this:

https://news.ycombinator.com/item?id=16143918

A great one, thanks for sharing. What‘s not to like about that approach?

And if you think I‘m sarcastic, we might have a different belief system underneath: For me the irreplaceability of an engineer is not measured in the creation of complexity and the mastering of technical acuity in a language that‘s hard to grasp — but much more about the value and delight any piece of code brings to its users through simplicity.

A language that is fast, easy and simple by default and doesn‘t get in the way of people trying to build something for the first time is a feature, not a bug.

Go has more line noise than Java combined with the expressiveness of COBOL
What about Python? It doesn't yell at you for having unused variables which is nice for actually developing the software.

My main gripe with Go is it doesn't seem geared toward figuring out new things, or letting people hack and experiment during development.

I think you just don't have enough practice, to be honest.

I came to Go from Ruby (and Python too, but I mostly used it before 2.7) and soon enough all my hacks and "let's try it this way" projects were in Go.

>It doesn't yell at you for having unused variables which is nice for actually developing the software.

No it is not. That was my first impression too but after a few weeks you understand that this was just a bad habit. Not a practice.

Yeah I will admit I only tried Go for a few hours and hated it, so I don't have much experience with it.
I'd also like to point out that much depends on what kind of software you are developing.

My main job for the past 5-6 years is system integration and I had a chance to compare Ruby and Go in this field.

And this is definitely where I'd prefer Go to most other languages. You don't need clever code most of the time, you need really clear and safe code that will run for a decade after deployment.

Ruby code can run for a decade after deployment as well...
Any code can.

The question which language makes it easier to write such code (assuming it still should be readable and maintainable, even by the new employees, even if they are not familiar with all the tech behind it)

Ruby does imo. Go looks incomprehensible to me and I can't stand its lack of expressiveness. This is all a matter of opinion, to you Go wins because you know Go well or like Go better, to me vice versa. There is no objective truth here.
Yeah, I love these dynamically typed languages that don't yell at you when you make a mistake, but then fail spectacularly in production (which you might not notice for some time if you don't look into the logs or if that part of the code isn't run that often).

But I agree that Go doesn't offer a lot for people who like to fiddle around endlessly with the language features - OTOH this allows you to concentrate on the thing you should be fiddling with, which is the actual implementation.

This probably explains every google product after Gmail and google search since Go was invented.
I didn't see Go used much at all within Google as of 2015; backends were pretty much half C++ and half Java with a bit of Python being deprecated over perf concerns. My team was all Java and had no plans for it.
I’d rather work in a programming language that is easier to read than one that is easier to write.
Whenever I see that quote being used to spurn Go I'm amazed of the seemingly large number of language researchers of a calibre of Wirth, de Moura or Wadler and the few actual used languages on the other hand.
Most tools we use in life are designed this way.
> So, the language that we give them has to be easy for them to understand and easy to adopt

And what about making it easy for them not to make mistakes?

“Easy to understand” goes a very long way towards that.
This takes my least favorite parts of Ruby, method_missing, module_eval, runtime constant name generation, the parts that make it such a painful language to use and scale, and uses them to load a language that supports static analysis. The cognitive dissonance is palpable. I would have guessed a post like this would be satire!
English is hard to scale too, but it’s beautiful when used by a talented writer
They're just having a bit of fun taking things to extreme. No need for the sour tone. The Go version of this post would be multicore fizzbuzz.
I didn't read that as sour, rather amused.
> I would have guessed a post like this would be satire!

It is?

> I would have guessed a post like this would be satire!

It is… burlesque!

(comment deleted)
This is a beautiful feat showcasing Ruby's expressive power, don't know of any other language that could be molded to accomplish the same feat.

As a non Ruby programmer I still appreciate its culture whose community best seems to explore code as art. One of Ruby's contributors @mame (also a talented #1 IOCCC winner) does this a lot who's famous for quine-relay [1] but has lots of other interesting art code projects in their repos.

[1] https://github.com/mame/quine-relay

> don't know of any other language that could be molded to accomplish the same feat.

This kind of stuff is the bread and butter of Racket. For example Racket comes bundled with an implementation of Algol 60 that lets you write Algol in your Racket programs. https://docs.racket-lang.org/algol60/

There's two implementations of Javascript https://docs.racket-lang.org/ecmascript/index.html and https://docs.racket-lang.org/javascript/intro.html, an implementation of Forth https://docs.racket-lang.org/forth/index.html and a lot more.

In e.g. the Algol example, it seems like you just get a function which can accept an Algol program as a string and run it. Seems quite different from what's been done in this case.
I think the process is exactly the same as the ruby example, except for the fact that while in ruby it was a hack, in racket, a programming-language programming language, is explicitly designed to allow for this kind of process. The linked website just mentions that the algol60 package also provides additional functions that allow executing over strings. The default mode of usage is to place a "#lang algol60" at the start of your files, and that configures the lexer/parser to allow the rest of the file to be parsed and interpreted as ALGOL code (just check out the examples in the packages's git forge page).
> don't know of any other language that could be molded to accomplish the same feat.

I guess any languages that have some kind of macros, like C, scala or rust.

I think its a bit rude to put C macros in the same sentence as scala (not sure about it) and rust
Haha as a scala and rust lover I can only agree with you, though one thing you cannot deny to C macros is that they are pretty flexible ^^
(comment deleted)
I've always thought it a bit of a shame that Ruby isn't more popular for Raspberry Pi projects. I mean, I use it, but the standard is still Python. And Python is great, don't get me wrong, but Ruby is just so much fun for hobby projects.

I used to try to write things in the most popular language for those things, like writing Prometheus exporters in Go. But I eventually realised I just didn't care that much, and now I write them in Ruby, and everything is sunshine and happiness again.

You should really look into the nerves platform.
Oh I totally forgot about that - I think I played around with it a few years back. I should check in and see what has changed, it was rather cool.
Last month I participated in a workshop with nerves + livebook and it was insane.

At the end we did a demo where we clustered all of our pis and we could send messages to each other's lcd screens.

Have you checked if crystal has enough raspberry Pi momentum?
It is both one of Ruby's greatest strengths and weakness. I found that metaprogramming was overused in Ruby with an obsession for clean syntax. This then made many projects very hard to debug, and many runtime errors that have traces like "in method_missing at line 68". Like you can't even grep where the code is being called or what was being called.
This has been my personal frustration with Ruby projects. Basic Ruby is easy to understand but metaprogrammed Ruby requires mastery of the Ruby REPL and a mental model to see where something could be going wrong. Save a few lines for an implementation but spend hours trying to modify/debug it.
This just proves that when looking at ruby code, you may not have any idea what you are actually looking at. Monkey patching saved me ... once.
Am I the only one thinking that it looks easier to interpret Ruby in Go with cgo than doing the opposite like they did in this article?

Also the good part of Go are the goroutines, the channels, the types, the safety...

The article was fun but they will find the limit as soon as they will try to support the important parts of Go.

Trying to go further will just demonstrate the opposite of their point.

> the types

Surely you jest. Go's type system is the worst thing about it by a country mile.

I think you took this article too seriously, I am pretty sure this is just a fun experiment displaying what things are possible, not anything that is supposed to be used in production[0].

[0] though there is a rich history of "lol jk" projects ending up in production, I'll admit

I thought the article would do the opposite; leverage the Go runtime but keep writing in Ruby syntax. How wrong I was, this is bananas, not sure I would go down that path!
I'm always on the lookout for a good language to transpile to Go, or parse Go and produce something readable, because it's getting harder to avoid at my day job.

But full Ruby dispatching is a little crazy (right up there with CLOS or Moose or Groovy) and I can't blame them for not wanting to implement that from scratch.

I think purescript can compile to go
Crystal is probably what you're looking for!
This is nutty and awesome and I am here for it.
I use some Go in Conjure's [1] Rails backend through FFI, for calculating Habit streaks and have had huge speed improvements.

Rewriting from Ruby to Go, some benchmarks for calculating long streaks showed going from ~5 sec to ~0.04 sec [2].

Conjure's habits use the iCalendar Recurrence Rule format (RRULE [3]) for their frequency, along with one or two other considerations (like Habit Completion Types and streak effects), which makes evaluating streaks more expensive (as you have to work backwards through habit completions one by one based on the next occurrence).

Data is still fetched from Postgres in Rails and passed to the compiled Go library and Ruby/Rails handles the results (persisting, notifying over web sockets, etc)[4]. I modified Conjure's Heroku buildpack to install Go and build on deploy.

No doubt there is further optimizations that can be made, but this approach has allowed me to sprinkle Go into a Rails app and progressively optimize certain things when needed.

[1] https://conjure.so/ [2] https://twitter.com/Whelton/status/1370482793558458370 [3] https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-... [4] https://jondot.medium.com/ruby-and-go-sitting-in-a-tree-38c1...

> Rewriting from Ruby to Go, some benchmarks for calculating long streaks showed going from ~5 sec to ~0.04 sec [2].

This is why sometimes it's worth looking for obscure methods in the core or standard library and use them instead of writing Ruby code, especially when iterating on Enumerables. Basically it's rewriting Ruby in C.

Entry level example: minmax_by [1] which does the obvious thing but it's not obvious that every Ruby developer knows about it (disclaimer: I went to the docs and looked for something with a fun name.)

[1] https://ruby-doc.org/core-3.0.1/Enumerable.html#method-i-min...

Now do channels and the 'go' keyword! ;)
Your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should.

Jokes aside, this is insanely cool.

I see a couple of comment suggesting that go routines will be a problem, or channels, as if these are unique to go and deeply magical. Ruby has Fibers which could easily be used to implement go routines, and Ruby 3 has Fiber scheduling support that would make the job easier, and channels aren’t terribly hard to implement.

I think CRuby’s limit on the total number of Fibrrs would be lower than the number of go routines that can normally be supported, but TruffleRuby using Project Loom’s virtual threads could support vast numbers of Fibers when I prototyped it several years ago.

Now we just need Loom to be released!
It’s getting closer, and quite a few bits of the supporting work have already been merged into the JDK.
If you want to do this at production quality, you probably ought to use the go AST module to parse the Go into an AST and extract that. This sort of technique works OK as long as you use the subset between the two target languages where the grammars are compatible, but as you push the level of support for Go up, the odds of the two languages having irreconcilable differences approach 1.

For instance, if there is an order-of-operations disagreement between the two languages, the only solution that works fully is to do a full parse anyhow, because no amount of regex can ever cover all the bases in that case. And that's just an easily-understandable example of irreconcilable grammar differences, they can pop up anywhere (disagreements about reserved words, disagreements about what constitutes legal identifiers, etc.), and when they do you end up backed into doing a full parse of the original language anyhow.

You can then either interpret or compile the resulting AST. That's actually not too hard; what's hard is implementing the more advanced stuff like reflection in Go or dealing with the unsafe package. (If you don't need that, then great! Problem solved.) With the AST in hand you no longer need to worry about those differences.

I don't know ruby well enough to say, but I know Python, a very close neighbor, has everything you need to be able to write a Python module that would allow you to directly import Go modules. With effort it could even compile the Go into Python bytecode directly.

I had contemplated to choose which language between python and ruby when I was python noob. At that time I tried both a little bit and I realized ruby had more powerful, rich features than python had. Ruby can handle lots of tasks on behalf of me out of the box so that I can reduce lots of code. So I liked it.

However I had no choice but to use python because it was variously used in practice. I felt it was difficult to persuade my colleagues to use ruby instead of python. Colleagues were not familiar with ruby and there wasn't any ruby project in my company. So I chose python and kept using it for several years. After the decision I didn't try learning ruby because I though they have many characteristic in common and I thought it was meaningless to know both of them, besides I had no time to study it.

It has been several years since I gave up learning ruby, but I still have unresolved feeling about it. Whenever I read articles that highlight the power of ruby, I want to know about it. Haha.. But still there are high prioritized tasks to do. Learning ruby is still remained in the todo list.