> 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

Reply via email to