koka-lang / koka

Koka language compiler and interpreter
http://koka-lang.org
Other
3.31k stars 167 forks source link

Default arguments, maybe<a> & optional<a> #240

Open iacore opened 2 years ago

iacore commented 2 years ago

Currently, optional is treated as compiler magic.

This will work:

struct duck
    baby: maybe<duck>

but this will not:

struct duck
    baby: optional<duck>

Default value Example: fun sumdown( sum : int = 0 )

I don't really like that there is two identical types with different names. Also, the type of a function argument isn't what it seems. Default arguments are weird, since sumdown(0) means different than sumdown() (according to documentation, the compiler treats it differently), even though I think they should be the same.

One solution is to introduce a special effect coerce<a, b>, which is used for "implicit cast" between types. So, if the user want to distinguish between sumdown(0) and sumdown(), the function will be fun sumdown( sum : optional<int> = None ). Additionally, there will be the following global effect handler to handle implicit coerce:

with fun coerce(value: e a) : e maybe<a> { Some(value) }
daanx commented 2 years ago

Yes, optional is not available to the programmer; there is only the maybe type.

(as an aside: the original reason for having optional internally is to be able to generate better code since an optional cannot contain an optional. However, recent other optimizations makes maybe now just as efficient so we may indeed drop optional completely)

Separately, the default arguments are correctly typed; if one writes fun sumdown( x : int = 0 ) the type of x in the body is int, and when called with an explicit argument, sumdown(42) the argument has type int as well. This is exactly what makes default arguments so convenient!!

If looking at the interface type of sumdown( x : optional<int> ) it is clear the argument x is optional; perhaps a nice refinement may be to display it as x : ?int or even ?x : int -- signifying more clearly that the parameter is optional (and completely hiding the internal implementation)

Coercions seem quite troublesome; they would pollute the effect type and also cause trouble with type inference.

iacore commented 2 years ago

It is already displayed as x: ?int. Check out sublist on https://koka-lang.github.io/koka/doc/book.html#sec-default. This feels confusing, since the type of x is int, not optional<int>. I feel like it's better to make it show x: int = 0, since ?int is not a real type.

daanx commented 2 years ago

Ah I see. Yes, I agree -- I will put this on the todo list and display indeed as either x : int = ? or (even better) x : int = <expr> where is the actual default value.