Hacker News new | ask | show | jobs
by norman784 1137 days ago
I also wished for a long time for Crystal to take off, but now having Go and Rust I don't see Crystal to gain too much relevance in the future, while it might be appealing to Ruby devs, Ruby is becoming better every day, but still Ruby devs stay in Ruby because of the ecosystem, the company where I work on already decided that no new project will be written in C, C++, Ruby, Java and instead use Go or Rust, I suppose that other companies are doing the same.
4 comments

As a Ruby dev, that Crystal is "close but different" means I know I won't be able to use my Ruby code but at the same time I get too little in return to make it feel worthwhile.

For the very rare circumstances where Ruby is too slow for what I need to do, there's usually code in some other language I can wrap in an extension, and that code is far more likely to be C or some other more established language than Crystal.

To me Crystal is actually a more polished Ruby implementation. There was some annoying inconsistent in ruby stdlib that was corrected in Crystal, for example the modules for file/directory interaction.

Ruby was my main language for scripting, but I switched to Crystal completely after getting comfortable with it. Now it is really hard to switch back to Ruby.

Also, I thing compiled language is the greatest friend for older programmers. Over the time I'm getting more and more sloppy and very often make some typing error. Crystal being compiled language saved me countless time by refusing to compile when I made the mistake. Meanwhile in Ruby it can only be found after the script ran for a while, sometime it became a disaster because the action was destructive.

The thing is, any annoyance in the stdlib you can paper over with gems if you want, and still be able to keep using all the libraries out there.

As for the type checking, Ruby is getting more and more opt in type checking, so that reason is slowly diminishing as well.

> , but now having Go and Rust

If you go for Go or Rust you would never go for something like Crystal regardless, as they have different focuses. Just like Ruby, Crystal optimizes for code legibility and expressiveness, which both Go and Rust never really cared about, as it's about stability + performance (in the case of Golang) or safety + performance (in the case of Rust). Both of Go and Rust have horrible syntax compared to Ruby/Crystal, which is a fine tradeoff to make in cases.

That must be subjective because Go's syntax is pretty fine to me.

To illustrate, when I started learning Go, I implemented Concurrent Hash Array Mapped Tries from some PhD thesis and the pseudo code algorithm actually looked pretty much like the Go code. A testament to how legible it is.

Then again, I have never tried ruby so I can't compare.

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”.
Rust is pretty expressive. Horrible syntax... that's just a subjective measure. I wish programmers would get over it, because it's a huge hindrance to trying a large number of languages out there with lots of nice things. But people are gonna be people, so it won't happen.
Yeah, I agree that it's highly subjective. And I don't mean that people shouldn't chose something just based on one variable, it obviously depends. No language is perfect for every use case. Personally I use Rust for a lot of things, even though I'm more productive in other languages, but sometimes it's just a really good fit for the problem.

Pseudo-code, but this is how I see the difference in expressiveness and syntax:

   3.times {
      println('Foobar')
   }

   for i in 0..3 {
      println!("Foobar")
   }
Both of them makes sense though, so not a huge difference, but it's the same way in lots of ways in Rust in general.

> because it's a huge hindrance to trying a large number of languages out there with lots of nice things

I know exactly what you're talking about, as most of the time I work in Clojure, and trying to show Clojure to other programmers who are used to C-like languages and never heard of any lisp-like language is a constant struggle, as their first reaction is always "eww, parenthesizes everywhere!" even though their favorite language usually has the same amount or even more.

Ruby is fine until your large application starts to include more and more dependencies. There is no coherent API across, every library has it's own mini DSL and the mess starts to build up. Then it comes method_missing, monkey patching and strings and dictionaries passing in all the places. True horror. All Ruby's readability dissapears. Small apps look beautiful, but large ones quickly become a mess. On top of that resource utilization is atrocious. But there are places where Ruby shines like RSpec, Rails, pry in runtime (I miss that one).
That's one of the aspects in which Crystal shines.

It retains most of the flexibility and DSL capabilities, but the type- and nil-safety allow you to leverage them without nasty surprises at runtime.

Not having to guess what a method or block returns and instead having the compiler tell you when you get it wrong makes an enormous difference.

Rust is spiky, like a crab.
I've been learning Rust over the last few months, because it seems like a good language to have on my CV.

It's certainly a taste thing, but I am not enjoying it at all. I find it unpleasant. I think it's going to join the short list of "languages I can use but would prefer not to".

I've never learned Crystal, but if it's like Ruby, then I think I'd enjoy it just fine.

It's funny how taste works. I love writing Rust. To the point that almost all of my personal projects are now in the Rust.
Exactly.. I was a Crystal enthusiast, but because of their slow development pace and small community, half-baked documentation (all understandable, no critics here) and the raise of Go (great documentation, fast pace development, huge community), was hard to keep focus on that. Go became my option to ruby, and I'm doing fine with that.
I can't suffer Go. C, Rust, C++, Ruby Python, Java, C#, VB.Net are all fine, F# looks cool too but I never used it.

I started to use Crystal in a small commercial project, as a web backend, and it was very fun and promising.

But the project got cancelled for completely unrelated reasons.

I long for an excuse to use Crystal again. Hard typing combined with Ruby carefree style and EXEs without runtime... really cool stuff.

I think Crystal will crack the Win32 nut eventually.

I think windows is the main thing holding crystal back. I make little games for jams and I'm always trying out new languages. I submitted a bug related to running processes on windows last november, it was just recently closed as completed. Although I spend almost all of my at-home time on linux, I know that I have to provided windows executables for jams. I plan to come back to crystal when I can write once and can compile the same code everywhere.
I stay in Ruby because my customers want Rails and because my own scripts don't need to be fast. Edit and run is one step faster than edit, compile, run.