~sircmpwn/hare-users

2 2

What's an idiomatic way for recursion?

Details
Message ID
<70ef913f-8960-e51c-3f42-b1d23c082aa6@gmail.com>
DKIM signature
pass
Download raw message
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?
Details
Message ID
<COOZTJK80ZJG.1T20MMKXRLLJQ@taiga>
In-Reply-To
<70ef913f-8960-e51c-3f42-b1d23c082aa6@gmail.com> (view parent)
DKIM signature
pass
Download raw message
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;
	};
};
Details
Message ID
<COOZVW9JMIAS.2WVBKMBEO5QHF@monch>
In-Reply-To
<COOZTJK80ZJG.1T20MMKXRLLJQ@taiga> (view parent)
DKIM signature
pass
Download raw message
In addition to what Drew said, you can also take a look at
bytes::tokenize
Reply to thread Export thread (mbox)