ANALYSIS vs. ANALOGY
--------------------
Analysis and analogy are two ways to tackle complexity, but they are
also "opposites" in a certain sense.
Analysis involves resolving a complex entity into simpler components.
This tends to add information; think of how a parse tree adds bits
to make explicit the implicit structures in the string being parsed.
Analogy involves treating a complex entity as a simpler one.
This tends to remove information; if it suffices to know that we
have a "man", we can forget the bits which distinguish "Socrates"
from the rest of us.
One can think of analysis as taking a simpler object bunch S and
seeing how we can map it onto the original complex object C; also
one can think of analogy as doing the opposite and mapping C onto
a suitable S.
CONDITIONAL TESTS
-----------------
Python's conditional tests are
great for analogical coding:
if animal():
elif vegetable():
elif mineral():
but they are not so good for
analytical coding; here C's
if((c = getchar()) != EOF)
serves the same purpose as a
unification in pattern matching
languages:
foo([X|Xs],A) = foo(Xs, A+X)
both breaking out a simpler term
and providing its value.
Note that the grouping operators
for a regexp allow it to return
more than a plain boolean result;
it also produces analyzed values.
-Dave
::::::::::::::::::
> Chuck Moore is considering having colorForth's "if" not consume the
> conditional value.
I think there are reasons to consume,
and reasons not to consume. (which
are analogous to the analogy/analysis
distinction made above) In my forth
variant, I wind up writing:
32 = [ consequent ] continuation
in situations where the continuation
needs the value, and the consequent
is just some special case processing,
and:
32 - z[ consequent ; ] otherwise ;
when only the boolean result of the
comparison is needed.
The second form would have sufficed for
equality, but what about sign branching?
32 - z[ 32 use-32 ; ] other ;
is verbose, but works because
equality is unique, but:
(*) 32 - n[ ?? use-neg ; ] other ;
doesn't determine a value for "??"
(if we prefix "dup", "id" might
work for ??, but then we need to
insert "drop" after "]"; also I
am interested in the forth style
for linearity, and gratuitous
dups are to be avoided. Compare
square0: dup * ;
square1: log 2 * exp ;
for a contrived example.)
NOTATION
--------
In my variant on colorForth, one
concatenates words to code their
sequential composition:
foo bar bletch
Labels, instead of being colored,
are indicated by a colon, and a
semi-colon serves to terminate a
sequentially composed list:
entry: foo bar bletch ;
Conditional execution (at the most
primitive level) is coded with the
brackets "[" and "]":
pred [ cons ] cont
is similar to C's:
if(pred) { cons } cont
and since "foo ; bar" = "foo ;",
one can also code alternation:
pred [ then ; ] else ;
or, a bit more graphically:
pred [ then ;
] else ;
"[" (and its variants z[ and n[*)
always consumes the top-of-stack
value.
The various comparison operators
"<", "=", etc. replace the top of
the stack with the boolean result.
'5 3 <' leaves '5 0'
This works well for the common
case where we compare a value
(needed later) with a constant
(not needed later).
::::::::::
* I haven't implemented signed
branches, because I have yet to
write code which only needs the
sign-bit, but not the value;
16 < [ handle-small ; ] drop else-punt ;
but not:
(*) n[ negative ; ] positive ;
::::::::::
# This whole forth project started
# in response to a kragen-tol or
# -hack a while ago involving the
# fibonacci numbers.
#
# This example runs about twice as
# as fast as gcc for me, and also
# demonstrates the conditionals.
fmain: iarg
0 = [ 33 + ]
recfib digits cr ;
recfib: 2 > [ dup
push 1 - recfib
pop 2 - recfib
+ ;
] drop 1 ;