/* not entirely sure about the final syntax just yet but something like this */

/* 'extern' functions (though some should probably be generic?) */
fwd_getline(
	(optional![string]) next);

fwd_some(optional![string] o,
	(string) something | () nothing);

fwd_insert(unordered_set![string] set, string line,
	(unordered_set![string]) next);

fwd_destroy(auto a);

/* at some point I'll probably add in a type system as well, but for now let's
 * pretend we're static-dynamic (or dynamic at compiletime? dunno) */
readlines(unordered_set![string] set, (unordered_set![string]) next)
{
	fwd_getline() => optional![string] line;
	!> e {
		own set {fwd_destroy(set);}
		error e
	}

	fwd_some(line) => string line {
		/* we had something in our option */
		fwd_insert(set, line) => unordered_set![string] set;

		/* at the moment the only supported looping construct is
		 * recursion */
		readlines(set, next);
	} => {
		/* option was illegal, we've read all input there is */
		next(set);
	}
}

fwd_foreach(unordered_set![string] set,
	(string) callback);

fwd_println(string s);

main()
{
	/* fwdlib.hpp uses namespace std, not good practice but allows us to do
	 * stuff like this without really caring about implementing "::" */
	unordered_set![string]{} => unordered_set![string] set;
	readlines(set) => unordered_set![string] set;
	fwd_foreach(set) => string node {
		fwd_println(node);
	}
}