7 ms·
Care to explain more? Having been using Ruby for about 8 years and Crystal for about 4, they actually have an extremely similar syntax and are also semantically
by watzon 6y ago
Care to explain more? Having been using Ruby for about 8 years and Crystal for about 4, they actually have an extremely similar syntax and are also semantically very close. To the point where many Ruby scripts are completely valid Crystal, or at the very least require only a few changes.
I do think that people trying to compare Crystal to Ruby kind of miss the point though. Ruby as an interpreted language, even optimized with JIT compilation, will never match the performance you can get out of a true compiled language. By the same token, Crystal as a compiled language will never be as quick to develop with since you have to wait for your code to compile after each change.
- nickbauman 6y agoYeah how fast is that compiler? If it's just another compiled language (rather than the kind of wicked fast compiled language like Go), my enthusiasm will be dampened...
- nine_k 6y agoIf it has reasonable incremental compilation, it can take a few seconds to compile. With good code structure, I see large Java projects compile small changes in seconds, even though compiling Java used to be a hog. You don't often rebuild from scratch during development, do you?
- abeppu 6y agoI often switch between feature branches, when working on more than one project in a repo with multiple related modules. If there's a change near the top of that dependency graph, I'm forced to not exactly rebuild from scratch, but still to rebuild quite a lot.
- nine_k 6y agoRight now I'm at the very same situation. Yes, it is frustrating. This is why things close to the top of the dependency graph should be small, well-tested, and rarely need changes. But when you still need to troubleshoot them, there's no way around recompiling a lot of stuff if you want these static guarantees :(
- nickbauman 6y agoBad language design, IMO. The language shouldn't make the writers in it worry about how to organize the code to speed up the compiler.
- nine_k 6y agoIn my case it's not even a language proper; I was using JavaScript which gives you near-zero static guarantees. I was fixing an issue in one common library; properly testing changes required rebuilding and restarting a number of containers. Unit tests only tell you so much; you need proper integration tests to see how certain things interact. If I were used a statically typechecked language (e.g. TypeScript), I could have eliminated 50%, or maybe 75% of the testing, because the compiler would check things for me before runtime. It would be drastically faster to localize and fix the bug even if the compilation increased build times 10x.
- nickbauman 6y agoOften I do because that's what CI does. This is pretty normal. But the point is having a different view of what compilation means in the developer's workflow as a language designer. Having the engineer have to think about how to organize the code for the compiler is bad design unless that organization is built into the compiler. The compiler should reject programs that are not organized for optimal compilation. And the organization required at least does not impede understanding of the code (best if it improves it). This is Go's design imprimatur and it's critically important to the success of Go. FWIW, I see large Java projects compile small changes take minutes to compile, even using hot-reload tools. Figwheel in Clojure is not like this, however: they're doing something right there.
- nine_k 6y agoHowever you frame it, compile times are going to be longer the more static guarantees you need to check, and the longer the more dependencies a particular code change affects. Making your code low-coupling if equally beneficial for the compiler and for the human to reason about the code. Hence modularization, limiting the visibility of parts, etc. OTOH there are situations when you have to have a common interface which is used across the board. Imagine Java's `List` or `CharSequence`. If you touch it, you have to recompile all the innumerable uses of it. So the more pervasive the dependency is, the smaller and simpler and more fine-grained it should be. Java's `List` does not do a hugely good job in the compactness department; it's pretty stable, though. You want the same trait from your most foundational interfaces.
- chrisseaton 6y ago> Care to explain more? Having been using Ruby for about 8 years and Crystal for about 4, they actually have an extremely similar syntax and are also semantically very close. To the point where many Ruby scripts are completely valid Crystal, or at the very least require only a few changes. It doesn't have Kernel#eval. It doesn't have Kernel#send. It doesn't have Kernel#binding. It doesn't has Proc#binding. It doesn't have Kernel#instance_variable_get/set. It doesn't have Binding#local_variable_get/set. It doesn't have BasicObject#method_missing. It doesn't have BasicObject#instance_eval. I could go on. All these methods have extreme far reaching non-local implications on the semantic model and practical performance, and specifically defeat many conventional optimisations. > To the point where many Ruby scripts are completely valid Crystal, or at the very least require only a few changes. You can't even load most of the Ruby standard library without these methods! And it doesn't matter if you use them or not. They're still there and they impact semantics and performance because the fact that you can use them affects performance. You can't even speculate against most of them as they're so non-local. Rails and the rest of the mainstream Ruby ecosystem fundamentally depend on them. > and are also semantically very close Sorry I super disagree with this. They look similar. Dig into it just below the surface? Start to model it formally? Not at all. Method dispatch, which is everything in Ruby, isn't even close. (Again, Crystal's great as its own thing, it's just not similar to Ruby's semantics. If you don't need Ruby's semantics or you can replicate them at compile time then maybe it's perfect for you.)
- dwheeler 6y agoAgreed. Crystal looks like it has many positive characteristics, but having similar syntax has nothing to do with having similar semantics. Without constructs like missing_method, you cannot run practically any of the Ruby ecosystem libraries, including everything involving Rails. Java and C also share a similar syntax, but that does not make that you can easily swap one for the other.
- remmargorp64 6y agoTo be fair, method_missing has caused more nightmares and problems with debugging than probably any other feature in Ruby. I actively avoid using it, and even the Rails team has massively dialed back on its use in their libraries over the years...