1.1.1.1 short definition of imperative, functional and OOP languages with Dylan examples
Albert Wagner
Would someone please post a short definition of imperative, functional and OOP languages. 
I thought I knew OOP from Smalltalk until I read of Dylan's approach. 
Neel
(Neelakantan Krishnaswami)
and
Joseph N. Wilson
Imperative programming:
a programming style that uses explicit
  • mutable state (mutable variables) and
  • control flow (goto, for-loops, branches, etc.).
Conceptually, you perform a computation by changing the state of the computer.
A procedural language adds functions and procedures on top of this foundation, and then you get C and Pascal.
For example, here's an imperative function to find the factorial of an integer:
define function factorial
 (n :: <integer>)
  => (n! :: <integer>)
  let n! :: <integer>= 1;
  while (n >0)
    n! := n! * n;
    n  := n - 1;
  end while;
  //
  n! // return n!
end function factorial;
Functional programming
A programming style that emphasizes an "equational" approach is taken:
  • instead of changing the state of a machine, a program is defined as the solution to a set of functions.
  • in order for mathematical laws to hold, in particular that

      a = b => f(a) == f(b)
  • mutable state and explicit control flow are avoided.

    (For example, if there were mutable global variables referenced in f, then there would be no guarantee that one call to f(3) would have the same value as another call f(3).)
The usual definitions of functional programming are also that
  • functions should be first-class.
In other words that they can be passed as arguments and created and returned as values.  (Both Smalltalk's blocks and Dylan's methods are first-class functions.)
For example, you might define factorial as:
define function factorial
  (n :: <integer>)
  => (n! :: <integer>)
  if (n = 0)
    1
  else
    n * factorial(n - 1)
  end if;
end function factorial;
taking the definition of factorial straight from the mathematical definition.
Object-oriented Programming (OOP)
A style of programming that emphasizes two concepts.
  • First, the idea of subtyping:
    ---  values can belong to more than one type.
  • Second the idea of dynamic dispatch
    --- a method is selected based on the most specific type of the arguments.
For example, here's an OO factorial:
define constant <zero> = singleton(0);
   // The type <zero> contains only the
   // int 0, so <zero> subtypes <integer>.
define method factorial (n :: <zero>)
   => (n! :: <integer>)
  // in case of type <zero> return
    1
end method factorial;
define method factorial (n :: <integer>) 
  => (n! :: <integer>)
   // in case of type <integer> which excludes
  //  the zero return
    n * factorial(n - 1)
end method factorial;
We still haven’t handled all the cases of possible argument values. If the argument is a negative, factorial has been asked to do an impossible job. We can create a type that consists of a limited range of integer values and use that to provide a behavior for the  rest of the cases
define method factorial (
      n:: limited(<integer>, max: -1))
  error ( “facorial: Bad argument“, n )
end method factorial
Note that the factorial method chosen for an argument depends on the value passed to the function factorial.
The way that Dylan's OO is different from Smalltalk is the way of selcting a method
  • In Smalltalk selecting the method based only on the first receiver (message-passing OO),
  • Dylan selects a method based on *all* of the arguments (multimethod dispatch OO).

    We need two or more arguments to demonstrate multimethods, and this post has gotten long enough, so I'll leave that for another day.
Joseph N. Wilson
More on generic functions:
We can create an argument whose type is the single value 0. (Such a type can be created by evaluating the expression singleton (value)).
  • as described above via

    define constant <zero> = singleton(0);
       // The type <zero> contains only the
       // int 0, so <zero> subtypes <integer>.
    define method factorial (n :: <zero>)
  • or via
     define method factorial (n == 0)

    That's possible, because
        x == $special-x
    is a shortcut for
        x :: singleton($special-x).
Why is the right method used if we evaluate factorial (1), factorial (0), or factorial (-1)?
    • Which type do you believe is more specific to the object 0, the singleton type that contains only the value 0 or the class <integer>?
    • Which type do you believe is more specific to the object -1, the range of integers containing only negative integers or the class <integer>?