Tutorial tour

From Liberty Eiffel Wiki
Jump to navigation Jump to search

Welcome to the guided tour of the tutorial!

All the classes in the tutorial are provided with your Liberty Eiffel installation, in the tutorial directory.

Easy starting: Hello World!

To compile the program, go to the LibertyEiffel/tutorial directory and execute the command:

se c HELLO_WORLD make -o hello

The meaning of the command is

se the front-end tool for the Liberty Eiffel compiler
c the tool invoked by se for compile into an executable
HELLO_WORLD the class of which an object is created (you may also write it in lower-case, or use its filename with the .e extension) we call it root class, as this is the root of the programs object tree
make the creation procedure of the HELLO_WORLD class to call
-o hello generates an executable with the name hello (linux) or hello.exe (windows)

The command produces an executable, usually hello or hello.exe depending on the system. After compiling is finished, you can run the executable.

This unavoidable program is in the file hello_world.e and lets you grasp the basic concepts of Eiffel. Those concepts are:

  • Everything is a class. In Eiffel, outside classes there is no salvation.
  • The program starts by creating an object (of the root class) and initializing it by execution of the given root creation procedure. Here, the make feature in the class HELLO_WORLD.
  • Each file is named after the name of the class it contains, in lower-case, with the .e extension.
  • Each class comes with a set of features, all its attributes and methods which come in form of functions (if they return a result) or procedures (in case they just 'do' something)
  • Note the special object io that allows you to write text on the standard output. We will see that it also lets you read data.
  • For the Eiffel syntax, look here.

Please take a look at the following examples in the tutorial folder to see some classical example programs (some of them are in organized in folders for better overview)

  • fibonacci.e
  • knight.e
  • pyramide.e and pyramide2.e
  • hanoi
  • parking
  • triangle

To compile the other samples you must obviously modify the compiler command to give another root class .

Some important concepts

Comments

As in every programming language there is the possibility to write comments into the source code, which do not have any effect for the final program, but are for the developer or reader of the source code to get an understanding of the ideas and algorithms behind the code. A comment in Eiffel starts with the sequence of a couple of minus signs and is terminated by a newline (RETURN).

-- this is a comment in Eiffel
a := b + 3 -- comments are also allowed after some code

Manifest notations

Liberty Eiffel comes with a big set of available datatypes. Famous examples as INTEGER, BOOLEAN, CHARACTER and STRING. For those (and also many collection types) there is the possibility to directly denote them in the program code, using the notations

123
True, False
'a'
"STRING"

See tutorial file manifest_notation.e for an example with nearly all options to define objects by manifest notations.

Everything is an Object

As mentioned above, in Eiffel every useful thing is an object. There are two different kinds of objects: expanded objects and referenced object. Expanded objects are passed by value, while reference objects are - who guesses - passed by reference. In case you write 7 in the source code this is a shorthand for an instance of the expanded type INTEGER and therefore it is an expanded object. Whenever you assign it to a variable or pass it to another feature it gets copied. A STRING object - e. g. denoted by "Hello World!" in the source code is a reference object, created implicitly by the compiler, allocated on the heap and passed by reference.

Local variables and Assignments

Every routine may define variables in a "local block" before its body (which start with the keyword do):

make
   local
      a: INTEGER
      s: STRING
   do
      a := 5
      a := a + 1
      s := "Hello World!"
   end

The visibility of these variables is limited to the method they are defined in and they do not keep their value from one execution of that routine to another. Assignment is done by the assignment operator ":=" which changes the variable (or let's say writable entity) on the left side to the value of the expression on the right side. In case of the "Hello World!" assignment a new object of type STRING is created on the heap, initialized to the text "Hello World!" and a link to this object is stored in the local variable s.

Loops

In Eiffel we have exactly one construct to do something repeatedly, so no need to learn about for, do-while, while, anyhow, one is sufficient:

from
  -- initialization
invariant
  -- what shall stay true during repetition
variant
  -- non-negative, but decreasing numeric value
until
  -- termination condition
loop
  -- what to do several times
end

Note, that the termination condition is an expression of type BOOLEAN and the loop body is executed until the condition evaluates to True, which differs in the logic from e. g. the loop constructs in C.

The most strange things for newcomers are probably the invariant and the variant. While the first is a BOOLEAN condition, that stays true for every iteration, the latter is an INTEGER value which decreases with every iteration and always stays positive and therefore shows that the loop terminates. Both are optional and are not used very often in practice, even though they are essential in case we want to prove a program to be totally correct (and therefore terminates). I fear, that these formal loop assertions stay more or less unused until a formal verification tool is able to take real benefit from them.

See tutorial/loops.e for an example of the Greatest Common Divider algorithm to show the usage of the loop.

Input-output

io cluster

The input-output cluster is made up of several parts.

The io/basic subcluster contains the staples of

  • the definitions of standard input and output streams, STD_INPUT and STD_OUTPUT that are available to all classes. In fact ANY offers those features:
    • io: STD_INPUT_OUTPUT -- Handle to standard file setup.
    • std_input: STD_INPUT -- The standard input stream
    • std_output: STD_OUTPUT -- The standard output stream
    • std_error: STD_ERROR -- The standard error stream
    • standard_streams: STANDARD_STREAMS, a singleton that allows to redirect std_input_stream, std_output_stream as well as std_error_stream.

Beyond this standards streams that are available to all processes you can get read files in the operative file system using an INPUT_STREAM using BINARY_FILE_READ to read a binary file or TEXT_FILE_READ to read a text file. Similarly, to write a file you use an OUTPUT_STREAM such as BINARY_FILE_WRITE for binary files or TEXT_FILE_WRITE for text files.

READLINE_INPUT_STREAM is an input stream where the data is read from Command Line Interface (CLI) using the GNU readline library. You probabily have already used this library without knowing as it is used by several programs as at the time this notes has been written almost nine hundred packages in Debian use a version of readline

You may have noticed that Eiffel uses streams to access files. This is a much more flexible way to access data. In fact when you use an INPUT_STREAM the actual data can come from plain files, or from a string with STRING_INPUT_STREAM or any classes that conforms to and INPUT_STREAM, or more properly any live type that is a proper heir of INPUT_STREAM, such as BINARY_INPUT_STREAM, EZMQ_SOCKET_INPUT (a sockect messaging library), FILTER_INPUT_STREAM{ (put references to filters and explaiin BASE64_INPUT_STREAM, HTTP_CLIENT_INPUT_STREAM, MONITORED_INPUT_STREAM, QUOTED_PRINTABLE_INPUT_STREAM, TEMPLATE_INPUT_STREAM ), TERMINAL_INPUT_STREAM.

Mostly for testing purposes there are also NULL_INPUT_STREAM, a "null" stream provides an unbroken sequence of zero, like /dev/zero does on Unix and NULL_OUTPUT_STREAM that swallows any character like /dev/null does on Unix.


  • directory
  • basic_directory?

Arguments

print_arguments.e

Feature calls

Contracts

Contracts are the main reason why Eiffel is superior to many other languages... ...

Garbage collection

Eiffel is garbage collected. That means, the objects created on the heap will automatically be freed after they lost reachability from the rest of the executing program.

ACE files

Collections

including iterator and sorting

Downcasting

downcasting.e

To go further

Agents

... and tuples

external

cecil

Memory management

memory

Extension libraries

Random

Date & time

Storable

Sequencer

Vision

visiopn, signal

Network

Execution