nevalang / neva

🌊 Dataflow programming language with static types and implicit parallelism. Compiles to native code and Go
https://nevalang.org
MIT License
85 stars 7 forks source link

Implement equality for structs #613

Open emil14 opened 1 month ago

emil14 commented 1 month ago

Turns out if you'll try to compare two struct (that are map under the hood in Go), there will be a panic. We need to implement this. However, it's not that simple.

The thing is - in Neva we have structural sub-typing which means you can pass {a b c} where only needs {a b}. Now imagine situation like this - you have inport type {a, b} and you compare that to {a:1, b:2}. Now the question - what would you expect if someone will actually pass {a:1, b:2, c:3}? They are not equal, right? But if we use this logic, then question arrive - should you be able then to express "compare but ignore extra fields?".

Structural type-system created a problem for us. One possible solution to that is to implement structural/partial equality. You assert that bigger struct is partially equal to the smallest one.

(Ofc they have to be compatible by their static type first).

type SomeStruct struct { a int b int }
const data SomeStruct = { a: 1, b: 2, c: 3 } // we're allowed to have extra fields

component Main(start) (stop) {
    nodes { Compare, Println }
    :start -> ($data -> compare -> println -> :stop)
}

const expected SomeStruct = { a: 1, b: 2 }

component CompareStruct(data SomeStruct) (res bool) {
    nodes { Eq<SomeStruct> }

    :data -> eq:a
    $expected -> eq:b

    eq:then -> (true -> :res)
    eq:else -> (false -> :res)
}

Related to #609

emil14 commented 1 month ago

On naming of Eq

Instead of having N-arity or a/b or value1/value2 we should probably have actual and expected (like in Go's require.Equal). That sounds like an assertion but we don't return error/panic