Motoko and array thought - sugar

these are just ramblings and likely unactionable but I’m posting them to see if someone smarter than me may have an easy solution to make my life easier

Just musing at the moment…but I write so many toArray calls that it would be interesting to explore some kind of sugar built in for unifying across different objects/collections. Many need a toArray function to convert from whatever creative structure they have to a basic array.

Maybe something along the lines of debug_show(which brings up another thought that it would be nice to be able to define show for our objects as well).

let myMap = Map.new<Principal, Nat>();
let myVector = Vector.new<Principal>();

//later

for(thisEntry in myMap[]){
  //do something
  // maybe there could also be an option for an accesor of some kind in that like myMap["keys"] or myMap["vals"]...
  // and maybe even a sexy built-in mapper like myMap[func (x:  (Principal, Nat): Nat { x.Nat}] .... which if there were a nice helper in the class then myMap[Map.keys]....
  // or maybe it is always a function and either Map.entries
};

for(thisCanister in myVector[Map.__entries]){

};

I don’t propose that as a solution as it looks kind of ugly.

I just end up with stuff like this all the time:

let trx = Map.fromIter<Text,ICRC16>(Array.map<ICRC16Property, ICRC16MapItem>(data, func(x) : ICRC16MapItem{(x.name, x.value)}).vals(), Map.thash);

// alternative

let trx = Map.fromIter<Text, ICRC16>(data[func(x) : ICRC16MapItem{(x.name, x.value)}].vals(), Map.thash);

// and if there were a fromArray, even better:

let tx = Map.fromArray<Text,ICRC16>(data[func(x) : ICRC16MapItem{(x.name, x.value)}]), Map.thash)

You can do this right now with piping…which I always forget about:


let trx2 = data |>
   Array.map<ICRC16Property, ICRC16MapItem>(_, func(x) : ICRC16MapItem {(x.name, x.value)}) |>
   _.vals() |>
   Map.fromIter<Text,ICRC16>(_, Map.thash);

//could become

let trx2 = data |>
   _[ func(x) : ICRC16MapItem {(x.name, x.value)})] |>
   _.vals() |>
   Map.fromIter<Text,ICRC16>(_, Map.thash);

so…as it comes together in my head:

    myObj[] returns an array by calling whatever is defined in __as_array;
    myObj[@] returns an iter by calling whatever is defined in __as_iter;
    myObj[function] returns the __as_array mapped through the function;
    myObj[@function] returns the __as_iter passed through he function as you iterate

   //example to define in object to get the funtionality
   system func __as_iter<K, V>(x: Map<K,V>) : [(K,V)]{
     return Map.entries(x);
   };

…is this really better than just saying Map.entries(myObj). or Map.map<MYType, YOURType>(myobj, func(x: MYType): YOURType{ x.y})

maybe…maybe not…not sure…but I kind of like the direction

and by defining __show we can define show for our objects for debugging and stringifying.

I’d write this like:

let trx2 = data
   |> Array.map<ICRC16Property, ICRC16MapItem>(_, func x = (x.name, x.value))
   |> _.vals()
   |> Map.fromIter<Text, ICRC16>(_, Map.thash);

and you can abbreviate as well:

let {fromIter; thash} = Map;
let trx2 = data
   |> Array.map<ICRC16Property, ICRC16MapItem>(_, func x = (x.name, x.value))
   |> _.vals()
   |> fromIter<Text, ICRC16>(_, thash);