Forem

Cover image for TIL Tuples vs Arrays in Crystal
Mario
Mario

Posted on

3 1

TIL Tuples vs Arrays in Crystal

Today I played around with Crystal... the programming language (🥁 ba-dum-tss).

Coming from Ruby, Crystal isn't a mystery in many cases, but in the end, I don't know much about it at all.

However, I learned something about Tuples and Arrays today.


It starts simple with a class that takes a String as an argument.

class TupleVsArray
  def initialize(@text : String)
    puts "Text: #{@text}"
  end
end
Enter fullscreen mode Exit fullscreen mode

Now let's decomposit an array into two variables, and then pass the first variable, foo, into the class:

foo, bar = ["foo", "bar"]
TupleVsArray.new(foo)     # Text: foo
Enter fullscreen mode Exit fullscreen mode

This works fine.
All elements in the array are of type String.
It compiles, it runs!


Let's change the second element in the array into a Symbol:

foo, bar = ["foo", :bar]
TupleVsArray.new(foo)
Enter fullscreen mode Exit fullscreen mode

This fails during compiling with this error:

Error: no overload matches 'TupleVsArray.new' with type (String | Symbol)
Enter fullscreen mode Exit fullscreen mode

To me, having little to 0 experience with type checking, this is fascinating... and confusing, because foo is allegedly never going to be a Symbol. Allegedly...

Then I realized that the array could be changed in the meantime, for example:

row = ["foo", :bar]
row[0] = :foo
foo, bar = row
TupleVsArray.new(foo)

# Error: no overload matches 'TupleVsArray.new' with type (String | Symbol)
Enter fullscreen mode Exit fullscreen mode

This time, the error makes absolutely sense.


Then I also learned, that in Crystal we cannot change an array's element to an not-yet-existing type:

row = ["foo", :bar]
row[0] = 42
Error: no overload matches '=' with types Int32, Int32
Enter fullscreen mode Exit fullscreen mode

If we want to change any element in row, we must only use String or Symbol.


So, in order to resolve the original problem, we need to use a Tuple, which is a

[...] fixed-size, immutable, stack-allocated sequence of values of possibly different types.

foo, bar = {"foo", :bar}
TupleVsArray.new(foo)     # Text: foo
Enter fullscreen mode Exit fullscreen mode

Alright, got it. 😊

(Photo by Cristofer Jeschke on Unsplash)

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay