1. 25
  1. 5

    Crystal seems interesting and really loved by its community !

    I write a lot of web services with Python/Django at work, and I am curious about how would it works in the Crystal land ? Does someone has some experience to share :) ?

    1. 2

      I’ve toyed around with some of Crystal’s web frameworks. There’s Kemal, which is Sinatra/Flask-ish, and Lucky which is more Rails/Django-like. I’ve also heard good things about Amber. All of these frameworks feel at least somewhat familiar. When I last used it (about a year ago, I think), Kemal felt a bit rough around the edges, but a quick perusal seems to show it’s grown a lot in that time.

    2. 4

      I love the dedication to cleaning up the language before 1.0. I do enjoy writing Ruby but I’m frequently frustrated by the quirks, inconsistent quality and conventions in the standard library, and lack of documentation (especially around types, where you often need to guess based on the parameter names). I see Crystal as a chance to fix all that while retaining the parts I love, so I hope it takes off when 1.0 comes along.

      1. 4

        Super exited about the addition of Exhaustive Case!

        Working with Crystal is pure pleasure: type safety with a familiar syntax, and best of all, the compiles result is quite fast!

        1. 3

          I wonder which of nim and crystal will emerge as the new “productive, readable, efficient language that compiles to native”. Both seem to have a lot in common, except nim is python-flavored and puts a bit more emphasis on compile-time evaluation, and crystal is ruby-flavored and has fibers instead of async/await. In any case I think it’s great we finally move towards less wasteful languages that still feel expressive (and safer!) to the user.

          1. 3

            That’s a weird way of framing it – there are a lot more than 2 languages vying to be that, some of which are already more popular than either Nim or Crystal, and there won’t necessarily be one “winner”.

            1. 3

              I don’t consider zig and rust to be in the same category, they place a lot more emphasis on manual resource management (either passing allocators explicitly everywhere, or dealing with explicit lifetimes). The goal is to get maximum performance. On the other hand, D, crystal, and nim still try to be more convenient to use by having a GC by default. To me that’s a big difference.

              1. 2

                Swift?

                1. 1

                  How about Go, then?

                  1. 1

                    Right, I imagine Go and Swift are aiming at a similar branch. I tend to not think too much of them because of personal preferences (swift is kind of second class on linux, and Go is… quite contrary to my tastes, it’s kind of vintage). They still do belong in this vein of “faster than dynamic languages, more convenient and easier than C”.

                2. 2

                  What other languages do you see in this space? Zig and rust come to mind. D as well.

                  1. 2

                    All of them? :) I don’t think there is any language that compiles to native code that is not trying to be more “productive” and readable like Python or Ruby, while still being efficient. Swift, Go, Kotlin (native), etc.

                    Beef is one of the more impressive efforts I’ve seen, at least by an individual:

                    https://github.com/beefytech/Beef (as far as I remember it’s basically C#-like productivity that compiles to native code)

                    Even Rust and C++ are there. You can find a lot of “advertisements” of them as being as productive and simple as Python. But I would say those two languages have some other goals that they are not willing to compromise:

                    • C++ consciously leaves no room for a lower level language between it and assembly language (the standards comittee seems to use this as a guiding principle)
                    • Rust seems not to compromise about safety or performance.

                    Every other new native language seems to be focused on Python/Ruby-like productivity as their #1 goal as far as I can tell (which is a generally good thing, although I guess the jury is still out on to what degree that’s possible.)

                    Personally I think most people misunderstand that dynamic languages are not really about being too lazy to write types; it’s more that metaprogramming/DSLs are a huge productivity advantage and are to a great degree in conflict with elaborate type systems.

                    1. 1

                      I mostly agree with your points (though I never heard anyone call C++ “simple” 😂). However, half these modern static languages also have powerful metaprogramming abilities that may compete (or out-compete, even?) what dynamic languages have to offer: Zig and D have compile time evaluation and introspection, Nim has full-on macros… And you don’t pay anything at runtime. I’m optimistic that this will also keep productivity on par with dynamic languages, or better due to less debugging.

              2. 2

                The way that Windows is mentioned in passing, while stressing that 1.0 is close, is making me worry that we will not see Windows support until after 1.0. I would not like that.

                Otherwise, I really appreciate the cleanup of the standard library! Better do it before 1.0 than to keep things for “backwards compatibility”.

                1. 2

                  Following a recent Crystal blog post about the upcoming 1.0 release*, it seems that the Windows support might end up in 1.X releases.

                  *Towards Crystal 1.0

                  1. 1

                    Esp. weird for me given they seem to claim being interested in portability.

                    1. 1

                      Yeah, that sounds like a recipe for breaking changes.

                  2. 2

                    I’m very intrigued by Crystal but find it a bit disappointing that code is not typechecked until it’s called. For example, this will compile just fine:

                    class Foo
                      def hello
                        asdf
                      end
                    end
                    

                    And only when we include a call to that method does a type error occur:

                    Foo.new.hello
                    

                    Error: undefined local variable or method 'asdf' for Foo

                    1. 7

                      If you squint it looks like a feature; the compiler doesn’t waste time evaluating dead code.

                      1. 4

                        The real reason behind this is that every method in Crystal is equivalent to a template function in C++. When you write,

                        def f(x, y, z)
                         x+y+z
                        end
                        

                        That is equivalent to C++’s

                        template <typename X, typename Y, typename Z>
                        auto f(X x, Y y, Z z) {
                          return x + y + z; 
                        }
                        

                        In C++, unless there’s a parse error, f would also not be checked until it’s called.

                        In Crystal, this decision allows for typechecking duck-typed code, but leads to the issue you describe.

                        1. 1

                          Ruby is the same way.

                          Most of your tests are just there to ensure every code path gets type checked during your test runs.

                          This is probably a concession to the dynamic nature of the language, it is very difficult (impossible?) to determine that the type will still be incorrect by the time it is actually invoked at runtime.

                          1. 6

                            This is not true. Crystal is type checked at compile time - you just need to have a call to a function in your code to cause it to get typechecked. So while annoying perhaps (code isn’t type checked if it isn’t used), this is not like Ruby (you will not get runtime type errors here - you either don’t call the function so it can’t cause a problem at runtime, or you do call the function and the error is caught at compile time).

                          2. 1

                            when is this ever an issue? You still will not get a runtime type error

                            1. 2

                              It’s certainly not a big deal but means that every code path needs a test in order to be typechecked (like andrewballinger mentioned).

                              1. 2

                                Every code path needs to be called statically, but every code path does not need a test.