Most programming languages offer two basic ways of altering the normal left-to-right, top-to-bottom code execution sequence: a way of looping repeatedly over a section of code, and a way of executing a section of code only if some condition is true.
We've seen a way to execute code repeatedly, using
for; Let's look at a way to execute code
Stack: : flip frandom 0.5 > if "heads!\n" else "tails!\n" fi , ; Stack: flip tails! Stack: flip tails! Stack: flip heads! Stack: flip tails! Stack: flip heads! Stack:
How does this work? Well, it introduces several new
functions. One is
frandom, a function which returns a
randomly selected number between 0.0 and 1.0:
Stack: frandom frandom frandom frandom Stack: 0.00176691 0.187589 0.990434 0.750497 pop pop pop pop frandom frandom frandom frandom Stack: 0.366273 0.351209 0.573344 0.132554 pop pop pop pop frandom frandom frandom frandom Stack: 0.0641664 0.950853 0.15356 0.584649
>, a function which returns a
if its first argument is greater than the second, else
false value. What is a
false value in MUF?
The special constant
nil. What is a
true value in
MUF? Any but
Stack: 1 2 > Stack: nil pop 2 1 > Stack: t
You can compare strings as well as numbers with
Stack: "alpha" "beta" > Stack: nil pop "beta" "alpha" > Stack: t
And, as you might expect, MUF has the full usual set of comparison functions:
!= Not-equal < Less-than <= Less-than-or-equal-to = Equal-to > Greater-than >= Greater-than-or-equal-to
Notice that it looks a little odd to write "1 2 >" instead
of "1 > 2" the way Ms Grundy did in third grade, but that
this order is required by our strict rule of evaluating
> cannot execute until we have
pushed both of its operands on the stack for it.
(We could make special exceptions from left-to-right evaluation order just for comparison functions, but then MUF would start getting more complicated than we want, and become a quite different sort of language. There is nothing wrong with building more complicated languages designed to look more like what Ms Grundy taught in school, and Muq will eventually have such languages as well as MUF, but for now let's stick to our simple-minded little language.)
With that background in mind, let's take another look
: flip random 0.5 > if "heads!\n" else "tails!\n" fi , ;
The "random 0.5 >" will leave a
true value on the
stack half the time, and a
false value (
on the stack the other half of the time. What does the
if pops one value off the stack and
looks at it. If that value is
true (anything but
nil), all the words from
executed. If that value is
the words from
fi are executed.
fi, as you might guess, is just
and serves to mark the end of the statement.)
flip, this means that the
if-else-fi pops a true/false value off the stack, and
then pushes either "heads!\n" or "tails!\n" on the stack, to
get printed by the final comma function.
Again, it looks peculiar to put the true/false value
if before the
that order is forced by our simple-minded left-to-right
if cannot make its decision until we
give it the information it needs.
You may wish to experiment interactively with
awhile, until it begins to feel natural:
Stack: nil if "Yup!" else "Nope!" fi Stack: "Nope!" pop t if "Yup!" else "Nope!" fi Stack: "Yup!" pop 2.3 if "Yup!" else "Nope!" fi Stack: "Yup!"
Believe it or not, you've now mastered most of the essentials of elementary MUF programming! In principle, you now know enough MUF to compute anything which can be computed.
Let's finish off by covering a few very handy and frequently used facilities.
Go to the first, previous, next, last section, table of contents.