> Sidney Reilley II <[email protected]> wrote:
>
> goal-directed evaluation -- I haven't even gone there yet! Sounds very
> MITish ;) I think I'll save that for last. L8r..
Noooo, no no no no no.... next learning task!
For instance, this was a line I wrote just yesterday
if col := (!(p | q | d)).named(thisname) then
which finds the first item named thisname out of the p, q and d lists. Try
looping that out.
This particular expression is "driving" to a goal using a few "generators". If
a later phase of the expression fails then the generators are driven to yield
a new piece, and the expression dives in again. To break it down:
p | q | d
suspends (yields) the values of p, q and d in succession. Wrapping in ( ) only
sets up the precedence for the next step.
!X yields all the entries of X in succession. So !(p | q | d) yields all the
members of p, q, d in order. Wrapping once again in ( ) only sets the
precedence.
.named( ) is a method I've written on the class of the members stored in p, q,
d. If the item matches the given name, then the object itself is returned,
otherwise the method fails.
So! ( ! ( p | q | d )).named(thisname) finally succeeds if one of the items
has that name.
Far simpler to read than describe, and clear in your head once you're fluent.
An Iconer would see that and understand it in a highlevel way. If it was
written as loops you'd have more code, and probably three separate loops and
associated IF statements too. Time to comprehend would be longer.
Even the named() method has some simple goal-driven code in it. The name
passed in can be either "table.column" or "column" (from SQL world) so I need
to break that out:
method named(buf)
local tab, col
buf ? {
tab <- ident() & ="."
(col := ident() & pos(0) | fail
}
buf is used as the &subject for some string scanning. ident() is a little
function I have that scans a string for your typical programming identifier.
The <- operator is "reversible assignment" - if it's driven to try again by
later phases of an expression, it "fails" after reversing the assignment (ie
restores the old value which is &null for a fresh variable).
What could make it fail? The next bit is a demand to successfully match a "."
character in the string. If it's there, the whole expression succeeds, and tab
now contains "table". If it fails, then there must be no "table." so tab
retains the &null value it starts with.
The next expression tries to match (another) identifier, then uses pos(0) to
test if it's reached the end of the string, or it fails the method. I could
have made it complain or die, but frankly I don't really care.
Finally the tab and col need to be compared with the objects name. Although
the following could probably be squeezed down to something tighter (and
sometimes I will depending on context) in this case the job is just as clear
split into a THEN and ELSE part
if /tab then {
if col == name then return self
}
else {
if tab == (\table).name & col == name then return self
}
/tab just checks if tab is &null, if it is the comparison is on col only.
Otherwise the comparison is on tab and col. Note that even this has a bit of
goal directed coding. Some objects in the p q or d lists DON'T have a value in
the table member; the \table bit merely fails if table is &null. This way, a
"table.column" won't falsely match only on col. An object with no table can
only be found using "table".
Just for the the exercise, I tried to make it smaller in my head and it's
simple enough:
if col == name & /tab | tab == (\table).name then return self
because I noticed that col == name is common, and then either tab must be
&null, or tab must equal the name of a non-null table member. Precedence rules
for & and | don't match the standard rules for "and" and "or" or && and || in
other languages, but are tuned to make things nicer in the context of Icon
coding.
Wooof - how big is this reply? I hope I've shown that generators and goal-
driven expressions are an essential part of good Iconing.
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Unicon-group mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/unicon-group