Functions: Difference between revisions
Adamcolton (talk | contribs) No edit summary |
Adamcolton (talk | contribs) |
||
| Line 43: | Line 43: | ||
If we treat func args as a struct, then the order either becomes optional or entirely goes away with named | If we treat func args as a struct, then the order either becomes optional or entirely goes away with named | ||
square := <x float> -> {<- x*x} | square := <[x float]> -> {<- x*x} | ||
square | square[x:10] | ||
then a method becomes | |||
Person.SetName := <[p *Person, newName string]> -> {p.Name = newName} | |||
[[Category:Gryphon]] | [[Category:Gryphon]] | ||
Revision as of 14:13, 15 October 2019
Basics
A function takes some argument and may return a value (or multiple values).
Multiple Returns
Not sure about these, there's an elegance to only allowing a single return type. With the tagged unions, it's not necessary the way it is with go.
Implicit Attributes
Pure
A pure function has no side effects. A pure function invoked with static arguments can be statically replaced at compile time.
Unsafe libraries can override this. The use cases are logging and memoization.
Async
If a function can cause a wait operation it is async. This is implicit to avoid the "what color" problem.
Error Types
Assuming Gryphon allows only a single return, then the most common case would be (like Rust) a tagged union with errors. If the errors are specific, we can create a list of all the possible errors.
Curry Closures
I think closures are a bad idea - they are a good source of errors and complicate what data a function has access to.
Instead I want to use currying.
const Add = (a, b int)-->(int){return a+b}
c5 = Add::(5) // c5 is now type (int)-->(int)
Inline
The compiler should be able to make an informed decision about inlining function calls. We may want a compiler flag to help tweak the threshold (setting the desired balance between performance and size).
Of course, a function only called from one place should always be inlined.
Context Struct and Methods
A function really takes an anonymous struct as context and may attach a method to the namespace of the first argument as a method:
func (f Foo) Bar(a,b int)
is like
method Bar{f Foo; a,b int}
and returns just add more context
func (f Foo) Bar(a,b int) (c int)
is
method Bar{ctxIn {f Foo; a,b int}; ctxOut{c int}}
If we treat func args as a struct, then the order either becomes optional or entirely goes away with named
square := <[x float]> -> {<- x*x}
square[x:10]
then a method becomes
Person.SetName := <[p *Person, newName string]> -> {p.Name = newName}