Home  |  FAQ  |  About  |  Contact  |  View Source   
 
SEARCH:
 
BROWSE:
    My Hood
Edit My Info
View Events
Read Tutorials
Training Modules
View Presentations
Download Tools
Scan News
Get Jobs
Message Forums
School Forums
Member Directory
   
CONTRIBUTE:
    Sign me up!
Post an Event
Submit Tutorials
Upload Tools
Link News
Post Jobs
   
   
Home >  Tutorials >  General Coding >  Intro to Eiffel.NET - Part One: language basics
Add to MyHood
   Intro to Eiffel.NET - Part One: language basics   [ printer friendly ]
Stats
  Rating: 4 out of 5 by 12 users
  Submitted: 11/11/02
Daniele Pagano ()

 
Introduction to Eiffel.NET
Part One: the Eiffel Language basics


Eiffel is an object-oriented language developed at by OO guru . In his classic book , Meyer gives a comprehensive itroduction to OO methodologies, and does so by introducing a notation for his code sample that turns out to be Eiffel. This language is incredibly lean, consistent, original, and scalable. Its porting to .NET is very good news, and with it's a resource worth checking out.

In this series of tutorials I will present the basic ideas of Eiffel and see how they integrate in .NET, from the CTS to Windows Forms. This is my plan:
  1. Language Basics
  2. More language: inheritance and design by contract
  3. ...one or more parts on Eiffel and .NET

Intended audience. In order to make the most of these tutorials, you should not only know how to code in some Object Oriented programming language (like C#), but also understand the basic theory of OO design (inheritance, polymorphism, and so on). Make sure you brush up on that before you begin.

In this tutorial I will present the basic ideas of the Eiffel language, like classes and control structures.

Getting the language

You can dowload trial versions of the classic for almost any platform, or the new , which is a plug-in for Visual Studio.NET from their .

I'll assume you have ENViSioN! installed as a language in your VS.NET.


Classes

As I mentioned, Eiffel is a purely Object-Oriented language. This implies the following (from the Eiffel documentation):
  • The unit of software reuse in Eiffel is the class.
  • The unit of modularity in Eiffel is the class.
  • The unit of type modeling in Eiffel is the class.
  • All Eiffel code must exist within the context of a class.
  • In Eiffel, application systems, or simply systems, are created by assembling a set of related classes. The classes in a system will be related only by one or both of the two allowable relationships in object-oriented design.

If you know anything about OO languages, this is the ideal (i.e. everything is a class). It is not accomplished by languages like C++ or Java (their base types are not classes), but the C# borrowed a lot of ideas from Eiffel (like Properties), so Eiffel fits nicely in the CLR (with the exception that it supports multiple implementation inheritance and the CLR does not).

The syntax of Eiffel is derived from Algol, so it looks like the other Algol-derived language Pascal (seems cheesy at the beginning, but it's so readable you won't mind after a bit).

This is the simplest class (and therefore language construct) you can define in Eiffel:


class
    FOO
end


This means that all the other parts we'll discuss later are optional.

Ok, now let's look at a more interesting class. I'll put tags in there marked by --{number} so I can reference it, but those are not part of the code (-- denotes comments). For some reason DevHood doesn't have code coloring for Eiffel, oh well :)

This class for the Eiffel docs uses all the required and optional features of a class.


--{1}
indexing  
    description: “Objects that model lists”  
    revision: “$Revision: 1.2.2.1 $”
--{2}
class 
    OLD_FASHIONED_LIST [G]

--{3}
obsolete "This class is obsolete, use LINKED_LIST [G] instead"

--{4}
inherit 
    DYNAMIC_LIST [G]

--{5}
create 
    make

--{6}
feature -- Initialization 

--{7}
    make is 
            -- Create an empty list. 
        do 
            before := True 
        ensure is_before: before 
        end 

feature -- Access 

--{8}
    item: G is 
            -- Current item 
        do 
            Result := active.item 
        end

    first: like item is 
            -- Item at first position 
        do 
            Result := first_element.item 
        end 
                (other features omitted)
--{9}
invariant 
    before_constraint: before implies (active = first_element) 
    after_constraint: after implies (active = last_element)


Now I'll go over those points, and we'll cover some these aspects more later:
  1. Indexing. This is some glorified documentation used to identify the class (which, recall, it's also a module). It's of course useful for generating automatic documentation.
  2. Header and Generics. This is the class header. This class is plain, but you can also add attributes here, in particular "deferred" would denote an abstract class. The generic parameter [G] is the equivalent of the C++ template using <G>. Basically you create instances of the class with your own type there, so you can use to contain anything you want. Eiffel supports both normal and constrained genericity (when you limit what classes go in the generic, like saying "SORTED_LIST [G -> COMPARABLE]"), but this is an advanced topic I won't cover here. The team lead of the Microsoft C# compiler team told me that they're currently introducing this feature in C# for its next revision.
  3. Obsolete. Just like deprecated.
  4. Inheritance. This a case of implementation inheritance, like "extends" in Java.
  5. Constructors. In Eiffel constructors (called creators) don't need to have the same name of the class, but need to appear here. This is better than the other system since (as you may have noticed) having multiple constructors differntiated just by arguments it's often not enough. This is how object creation looks like in Eiffel:
    
    
    spam_list : OLD_FASHIONED_LIST[SPAM]
    create spam_list.make
    

    This is a two-step process where type is assigned first (with a null pointer) and then the constructor is called (create is like new).
  6. Features. That's where most of the code goes. You'll see that there are two feature fields in this class with different comments, these are just handy groups, one feature statement for each class is enough.
  7. Methods. This is our constructor. Don't worry about its content yet, we'll go over the coding details later. But note that it has no parameters and no return type.
  8. Properties. In Eiffel, a feature with no arguments is called without parentheses, so these features are in effect what in C# we call properties. G is the return type. The "like" statement is used in generics to refer to a type but without having to type it too many times (for mainteinance).
  9. Invariant. If you have taken a data structures class, you may know what this is: statement always true about the class. What you may not know is that this is actual code, and it's checked for by the compiler (you can disable this in release for efficiency). We'll cover this exciting fact in our Design by contract section.

Ok, so you know how Eiffel looks like. Let's add some meat to our class by implementing features and see some old-fashioned code.


Implementing Features

There are three types of features in Eiffel:
  • Attributes. Attributes are the properties of class, or the features that actually occupy memory.
  • Functions. Functions are methods that return values. Like in Pascal, functions always return values, even if it's a null pointer.
  • Procedures. Procedures, like in Pascal, cannot return values.
Both functions and procedures all called "Routines".

Let's dissect another sample class from the docs to see what features can do:


class 
    SOME_CLASS

create 
--{1}
    make, 
    make_with_arguments

feature -- Initialization

    make is  
            -- Creation procedure  
        do  
            an_attribute := 5  
        end
--{2}
    make_with_arguments (hour: INTEGER; minute: INTEGER; second: INTEGER) is  
            -- Another creation procedure  
        do  
            an_attribute := second + (minute * 60) + (hour * 3600)  
        end

feature -- Access
--{3}
    an_attribute: INTEGER  
            -- An attribute of type INTEGER
--{4}
    another_attribute: INTEGER is 46
            -- A constant attribute
--{5}
    a_function: STRING is  
            -- A function without arguments  
        do  
            Result := an_attribute.out  
        end

    another_function (an_int: INTEGER): INTEGER is  
            -- A function with arguments  
        do  
            Result := an_attribute + an_int  
        end

feature -- Basic Operations
--{6}
    a_procedure is  
            -- A procedure with no arguments  
        do  
            an_attribute := an_attribute + 5  
        end

    another_procedure (an_int: INTEGER; another_int: INTEGER) is  
            -- A procedure with arguments  
        do  
            an_attribute := an_attribute + an_int + another_int  
        end

end -- Class SOME_CLASS


  1. Multiple Constructors. So this is how multiple constructors are declared. All features within a class need to have unique names, so you can't overload constructors in the C way.
  2. Constructor wiht arguments. This is an example of passing arguments, in the usual Pascal-like syntax.
  3. Attribute. An attribute. You see no "private" keyword here. We'll talk about access restriction soon.
  4. Constant. Same as above, but with a value assigned.
  5. Functions. Note how ": TYPE" specifies a return value. Values are returned by assigning to the special variable Result, which content is inspected after the function in over (so it's not like a return statement that ends the function).
  6. Procedures. With or without arguments, but not return value.

Now about some more details:

    Access Restriction. As I promised, here's the deal. In Eiffel, the class hierarchy is a lattice (i.e. all classes derive from the same class, ANY, and, low and behold, there is a class that inherits from all classes, NONE; this naming has of course to do with polymorphic behavior, i.e. Null is of type NONE). In Eiffel, access control is incredibly precise: you can restrict every feature independently to any classes that you'd like to.
    Recall that we had multiple "feature" blocks for kicks. Well, every feature block (so in theory every feature) can have its own access policy by specifying what classes can access it. The default is to specify nothing, which is the equivalent of typing:
    
    
    feature {ANY}
    

    Every class conforms (in the technical sense of class conformance) to ANY (since they inherit from it), so this is a "public" feature.

    To create a "private" member, you can say
    
    
    feature {NONE}
    

    Since no class conforms to NONE (since NONE is derived from every class). Now you see why the names ANY and NONE instad of Object and Null.

    To grant access to one or more classes and all their proper descendants (since they conform to them), you can say something like:
    
    
    feature {CLASS_A, CLASS_B, CLASS_C}
    

    This you cannot do (with any ease anyway) in languages like C# or Java. And it's really cool.

    We'll talk about export control to derived classes on our section on inheritance.

    Instructions and Control Structures. A bit about what to write in the bodies of the routines:
    • Creation. We discussed creation above, it's accomplished with the "create" keyword.
    • Procedure call. Applying a feature to an object. For example:
      
      
      hd_item.set_text (a_label)
      

    • Assignment. The ":=" operator is used. It's quite straightforward, but remember that the type of the LHS must conform to the type of the RHS. Also, Eiffel has value types like in C#, but they are called "expanded types", so all the boxing issues have to be considered.
    • Conditional. if/then/else, here's all there is to it:
      
      
       if l_c.is_digit then  
           l_state := 2  
       elseif l_c = '-' or l_c = '+' then  
           l_state := 1  
       else  
           l_state := 3  
       end
      

    • Loop. There's only one loop structure in Eiffel, and it does the job fine. Here's an example:
      
      
       from  
           i := lower  
       until  
           i > upper  
       loop  
           if item (i) /= Void and then v.is_equal (item (i)) then  
               Result := Result + 1  
           end  
           i := i + 1  
       end
      


    Deferred routines. If your class is deferred, you can have one or more deferred routines, just write "deferred" instead of the "begin ... end" body block.

    This should keep you busy for now :)

    Next time I'll talk about Inheritance and Design by Contract (very exciting stuff).

Return to Browsing Tutorials

Email this Tutorial to a Friend

Rate this Content:  
low quality  1 2 3 4 5  high quality

Reader's Comments Post a Comment
 
now do you know if eiffle has been finished for .NET yet, and if so, where can you pick it up?
-- J J, November 13, 2002
 
Well, that's actually explained at the very beginning of the tutorial (the free version you can download is fully implemented and stable). Sorry if it doens't jump off the page, but it's there :)
-- Daniele Pagano, November 13, 2002
 
weird....... cool just the same. have you thought about doing a scheme.net-related tutorial? That would be fun.
-- Aaron Brethorst, November 14, 2002
 
Wow, that's pretty cool! Thanks for the intro!! Looking forward to more!
-- Robert Wlodarczyk, November 14, 2002
 
I did think about Scheme.net, actually. Unfortunately HotDog Scheme (to only .net port I know) it's not very complete, and not integrated in VS.net (barely compiles to IL). But I'd be fun anyway, after I'm done with this series. Do you think I should teach the language from scratch and then see how it works on .net? I'm really more a Common Lisp guy, but it's certainly close enough. Anyone wanna write a CL compiler for .net? ;)

And thanks for the feedback, the second part should be approved shortly and the third is already in the works!
-- Daniele Pagano, November 15, 2002
 
Copyright © 2001 DevHood® All Rights Reserved