I was porting some ruby code to crystal at work that had constants declared as:
FOO = %w(hey ho)
The natural Crystal version of this is
FOO = {"hey, "ho"}
So I was thinking if would be nice to have a %something to declare tuples of strings. First I was thinking about having a %t to do that, but it is misleading, t reminds tuple however tuples can be made from anything, so %t(1 2 3) can confuse people thinking is translates to {1, 2, 3} instead of {"1", "2", "3"}.
So maybe %wt(hey ho) is better, wt => words tuple. Is this reasonable? Do we already have too many %things?
I think this would be too much.
Also the natural Crystal version is already %w(hey ho) == ["hey", "ho"]. IMO this is not a typical use case for tuples.
I would not disagree about the “too much”, since there are %r, %q, %Q, %w, %W and %i that I remember…
But I disagree about the natural Crystal version, since it’s a constant it’s better to have the data in a static array or a tuple to avoid memory allocation.
For constants, tuples are a great way to avoid accidental mutation — for example, when a misguided developer uses FOO << "bar" instead of FOO + ["bar"] or other similar mutation. We don’t have Ruby’s freeze in Crystal so we can’t protect arrays against modification.
Though, array is a reference, but, why we want to use a const like Foo < 'c' ? Why we are not consider FOO is frozen as default? i don’t think there is any benefit.
if frozen as default, user can copy code like FOO = %w(hey ho) directly from ruby, and compiler can deduce, 1. it is a const. 2. it length is small, we can allocate it directly in stack (same as FOO = {'a', 'b'})