pre-srfi / static-scheme

11 stars 0 forks source link

Multiple values, boxes, multiple-value boxes, and refs/vars #12

Open lassik opened 3 years ago

lassik commented 3 years ago

We discovered by experimenting that (values 1 2 3) in dynamic Scheme is an excellent analog for (tuple 1 2 3) in static Scheme. So good that if we write (values ...) instead of (tuple ...) in static code, it looks a lot like Scheme code and can be readily understood by a Schemer.

In most static languages, multiple values don't exist since tuples serve the same purpose. When returning a value across the boundary from static to dynamic, unpacking a tuple into multiple values is a reasonable idea.

On the other hand, Scheme also has multiple-value boxes, so we could represent a tuple as one of those. Maybe return a tuple as multiple values in return-value position, but pass as a tuple as a multiple-value box when it's not in return-value position. For the return-value case, we can also let the user specify on a function-by-function basis whether to return real multiple values or a multiple-value box to Scheme.

On the third hand, a single-value box is a good analog for ML-style refs (called vars in clojure), i.e. first-class variables (ordinary variables are single-assignment only in these languages).

johnwcowan commented 3 years ago

The Steme compiler should deal in multiple values until it needs to store them in a data structure, and then it can reify them as a multiple-value box. There may be other cases.

lassik commented 3 years ago

Isn't it an implementation issue whether it internally uses multiple values or not? Are you planning to incorporate multiple values into the Steme type system?

mnieper commented 3 years ago

I think it is the idea to incorporate multiple values in the type system. In ML or Haskell, a function type is of the form X -> Y, where X and Y are types. In Steme, a function type would be of the form X1 X2 ... Xn -> Y1 Y2 ... Ym where the Xi and the Yj are types. Note that X1 X2 ... Xn itself is no type (as multiple values are not the same as one multiple-value box).

Strictly speaking, we have to be even a bit more general. A Steme function type could also be

X1 X2 ... Xn <ellipsis> -> Y1 Y2 ... Ym <ellipsis>

meaning that the function allows arbitrary many Xn's in the input and can output arbitrary many Ym's (i.e. it is variadic and covariadic).

Case-lambda would allow for even more complicated types (disjoint unions of these types), which can be used to model procedures with optional arguments.

johnwcowan commented 3 years ago

as multiple values are not the same as one multiple-value box

They are the same if we say they are, just like characters and perhaps pairs.

mnieper commented 3 years ago

as multiple values are not the same as one multiple-value box

They are the same if we say they are, just like characters and perhaps pairs.

Well, we can do this but then we are back to ML/Haskell in that every procedure takes just one value and returns just one value.

aijony commented 3 years ago

We also may want to consider optional and keyword parameters, that would make the ML/Haskell approach less appealing (at least when I try to think about it in my head).

Perhaps it is more 'schemey' to have functions that take multiple (unboxed) values.

johnwcowan commented 3 years ago

What I'm saying is that MultipleValueBox is not a type in the Steme system: the type is Tuple, and like any Steme type it can have multiple Scheme representations.

mnieper commented 3 years ago

What I'm saying is that MultipleValueBox is not a type in the Steme system: the type is Tuple, and like any Steme type it can have multiple Scheme representations.

So how would the type constructor for a function type look in your vision?