<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dw="https://www.dreamwidth.org">
  <id>tag:dreamwidth.org,2010-04-27:505737</id>
  <title>The Mandelbear's Musings</title>
  <subtitle>mdlbear</subtitle>
  <author>
    <name>mdlbear</name>
  </author>
  <link rel="alternate" type="text/html" href="https://mdlbear.dreamwidth.org/"/>
  <link rel="self" type="text/xml" href="https://mdlbear.dreamwidth.org/data/atom"/>
  <updated>2018-07-06T16:12:54Z</updated>
  <dw:journal username="mdlbear" type="personal"/>
  <entry>
    <id>tag:dreamwidth.org,2010-04-27:505737:1628698</id>
    <link rel="alternate" type="text/html" href="https://mdlbear.dreamwidth.org/1628698.html"/>
    <link rel="self" type="text/xml" href="https://mdlbear.dreamwidth.org/data/atom/?itemid=1628698"/>
    <title>Languages: Imperative, Object-Oriented, and Functional</title>
    <published>2018-07-06T05:36:51Z</published>
    <updated>2018-07-06T16:12:54Z</updated>
    <category term="programming"/>
    <category term="software"/>
    <category term="structured"/>
    <category term="fp"/>
    <category term="curmudgeon"/>
    <category term="languages"/>
    <category term="oop"/>
    <category term="computers"/>
    <dw:mood>didactic</dw:mood>
    <dw:security>public</dw:security>
    <dw:reply-count>15</dw:reply-count>
    <content type="html">&lt;blockquote style="white-space: pre-wrap;"&gt;
Back when smalltalk was sports and the weather,
And an object was what you could see,
And we watched "Captain Video" in black-and-white,
Before there was color TV.
-- &lt;a href="https://steve.savitzky.net/Songs/lad/"&gt;"When I Was a Lad"&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt; Even if you're not a programmer (and most of the people I expect to be
    reading this aren't) you've probably heard one of your geek friends
    mentioning "object-oriented" programming.  You might even have heard them
    mention "functional" programming, and wondered how it differs from
    non-functional programming.  The computer curmudgeon can help you.

&lt;p&gt; If you &lt;em&gt;are&lt;/em&gt; a programmer, you probably know a lot of this.  You may
    find a few items of historical interest, and it might be useful explaining
    things to the non-programmers in your life.

&lt;h2&gt;Imperative languages&lt;/h2&gt;

&lt;p&gt; As you may recall from last month's post on &lt;a href="https://mdlbear.dreamwidth.org/1621179.html"&gt;computer
    languages&lt;/a&gt;, the first programming languages were assembly languages --
    just sequences of things for the computer to do, one after another (with a
    few side-trips).  This kind of language is called "imperative", because
    each statement is a command telling the computer what to do next:  "load a
    into register 2!" "add register 2 to register 3!" "roll over!"  "sit!"
    You get the idea.

&lt;p&gt; Most programmers use "statement" instead of "command" for these things
    even though the latter might be more correct from a grammatical point of
    view; a "command" is something one types at a terminal in order to run a
    program (which is &lt;em&gt;also&lt;/em&gt; called a "command").

&lt;p&gt; Most of the earlier programming languages (with one notable exception that
    we'll get to later) were also imperative.  Fortran, Cobol, and Algol were
    the most prominent of these; most of today's languages descend
    more-or-less from Algol.  (By the way, the &lt;a href="http://www.softwarepreservation.org/projects/ALGOL/report/Algol60_report_CACM_1960_June.pdf"&gt;Report on the Algorithmic Language Algol 60&lt;/a&gt; is something I always
    point to as an example of excellent technical writing.)

&lt;p&gt; Imperative languages make a distinction between statements, which
    &lt;em&gt;do&lt;/em&gt; things (like "a := 2", which puts the number 2 into a variable
    called "a"), and "expressions", which compute results.  Another way of
    saying that is that an expression has a &lt;em&gt;value&lt;/em&gt; (like 2+2, which
    has a value of 4), and a statement doesn't.  In earlier languages that
    value was always a number; later languages add things like lists of
    symbols and strings of characters enclosed in quotes.

&lt;p&gt; Algol and its descendents lend themselves to what's called "Structured
    Programming" -- control structures like conditionals ("if this then {that}
    else {something-else}") and loops (for x in some-collection do
    {something}) let you build your program out of simple sections that nest
    together but always have a single entrance and exit.  Notice the braces
    around those sections.  Programming languages have different ways of
    grouping statements; braces and indentation are probably the most common,
    but some languages use "if ... fi" and "do ... done".

&lt;p&gt; Languages also have ways of packaging up groups of statements so that they
    can be used in different places in the program.  These are called either
    "subroutines" or "functions"; if a language has both it means that a
    function returns a value (like "sqrt(2)", which returns the square root of
    2) and a subroutine doesn't (like "print('Hello world!')", which prints a
    familiar greeting.)  Subroutines are statements, and functions are
    expressions.  The expressions in parentheses are called either "arguments"
    or "parameters" -- I was bemused to find out recently that &lt;em&gt;verbs&lt;/em&gt;
    have arguments, too.  (A verb's arguments are the subject, and the direct
    and indirect objects.)

&lt;h2&gt;Object-oriented languages&lt;/h2&gt;

&lt;p&gt; As long as we're on the subject of objects, ...

&lt;p&gt; In the mid 1960s Ole-Johan Dahl and Kristen Nygaard, working at the
    University of Oslo, developed a language called &lt;a href="https://en.wikipedia.org/wiki/Simula"&gt;Simula&lt;/a&gt;, designed for
    simulating objects and events in the real world.  Objects are things like
    cars, houses, people, and cats, and Simula introduced &lt;em&gt;software&lt;/em&gt;
    objects to represent them.  Objects have "attributes":  my car is blue, my
    cats are both female, my wife has purple hair.  Some of these attributes
    are objects in their own right:  a car has wheels, a cat has four legs and
    a person has two legs and two arms.  Some of these are variables:
    sometimes my driveway has a car in it, sometimes it doesn't, and sometimes
    it has two or three.

&lt;p&gt; What this means is that objects have &lt;em&gt;state.&lt;/em&gt;  A car's speed and
    direction vary all the time, as does the position of a cat's tail.  An
    object is a natural way to bundle up a collection of state variables.

&lt;p&gt; An object also can &lt;em&gt;do things&lt;/em&gt;.  In a program, objects rarely do
    things on their own, some other object &lt;em&gt;tells&lt;/em&gt; them what to do.
    This is a lot like sending the object a message.  "Hey, car -- turn left!"
    "Hey, cat!  What color are your eyes?"  Software objects don't usually
    have any of their state on the outside where other parts of the program
    can see it; they have to be asked politely.  That means that the object
    might be &lt;em&gt;computing&lt;/em&gt; something that looks to the outside like a
    simple state variable -- a car computes its speed from the diameter of its
    tires and how fast its wheels are turning.  All these things are hidden
    from the rest of the program.

&lt;p&gt; An object has to have a &lt;em&gt;method&lt;/em&gt; for handling any message thrown at
    it, so the documentation of most languages refers to "calling a method"
    rather than "sending a message".  It's the same thing in most cases.  As
    seen from the outside, calling a method is just like calling a function or
    subroutine, except that there's an extra argument that represents the
    object.  If you think of the message as a command -- an imperative
    sentence -- it has an implied subject, which is the object you're talking
    to.  &lt;em&gt;Inside&lt;/em&gt; the little program that handles the method, the
    object is represented by a name that is usually either "self" or "this",
    depending on the language.

&lt;p&gt; One natural thing to do with objects is to classify them, so objects have
    "classes", and classes tend to be arranged in hierarchies.  My cats are
    cats -- we say that Ticia and Desti are &lt;em&gt;instances&lt;/em&gt; of the class
    "Cat".  All cats are animals, so Cat is a &lt;em&gt;subclass&lt;/em&gt; of Animal, as
    are Dog and Person.  (In programming languages, classes tend to have their
    names capitalized.  Variables (like "x" or "cat") almost always start with
    a lowercase letter.  Constants (like "Pi", "True", and "Ticia") can go
    either way.)

&lt;p&gt; An object's class contains everything the computer needs to determine the
    behavior of its instances:  a list of the state variables, a list of the
    methods it can handle, and so on.  Now we get to the fun part.

&lt;p&gt; Simula was just objects and methods tacked on to a "traditional"
    imperative language -- Algol in that case.  Most other "object-oriented"
    languages work the same way -- C++ is just objects tacked on to C; Python
    and Perl had objects from the beginning or close to it, but they still
    include a lot of things -- numbers, strings, arrays, and so on, that
    aren't objects or (like strings in Java) are pretending to be objects.  It
    doesn't have to be that complicated.

&lt;p&gt; Shortly after Simula was released, Alan Kay at Xerox PARC realized that
    you could design a programming language where &lt;em&gt;everything&lt;/em&gt; was an
    object.  The result was Smalltalk, and it's still the best example of a
    &lt;em&gt;pure&lt;/em&gt; object-oriented language.  (It inspired C++ and Java, and
    indeed almost all existing OO languages, but very few of them went all the
    way.  Ruby comes closest of the languages I'm familiar with.)  Smalltalk
    is &lt;del&gt;turtles&lt;/del&gt; &lt;ins&gt;objects&lt;/ins&gt; all the way down.

&lt;p&gt; In Smalltalk numbers are objects -- you can add new methods to them, or
    redefine existing methods.  (Your program will eventually stop working if
    you redefine addition so that 2+2 is 5, but it will keep going for a
    surprisingly long time.)  So are booleans.  True and False are instances
    of different subclasses of Boolean, and they behave differently when given
    messages like &lt;code&gt;ifTrue:&lt;/code&gt; or &lt;code&gt;ifFalse:&lt;/code&gt;.  (I'm not
    going to go into the details here; Smalltalk warrants an article all by
    itself).  Loops are methods, too.  The trickiest bit, though, is that
    &lt;em&gt;classes&lt;/em&gt; are objects.  A class is just an instance of Metaclass,
    and Metaclass is an instance of &lt;em&gt;itself.&lt;/em&gt;

&lt;p&gt; Someone trying to implement Smalltalk has to cheat in a couple of places
    -- the Metaclass weirdness is one of them -- but they have to hide their
    tracks and not get caught.

&lt;h2&gt;Functional languages&lt;/h2&gt;

&lt;p&gt; Smalltalk, for all its object orientation, is still an imperative language
    underneath.  A program is still a sequence of statements, even if they're
    all wrapped up in methods.  Objects have state -- lots of it; they're just
    a good way of organizing it.  Alan Kay once remarked that programming in
    Smalltalk was a lot like training a collection of animals to perform
    tricks together.  Sometimes it's more like herding cats.

&lt;p&gt; But it turns out that you don't need statements -- or even state -- at
    all!  All you need is functions.

&lt;p&gt; About the same time Alan Turing was inventing the &lt;a href="https://en.wikipedia.org/wiki/Turing_machine"&gt;Turing Machine&lt;/a&gt;,
    which is basically a computer stripped-down and simplified to something
    that will just barely work, Alonzo Church was developing something he
    called the &lt;a href="https://en.wikipedia.org/wiki/Lambda_calculus"&gt;Lambda
    Calculus&lt;/a&gt;, which did something similar to the mathematical concept of
    &lt;em&gt;functions&lt;/em&gt;.

&lt;p&gt; A mathematical function takes a set of inputs, and produces an output.
    The key thing about it is that a given set of inputs will always produce
    exactly the same output.  It's like a meat grinder -- put in beef, and you
    get ground beef.  Put in pork, and you get ground pork.  &lt;em&gt;A function
    has no state, and no side-effects.&lt;/em&gt;  State would be like a secret
    compartment in the meat grinder, so that you get a little chicken mixed in
    with your ground beef, and beef in your ground pork.  Ugh.  A side effect
    would be like a hole in the side that lets a little of the ground meat
    escape.

&lt;p&gt; Objects are all about state and side effects.  You can call a method like
    "turn left" on a car (in most languages that would look like
    &lt;code&gt;car.turn(left)&lt;/code&gt;) and as a side effect it will change the car's
    direction state to something 90 degrees counterclockwise from where it
    was.  That makes it hard to reason about what's going to happen when you
    call a particular method.  It's even harder with cats.

&lt;p&gt; Anyway, in lambda calculus, functions are things that you can pass around,
    pass to other functions, and return from functions.  They're &lt;em&gt;first
    class&lt;/em&gt; values, just like numbers, strings, and lists.  It turns out
    that you can use functions to compute anything that you can compute with a
    Turing machine.

&lt;p&gt; Lambda calculus gets its name from the way you represent functions:  To
    define a function that squares a number, for example, we say something
    like: 

&lt;blockquote&gt;&lt;pre&gt;square = &amp;lambda; x: x*x
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt; Now, this looks suspiciously like assigning a value to a variable, and
    that's exactly what it's doing.  If you like, you can even think of
    &amp;lambda; as a funny kind of function that takes a list of symbols and
    turns it into a function.  You find the value of an expression like
    &lt;code&gt;square(3)&lt;/code&gt; by plugging the value 3 into the function's
    definition in place of &lt;code&gt;x&lt;/code&gt;.  So,

&lt;blockquote&gt;&lt;pre&gt;square(3)
  &amp;rightarrow; (&amp;lambda; x: x*x)(3)
  &amp;rightarrow; 3*3
  &amp;rightarrow; 9
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;small&gt;
&lt;p&gt; Most functional languages don't allow you to redefine a name once you've
    bound it to a value; if you have a function like &lt;code&gt;square&lt;/code&gt; it
    wouldn't make much sense to redefine it in another part of the program as
    &lt;code&gt;x*x*x&lt;/code&gt;.  This is vary different from imperative languages,
    where variables represent state and vary all over the place.  (Names that
    represent the arguments of functions are only defined inside any one call
    to the function, so &lt;code&gt;x&lt;/code&gt; can have different values in
    &lt;code&gt;square(2)&lt;/code&gt; and &lt;code&gt;square(3)&lt;/code&gt; and nobody gets
    confused.)
&lt;/p&gt;&lt;/small&gt;&lt;/blockquote&gt;

&lt;p&gt; Lambda calculus lends itself to &lt;em&gt;recursive&lt;/em&gt; functions -- functions
    that call themselves -- and recursion is particularly useful when you're
    dealing with lists.  You do something to the first thing on the list, and
    then combine that with the result of doing the same thing to the rest of
    the list.Suppose you have a list of numbers, like &lt;code&gt;(6 2 8 3)&lt;/code&gt;.
    If you want another list that contains the squares of those numbers, you
    can use a function called &lt;code&gt;map&lt;/code&gt; that takes two arguments: a
    function and a list.  It returns the result of applying the function to
    each element of the list.  So

&lt;blockquote&gt;&lt;pre&gt;map(square, (6, 2, 8, 3))
 &amp;rightarrow; (36, 4, 64, 9)
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt; It's pretty easy to define &lt;code&gt;map&lt;/code&gt;, too.  It's just
&lt;blockquote&gt;&lt;pre&gt;
map = &amp;lambda; (f, l):
	if isEmpty(l)
           then l
	   else cons(f(first(l)), map(f, rest(l)))
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;small&gt;
&lt;p&gt; The &lt;code&gt;cons&lt;/code&gt; function constructs a new list that consists of its
    first argument, which can be anything, tacked onto the front of its second
    argument, which is a list.  Using &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt;
    as the names of the functions that get the first item in a list, and the
    remainder of the list after the first item, is pretty common tese days.
    &lt;a href="https://en.wikipedia.org/wiki/CAR_and_CDR"&gt;Historically&lt;/a&gt;, the
    function that returns the first item in a list is called &lt;code&gt;car&lt;/code&gt;,
    and the function that returns the rest of the list is called
    &lt;code&gt;cdr&lt;/code&gt; (pronounced sort of like "could'r").

&lt;p&gt; I know, the classic introduction to recursive functions is factorial.
    Lists are more interesting.  Besides, I couldn't resist an excuse for
    mentioning "car".  We'll see "cat" in a future post when I discuss
    scripting languages.
&lt;/p&gt;&lt;/p&gt;&lt;/small&gt;&lt;/blockquote&gt;

&lt;p&gt; We call &lt;code&gt;map&lt;/code&gt; a "higher-level" function because it takes a
    function as one of its arguments.  Other useful higher-level functions
    include &lt;code&gt;filter&lt;/code&gt;, which takes a boolean function (one that
    returns true or false) and &lt;code&gt;flatmap&lt;/code&gt;, which takes a function
    that returns lists and flattens them out into into a single list.  (Some
    languages call that &lt;code&gt;concatmap&lt;/code&gt;.)  &lt;strong&gt;Higher-level
    functions are what make functional languages powerful, beautiful, and easy
    to program in.&lt;/strong&gt;

&lt;p&gt; Now, Church's lambda calculus was purely mathematical -- Church used it to
    prove things about what kinds of functions were computable, and which
    weren't, which is exactly what Alan Turing did with the Turing Machine.
    We'll save that for another post, except to point out that &lt;em&gt;Church's
    lambda calculus can compute anything that a Turing machine can compute,
    and vice versa.&lt;/em&gt;

&lt;p&gt; But in 1958 John McCarthy at MIT invented a simple way of representing
    lambda expressions as lists, so that they could be processed by a
    computer:  just represent a function and its arguments as a list with the
    function first, followed by its arguments.  Trivial?  Yes.  But
    brilliant.  His paper included a simple function called &lt;code&gt;eval&lt;/code&gt;
    that takes a list representing a function and its arguments, and returns
    the result.  Steve Russell realized that it wouldn't be hard to implement
    &lt;code&gt;eval&lt;/code&gt; in machine language (on an IBM 704).

&lt;p&gt; I'll save the details for another post, but the result was a language
    called &lt;a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)"&gt;Lisp&lt;/a&gt;.  It's the second oldest programming language still in use.  The
    post about LISP will explain how it works (elsewhere I've described
    &lt;code&gt;eval&lt;/code&gt; as &lt;a href="https://www.quora.com/What-is-the-most-amazing-piece-of-software-in-the-world/answer/Stephen-M-Bear"&gt;The most amazing piece of software in the world&lt;/a&gt;), and hopefully show
    you why Kanef's song &lt;a href="http://songworm.com/lyrics/songworm-parody/EternalFlame.html"&gt;The
    Eternal Flame&lt;/a&gt; says that God wrote the universe in LISP.  Programmers
    may want to take a look at &lt;a href="https://stephen.savitzky.net/Doc/single-link/"&gt;"Sex and the Single
    Link"&lt;/a&gt;.

&lt;h2&gt;And finally,&lt;/h2&gt;

&lt;p&gt; I'd be particularly interested in seeing comments from the
    &lt;em&gt;non-&lt;/em&gt;programmers among my readers, if I haven't lost you all by
    now.  Was this post interesting?  Was it understandable?  Was it too long?
    Were my examples sufficiently silly?  Inquiring minds...


&lt;p&gt; &lt;em&gt;Another fine post from
    &lt;a href="https://mdlbear.dreamwidth.org/tag/curmudgeon"&gt;The Computer Curmudgeon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1628698" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
</feed>
