top | item 17753367

Crystal 0.26.0 released

102 points| parvenu74 | 7 years ago |crystal-lang.org | reply

40 comments

order
[+] interfixus|7 years ago|reply
Some grumpiness in quite a few comments. Pity. This is an awfully nice language to work with, and the toolchain is starting to grow up - the compiler appears much speedier these days than it used to. Also: A real grassroots effort unencumbered by megacorporation agendas (Yes, I know. Manas is a comparatively small Argentinian company, and kudos to them for having got the ball rolling). Give these guys a hand like they deserve. If Crystal keeps on the way it promises, parallellism will be there, and will be a joy to handle.
[+] payne92|7 years ago|reply
Pro tip: when posting to HN, include a summary of "what it is"! It's often hard for readers to figure it out from a changelog.

From the docs:

"Crystal is a programming language with the following goals:

Have a syntax similar to Ruby (but compatibility with it is not a goal).

Be statically type-checked, but without having to specify the type of variables or method arguments.

Be able to call C code by writing bindings to it in Crystal.

Have compile-time evaluation and generation of code, to avoid boilerplate code.

Compile to efficient native code."

See: https://crystal-lang.org/docs/

[+] xellisx|7 years ago|reply
I keep thinking it's Crystal Reports every time it shows up on HN.
[+] farresito|7 years ago|reply
You are one click away from the home page, where there is a nice explanation.
[+] weberc2|7 years ago|reply
> Be statically type-checked, but without having to specify the type of variables or method arguments.

My experience with both Go (type annotations always) and Python (type annotations sometimes) has me pretty skeptical about this misfeature (perhaps someone with Crystal or OCaml experience can tell me why I'm wrong).

When implemented properly (i.e., like Go, not like Java), code with annotations is more readable (this isn't controversial), and adding them is a matter of keystrokes. Note that this isn't a static vs dynamic argument; Crystal is still a static language and you still have to deal with type errors, so you don't get the "get the happy path working at the expense of bugs in other paths" rapid-prototyping benefits that dynamic languages boast about; you just hit fewer keys (maybe this is Crystal's workaround for supporting multi-char scope delimiters!).

I'm guessing in practice you have a mediocre editor that will show you the type annotations with some nonzero amount of effort, and when you're doing code review, you're just forced to jump around to figure out what types are? Or depend on docstrings that grow stale? These seem like a lot of costs, not to mention the effort from the dev team to support this "feature", all to save users a few keystrokes?

[+] weberc2|7 years ago|reply
> In 0.25.0 we tried to improve the inferred type of unions of sibling types. Although it worked well for the compiler itself, some codebases out there exhibited some combinatorial explosion of unions due to this change.

What is a union of sibling types? Why would improving type inference require unions to be _generated_? I skimmed the PR referenced in the changelog, but it assumes domain knowledge I don't have (I'm only nominally familiar with Crystal).

[+] ezrast|7 years ago|reply
I'm not a Crystal developer but I think this is accurate:

The way Crystal's type inference works, if you have a variable that sometimes can be assigned a Foo and sometimes can be assigned a Bar, then that variable will have the inferred ("generated") union type (Foo | Bar). This usually works great, but the compiler runs into performance issues if these unions become very large (more accurately, it happens when the number of distinct such unions that gets passed to a particular method is large, for which a large possible union space is a precondition).

In practice, this tends to happen in class hierarchies with many descendants from a single root class. As a somewhat kludgey workaround, the compiler will simply forget about the union in these cases and use the parent class instead. For example, a method that looks like it should take a (Bat | Cat | Dolphin | Dog | KoalaBear | Hog) will actually just take a Mammal. This can be bad if Mammal doesn't implement all the common capabilities of those specific subtypes. For example, adding an Echidna subclass that doesn't implement the birth_live_young method can cause calls to `cat_or_dog.birth_live_young` to fail even in places that type inference "should" be able to determine that `cat_or_dog` will never hold an Echidna. However, it's deemed a necessary evil unless/until the compiler can be reworked to handle such cases without exploding compile times.

[+] emmelaich|7 years ago|reply
People interested in Crystal might also be interested in Inko.

It's Ruby-ish but less compatible, https://gitlab.com/inko-lang/inko

> "Safe and concurrent object-oriented programming, without the headaches. Inko is a gradually-typed, safe, object-oriented programming language for writing concurrent programs. By using lightweight isolated processes, data race conditions can not occur. The syntax is easy to learn and remember, and thanks to its error handling model you will never have to worry about unexpected runtime errors."