Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Destructure more complicated data structures #226

Closed
Namek opened this issue Mar 21, 2020 · 8 comments · Fixed by #593
Closed

Destructure more complicated data structures #226

Namek opened this issue Mar 21, 2020 · 8 comments · Fixed by #593
Assignees
Labels
feature request help wanted Extra attention is needed language Language feature

Comments

@Namek
Copy link
Contributor

Namek commented Mar 21, 2020

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.

@Namek Namek changed the title Destructure enum in a tuple Destructure more complicated data structures Mar 21, 2020
@Namek
Copy link
Contributor Author

Namek commented Mar 21, 2020

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 */
    }
  => []
}

@teggotic
Copy link

teggotic commented May 4, 2020

I can take it

@teggotic
Copy link

teggotic commented May 5, 2020

@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")))
  }
}

DeepinScreenshot_select-area_20200505031206

@gdotdesign
Copy link
Member

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

@teggotic
Copy link

teggotic commented May 5, 2020

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

That worked out

@matthewmcgarvey
Copy link
Contributor

Trying to pick this back up. Will be taking from #283

@matthewmcgarvey
Copy link
Contributor

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.

value = tuple_destructuring || variable

What do you think?

@gdotdesign
Copy link
Member

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

@Sija Sija added the help wanted Extra attention is needed label Feb 16, 2022
@Sija Sija linked a pull request May 5, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request help wanted Extra attention is needed language Language feature
Development

Successfully merging a pull request may close this issue.

5 participants