Convert an StaticArray to a Tuple

I understand Array cannot be converted to Tuple without specifing the type because Array size is runtime known.

But why is converting StaticArray to Tuple not supported?

Tuple.from(StaticArray[1, 2])
expected argument #1 to 'Tuple(*T).from' to be Array(T), not StaticArray(Int32, 2)
                                         Overloads are:
                                          - Tuple(*T).from(array : Array)

May I ask what’s the use case? I can’t imagine why you would need this.

You can do something like StaticArray[1, 2].unsafe_as(Tuple(Int32, Int32)) because the memory representation is the same.

1 Like

I suspect it wasn’t a conscious choice not to support it, but I bet it’s just that nobody has had a need for it. Most things in the stdlib exist because someone needed it, but StaticArray is pretty rare. I’ve only ever really seen it used as a micro-optimization, such as the buffer for a Slice to avoid allocating on the heap inside a completely encapsulated operation where the StaticArray and the Slice never leave the method. It seems either you have a very uncommon use case or a different solution may be more appropriate for what you’re trying to accomplish.

That said, if you really need this, you can make it work pretty simply with this patch:

struct StaticArray
  def to_tuple
    {% begin %}
      {
        {% for index in 0...N %}
          self[{{index}}],
        {% end %}
      }
    {% end %}
  end
end
3 Likes

Just curious, why is StaticArray rarely used? Is fixed size array not very useful in crystal?

For most things, a Slice fills that role. StaticArray doesn’t incur GC cost, but Slice has a few benefits over the StaticArray:

  • It doesn’t require the size to be known at compile time because the size is part of the type
  • Mutating a StaticArray can cause subtle bugs because the buffer is allocated on the stack, whereas Slice’s buffer is typically a reference to heap-allocated memory

My question was not insinuating that StaticArray is rarely used. I was asking about the conversion from StaticArray to Tuple for which I cannot think of many use cases.

I was reading about Splats and tuples and I thought it would be cool to splat StaticArray. But splat was only for the tuple type. (I’m learning the language and I really like it :blush:)

I just wanted to know if this is possible:

def some_fn(a, b, c) end
some_fn *StaticArray[1, 2, 3].to_tuple

and now I know it is possible thanks to @straight-shoota and @jgaskins