Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Custom iterators have landed.


As in the title, you can now define custom iterators. The trait is
called `iterable`, and it's built in. The signature is

	trait iterable @a -> @b =
		/*
		fills in 'outval' and returns true if we should continue,
		false otherwise
		*/
		__iternext__	: (iter : @a#, outval : @b# -> bool)

		/*
		called once per iteration to clean up the iteratee
		if needed.
		*/
		__iterfin__	: (iter : @a#, val : @b# -> void)
	;;

Where a loop in the following form

	for x in iter-expr
		/* loop body */
	;;

desugars to

	.iter : @a = iter-expr
	.tmp : @b
	while __iternext__(&a, &b)
		/* loop body */
		__iterfin__(&a, &b)
	;;

There are a few hacks involved, and I wouldn't be surprised to find
that it's buggy across modules, so bang on it and let me know what breaks.

An example is included in the tests:

	use std

	type range = struct
		lo	: int
		hi	: int
	;;

	impl iterable range -> int =
		__iternext__ = {rng, output
			if rng.lo > rng.hi
				-> false
			else
				output# = rng.lo++
				-> true
			;;
		}

		__iterfin__ = {it, val
		}
	;;

	const main = {
		var r : range
		var x : int

		r = [.lo=6, .hi=11]
		for v in r
			x = v
			std.put("{}", x)
		;;
		std.put("\n")
	}

Next step: iteratizing the standard library. There are four iterators
I find myself wanting fairly commonly:

	- enumeration: Pairing each element in a sequence with its
	  index

	- Character by character string iteration: Basically what
	  it says.

	- Iterating over files line by line.
	
	- Zipping together two sequences.

As always, if something is generally useful, and has some code out
there that uses it, I'd be happy to ship that with mc.

-- 
    Ori Bernstein