[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Icon

> -----Original Message-----
> From: owner-ll1-discuss@ai.mit.edu
> On Behalf Of Todd Proebsting
> Sent: Wednesday, December 19, 2001 10:00 PM
> To: Richard Todd; ll1-discuss@ai.mit.edu
> Subject: RE: Icon
> Icon does do its best to make everything an expression, including
> The description below is incorrect, however, in its assertion that
> simply return a null value.  It is wrong in two ways, and one of them
> important.  (Icon is my favorite language, and it has features that
> *none* of this list's well-represented languages have, e.g., string
> scanning and goal-directed evaluation.
> The unimportant error is the assertion that loops to not "return
> anything interesting."  A loop can return anything you want it to
> return.  Icon's "break" statement takes an optional expression as its
> argument and that is the value returned by the loop.  (Actually, break
> is more interesting than that, but I'll omit details here.)
> The important error is the assertion that a loop returns "just a
> Actually, a loop without a break returns *nothing* at all, which is
> distinct from a null value.  The loop expression is said to "fail" to
> generate a value.  This would have become apparent had  the local
> below been initialized to a value, say 5.  The "display" of foo would
> have shown a value of 5.  Why?  Because the while loop failed, which
> meant that the assignment would fail and hence not overwrite the
> previous value of foo.

The "failure" blocking the assignment is different from what I would
have guessed on the surface. 

Am I correct in assuming that the assignment expression is actually
coupled to the control-flow expression?

Are the Icon "break" facilities similar to the following features from

In the example below, a break expression in SmallScript is returning an
explicit value to its (implicit) outer context.

    |r| := while(true) [

Where <r> will be assigned the value 10. If we had not supplied an
explicit value to "break" it would have defaulted to <nil>, making it
different from Icon.

    |r| := <:MyOuterLoop:>while(true) [
        while(true) [
            break <:MyOuterLoop:>(12).

In this case <r> will be assigned the value 12. Since we used a labeled
break to specify what was, in this example, the outermost loop. We can
also use "retry", "continue", "goto", etc. The same expressions will
work within <Block> forms to allow a variety of efficient control flow
extensions.  The "switch" expressions provide some similar features for
combining cases and fall-through usage.

> So, I'll give a brief plug for Icon's goal-directed evaluation.
> Goal-directed evaluation mirrors a fundamental concept better than any
> alternative that I have seen---the concept of success and failure.
> programming languages have Boolean values, but almost never squirrel
> them away in a variable.  They are almost always computed and then
> immediately consumed as a predicate to some control-flow construct.
> Thought of more generally than True vs. False, the control construct
> guided by the success or failure of some expression.  Icon does not
> a Boolean datatype, but it has made success and failure central to its
> computational mechanism.  More over, it generalizes expression to
> "generators" that may produce zero or more values.  I.e., it succeeds
> producing values until it fails.  Notice that this is *more* general
> than the functional world's handcuffed world in which every function
> produces exactly one value.
Interesting declarative forms for iterator/generator examples.

I'm confident that those examples can be done in lisp, and reasonably
sure there must be basic linear algebra facilities available as scheme

On the surface, the generator/iterator your describing in these "to"
examples involves a "vector op scalar", "scalar op vector", "vector sum
vector". And more linear algebra facilities such a matrices, etc have
been around for a long time in dynamic languages. Have you seen or used
APL?  I used it quite heavily some 18-22 years ago.

Smalltalk provides <Interval> classes.  Where an expression such as, "1
to: 3" returns an instance of <Interval>.

If one wants it to be appropriate to treat an interval-op-scalar as you
described, then you can define the "+" message on <Interval> to do just
that. SmallScript makes this very convenient with the use of

In a number of Smalltalk libraries, people have provided linear-algebra
services for a variety of collection classes and added formal vector and
matrix operations as well. 

There is a Smalltalk specific book that covers classes and framework
design of numerical operations in Smalltalk, "Object-Oriented
Implementation of Numerical Methods: An Introduction with Java and

    Function [
        ((1 to: 3)+1) do: [:n| stdout << n].

Would the above operation using a "do:" message to a
sequenceable-collection be consistent with the Icon notion of "every"?

Smalltalk also provides <Stream> classes that act as generators. Some
dialects also provide <Iterator> classes or equivalently

By and large, the pattern is pretty common in Smalltalk, [and is the
foundation for large portions of the collection frameworks] so you would
find many classes support the messages #do:, #next, #previous, #atEnd,
#readLimit, #size. 

On the surface, these capabilities appear similar to "every". Is there
more to illustrate the "generator/goal-directed" facilities in Icon?

I have seen extensive work on iterator forms in the languages SK8,
ScriptX, etc when I was involved with dynamic languages and Apple/IBM in
the early to mid-90's. It is not clear if what you're describing is
actually unique to Icon. But I am pretty ignorant of Icon features,
although I was aware of its existence.

> procedure main()
>    every write((1 to 3) + 1)
> end

... snip...

Ok. Curiosity has gotten the better of me. I've gone to my bookshelf and
pulled out the "Handbook of Programming Languages, Volume II" and gone
to the section on "Icon:Generators and Goal-Directed Evaluation".

>From what I've just read, the Icon concept of "generators" is supported
and is quite common in the dynamic languages we've been discussing in
this group.

Ahh, more explanation in the goal-directed evaluation section. The
notion of "resume" and "suspend" as intrinsic features in the language
are different. But, on my surface read, these concepts are used
frequently in the design of iterator/stream/collection objects in a
number of the languages I've mentioned in this post. 

I.e., using blocks (closures and continuations) one can create what Icon
seems to call procedures as generators. This is the primary pattern used
in Smalltalk for the looping (based on messages -- Smalltalk does not
have explicit keywords for control-flow -- SmallScript adds them as
syntactic sugar).

    exprA whileNotNil: [exprsB].

Where <exprsA> can be written as a Icon-generator procedure. Taking the
example from page 342 of the HPLvII book mentioned above.

    |power| := 
    [:i:j|| k:= i. cnt:=0|
             if ((cnt:+=1) > j) [
             else [
             	|t| := k.
                  k :*= i.

    power(i,j) whileNotNil: [...]   


Having read more on the conjunction and backtracking features, and
looked over examples of how these features are intrinsically integrated
into the Icon language, I do see where you are coming from in describing
Icon's goal-directed nature as being distinct from the languages [other
than lisp] which have been under discussion.

That said, these kind of facilities do exist or have been built as
libraries/frameworks in other dynamic languages. Prolog implementations
built on top of Smalltalk have been around since the 80's. And lisp, of
course, has provided numerous facilities for goal-directed decision
making (tongue-in-cheek, wasn't there something call AI in the 80's?).

-- Dave S. [www.smallscript.org]