You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It'd be neat to allow for ... in ... do ... end loops to work on things other than the built-in ranges and arrays. Since we're not object-oriented (and afaik have no aspirations to be so), I'd like to suggest the following protocol for iterable types. For an iterable type foo, define three methods in the same unit (where T and U are arbitrary types):
a foo#iter function to create the iterator, one of:
fun foo#iter(x: &foo) -> T ... endfun
fun foo#iter(x: foo) -> T ... endfun
a foo#iter-next function to advance the iterator, one of:
fun foo#iter-next(x: &foo, i: &mut T) -> bool ... endfun
fun foo#iter-next(x: foo, i: &mut T) -> bool ... endfun
fun foo#iter-next(i: &mut T) -> bool ... endfun
a foo#iter-value function to get the current value of the iterator, one of:
fun foo#iter-value(x: &foo, i: &T) -> U ... endfun
fun foo#iter-value(x: &foo, i: T) -> U ... endfun
fun foo#iter-value(x: foo, i: &T) -> U ... endfun
fun foo#iter-value(x: foo, i: T) -> U ... endfun
fun foo#iter-value(i: &T) -> U ... endfun
fun foo#iter-value(i: T) -> U ... endfun
Yes, the # is part of the function name, so I'm suggesting that name for "protocols". Note that we allow some wobbliness in the protocol as to by-value/by-address passing, and whether or not the iterated-upon object is passed in; as long as the compiler can resolve a function from each of the three groups, the object is considered iterable.
An (example, unnecessary) implementation for a struct wrapping an array of u8s (using unreviewed struct syntax):
struct my-u8s
values: [u8; 10]
endstruct
fun my-u8s#iter(x: &my-u8s) -> u8
return 255
endfun
fun my-u8s#iter-next(i: &mut u8) -> bool
@i += 1 --[[ this overflows to 0 on the first call ]]
return @i < 10
endfun
fun my-u8s#iter-value(x: &my-u8s, i: u8) -> u8
return x.values[i]
endfun
Given the above, we can write a for ... in ... do ... end loop:
let z: my-u8s = ...
for x: u8 in z do
...
endfor
... which would desugar to something like:
let z: my-u8s = ...
let mut _z#iter = my-u8s#iter(&z)
while my-u8s#iter-next(&mut _z#iter) do
let x: u8 = my-u8s#iter-value(&z, _z#iter)
...
end
Additional functions could be defined for mutating iterators (for mut ... in ... do ... end), e.g. a foo#iter-mut-value which returns a mutable pointer.
The text was updated successfully, but these errors were encountered:
It'd be neat to allow
for ... in ... do ... end
loops to work on things other than the built-in ranges and arrays. Since we're not object-oriented (and afaik have no aspirations to be so), I'd like to suggest the following protocol for iterable types. For an iterable typefoo
, define three methods in the same unit (whereT
andU
are arbitrary types):a
foo#iter
function to create the iterator, one of:a
foo#iter-next
function to advance the iterator, one of:a
foo#iter-value
function to get the current value of the iterator, one of:Yes, the
#
is part of the function name, so I'm suggesting that name for "protocols". Note that we allow some wobbliness in the protocol as to by-value/by-address passing, and whether or not the iterated-upon object is passed in; as long as the compiler can resolve a function from each of the three groups, the object is considered iterable.An (example, unnecessary) implementation for a struct wrapping an array of
u8
s (using unreviewed struct syntax):Given the above, we can write a
for ... in ... do ... end
loop:... which would desugar to something like:
Additional functions could be defined for mutating iterators (
for mut ... in ... do ... end
), e.g. afoo#iter-mut-value
which returns a mutable pointer.The text was updated successfully, but these errors were encountered: