Hi I am using Harlowe version 2.3.12 and am confused by the behavior of the cond: macro. Here’s a simple piece of code that demonstrates my confusion. I want the macro $getFirst to return the first element of an array of numbers but, if the input array is empty, to return the value 0,
(set: $getFirst to (macro: array-type _v, [
(set: _output to (cond:
_v’s length is 0, 0,
(1) of _v))
(output-data: _output)]))
When I run this with _v as the empty array I expect it to detect that _v has length 0 and to return 0 before it tries to find _v’s first element. But instead it gives me an error because _v does not have a first element.
In contrast, when I replace the default output of cond to a fixed value just to test it, it works and returns the right value before reaching that condition. So this condition correctly returns 0 when given the empty array, even though it is exactly the same up to and including the condition testing true.
(set: $getFirst to (macro: array-type _v, [
(set: _output to (cond:
_v’s length is 0, 0,
1))
(output-data: _output)]))
I’d like to understand what is happening here. Also, if anybody knows an easy way to get a macro to return the first member of an array, but not to return an error for the empty array, please tell me!
Please use the comment field’s Preformatted text option when including code examples in your comments, it makes the code easier to copy-n-paste and stops the forum’s software converting valid standard single & double quotes into invalid typographical (curvy) equivalents.
It appears that the (cond:) macro evaluates all of the expression being passed to it before the macro itself is called.
eg. when your (cond: _v's length is 0, 0, (1) of _v) is about to be executed the _v's length is 0 and (1) of _v expressions are both evaluated before the results of those evaluations are passed to the (cond:) macro. And in the case where the _v array has no elements the (1) of _v expression will cause an error because that expression is trying to access the 1st element of an array that has no such element.
In your use-case you would be better off defining your ($getFirst:) macro like so…
Thanks a lot! That also solves a different problem I was having, which was getting info out of an if hook (the reason I was using cond: in the first place). It appears output-data works, even though setting local variables in the hook fizzles.