Skip to content

Suspended application of default arguments playing badly with warnings and causing weird behaviour #10605

@radeusgd

Description

@radeusgd

Consider the following repro suspending-defaults.enso:

from Standard.Base import all

type My_Table
    Value x

    union self (tables : My_Table | Vector) arg1=1 arg2=2 arg3=3 =
        IO.println "Called ("+self.to_text+").union "+tables.to_text+" with "+arg1.to_text+" "+arg2.to_text+" "+arg3.to_text
        My_Table.Value [self.x, tables, arg1+arg2+arg3]

    columns self =
        "{Columns = "+self.x.to_text+"}"

call_union tables =
    first = tables.first
    rest = tables.drop 1
    first.union rest ...

main =
    check table =
        IO.println table.columns
    check <| call_union [My_Table.Value 1]
    tw = Warning.attach "foo" (My_Table.Value 2)
    check <| call_union [tw]
	check <| call_union [tw] arg2=1000

Actual behaviour

Running the above script yields:

Called ((My_Table.Value 1)).union [] with 1 2 3
{Columns = [1, [], 6]}
Called ((My_Table.Value 2)).union [] with 1 2 3
Called ((My_Table.Value 2)).union [] with 1 2 3
Called ((My_Table.Value 2)).union [] with 1 2 3
Execution finished with an error: Method `columns` of type My_Table could not be found.
        at <enso> suspending-defaults.main.check<arg-1>(suspending-defaults.enso:20:20-32)
        at <enso> suspending-defaults.main.check(suspending-defaults.enso:20:9-32)
        at <enso> suspending-defaults.main(suspending-defaults.enso:23:5-28)

We can see 2 anomalies here:

  1. The second call to union is executed 3 times (!) (as indicated by the prints) even though it should only happen once. We have a problem with re-running a side-effecting computation - that should never happen!
  2. Afterwards, the return value is somehow broken and we cannot call the columns method on it. Even though in the exactly same scenario above such call has worked all fine.

The difference between first and second calls is only that the second one contains warnings.

Expected behaviour

The program should print

Called ((My_Table.Value 1)).union [] with 1 2 3
{Columns = [1, [], 6]}
Called ((My_Table.Value 2)).union [] with 1 2 3
{Columns = [2, [], 6]}
Called ((My_Table.Value 2)).union [] with 1 1000 3
{Columns = [2, [], 1004]}

Metadata

Metadata

Type

No type

Projects

Status

🟢 Accepted

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions