Hi Kurt,
A function is syntactic sugar for a procedure that takes an extra argument
to which the return value is bound. Since Inc is declared with 'fun' it
expects two arguments: the amount by which to increment, and the return
value: the resulting total. You can "pass" this extra argument (which is
supposed to be an unbound variable) by binding the return value of the
function. So, you can call Inc in one of these three ways:
1) {Inc N CounterValue}
2) CounterValue={Inc N}
3) {Inc N}
The CounterValue is the new value of the counter after the Inc operation, as
returned by the Inc function. In these examples, the CounterValue variable
must be declared somewhere before using it.
Calling method (3) can only be used following all statements in a function
definition (in other words, be at the end of the control flow). In your case
you have a call using method (3) that is not at the end, which is illegal.
That's why you got the error. You can rewrite the Sum line in AddDigits like
this:
_={Sum.inc 1}
or
{Sum.inc _}
Either of those options will ignore the return value by using the
placeholder (_) to not bind it. The call to Carry.inc is OK because it
occurs at the end of the control flow. The return value of Carry.inc will
become the return value to AddDigits.
There's another problem: if X+Y == 2 is false, there's no else clause, so
your function fails to return a value. You could put in an else clause like
'else 0' to return some value when your condition fails.
However, you might reconsider defining AddDigits as a function. If it's a
function, it should have a well-defined return value. What do you intend the
return value to be? It is not clear from your example. Should it be the new
value of the Sum counter? Of the Carry counter? The sum of both? Or perhaps
it shouldn't be a function at all, but a procedure? If so, you can rewrite
it like this:
proc {AddDigits X Y}
if X+Y==2 then
_={Sum.inc 1}
_={Carry.inc 1}
end
end
Now you need to throw away the result of Carry.inc as well, because
AddDigits doesn't return a value. And you don't need an else clause, because
AddDigits doesn't need to return anything. Let's say instead you wanted to
return a pair of the new values of Sum and Carry. You'd write it like this:
fun {AddDigits X Y}
NewSum NewCarry
in
if X+Y==2 then
NewSum={Sum.inc 1}
NewCarry={Carry.inc 1}
NewSum#NewCarry
else
{Sum.read}#{Carry.read}
end
end
Or you could do the read in either case, and throw away the return values of
the inc calls:
fun {AddDigits X Y}
if X+Y==2 then
_={Sum.inc 1}
_={Carry.inc 1}
end
{Sum.read}#{Carry.read}
end
Hope that helps,
Lyle
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users