Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between Hash and NamedTuple in Crystal?

Both syntaxes look rather equivalent, and their use cases are similar too. Example:

# Hash
hash = {"name" => "Crystal", "year" => 2011}
hash["name"] # outputs: Crystal

# NamedTuple
tuple = {name: "Crystal", year: 2011}
tuple[:name] # outputs: Crystal

So where exactly those two primitive differ from each other?

like image 503
Claudio Holanda Avatar asked Jul 27 '18 15:07

Claudio Holanda


1 Answers

The API docs already explain this pretty good. From NamedTuple (emphasis by me):

A named tuple is a fixed-size, immutable, stack-allocated mapping of a fixed set of keys to values.

You can think of a NamedTuple as an immutable Hash whose keys (which are of type Symbol), and the types for each key, are known at compile time.

And further:

The compiler knows what types are in each key, so when indexing a named tuple with a symbol literal the compiler will return the value for that key and with the expected type. Indexing with a symbol literal for which there's no key will give a compile-time error.

In contrast, Hash:

A Hash is a generic collection of key-value pairs mapping keys of type K to values of type V.

Put in simple words, a hash is a data structure that can be changed at runtime and all keys/values can have any type as long as it matches the generic type arguments K/V. A named tuple on the other hand is an immutable data structure which is completely known at compile time. If you access a key, the compiler knows its type. Having a named tuple is pretty much similar to just having the keys as variables with a common prefix:

foo = {bar: "bar", baz: 1}

foo_bar = "bar"
foo_baz = 1

NamedTuple just adds a few tools to use these variables as a coherent set.

like image 140
Johannes Müller Avatar answered Nov 10 '22 20:11

Johannes Müller