Crystal: Should crystal have something like Mutable Tuples

Created on 4 Jun 2019  路  10Comments  路  Source: crystal-lang/crystal

I recently ran into a situation where I was doing some unsafe casting, and I could not find a data-structure that mapped well.
I wanted to map one structure over another, and a Tuple was the best fit so something like.

x.unsafe_as(Tuple(Int64, UInt64))

The problem with this is that you cannot mutate the data underneath. There are some other options like StaticArray, Array, Slice. But none of these have different types for different positions. Would it be a benefit to add a positionally typed data structure that is mutable?

example:

x.unsafe_as(MTuple(Int64, UInt64))
question

All 10 comments

Or should []= be added to Tuple.

You could create a struct to matches your types:

struct MData
  # give default 'cause we don't need an initializer
  property first : Int64 = 0
  property second : UInt64 = 0
end

y = x.unsafe_as(MData)
y.first = 42_i64
y.second = 41_u64

(not tested)

@bew I am currently using custom structs for this. I did something similar to your example and I was still getting an initializer error. This Issue is more of a question of should there be a type ordered data structure in Crystal.

I don't think tuples and named tuple will become mutable. Making them immutable is helpful to implement some subtyping rules.

If something like mutable is to be implemented it would need to be invariant in their generic types always.

Mutable references which act as both sources and sinks are invariant. https://en.wikipedia.org/wiki/Subtyping

@wontruefree feel free to share the initialization error in other thread.

Not adding mutability to tuples makes a lot of sense. This originally was should there be a mutable data structure that has ordered types. Something like and ordered list or something.

OrderedList(UInt64, UInt64, Byte, Byte)

Interesting. Should values in a tuple be mutable, as long as they don't change their type?

AFAIK a tuple is an anonymous struct with indexed fields instead of named fields. Being mutable or immutable doesn't change the type system 鈥攊ndexed fields do have a type that must be respected, just like struct named fields do.

A difficulty, thought, is that []= can't represent that each index has its own type, and it may be awkward to have a special case in the compiler for that. And what about NamedTuple: should be mutable, too?

Or maybe a solution is just to create another Tuple with copied / new values, or to use a Record and #copy_with.

I am trying to avoid copies in my case but maybe copy is the best way to do this.
If you use constants Tuples can currently figure out the type I wonder if []= could also do that.
https://github.com/crystal-lang/crystal/blob/master/src/tuple.cr#L135

if using Tuple and you want it "modified" per say, you can just re-assign it to a newly changed Tuple. Or, can just use an Array

my ItemTuple has over 20 indexes, and I have a modify_item_tuple method that updates it. it works perfect.

Tuple is inherently immutable by definition, so there is no issue here. Although, if you want something more like a Tuple, but modifiable, it should be named something else.

edit: I just saw your example, ignore my last sentence ty

x.unsafe_as(MTuple(Int64, UInt64))

Interesting

There's also a merge method, FWIW...

So, can we close this with a "no"? :)

Was this page helpful?
0 / 5 - 0 ratings