mint
mint copied to clipboard
Destructure more complicated data structures
Let's examine this ugly function:
enum FieldType {
Island(Number, ConnectionSizes)
Connection(Number)
}
/* in a module */
addConnection =
(
idx1 : Number,
idx2 : Number,
genState : GenerationState
) : GenerationState {
case (Map.get(idx1, genState.fieldsMap)) {
Maybe::Just isl1 =>
case (isl1) {
FieldType::Island idx conns1 =>
case (Map.get(idx2, genState.fieldsMap)) {
Maybe::Just isl2 =>
case (isl2) {
FieldType::Island idx conns2 =>
try {
/* TODO update the genState */
genState
}
=> genState
}
=> genState
}
=> genState
}
=> genState
}
}
I would like to destructure tuple of 2 Maybes containing enums and directly access internal values of those enums.
case ({Map.get(idx1, genState.fieldsMap), Map.get(idx2, genState.fieldsMap)}) {
{Maybe::Just(FieldType::Island(_, conns1)), Maybe::Just(FieldType::Island(_, conns2))} =>
try {
/* TODO update the genState */
genState
}
=> genState
}
Currently even a Tuple of built-in types is not destructurable.
However, not just enums are important. Another useful case would be to destructure an array inside Maybe.
dirs = case (maybeDirections) {
Maybe::Just([dir, ...restDirs]) =>
try {
/* TODO process the stuff */
}
=> []
}
I can take it
@gdotdesign Could you help me a bit? @gdotdesign I have an issue when try getting a type of Ast::EnumDestructure on the compile stage. https://github.com/teggotic/mint/blob/19a247703cd2814a669fda0a5c5d73d18ee8abfb/src/compilers/case_branch.cr#L78 lookups[match] works on first function call, but params are not found there. This is the code Im trying to compile
enum A {
B(D)
C
}
enum D {
E(String)
F
}
component Main {
fun test(str : String) : Html {
<div>
<{str}>
</div>
}
fun isLoggedIn (userState : A) : Html {
case (userState) {
A::B (D::E str) => test(str)
A::C => <span/>
}
}
fun render() : Html {
isLoggedIn(A::B(D::E("Hello world")))
}
}

The lookups map is populated in the type checking phase: for the EnumDestructuring it's here https://github.com/mint-lang/mint/blob/master/src/type_checkers/enum_destructuring.cr#L26
What is missing is that since EnumDestructuring can take other things than TypeVariable you need to type check them here: https://github.com/mint-lang/mint/blob/master/src/type_checkers/enum_destructuring.cr#L28 (resolve param) which will type check the nested EnumDestructuring and populate the correct key in lookups
The
lookupsmap is populated in the type checking phase: for theEnumDestructuringit's here https://github.com/mint-lang/mint/blob/master/src/type_checkers/enum_destructuring.cr#L26What is missing is that since
EnumDestructuringcan take other things thanTypeVariableyou need to type check them here: https://github.com/mint-lang/mint/blob/master/src/type_checkers/enum_destructuring.cr#L28 (resolve param) which will type check the nestedEnumDestructuringand populate the correct key inlookups
That worked out
Trying to pick this back up. Will be taking from https://github.com/mint-lang/mint/pull/283
One problem that I'm not sure of a good way to solve right now is how to make sure that nested destructuring of non-tuples doesn't happen outside of a case statements. The problem I'm thinking of is trying to destructure an Enum inside of a tuple. In the parsing level, the compiler would have to know that it can be a tuple destructuring but only other tuple destructurings can be in it and not other types of destructuring. https://github.com/mint-lang/mint/blob/a700b11d0d3124c7afdd57f757e4f3eaf468f1a0/src/parsers/tuple_destructuring.cr#L9
What do you think?
In the parsing level, the compiler would have to know that it can be a tuple destructuring but only other tuple destructurings can be in it and not other types of destructuring.
I think this can be solved by having an argument for the tuple_destructuring function:
def tuple_destructuring(only_tuples_inside = false) : Ast::TupleDestructuring?
and then later on:
if only_tuples_inside
tuple_destructuring(only_tuples_inside) || variable
else
tuple_destructuring(only_tuples_inside) || variable || enum_destructuring
end