5 ms·
I wonder how Ruby will compete with this. Crystal basically seems like Ruby 3.0 to me (major improvement is speed, btw Ruby is currently on 2.*).
by stevemk14ebr 10y ago
I wonder how Ruby will compete with this. Crystal basically seems like Ruby 3.0 to me (major improvement is speed, btw Ruby is currently on 2.*).
- eropple 10y agoPretty easily. Crystal looks like Ruby, but it doesn't feel like Ruby or work like Ruby. It seems fine, in a very Golang "it works for projects where you need to fling a blob of binary somewhere" sort of way, but it's not remotely as dynamic-as-a-language as Ruby (and that dynamism is precisely why I use Ruby), nor is it dynamic-as-a-platform--something like CLR assembly loading or Java classloading to get a statically-typed, reflective representation that gives me something similar. And you might not need that, and it's totally cool. But Ruby enables a lot of things Crystal, as designed, seems unable to. It's not bad. It's fine. Not the pejorative, dismissive sort of "fine", but fine. But it's not Ruby. Ruby is slow in large part because Ruby does hard things. Some of them aren't really advisable, from a perf perspective--but they are from a human perspective, and Ruby preferring humans over computers is a huge feature for me.
- stcredzero 10y agoWhat if it had a really powerful debugger?
- eropple 10y agoHaving a "powerful debugger" is orthogonal to "can I dynamically define classes at runtime, when that makes sense to solve my problems?" and "can I load a library that's annotated to make for a simple extension system?". Like, take a look at this[1]. I wrote it for a game engine in C#. It allows for dynamic loading of modules or static packaging on platforms that require it. This is what I would consider a low-end thing for a Ruby application that needed extensibility--just something you do out of hand. Crystal can't do that. Maybe it will in the future, but it's not even a 1.0 feature. So Crystal might be a challenge to a Golang-ish thing, but it's not a challenge to a Ruby or a JVM/CLR thing on that front. [1] - https://github.com/eropple/Exor https://github.com/eropple/Exor
- AstralStorm 10y agoDo you really need to define code at runtime? Why not at compile time? Need to pull in templates and macros made by someone, but not the code that uses them? Plugins have a long tradition already, starting with the old dlopen and loadLibrary. Even in C++ (mostly) you can have it done, just look at Qt.
- chrisseaton 10y ago> Do you really need to define code at runtime? The people who wrote Rails thought they did - it defines tons of code at runtime. We can't say that they needed to or not. Nobody needs a programming language abstraction. But it worked for them.
- eropple 10y agoWell, for one, Crystal doesn't support PIC, so you can't write dynamic code in the first place. For two: yeah, I very regularly do need to define code at runtime. Consider ActiveRecord (or, like, all of Rails, but ActiveRecord specifically), which hits up your database for its schema at runtime to build its API. Consider that it's totally normal in Ruby to use an `if` statement in your class definition; for example, I will replace entire implementations of functionality if I know I'm running in JRuby rather than MRI, without having to add some weird thunking layer. Consider that it's normal to not only `extend` other people's classes, but to write `self.extended` hooks in your own classes to respond to it. A class in Ruby is just an object. It is not a Class, it inherits from Class. Mutating them to achieve your goals is commonplace and valuable. It's the closest thing to brain candy as a meaningful, good Lisp I've used since college. (Clojure is not my thing. And obviously I know that Ruby has a lot of Smalltalk-ish stuff in it rather than Lisp, but I never used Smalltalk...) You can fake a lot in a compiled language. I have done this. But you had better be getting significant wins for doing it, and something like Crystal does not offer them over something like Ruby unless you're doing something that doing it in Ruby was a bad idea in the first place. (If you wrote something in Ruby where you actually cared about perf, for example, you picked wrong.) Right now, writing Rust plugins and using them from Ruby is a more Ruby experience than Crystal is. Which isn't a shot at the language, I have to stress--just that it's not Ruby, it's something very different.
- rifung 10y ago> that dynamism is precisely why I use Ruby Could you elaborate? I've never felt like I really needed a dynamic language but that might be because among dynamic languages I only know Python and a little Javascript. I still use them, but I don't feel like I really take advantage of the fact they are dynamic.
- eropple 10y agoI don't need a dynamic language. But for many tasks, I want one. For others, I have languages that are, to be honest, more expressive than Crystal--C++ or C# or Kotlin or Scala. I would not attack Ruby problems in those languages, nor would I in Crystal. Don't get me wrong: it's more expressive than Go, so that crowd should totally pile on Crystal and make it better 'cause I'd rather have to deal with Crystal, which while I think it's not really anything special I don't think it's bad, and to me that's a big step up. But they won't, so, whatever. Anyway, moving on. `include`, `extend`, and `prepend` are used a lot in Ruby because the very mutable nature of class definitions allows for powerful metaprogramming without having to do a lot of work--and all are, and can't not be, runtime-evaluated. I regularly build objects in Ruby out of dynamically generated mixins reliant on runtime behavior. As do most people. Consider ActiveRecord (which I don't care for, but it's a good example). You create a class that inherits from ActiveRecord::Base--and, at runtime, it queries the database and builds a set of methods for the class based on the schema of its table. Or something like dry-struct, which evaluates, at runtime, a set of attribute specifications and dynamically creates the API for accessing it (as well as validators, etc., which can be programmatically devised). And that's not even taking into account a plugin architecture that is functionally "require this file" and being able to interpret it at runtime; Exor, linked above, is a lot of pretty finicky work to simulate a worse version of that in C#. Or the general usefulness and value of monkey-patching in a lot of contexts. Oh, and I can drop `binding.pry` into any spot in my code and have a REPL in which I can define methods on existing classes, inline, and build functionality that I can then dump out into my editor. Compiled languages that do that are, er, rare. (JRebel and hot reloading isn't as nice as just doing it.) Ruby isn't the perfect tool. But when I want to write a little code to do a lot and don't have many other concerns, that's why I go to it. That's why something like Chef uses it instead of the programming mistake of 2014-2016 (using YAML for everything). Because nothing code-related expresses intent better than code itself, and Ruby is built around making that easy for me when I can think about classes and modules as things that exist rather than immutable blueprints off in the ether.
- rubyfan 10y agoYou sum up my finding on Crystal really nicely. I wish I could upvote your comment more than once. Crystal is nice but I've found simple dynamic things to be a challenge. I haven't looked in a few months but I wasn't able to do this a = [] a << 1 a << "two" Same with hashes. This broke some things for me and ended up feeling like I wanted to program in Ruby but there were all these gotchas. If I have to break the mental expectations I have for writing something to get the performance needed, then I'm fine to switch gears and write Java or C in order to get it.
- RX14 10y agoYou seem to make the assumption that crystal's purpose is to be for ruby developers, and as soon as it deviates from ruby, you've switched gears and might as well use Java or C. I don't think that's the case. Crystal takes its syntax from ruby because it's easy to write, easy to read, and familiar, it doesn't have to be the same as ruby in semantics. In fact that's impossible because it's statically typed (which I personally prefer to ruby). If you're going to resort to Java or c for speed, why not use crystal? Crystal beats Java and c on expressivity of type system, expressivity of code (less boilerplate) and performance per unit effort (at least on common tasks). So the question is why Java or c? They both certainly have larger and more mature ecosystems, and if you have compute-heavy workloads they'll probably win out on performance, but why do you instantly make the leap from crystal != ruby to "might as well use java/c"?
- RX14 10y agoActually, I'll expand on that and say that crystal isn't "static typing for rubyists", its more like "the best bits of ruby applied to static typing". There's a big difference in that the bits of ruby that crystal chooses to take may not be the parts that are most familiar to rubyists. That it is so similar to ruby is a huge complement to ruby in that there was so much that the team wanted to take. The hardest part of learning crystal for rubyists is unlearning their ruby habits when working on crystal. Once you're over that hill you might find crystal a wonderful language in its own right.
- 10y ago