14 ms·
I would prefer to add a `yield` param to functions so it can better interact with the current type system. This means that for a function to yield, it needs to
by uhura 3y ago
I would prefer to add a `yield` param to functions so it can better interact with the current type system.
This means that for a function to yield, it needs to have the so called `yield` param and you can only yield inside a yield function functions with the same yield signature or does not contain a signature at all.
So the example would be rewritten into something like:
x := func(:z int) {
for {
z++
:- z
}
}
for y := range x() {
...
}
The : adds the yield signature and :< yields the value.
Functions that only yield a value `X` would just have the `: X` or `: name X`.
To accept a value of type `Y` in the resume the signature would change to `:[Y] X` or `:[Y] name X`.
Accepting is weak, so if something expects a yielding function that resumes with Y and yield X, yielding functions that only yield X without a resume should also be accepted.
Consider the following code example:
func filter[T comparable](it func(:T), f func(T) bool, :T) {
for v := range it {
if f(v) { :- v }
}
}
func map[T](arr []T, :T) {
for _, v := range arr {
:- v
}
}
for v := range filter(map({1, 2, 3}), func(x) { return x < 3 }) {
print(v)
}
Special functions in a co package could give resume and New functionality to keep the go style.
A basic counter could be written like this:
func counter(:[bool]c int) {
for {
if ! :- c { break }
c += 1
}
}
A func that counts twice could be as simple as:
func countTwice(:[bool]c int) {
count()
count()
}
To interact with the resume value the range syntax could be expanded to something like:
for c := range count() {
if c > 10 { -: false }
-: true
print(c)
}
Range would resume with a default zero value if the range does not pass a value to -:.
- gpderetta 3y agoSure, as long as I can close over a yield object. There is no reason for filter and map to know that the last function parameter takes a continuation.
- uhura 3y agoBut then, how could you guarantee type safety? This yield is not an object, it is handling the execution context to another stack.
- gpderetta 3y agoIt is a delimited one-shot continuation. Delimited continuations are first class objects like any other and it should be possible to close over them.