\nuovoarticolo{Wouter van Oortmerssen}{\amiga{} E V3.0b}{%
Wouter van Oortmerssen \\
Levendaal 87 \\
2311 JG Leiden \\
The Netherlands
}{%
Internet:~wouter@alf.let.uva.nl \\
~~~~~~~~~~wouter@mars.let.uva.nl
}{english}{{\em Husband}, n.: See {\em brute}.}{Ambrose Bierce}
 
\sez{Introduction}
 
E is a language that has grown in popularity ever since the
release of v2.1 compiler in January '93, and recently a much
enhanced version of it has been released as V3.0. For those
who have never heard of E: It's a powerful and flexible object
oriented/\discretionary{}{}{}procedural/\discretionary{}{}{}impure
functional higher programming language, mainly influenced by languages such
as C++, Ada, Lisp etc., and \amiga{} E is a very fast compiler for it, with
features such as speed of 20\,000 lines/minute on a 7~Mhz \amiga{}, inline
assembler and linker integrated into compiler, large set of integrated
functions, great module concept with V39 includes as modules, flexible
type-system, quoted expressions, immediate and typed lists, low-level and
object polymorphism, exception handling, inheritance, data-hiding, methods,
multiple return values, default arguments, register allocation, fast memory
management, unification, Lisp-Cells, and much, much more.
 
The compiler itself is best known for it's speed. Not only
does it compile large sources before you can say ``E'': its
integrated linker joins modules of large applications in a
second (literally).
 
The language itself exists at this moment only on the \amiga{},
and is based on a comfortable Modula-2 look-alike syntax,
whereas the semantics has more of a C flavour. On top of
that E features a host of advanced features (inspiration for
which can be sought in Ada, C++, Lisp and more obscure
research languages), some of which I'll demonstrate by
tiny bits of example code below. 
 
\sez{Object Oriented Programming}
 
A tiny example that shows some features of OOP in E is shown below
 
\begin{verbatim}
 -> classical OO polymorphic example
 
 OBJECT loc
   PRIVATE xpos:INT, ypos:INT
 ENDOBJECT
 
 OBJECT point OF loc
   PRIVATE colour:INT
 ENDOBJECT
 
 OBJECT circle OF point
   PRIVATE radius:INT
 ENDOBJECT
 
 PROC show() OF loc IS 
      WriteF('I''m a Location!\n')
 PROC show() OF point IS
      WriteF('I''m a Point!\n')
 PROC show() OF circle IS
      WriteF('I''m a Circle!\n')
 
 PROC main()
   DEF x:PTR TO loc,
   l:PTR TO loc,
   p:PTR TO point,
   c:PTR TO circle

   ForAll({x},[NEW l,NEW p,NEW c],`x.show())
 ENDPROC
\end{verbatim}
 
This is a classical example, and shows what polymorphism is good
for. Based on the type of ¶{x} in the source, a procedural
programmer would expect the program to write the same message
three times, but instead it will write the correct message for
each object, without knowing its exact type at compile time.
Surprise!
 
\begin{verbatim}
 -> binary tree implementation in E
 
 OBJECT bintree PRIVATE
   left:PTR TO bintree
   right:PTR TO bintree
 ENDOBJECT
 
 PROC is_bigger(other:PTR TO bintree) 
     OF bintree IS EMPTY
 PROC is_equal(other:PTR TO bintree)
     OF bintree IS EMPTY
 
 PROC bintree(l,r) OF bintree
   self.left:=l
   self.right:=r
 ENDPROC
 
 -> folds value v with proc through the tree.
 
 PROC traverse(proc,v) OF bintree
   v:=proc(self,v)
   IF self.left 
     THEN v:=self.left.traverse(proc,v)
   IF self.left 
     THEN v:=self.right.traverse(proc,v)
 ENDPROC v
 
 /*-------------------------------------*/
 
 -> integer tree
 
 OBJECT intbintree OF bintree
   i:LONG
 ENDOBJECT
 
 PROC intbintree(l,r,i) OF intbintree
   self.bintree(l,r) 
       -> call super constructor
   self.i:=i
 ENDPROC
 
 PROC is_bigger(other:PTR TO intbintree) 
   OF intbintree IS self.i>other.i
 PROC is_equal(other:PTR TO intbintree) 
   OF intbintree IS self.i=other.i
 PROC total() 
   OF intbintree IS self.traverse({sum},0)
 PROC sum(t:PTR TO intbintree,v) IS t.i+v
\end{verbatim}

All methods in E are what is most often called ``virtual'', i.e.,
they behave polymorphic-ally. This is exploited by the ¶{is\_bigger}
method, which can be re-implemented by a subclass (as shown
by the integer tree), and as such ¶{bintree} can have a method
like sort that needs to compare, without knowing what the
data stored in some subclass of the tree looks like.
 
\sez{Exception handling}
 
Exception handling is a technique by which error-situations in
a program (think of missing resources such as memory) are
checked and handled in a uniform way. 
 
\begin{verbatim}
 CONST SIZE=100000
 ENUM NOMEM  /* ,... */
 
 RAISE NOMEM IF AllocMem()=NIL
 
 PROC main()
   alloc()
 ENDPROC
 
 PROC alloc() HANDLE
   DEF mem
   mem:=AllocMem(SIZE,0)           
    /* see how many blocks we can get */
   alloc()                         
       /* do recursion */
 EXCEPT DO
   IF mem THEN FreeMem(mem,SIZE)
   ReThrow()                       
    /* recursively call all handlers */
 ENDPROC
\end{verbatim}
 
As shown by the fictional example above, error conditions are automatically checked
(no endless ¶{IF}s required), and an appropriate piece of code called an
exception handler is called to deal with the problem. This can also
happen recursively on different levels of your programs call-graph;
it can break down complex nesting of allocated resources.
 
 
\sez{Functional programming}
E has various features inspired by functional/\discretionary{}{}{}logic
programming, such as:
 
\begin{description}

\item[Quoted expressions.] (use of unevaluated expressions, and
ability to pass them on as values).
 
\begin{verbatim}
 MapList({x},[1,2,3,4,5],r,`x*x)
\end{verbatim}
 
results ¶{r} in: ¶{[1,4,9,16,25]}.
 
\begin{verbatim}
 PROC main()
   DEF mem[4]:LIST,x
   MapList({x},[200,80,10,2500],
        mem,`AllocVec(x,0))     
           -> alloc some
   WriteF(IF ForAll({x},mem,`x) 
          THEN 'Yes!\n' ELSE 'No!\n')
           -> success ?
   ForAll({x},mem,
      `IF x THEN FreeVec(x) ELSE NIL)     
           -> free only those <>NIL
 ENDPROC
\end{verbatim}
 
both examples show quoted expressions (`) being used with functions
that more or less build own control-structures.
 
\item[Unification.] (pattern matching on large \& nested data structures).
A simple example:
 
\begin{verbatim}
 a:=[1,2,3]
 ...
 IF a <=> [1,x,y] THEN ...
\end{verbatim}
 
¶{a} is a list of values, and pattern matching later on binds ¶{x} and ¶{y}
to 2 and 3. If the pattern match failed, for example because
the list was too short, the ¶{IF} would fail.
 
 
\item[The functionality of Lisp-lists] (garbage collected).
 
\begin{verbatim}
 MODULE 'tools/lisp'
 
 PROC main()
   DEF a,b
 
   -> map a reverse over lists
 
   showcellint(map(<<1,2,3>,<4,5,6>,
                    <7,8,9>>,{nrev}))
 
   -> sum a list
 
   WriteF('\n\d\n',foldr(<1,2,3>,
                         {add},0))
 
   -> select a list of zipped pairs
      whose head>tail
 
   showcellint(filter(zip(<1,2,3,4,5>,
                          <2,1,-1,5,4>),
                          {greater}))
 
   -> number of positive and negative 
      number of elements in a list
 
   a,b:=partition(<1,-5,8,2,-2,4,5,7>,
                       {pos})

   WriteF('\n\d \d\n',length(a),
                      length(b))
 
 ENDPROC
 
 PROC add(x,y) IS x+y
 PROC pos(x) IS x>=0
 
 PROC greater(c)
   DEF h,t
   c <=> <h|t>
 ENDPROC h>t
\end{verbatim}
 
\end{description}
 
Examples like these will be familiar to functional programmers,
though maybe in different syntax. A function such as ¶{append()} may be
defined using unification as:
 
 
\begin{verbatim}
 PROC append(x,y)
   DEF h,t
   IF x
     x <=> <h|t>
     RETURN <h|append(t,y)>
   ENDIF
 ENDPROC y
\end{verbatim}
 

 
\sez{Miscellaneous features}
 
Inline assembly allows for the perfect integration of E code
with pieces of MC68000 code:
 
\begin{verbatim}
 PROC bla()
   DEF count:REG
   MOVEQ #10,count
 loop: WriteF('count=\d\n',count)
   DBRA count,loop
 ENDPROC
\end{verbatim}
 
Easy creation of structures ``on the fly'', without declaration:
\begin{verbatim}
 CreateGadgetA(BUTTON_KIND,NIL,
               [...]:newgadget,[...])
\end{verbatim}
where the two ¶{[...]} stand for list of values, either as structure
(¶{NewGadget}) or as ¶{taglist}, for example.
 
I've only touched the surface of E, but it isn't possible to
show each feature in detail. 
 
\sez{Future directions}
 
\amiga{} E, as a program development system for the \amiga{}, will continue
to evolve. For the near future we'll see the release of an E specific
source-level debugger, with a nice font-sensitive multi-window GUI.

\finearticolo
