roc-lang / roc

A fast, friendly, functional language.
https://roc-lang.org
Universal Permissive License v1.0
4.4k stars 309 forks source link

Monomorphization bug in `Pair x y = ...` #451

Closed rtfeldman closed 2 years ago

rtfeldman commented 4 years ago

To reproduce: change the Quicksort example to destructure Pair values inline where possible, instead of using when with one branch.

Like so:

quicksortHelp : List (Num a), Int, Int -> List (Num a)
quicksortHelp = \list, low, high ->
    if low < high then
        Pair partitionIndex partitioned = partition low high list is

        partitioned
            |> quicksortHelp low (partitionIndex - 1)
            |> quicksortHelp (partitionIndex + 1) high
    else
        list

partition : Int, Int, List (Num a) -> [ Pair Int (List (Num a)) ]
partition = \low, high, initialList ->
    when List.get initialList high is
        Ok pivot ->
            Pair newI newList = partitionHelp (low - 1) low initialList high pivot

            Pair (newI + 1) (swap (newI + 1) high newList)
        Err _ ->
            Pair (low - 1) initialList
folkertdev commented 3 years ago

This is really a parsing bug. This code causes a MalformedClosure

partition : I64, I64, List (Num a) -> [ Pair I64 (List (Num a)) ]
partition = \low, high, initialList ->
    when List.get initialList high is
        Ok pivot ->
            Pair newI newList = partitionHelp (low - 1) low initialList high pivot
            Pair (newI + 1) (swap (newI + 1) high newList)

        Err _ ->
            Pair (low - 1) initialList

but everything is fine when we put parens around the pattern match:

partition : I64, I64, List (Num a) -> [ Pair I64 (List (Num a)) ]
partition = \low, high, initialList ->
    when List.get initialList high is
        Ok pivot ->
            (Pair newI newList) = partitionHelp (low - 1) low initialList high pivot
            Pair (newI + 1) (swap (newI + 1) high newList)

        Err _ ->
            Pair (low - 1) initialList
rtfeldman commented 2 years ago

This works now, even without the parens!