I think this is quite an interesting topic. The current status in the language is not finished. We have symbols and enums, and having both is probably not a good idea. There seems to be a common understanding that enums are strictly superior to symbols for their type safety. So there need to be some refinements, probably before 1.0 release of Crystal. So it’s a good idea to consider and discuss ideas how this could evolve.
I read your blog post comparing Crystal and Type Script where you claim that enums should be removed from the language and replaced by literal types. I understand the general concept, but I’m not familiar with literal types in TypeScript. I’ve read a short overvier about it to follow up on what you’re talking about.
First of all, it seems TypeScript also has enum types besides literal types. So it seems they can’t fully replace them? Or do you think that enum types are unnecessary in TypeScript as well?
Considering your comparison in the above comment, I think there’s actually little point to. The imaginary syntax for literal types could very well just refer to enums. The implementation doesn’t exist yet, but everything we need to make the suggested syntax work could essentially just be applied to enums. Even
alias Foo = :foo | :bar could work as syntactic sugar for
enum Foo; FOO; BAR; end.
I also believe that
Enum#to_json should use the downcased name by default. This is probably what most users would expect, especially since it corresponds to the string literal.
Literal types don’t provide a mapping between labels and values. They can only ever be either a label (string/symbol) or a value (number or other data types).
When you only need labels, type literals might be good enough. But many use cases need to connect labels with specific values (for example for interfacing with some kind of external API). Then you have to choose to either use fixed values in code (which then also serve as labels), or you use only labels and need to map them to values in a different way. Both options are not desirable because they lack context.
Crystal’s enums can only use number types as values. Enums in Java for example are more powerful, you can declare custom properties and even override methods for individual entries. I suppose this could technically be added in Crystal as well, but maybe we can live without it. Technically, it should probably even be able to work without compiler support using macros.
In case I missed something, please correct me. Do you agree with my assessment or are there other benefits of literal types that can’t work with enums? I actually don’t see much difference between how you described literal types and how enums could work when we remove symbol as a data type.