| 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 -:. |