One of Ruby’s pillars is metaprogramming. Crystal lacks that entirely, making it a non-option for many Rubyists.
Crystal has compile-time metaprogramming, which is it's own thing and has many sensible uses... but yes it's not the metaprogramming people are used to in Ruby and that the entire Ruby ecosystem is pretty fundamentally built on.
Switch from Ruby to Crystal
11–20 of 37 posts
Re: Switch from Ruby to Crystal
#12One of Ruby’s pillars is metaprogramming. Crystal lacks that entirely, making it a non-option for many Rubyists.
Re: Switch from Ruby to Crystal
#13Earlier quoted context omitted.
Compilation times can hurt too, I'm not sure if that's improved or being worked on though.
Crystal does global type inference to be performant while “feeling like a dynamic language” - as claimed by the article. This leads to very high compilation times (which is non-linear so a program double the size will likely take more than double the time to compile) and last time I asked I was told it is not a solvable problem.
Re: Switch from Ruby to Crystal
#14Earlier quoted context omitted.
Crystal does global type inference to be performant while “feeling like a dynamic language” - as claimed by the article. This leads to very high compilation times (which is non-linear so a program double the size will likely take more than double the time to compile) and last time I asked I was told it is not a solvable problem.
Does that overhead go down if you tag lots of places with types manually?
There is some caching to help but times are still high. IIRC the compiler is not parallel either, so having more cores won't help.
There is also a —release compile flag that you would want to use for production and it is much slower.
Re: Switch from Ruby to Crystal
#15The authors of the language avoided aliases (no more size vs. length or inject vs. reduce discussions) and generally there's only one way to do things (Strings are always wrapped in double quotes).
Crystal has abstract classes/modules/methods, generics and method overloading, three powerful techniques which are missing in Ruby entirely and which can be very helpful in some cases.
You can mark global methods as private and you can also mark classes as private. The latter can prevent users of your "shard" (gem) from accessing such classes, pretty much like how Rust modules can be marked for external use or not.
Constructor arguments can be turned into instance variables automatically, if you add `@` to the argument names.
Marking a construct as private happens inline with the definition, unlike in Ruby where it functions as a divider. This makes your code a bit easier to read and you can group methods in any way you like.
I find the built-in JSON, YAML and XML parsers to be very elegant. For the common use cases, you just have to define normal classes with attributes and include the JSON::Serializable module - this will also traverse attributes in search of serializable types. You can also do more complex transformations with annotations - have a look at https://crystal-lang.org/api/0.35.1/JSON/Serializable.html - but writing an HTTP client for some random API in Crystal feels very natural. On top of that, the built-in HTTP client is more than decent (which I can't say about Net:HTTP).
Generally the standard library is packed with goodies and, though the ecosystem is scarce in some areas, it's usually easy to replace and you can get away with less dependencies.
The inferred static typing which allows for union types is a neat choice - it doesn't force you to write types (most of the times) but it does give you some guarantees. I personally prefer to explicitly name my types, especially in public method definitions, because it helps document the code without having to write anything on top, but it's up to you.
To be honest I'm not really missing the metaprogramming aspect. In large Ruby projects this can easily turn into a mess and it makes searching through your codebase a horrid experience. Crystal does have macros but they have some limitations (they operate at compile-time).
Performance is just amazing and you can also build static binaries.
If you like Ruby, I'd really encourage you to give it a try, at least as an experiment to an "alternative Ruby".
To conclude, here are some code samples (shameless plug, but you can also browse https://crystalshards.xyz/ for other projects):
* https://github.com/defense-cr/defense/blob/master/src/defens...
* https://github.com/defense-cr/defense/blob/master/src/defens...
* https://github.com/lipanski/kilometric/blob/master/src/kilom...
Re: Switch from Ruby to Crystal
#16Not necessarily a ringing endorsement.
Re: Switch from Ruby to Crystal
#17Earlier quoted context omitted.
Compilation times can hurt too, I'm not sure if that's improved or being worked on though.
Crystal does global type inference to be performant while “feeling like a dynamic language” - as claimed by the article. This leads to very high compilation times (which is non-linear so a program double the size will likely take more than double the time to compile) and last time I asked I was told it is not a solvable problem.
I think they stepped back from this a few years ago. It's not globally inferred anymore - you need to specify some types manually.
Re: Switch from Ruby to Crystal
#18Anyone have production experience with Crystal? I know it's not 1.0 yet, but there are some fairly mature web frameworks available that make the language look pretty attractive.
Base API runs on Heroku and it's memory consumption is really low (around 20Mb on average) also it's slug size is 3.3MB.
I think it's a really good language, the syntax is way more clearer then any of the other similar languages (Go, Rust, Nim).
It has two problems currently as far as I can tell: - Windows support - when it hits there is no reason for me to use anything else, I'll be able to write desktop applications in it with a Webview or CLI apps - Lack of mature libraries - in time I think this will remedy itself
Base API: www.base-api.io Mint: www.mint-lang.com
Re: Switch from Ruby to Crystal
#19One of Ruby’s pillars is metaprogramming. Crystal lacks that entirely, making it a non-option for many Rubyists.
Crystal has macros which is the metaprogramming for static/compiled languages. And last time I checked, there are way more things that you can do with Crystal macros than Rust's macros. And crystal's macros feel very familiar to the language itself, are easy to understand and use them whereas Rust's macros..
[1] https://crystal-lang.org/reference/syntax_and_semantics/macr...
[2] https://doc.rust-lang.org/reference/procedural-macros.html
[3] https://doc.rust-lang.org/reference/macros-by-example.html