I tried Crystal for a small hobby project a few months back, and was generally impressed by the stability, ease of use and documentation. I found the type-system very straight forward, and with less mental overhead than Rust, obviously with all the design tradeoffs that entails. For the use-cases I'm interested in, Crystal has a little ways to go in terms of mindshare and ecosystem support, but it's a fun language to learn and try.
I generally like Crystal. However I think there’s a some unfortunate choices that make it hard to use. I’d really love to see them addressed (or planned for) before 1.0:
- global inference is more trouble than its worth. some way to opt sections of code out of global inference in exchange for faster compile times and better type error messages would be wonderful
- conflicting/duplicate C bindings in libraries aren’t easy (or even possible sometimes) to reconcile
- a lot of standard library interfaces to system stuff (e.g. sockets) are hard to extend for additional uses. there’s a number of reasons for this, but among them: enums wrapping simple integer based enums, but not actually covering all the values.
- parser is hard to reuse outside of the compiler itself, which is an impediment to making neat tools.
- some strange choices around co/contra-variance when dealing with arrays
I think it's maybe less global than it was previously (and in a way that helps pave the way for improving compile times), but there's still a lot of ways to cause spooky type errors at a distance due to the assignment type inference rule.
module Example
def self.some_method
"string"
end
class Foo
getter :var1
def initialize
@var1 = SomeUtilities.something
end
end
module SomeUtilities
def self.something
Example.some_method
end
def self.do_something_with_string(input : String)
puts input
end
end
end
Example::SomeUtilities.do_something_with_string(Example::Foo.new)
If you change Example.some_method to return :symbol, you now get a type error on the final line.
I like that behaviour. Normally you don't get to pay the overhead of having to spell it out but it is a nice tool to have, being able to gradually add type information to fence in errors.
Editor story is a bit rough still. I'm using scry (the Crystal Language Server) with coc-nvim. It seems to be a little bit smarter than simple "words in buffer" completion, but not much. Sometimes it just quits and I haven't investigated why. Currently I'm just writing spec tests and simple data structures/algorithms. (the typical thing I do when learning a language) I did start a Lucky project this past weekend to see what that's all about. If I get more into it, I'll probably break down and figure out how to fix autocompletion/go-to-definition/show-references/etc.
I used Crystal with VS code, I don't remember the autocomplete issues, but I'm not a big consumer of that functionality. Syntax highlighting (and I think formatting) were supported with the plugin I used, which was good enough for my purposes.
Depends on if you have any cpu-bound endpoints. At my previous employer we moved a very intensive check (high dimensional vector nearest neighbor search) into a separate Crystal microservice and even with RPC overhead it was easily 100x faster than the ruby version. This with code that any Ruby dev could instantly read, unlike if we would have gone for a C extension. That said, Ruby still has a massive lead in available gems, so don't uninstall Rails yet.
Though I have a long history with IDEs I feel just as comfortable with the console, or the lighter-weight, electron-based IDEs.
For the last couple of years I've lived pretty much exclusive in the Ruby/RubyMine, Python/PyCharm, Scala/IntelliJ worlds.
However, I recently finished a medium-sized Crystral project only using VSCode. For debugging, I wrote unit tests and kept Sentry running. The compiler pretty much catches everything else. The combination worked out very well.
I don't yet use Crystal, but it's kind of painful that Windows support is in the "What can wait? - after 1.0" section. Cross-platform support is one of the reasons I've been diving into Rust.
However "we integrated a CI for Windows to ensure we continue moving steadily forward" sounds like a good compromise for limited resources.
Yeah, especially as the idea that adding windows support won't end up affecting public APIs is pretty naive. Windows and unix-like systems have very different APIs for lot's of things, and it's very easy to fall into designing something unix-specific if you don't make it cross-platform from the start.
Ruby has a pretty solid Api story on windows (meaning code and gems generally work) - but it's not quite a tier one platform - it's gotten better, but eg automatic compilation of c level extensions isn't quite as good as on Linux. This mostly stems from using msys and not vc++ - and is similar to the issues python used to face on windows. But if I'm not mistaken python moved to vc a while after community edition became a thing.
We're also running some rather old code (w old versions of ruby) - and that's obviously not great - but also somewhat worse on windows than on Linux.
All that might make it sounds like ruby on windows is tricky - but it really has gotten quite great, especially after 2.4.
I find it a little sad that windows support is considered essential (and its lack is a dealbreaker), but linux support is not, even though developers predominantly use macos and linux.
If you compare to ruby, there are a couple of quite nice packages for os automation that allows for scripting setup of services etc. That's a space where os level support is essential.
That said, crystal being new, and wsl 1/2 being a thing... I'm à little surprised for the demand for a windows version.
OTOH being able to create a gui rad ide like Lazarus or Delphi, that is cross-platform, compiles to native executables and uses crystal in place of Pascal would probably be great.
I actually started writing my blog in Crystal, took a little break, and started writing it in Nim. I really like Nim a lot. Some of the code came out more concise in Nim. I like how Nim handles nils better. Options instead of temp var shadowing. I would've finished my blog in Nim had I not ran into an issue with embedded-style templates. Think eRb in Ruby. Crystal handles this by compiling and embedded. Nim doesn't support that. I had to resort to something like Mustache which I didn't want to use. Ultimately, I went back to Crystal and finished it.