Without worrying too much about why I'm doing it, I was trying to do
something recursive like this:
export fn main() void = {
let tail = io::drain(os::stdin) as []u8;
defer free(tail);
while (len(tail) > 0) {
let (hd, tail) = bytes::cut(tail, ' ');
io::write(os::stdout, hd)!;
};
};
This obviously doesn't work, not least because Hare has no "while"
statement. The haredoc says that "The contents are borrowed from the
input slice.", but I don't really know what that means.
I guess that tail is actually a pointer to an array, so the defer
statement is wrong in any event.
How would you rewrite this code to be idiomatic Hare?
On Tue Nov 29, 2022 at 7:28 PM CET, Person wrote:
> Without worrying too much about why I'm doing it, I was trying to do
> something recursive like this:
>
> export fn main() void = {
> let tail = io::drain(os::stdin) as []u8;
> defer free(tail);
>
> while (len(tail) > 0) {
> let (hd, tail) = bytes::cut(tail, ' ');
> io::write(os::stdout, hd)!;
> };
> };
>
>
> This obviously doesn't work, not least because Hare has no "while"
> statement. The haredoc says that "The contents are borrowed from the
> input slice.", but I don't really know what that means.
for (whatever) is semantically equivalent to a while loop
Borrowing from the input slice means that the lifetime of the return
value is only as long as the lifetime of the input. Which in this case
looks fine.
> How would you rewrite this code to be idiomatic Hare?
Probably skip the allocation/drain step and copy bytes until you get to
a space, something like this:
for (true) {
static let buf: [os::BUFSIZ]u8 = [0...];
const n = match (io::read(os::stdin, buf)?) {
case io::EOF =>
break;
case let n: size =>
yield n;
};
const (head, tail) = bytes::cut(tail, ' ');
io::writeall(os::stdout, head)?;
if (len(tail) != 0) {
break;
};
};