Plans on certain language features


Hello there,

I’d like to ask about the future of some language features to find out if the team has strong opinion on that. I’m asking that because there were doubts either on Gitter or in the issues, and I want to clarify:

  1. Annotations – these bother me a lot, because they don’t have the most beautiful syntax there yet they’re extremely helpful, as they allow to do great composition and work well with upcoming incremental compilation feature. I’ve rewritten my params parsing shard to annotations – – and I’m very pleased
  2. Generics – they’re currently quite buggy and I wonder if the team is going to keep them
  3. Unions – they’re not buggy, so just to be sure
  4. Macros – Ary once said that he doesn’t like them. But for me, they’re one of the greatest features of the language. Any plans on removing them on 1.0?
  5. Symbols – IIRC they’re going to be removed in favor of autocasting enums
  6. NamedTuples – some say using Structs is better
  7. [] of Foo and {} of Foo => Bar syntax – hm?

Thanks for the response, team!


There are naturally some differing opinions in the core team on these features. Here’s mine:

  1. I like them, I think they’ll keep the same syntax.
  2. They’re a necessary feature, they won’t be going away, but there’s some nasty bugs here and corner cases will likely change before 1.0.
  3. Removing unions isn’t going to happen while this project is still called crystal.
  4. Macros will stay, that they exist is a good thing. But you should try as hard as you can not to use them because they’re a last resort. They may change syntax, but that’s unlikely.
  5. They might or might not be removed. I don’t think anyone has scoped out fully the barriers to removing them. I’d be supportive of removing them.
  6. Named tuples I don’t think will go, but often using records is cleaner.
  7. Won’t go.

I doubt you’ll get the same answer from every core team member, but that’s fine and expected. Until something is decided officially on github, in an issue, its just an opinion.


Read this as my point of view only,

Beauty is in the eyes of the beholder :-). I know you don’t like the syntax that much, but I found it good enough. What I do think is missing in annotation is a way to query/iterate what constants/methods have them applied. Having those constructs in macros will enable a more declarative metaprogramming in some scenarios.

The bugs are related to the metaclass model and there since there is no variance/covariance syntax there is a limit in what can be expressed regarding the subtypes when generics are involved. I don’t think that generics are going away. Some languages lacks generics at all for some versions, crystal might have some gaps.

United Unions for the win. They are in the very core of the language. Although having explicit unions (like Haskell) leads to great results I think implicit unions plays good with other aspects of the language.

There are no specific plans on how macros could change right now.

There are no specific plans on how symbols could change right now.

There might be some gaps in the metaclass model here also, but NamedTuples has some flexibility that structs don’t support. Better or worst depends on the use case.

I don’t follow the question here. You can use Array(Foo).new but we won’t have a plain [].

In general crystal has been provided with lots of features we wished to have in other languages. The result is that maybe they impact in half way features in some cases. This is in contrast of starting really really small and adding feature as time goes.


Thanks for detailed responses, Brian, Chris! I’m glad that core features are about to stay.

I’m already trying to avoid them anywhere in my code :wink:

I agree, plus it could be useful to iterate through all the annotations a specific constant has!

Could you please elaborate on what are the limits? I’m concerned about abstract generic classes, generics specializations and accessing T in the macros outside the methods.


If Cat < Animal, then it would be good to infer that Enumerable(Cat) < Enumerable(Animal). But for example it is not true that Array(Cat) < Array(Animal). In order to express that, the usual path is to express the relationship of the type argument with respect the generic class. If we can’t express, we need to fix what is the semantic (and it will be 1/3rd of the options); or hardcode how some classes behave.