Welcome to the Squeak pages of Maarten Maartensz. See:  Map + Tour + Tips + Notes + News + Home


 

 

(very much so!)

A simple abstract specification of OOP-like programming

This chapter is motivated by my reaction to the book"Smalltalk 80" by Goldberger and Robson, that gives the Standard Received Version of the computer language Smalltalk. I started reading this because of my great interest in Squeak, which is a language derived from and based on Smalltalk 80, and because the book is highly recommended at various places on the internet.

Reading this book was no rewarding experience at all, and I stranded somewhere around chapter 10. This may be due to my utter stupidity and bad command of English, but it may also be due to my having read mathematical logic and mathematics since before Smalltalk was invented, and having quite outspoken ideas, based on much relevant reading, how texts explaining mathematics should and should not be written.

So I start this chapter with a description of my reaction to "Smalltalk 80" and the semantics of the term "object", that may perhaps appear to weaker minds of fainter hearts somewhat of "a rant", and end with an attempt to give a simple set-theoretical model for "object-oriented programming" - by my present lights, based on a rather wide reading about and experience with computer languages and programming.

And before starting my criticism and exposition, let me clearly note that Smalltalk and Squeak are quite beautiful and elegant programming languages, so that part what I am trying to do - by my lights - is to save these languages from the Standard Received Version of presenting them, talking about them, and explaining them.

Sections:

1. Talking of "objects" in Smalltalk
2.
What talking of "objects" in Smalltalk confuses
3.
A simple abstract specification of OOP-like programming


1. Talking of "objects" in Smalltalk

The Standard Received Version of presenting Smalltalk, that is stated in the book "Smalltalk 80" by Goldberger and Robson", is presented in terms of "objects" sending "messages". 

That these terms and the associated language are in fact intended as an extended metaphor rather than a presumed fact of a mathematical kind about a mathematical subject (a programming language) only is clearly stated in "Smalltalk 80" ...... in chapter 8, on page 119 of this supposed Bible of Smalltalk, in the following terms: 

"One of the major goals of the Smalltalk programming language is to apply a single metaphor for information processing as uniformly as possible. The Smalltalk metaphor, as described in earlier chapters, is one of objects that communicate by sending messages." (Stresses  added by me).

Before and after page 119 the reader must wade through many pages of quite odd animistic very bad  English - relative to the eyes of myself,  who is an 51 year old logical philosopher,  who  knows how to  program, and loves real logic and mathematics, and  who also can write - in which it is nauseatingly  many times said and repeated that "everything is an object", that "objects" "know" and "understand" and often also "desire" many sorts of things , all as a  matter  of course, as if a prior conversion to  metaphysical animism,  pan-psychism and the habits of  prose-writing derived from a combination of tech-talk and the wilder pages  of Heideggerian metaphysical prose must be part and parcel of learning to program Smalltalk.

Now I am too old, too erudite in relevant  matters, and too much of a non-conformist and independent  individual who likes thinking for himself to follow or accept a path of mangled and  broken English,  not based  on any clear mathematics, and in fact embodying a major pretension: 

"One of the major goals of the Smalltalk programming language is to apply a single metaphor for information processing as uniformly as possible.

This itself sounds pretty Orwellian and must be false as stated,  for "the Smalltalk programming language" addresses a far too simple entity (a computer)  to address with metaphors - although I do agree that one can not miss some sort of metaphors - or analogies - in (almost) any kind of explanation addressed at human beings.

Also, the 118 pages  before the above quotation failed to describe this intended major revision of English that makes up so much of  the  prose of the "Smalltalk 80" text as metaphor nor as  major goal  of the Smalltalk programming language - and is some of  the  worst English I have read,  including translations  of Heidegger's very bad prose. (Heidegger,  if you did not know it, was a  German  professors of pilosophy  who glorified in writing sentences like  "The Nothing nothings" and loved helping the Nazi-regime of his days persecute Jews, especially his brighter colleagues in philosophy. Hence, amongst rational philosophers with some gift for mathematics, logic and clear English Heidegger, and Heideggerian pretensions, practices and prose in philosophy tend  to be the stock example of  how NOT to be a  philosopher and how NOT to write philosophy.)

Besides, there tends to be much use of fancy terms like "polymorphism", "encapsulation", "inheritance" and such like in a none too clear way, as if using a term derived from the Greek or Latin immediately clarifies one's mind and terms. (These terms are  not entirely  meaningless in context nor entirely inappropriate,  but apart from that are as useful in  English as any Latin or Greek. What if "polymorphism", "encapsulation", "inheritance" had been named "multiple meanings", "contained data" and "shared code" respectively - for example?)

Nowe what is the reason for this revision of  English in Smalltalk 80 and most subsequent Smalltalk literature?  

The Smalltalk Programming Language and also the Programming Environment indeed are quite different from C, Prolog, Basic, Pascal etc. and their environments, and these differences seem to require another approach to teaching the language and talking about it. So much seems true.

But this does not mean - it seems to me - that in order to learn the Smalltalk Programming Language one must first give up ordinary English and learn to speak and write in a new sort of philosophical dialect about code that reminds me very much of Heidegger's wilder moments in his more obscure writings (which to a logical philosopher of my type of mind is ludicrous at best, and is a benighted form of academic fascism in its more everyday  factual appearance).

Of course: One CAN teach Smalltalk this way, for it HAS been done this way: Most who learned Smalltalk learned so by way of "Smalltalk 80", and after having finally succeeded (a path that the more fortright Smalltalk-gurus admit took them many months to a year!)- and forgetting about the many that failed - were indeed thankful and pleased. Likewise, the Pythagoreans apparently taught good mathematics in the context of wild ascetic theological aspirations, no doubt likewise based on much abuse of language next to highly praiseworthy motives. (The nobility of the human mind tends to be shown as much in its transgressions and aspirations as in its rational successes.) 

It NEED not be done in this way, though. and Smalltalk needs not be explained nor talked about in atrocious animistic prose, and five good examples of how to explain and talk about Smalltalk in a clear way are these:

(1) Simon Lewis: "The Art and Science of Smalltalk" (Prentice Hall 1995, ISBN 0-13-371345-8)
(2) The ANSI Smalltalk specification
(3) Mario Wolczko's article
(4) The Self Tutorial
(5) The System and the Whisker Browser in Squeak

About each of these I will say something more in a moment, after first repeating my basic reasons why I cannot stomach "Smalltalk 80": I am a mathematical and logical philosopher, who has much knowledge and reading experience in mathematics and logic, and I simply gave up in disgust on "Smalltalk 80" around chapter 10, because I refuse to learn a metaphorical Newspeak to learn a programming language, just as I refuse to give up logic and refuse to give up clear English to transform myself into a true believer in some silly philosophy.

Furthermore, it would seem VERY  likely to me that the great majority  of  people with serious  logical and mathematical minds over the  past 20  years have had similar reactions to "Smalltalk 80",  thus contributing to its status of major programming language that is difficult  to understand and difficult to learn to program in, except that they didn't say so loudly, and  instead  learned  worse  programming languages, simply because these came with introductions written in less bad or better English. In any case, for me it "Smalltalk 80"has the status of being absolutely the worst introduction to  a mathematical subject I  have ever read - which happens to be quite a strong claim in my case, for I have read  thousands of these.

Now for some more on the texts I mentioned that - mostly - are  not animistic nor do they mangle the semantical conventions of standard English to explain what they seek to explain, and do explain fairly well.

(1) Simon Lewis: "The Art and Science of Smalltalk": This is the clearest basic introduction to Smalltalk I read. It is a paper book of 1995, and oriented around VisualWorks 2.0 (the most direct commercial descendant of Smalltalk 80). It seems to be by an Englishman, and is considerably more held back and polite about the Standard Received Version of presenting Smalltalk than I am, but it does say in its opening lines that

"Smalltalk is different from other languages not only in its syntax (the parts of the language and how they go together), but in its whole philosophy of programming. Few programming languages are as interactive as Smalltalk. Fewer still make nearly all their source-code visible to the programmer on-line. This combination of features makes Smalltalk very powerful, but it can also make it intimidating to learn. This books aims to de-mystify that process by providing a practical rather than an academic introduction."(Stresses  added by me).

This is very well (and politely) put, and indeed Lewis is the book to turn to once you've lost your way in the far more academic and mystifying "Smalltalk 80". Indeed, I had read 5 books expounding  Smalltalk in the Standard Received Version, and will spare the reader my  thoughts on  these. But Lewis at least showed me that  Smalltalk in fact had  been mostly rationally and  clearly explained before, and so was a considerable joy for me - as if reading Bertrand  Russell after  having been made to believe that all  philosophy  ought to be written in a Heideggerian kind of prose. Also, as Lewis says, it is the philosophy of programming presented and put into words by "Smalltalk 80" I object to, not to programming language itself, which is quite beautiful and elegant. 

(2) The ANSI Smalltalk specification: In the 90-ies several languages got "standardized", which means that some basic explanation of all essential features of a language were written down by collections of experts on the languages. There is a 1997 ANSI specification that is fairly clear though densely written, as such standardizations by committees may be expected to be. It does have the great merit of not offering metaphors as facts.

(3) Mario Wolczko's article: This dates from 1985 and is preparatory to his Ph.D.-thesis - that I have not been able to get in my hands sofar. The merit of the article is that it is a clear specification of a considerable part of the semantics of Smalltalk in set-theory, which at the same time is its handicap, for one must be rather fluent in that to understand the article. But again: If one understands set-theory, here is a clear set-theoretical explanation of the basis of Smalltalk (worth very  many "Smalltalk 80"s in explanatory power, for my type of mind).

(4) The Self Tutorial: Self is a language derived from Smalltalk and used to develop Morphic, which in turn came to Squeak by way of Self. So both Self and Squeak are dialects of Smalltalk, and the main differences between Squeak and Self on the moment are that Squeak contains more of Smalltalk (indeed all of Smalltalk 80 + Morphic) and is more complicated, while Self does not seem to have been actively developed since 1995, which is also when Squeak started and John Maloney, until then a co-developer Self, turned to help develop Squeak.

But the Self Tutorial is available on line and those who know some Squeak and Morphic will find much of conceptual interest in this tutorial, that has the great merit of being fairly brief and quite clear and direct, and to be wholly inanimistic and also quite concrete, as introductions to programming language go. The reason seems to be that all "objects" in Self are "morphs" i.e. identifiable parts of the screen that can be attached code to. (This is the same in Squeak.)

So regardless from the merits of Self, the Tutorial of Self has the merit of showing one can explain an OOP language in simple clear English, without first having to acquire an animistic dialect of mangled English, that poses as a philosophy of programming of Orwellian dimensions and language. (Smalltalkers of many years of experience who wish  to criticize  me should realize that  I have more years of experience with botj mathematical logic and philosophy than they have with Smalltalk, since  I started reading botj before Smalltalk was invented - and they also should ask e.g. John Maloney why the Self Tutorial is so totally non-Goldberg&Robson like.)

(5) It is often said that Smalltalk comes with its own documentation, namely in its browsers, especially its System Browser. This is true once you start understanding the code - which is not difficult to read, unlike most programming languages, that are very full of parentheses and all manner of gobblydegook to please the compilers of those languages. (Indeed, in the end trying to make sense of Smalltalk and Squeak by means of the browsers taught me the most, just like reading Smalltalk code for mathematics I  know convinced me that the Smalltalk programming  language is a Good Thing - while "Smalltalk 80" by Goldberger & Robson is a major example of how NOT to write about programming and how NOT to write a philosophy of programming.

And as it happens, Doug Way wrote a new type of browser for Squeak he calls "Whisker  Browser" that has the great merit of being able to show many windows with related code at once in the same browser. This  is very helpful, and Whisker also is smoother than the standard System Browser, and gives a much better picture of what is available in Squeak in one browser. 

What one will find if  one dives into the Smalltalk and Squeak  code with a browser is that there is very much code, for many  ends, and of considerable formal beauty - and one will also find that a considerable amount of the comments to this code are pure animism (with comments describing code in terms of "I", which even after nearly six months of daily reading this nonsense, still evokes reactions like "I am a piece  of printed text with a soul, a philosophy, a bill of rights" and "I am a text with an Oedipus conflict" and other nonsense.)

Now let me deepen and unconfuse my theme a little.

2. What talking of "objects" in Smalltalk confuses

Apart from much mangled English in the Standard Received Version a major irritant - to my type of mind, that has read lots of philosophical, logical, psychological and even theological texts with lots of talk about "objects" outside Smalltalk, and who therefore has fairly extended and precise semantical notions about what a term like "object" might be used to mean - the problem with the term "object" and the slogan "Everything is an object" (in Smalltalk -  which is, in Smalltalk tutorials, rarely added) is that in actual fact when one programs the term "object" fairly refers to distinct items on at least  five distinct levels:

When the term "object" as used in Smalltalk and OOP occurs, it may refer to each, any or all of:




"Objects

 

 




as:

say:

located:




   imagined

imagined object

in one's mind as experience

   described

commented object

in one's editor as English

   coded

coded object

in one's editor as programming code

   working

virtual object 

in one's computer, run by executing code

   represented

model object

in some world outside the computer 




where the last may be absent (as in programming fantasy games) and each may be subdivided.

In any case, and apart from any real entities, events, processes or things one may seek to model by one's programs, there are at least four levels about - let's say - the virtual object one is trying to write the code for:

One's ideas about it; one's talk and writing about it; one's code for it; and what's produced by the code and working in the computer, if all goes well enough (that may or may not adequately represent something one seeks to model  and that may or may not do work one intends it to work).

Also, it ought to be intuitively obvious that the "object" on each level is quite different, and indeed made of different things related in different ways even if all are called - very confusingly: four- or five-fold ambiguity! - by the very same name: Ideas are not prose; code is not prose; running code on a computer is something else again; and what happens inside a computer may be independent of most that happens outside it, intended or not by its human users.

Indeed, a considerable part of the difficulty of programming is that so many different levels of being human in a rational and creative way are involved, since in fact to write a program is to make a machine do certain kinds of things in a language that is simple enough to be processed by it, yet clear enough, with or without comments, to be also interpreted and understood by humans.

This takes a lot of rational thinking and planning and acting by a human being on many levels, from choosing apt terms to knowing the subject one seeks to model by programs and many related things, precisely because computing machines, while being capable of much, at least sofar are no way capable of understanding English, and must therefore be addressed in a formal language that differs considerably from English, and that indeed serves a different end: It must be both processed by a computer and be understandable by a human being, and indeed it should be as easy as is possible to write and understand for a human being, while still being fit and simple enough to make a computer do things.

3. A simple abstract specification of OOP-like programming

So what IS "Object-Oriented Programming" briefly "OOP"? It is far from easy to say, in clear English,  without jargon. I have been exposed to it and explanations of it in the context of C++, Java, Delphi and VisualBasic, apart from Smalltalk, and I have programmed some in all of these, including their non-OOP precursors, if any (C, Pascal, Basic).

In programming practice, the "OOP" these languages have in common seems mostly to consist in their having large organized libraries of code that can be readily and easily used mostly through the setting of parameters in menus. That's quite impressive compared to what was possible in earlier, so-called non-OOP versions of these languages, and a true enrichment and simplification, but what precisely "OOP" is also is hard to glean from such documentation I have read (including quite a lot for Java).

I have to admit that I don't like C or Java or Basic much, and the same applies to their OOP-forms, because I don't like the languages , for various reasons. I do like Pascal and Delphi, and especially Prolog, in which I have programmed quite a lot.

Since I like Squeak, which has by far the best programming environment I have ever seen, and since I like the Squeak language, I have had - next to earlier exposures to OOP, mentioned above - good reason to contemplate the question what may be meant, and having a bend and a liking for mathematical logic, have arrived at the following, which I shall try to explain "from first principles".

To understand things in a human way is to embed them in a wider context of things one does understand already (to some extent, at least). 

A systematic approach to understand things is to embed them in mathematics, on the hypotheses that 

(1) mathematics is general and formal knowledge about structures and sets and relations of any kind, so that once one can translate the essentials or basics of something into some mathematical language one at least has thereby acquired an understanding of the structures and sets and relations involved in the thing one seeks to understand, and that 

(2) anything one seeks to understand at least involves some structures, sets and relations in some fundamental ways that have much to do with what it really is, can do and may be.

Trying to understand Squeak and Smalltalk, I have arrived at the following simple explanation of what seems to be involved in OOP-like programming in logical and simple set-theoretical terms.

However, I will be very sparingly in my use of set-theoy (in fact, the way I like to see these things done is well illustrated by Van der Waerden's "Algebra" or Halmos' "Naive Set Theory", though what follows is much simpler) and I try to explain it all clearly and simply. Indeed, one difference between the present set of metaphors to explain OOP and Smalltalk and those of "Smalltalk 80" are that mine are essentially mathematical and logical, and are  not merely twisted English, presented as "a single metaphor for information processing [applied] as uniformly as possible"

Let me start with a simple explanation of what a formal grammar is.

I suppose the reader knows what the characters and digits of English are and what strings of characters and digits are. There are many examples in this text, and one important factual thing to notice is that much of the strings of languages for humans consist of interpunction, also known as white space: dots, commas etc. and the empty character. These mark off substrings that are the words and terms of the language. Words in the present context may be defined as strings without white space and terms sequences of word smaller than statements, which are the basic structural units of a language. (For more see The Squeak Stated especially The formal specification).

 Now English is a proper subset of the strings that can be formed with English characters, and in general a language is a subset of the strings that can be formed with the characters of the language. 

Now a grammar for a language= a statement of the basic valid forms of a language and the rules to make other valid forms from these by systematic uniform substitution and ordinary logic.

The grammatical form of a string consists of a sequence of terms for  grammatical categories, that we may as well call a form, for as many words as the string contains such that the n-th word in the string indeed is a term of kind named by the n-th term in the form for any term in the string, and such that the form can be produced by the grammar (as a grammatically valid form).

A grammar = a statement of the basic valid forms of a language and the rules to make other valid forms from these by systematic uniform substitution and ordinary logic.

This is easily illustrated by algebra: "0" is a numerical expression, and "1" is a numerical expression are here specifications of some basic valid forms of algebra, while "if "X" is a numerical expression and "Y" is a numerical expression then "X+Y" is a numerical expression" is an example of a rule to derive a valid form. From this one can derive by uniform substitution e.g. if " 1" is a numerical expression, " 1" is a numerical expression then "1+1" is a numerical expression, whence by logic (modus ponens) and the prior assumption that "1" is a numerical expression on can obtain that "1+1" is a numerical expression.

Indeed, in the present context it is to the point to remark that in this specification in fact another assumption tends to be involved: If "X" is a numerical expression, then "X" represents the number X, since "1" and "1+1" are just strings. An assumption of this kind - that one's terms represent certain things - is involved in the use of all terms, but indeed often silently passed by and indeed terminologically confused, just like one uses the string "elephants" to refer to elephants automatically.

Also, it is noteworthy that grammars are stated in English or some other natural language (to start with, at least) enriched by variables like "X" and "Y" together with an assumption about substitution.

 

 

Help

Glossary is a dictionary of terms used to talk about Squeak. The terms in magenta are contained in this Glossary.

== Begin Glossary of some technical terms for Squeak ==

Abstract
Objects that contain only methods meant to be inherited by some Subclass.

Browser
Browsers in Squeak are Objects written in Squeak that allow the human user to see the code and internal states of Squeak as it runs. There are many Browsers in Squeak. See BrowsingSqueak. Here is the code for opening one: " Browser openBrowser " (highlight and do it).

Class
General kind of Object that runs when Squeak runs. The methods of a class are the most general methods objects of that class that objects of that class need to perform. Objects of a Class are made by Squeak's keyword new. Thus " Morph new openInWorld " puts a new basic Morph (that looks like a blue square) in the current World one is in inside the Squeak environment.

Classes in Squeak are part of a tree of Classes and so may contain classes (called their subclasses) and be contained in classes (their superclasses). The top is ProtoObject directly followed by Object. This last class contains the basic methods all Objects in Squeak inherit. A

Category
Collection of Objects in Squeak that are of some specific kind (usually: serve a common end). Examples: Kernel, Collections, Morph etc. Categories exist for the convenience of the human user. In a System Browser the leftmost pane is the Category Pane. All the Objects listed in all the Categories together comprise the things the Squeak Environment they are part of to do whatever it may do.

Encapsulation
refers to a basic feature of Squeak (and Smalltalk): The programs written and running inside Squeak are Objects, that is packages of data (stored in instanceVariables or classVariables) and methods, such that the data of an Object can only be manipulated by the Methods of that Object. This last feature is called "encapsulation". In other programming languages data and programs (methods) are far less tightly knit together.

Halo
Every Morph has a halo around its boundary when (Cmd/Alt) Left Clicked (or with the middle mouse button, if you use a 3 button mouse). The halos are in fact a number of icons that when clicked give access to some of the things any Morph can do and often some of the things the Morph one clicked on can do.

Method
Program (routine) written in the Squeak language that can be compiled by the Squeak programming environmet, as part of some Object.

Message
String made up of the name of a Method including where necessary specific parameters. In Squeak the human user and Objects running in the Squeak environment may receive and send messages to Objects running in the Squeak environment. An Object that receives a Message performs the Method the Message and addresses, and answers the result, and usually also changes some of its internal states.

Morph
Object in Squeak that exists as a form on the screen. For example: " Morph new openInWorld " (highlight the red phrase with the mouse; rightclick; and choose 'do it') puts a new basic Morph (that looks like a blue square) in the current World one is in inside the Squeak environment. Although this new Morph is not special in any way, using its Halo it can be resized, moved, turned, inspected, debugged and attached code to. (You can remove by way of the x-Halo.)

Image
The Squeak.exe on you harddisk when started loads an Image, which is a total Squeak environment as it was last saved. Images can be large - many megabytes - and are the basic format in which Squeak is maintained, worked and saved. It is wise to save your images often, and to make copies of images that contain important matter. You can have as many images as you please by saving existing images under new names. Each contains the full power of Squeak and whatever information you or others have put into it.

Inheritance
The Objects in Squeak are organized as instances of Classes that are contained in other Classes. A Class A that is contained in a Class B in Squeak has access to the Methods of the Class B. Thus an object of kind A is said to inherit - the methods from - the objects it is contained in. And inheritance is a way to give Objects more capacities (access to methods) without having to write special code. (The hierachy button is very useful here: Go to TextMorph and push the hierachy button to see a fairly deeply nested morph in context.)

Object
Computerprogram that is a package of data and methods, such that only the methods in the package can access the data in the package. A running Squeak is an object that consists of many objects working together. Objects can be addressed by Messages, which are names of the methods an object can execute, possibly with some Parameters. Objects are written in Squeak inside the codepane of a Browser. When accepted by Squeak's Interpreter they are compiled into bytecode and are ready to be run inside the Squeak environment.

Objects in Squeak are normally instances of their classes, and one class may have many instances. Classes in Squeak run when Squeak runs, and can be send Messages to make instances. The key-word in Squeak for this purpose is 'new'. (Highligh the red keyword and do Cmd/Alt-m to see where it is used.)

Polymorphism
is: A term used to refer to the fact that in Squeak (and Smalltalk) there may be methods with the same name that function differently in different contexts. This is useful for the human user.

Programming
is: Writing programs a computer can execute. Programs are series of instructions to a processor and are calculable functions. In the Squeak Environment the human user writes programs in the Squeak Language that always must belong to Objects, as the methods an Object can execute. One of the things that makes Squeak special and powerful is that the Objects one writes in the Squeak language run in the Squeak environment, and can be rewritten, extended, and altered as and when one pleases.

Programming Environment
A running program in which one can write programs. One of the special things about Squeak is that the programs one writes in the Squeak Programming Environment also run in it, and can be altered - rewritten, tweaked - on the fly. Some other special thing about Squeak is that it is written in Squeak; that it is open source, i.e. you get ALL the source code; and that everything about it can be altered by you, according to your tastes and abilities.

Primitive
A fundamental routine that needs to be fast and is run by the Squeak Virtual Machine.

Project
In Squeak a project is a collection of objects running in a window called World.

Squeak
Squeak is a programming environment and programming language bundled together. It is a development of Smalltalk and goes beyond Smalltalk in containing and being oriented around Morphs: Parts of a computer-screen that are Objects in Squeak, and thus can run all manner of programs inside Squeak.

Subclass
See Class.

Superclass
See Class.

VM = Virtual Machine
The Squeak.exe loads a Squeak Image and starts a Virtual Machine. This is a part of the Squeak Environment that mediates between the code running inside the Squeak environment and the processor, and that - figuratively speaking - helps precook code for the procesor. It is worked with so-called Primitives, that are written in C (or in a part of Squeak that translates Squeak code to C), and can be called from ordinary Squeak code.

World
In Squeak a World contains a Project as it appears on the screen, and takes the form of either a small project window or the full screen when activated. See WorldWindow.

== End Glossary ==

MM 10/4/2002 11:49

 

 

 

 

 


Welcome to the Squeak pages of Maarten Maartensz. See:  Map + Tour + Tips + Notes + News + Home