Open tomoyanonymous opened 1 week ago
Random thoughts:
For this code, can the compiler infer correct type?
{ freq = 200.0 .. } |> myugen(_)
Elm's update syntax may conflict with an existing syntactic rule.
{ default_v | freq = 200.0 }
can be parsed as "block(bitor(var(default_v) ,assign(var(freq),float(200.0))))" though it apparently violates typing rule.
Other candidates: use arrow?
{ default_v <- freq = 200.0 }
or { freq = 200.0 -> default_v }
The other concern: should we allow function as a member of the record?
It makes difficult to implement a garbage collection(need to implement destructor functionality).
Though old v0.4.0 had a experimental record (struct) type but I'm going to implement a new syntax for record type.
The new syntax design allows the code to more directly reflect the programmer's intent by grouping data by name, in addition to allowing default values to reduce the amount of code written.
Also, combining the parameter packs discussed in #58 with this default-valued record type will allow the concept of "UGen as a function" to be expressed directly while maintaining type safety, and without the confusion over the number of arguments that is common in function w/ default argument.
Basic Syntax
The syntax is based on Elm, I'm not going to make it similar to Rust here.
We use an anonymous record type positively.
I'm going to implement this later but in the type alias/newtype declaration, default value can be set. In the type declaration, default value is needed to be a literal.
Each element can be accessed through dot operator, or captured at let pattern syntax.
With the partial application using underscore syntactic sugar, a little tricky code like this can be work.
"Update" syntax inspired from elm is also available though we uses arrow instead of pipe as a separator(see following discussion).
This can be implemented as a syntax sugar like this.
Note that this expansion can only be done after the type inference. It will be implemented in mirgen.
Default Argument with function declaration
Auto Parameter pack with Record Type
In the function application for the function w/ more than 2 arguments, either of 2 cases are allowed.
This is the part I'm wondering now, kind of "anonymous update syntax". Let's think about the case of the function that has both of arguments with default-value and without.
This
{key = val ..}
syntax used in right-hand value, same as in the let pattern capture, will emit something likeImcompleteRecord
ast node, which has aImcompleteRecord
type. I guess thatImcompleteRecord
expression can be used only as an argument, same as underscore for the partial application.In the type system level,
Record
type has only the information whether the each field has a default value or not, not the value itself.In the type inference,
Record
andImcompleteRecord
can be unified as like this.Any
ImcompleteRecord
type left in the end of type inference, it should be a compile error.Then, if the single ImcompleteRecord argument was given for the multi-arguments function(case 2), the pre-mirgen syntax sugar remover expands the ast to like this using update syntax.
I don't know how to implement the logic to generate default value but it will be a kind of restricted version of typeclass(interface) like Rust's
Default
trait.