BlockstreamResearch / simfony

Rust-like high-level language that compiles down to Simplicity bytecode. Work in progress.
26 stars 9 forks source link

Handle function types #20

Closed uncomputable closed 2 days ago

uncomputable commented 6 months ago

The Simfony type system should handle values that are functions, such as closures.

apoelstra commented 6 months ago

Simplicity itself does not have a notion of function types.

How would you compile something like map(f, g) which outputs g . f?

uncomputable commented 6 months ago

Simplicity expressions are functions that take an input value and return an output value. This is what I am trying to replicate in Simfony.

If we have a Simfony function f with a signature, then we can construct an input type. We translate variables inside f as Simplicity expressions that return the corresponding value from the input type.

Calls to f assign each argument variable to a value. We translate the call by constructing a value of the input type of f, using the assigned argument values, and passing the input value to the translation of f via comp: comp [input value] [f].

map(f, g) is translated as comp [f] [g].

(We need to redefine the environment and translation of Simfony to Simplicity before we can do what I just described. However, translating functions should be possible.)

apoelstra commented 6 months ago

map(f, g) is translated as comp [f] [g].

Innnnteresting. Ok. I would like to see an example which does something like this to better understand the closure syntax.

Could a user define map in Simfony or would it need to be a builtin? Maybe we need a builtin apply which takes a closure f and value x and evaluates f and x, and that would be sufficient?

uncomputable commented 6 months ago

If we allow higher-order functions in Simfony then users could write their own map. That would be a lot of work to implement and I don't think we should focus on that for a while, but conceptually it should be possible. The Simfony compiler would require that all "generics" are resolved, similar to the Rust compiler. Simplicity handles values and first-order functions only.

apoelstra commented 6 months ago

If we don't have higher-order functions then we should not use the let keyword to define functions.

apoelstra commented 6 months ago

Actually I guess, if we had a few builtin functions ... apply, map, fold and so on, then it would be fine to use let.

But if we are using let then there should not be two separate namespaces for functions and "normal" variables.

uncomputable commented 2 days ago

I'm closing this issue because we have functions now. We might add closures or higher-order functions in a later version of Simfony, but right now this is out of scope.