brownplt / pyret-lang

The Pyret language.
Other
1.07k stars 111 forks source link

odd error when using sets #1665

Open shriram opened 2 years ago

shriram commented 2 years ago
import sets as S

type Key = String

cities =
  table: code :: Key, name :: Key
    row: "PVD", "Providence"
    row: "EWR", "Newark"
    row: "SFO", "San Francisco"
  end

flights =
  table: origin :: Key, destination :: Key
    row: "EWR", "SFO"
    row: "SFO", "EWR"
    row: "PVD", "EWR"
    row: "EWR", "PVD"
  end

fun neighbors(k :: Key) -> List<Key>:
  matches = sieve flights using origin: origin == k end
  #  matches.get-column("destination")
  extract destination from matches end
end

check:
  neighbors("PVD") is [list: "EWR"]
  neighbors("SFO") is [list: "EWR"]
end

If I run the above (the two tests pass) and then run

S.list-to-set(neighbors("EWR")) == [S.set: "PVD", "SFO"]

I get true (the expected output). If I make the above into a test

check:
  S.list-to-set(neighbors("EWR")) is [S.set: "PVD", "SFO"]
end

everything still works. But if I remove the S. on the RHS:

S.list-to-set(neighbors("EWR")) is [set: "PVD", "SFO"]

then

  1. The error looks as follows; in particular, it says "the left side as not a defined convenience operator":
image
  1. All subsequent uses of the REPL error:
image
shriram commented 2 years ago

Worse: even AFTER the tests pass, the REPL is unusable, giving the "Key" error!

shriram commented 2 years ago

Removing the Key definition entirely makes all these problems go away.

Note that I'm in untyped CPO.

blerner commented 2 years ago

I can solve one part of this: That "not a convenience constructor" is working as intended: set is referring to this set from the lists module, as exported by essentials2021 line 73.

use context essentials2021
import sets as S
[S.set: 1, 2, 3, 2]
set([list: 1, 2, 3], 2, 5)

produces

[list-set: 1, 2, 3]
[list: 1, 2, 5]

The business with the Key type definition is a bit weird, though.

shriram commented 2 years ago

I don't understand this response. It says the LEFT side was not a defined convenience constructor. There is no convenience constructor on the left side.

blerner commented 2 years ago

There are two left sides here. The left side of the overall test expression... And the left side of set.make(...), which is the desugaring of [set: ...]

shriram commented 2 years ago

That's not very clear at all!

blerner commented 2 years ago

To be fair, it highlights only the construction expression when it's talking about a left side of [set: ...]. It's unfortunate that you happen to be using it in a context with a far more intuitively "left" left side.