# Author: Paul Fitzpatrick, firstname.lastname@example.org # Copyright (c) 2018 Paul Fitzpatrick # # This file is part of CosmicOS. # # CosmicOS is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # CosmicOS is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with CosmicOS; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
Here we count up from zero, go through some primes, that sort of thing. Just like in the movies! There is some syntax around the numbers, and a structure to the “lesson,” but it will be fine for the listener to ignore all that for now. Hopefully what they will pick up on is:
We’ll get to a more compact representation of numbers later, once we’ve established the basics.
We’ve hopefully cued our listeners to be looking for mathematical patterns. So let’s give them some more. It doesn’t matter so much what patterns we give, as long as they are clear, and that there are several of them. Eventually we’ll want the listener to start turning things around, and use the parts of the message they understand (the mathematical patterns) to learn something about the parts they don’t (the message structure and syntax).
Let’s take a shot at introducing ways of comparing numbers. No doubt we’re revealing a feudal, reductive mindset in which all things must be ranked in a hierachy. ¯\_(ツ)_/¯.
Equality is introduced by a series of true statements of the form
X = X
(the syntax is a little different than regular math, more like
= X X, but that isn’t important yet). The listener will hopefully
discern a number getting repeated twice within the “sentence”
structure they’ve been seeing, but won’t be sure yet what we are
driving at until we introduce non-equality and contrast with it.
Now introduce symbols for ‘greater than’ and ‘less than,’ and contrast with equality. Hopefully the listener will start to understand what part of the sentences are numbers, what part is a function of the relationship between the numbers, and what parts are just meaningless (for now) scaffolding around all that. There’s an ambiguity between the ‘greater than’ and ‘less than’ symbols, depending on how you interpret the sentences, but it doesn’t matter yet.
Add some random examples.
Even more random examples. We shouldn’t be shy about piling on examples at this early stage of the message. Even just the repetition of the sentence structure with many small variations could help guide the listener at a more fundamental level than what we’re ostensibly trying to communicate here.
At this point, the listener can find numbers in our sentences, and has some idea of symbols related to equality and inequality. But the structure of the sentences remains a mystery. Let’s introduce more math, so that we can show different sentence structures. First, let’s introduce logical negation. We construct some sentences the listener should know are wrong, and put “not” in front of them.
Show an equality, then negate two conflicting inequalities.
Show an inequality, then two negations.
Show another batch of inequalities with negations.
Let’s introduce some arithmetic, to show off still more sentence structure.
We show sentences of the mathematical form
X = Y + Z, which in our message look like
= X | + Y Z. From this, and the negation lesson, the listener will hopefully
start picking up on how to chain operations.
If the listener didn’t already have a pretty clear idea of what
then these sentences could just as easily be interpreted as being about subtraction.
Even having an idea of
=, syntax is still fuzzy enough that this lesson may not
be unambiguous by itself.
Introduce subtraction via
= X | - Y Z sentences. Until syntax is fully understood,
an ambiguity may remain between this and addition.
While we’re at it, let’s introduce multiplication with
= X | * Y Z sentences.
As for addition and subtraction, there will be some ambiguity as to whether we are
presenting multiplication or division here, until syntax is clearly understood.
Switch from unary numbers to another representation. The best representation will depend on the details of how the message is being transmitted, and the rest of the message doesn’t depend on that choice for correctness (though the choice will have implications for how easy the message will be to interpret). As a base-line, imagine we use a binary representation.
It isn’t important for the listener to understand, but it might be worth explaining at this point how the unary representation worked. In fact there’s no special syntax used, just three objects:
unaryin English) that takes a value and:
0, the function returns
1, the function returns another function, just like itself, except with any ultimate return value increased by
Using syntax defined later in the message,
unary could be defined as:
@ unary-v | ? v | ? x | if (= $x 0) $v (unary-v | + $v 1) @ unary | unary-v 0
If you know Lisp/Scheme/etc, just read
| as opening a parenthesis that gets closed at the end
of the statement.
Anyway, all of this is a digression, but it is worth knowing that as much as possible the message is built from itself, so that in the end everything dovetails nicely.
We’ve advanced enough that we’re starting to have choices about how something is expressed. Let’s pause to acknowledge that, and reinforce some syntactic equivalences so the listener can be confident of them.
Parentheses play a role in grouping expressions, just like in regular
math. To reduce the mental burden of tracking nesting, we use a
that means “add parentheses between this point and as far as you can go.” So for
(= 7 | + 3 4) is equivalent to
(= 7 (+ 3 4)).
An expression starting with
assign is a way to name values for use within that expression. To use the assigned value, simply place its name at the beginning of an expression. For example, a value assigned to
x can be used by writing
(x). The name is entirely arbitrary, and can be just an integer.
We are pretty ruthless about adding syntax to reduce parentheses. So let’s allow writing
$x (or equivalent in other renderings). This and
| are in fact global options for the message that you can turn off if they are not to your taste.
Add more examples to give hints about scoping and other odd corners.
We’re ready for functions.
? starts a lambda function. Now we can have fun!
Emphasize the arbitrary nature of names, and hint that things we’ve learned already like addition could possibly be re-imagined as a named value.
Show that we can name functions and use them later - still within a single expression for now.
Show that we can nest functions to take multiple values.
We’ve set up a way to name a value within an expression. Now let’s go beyond that, and introduce a way to name a value in one sentence and use it in a later sentence. In other words, a message-level memory. After this, we’ll be able to define new symbols from existing ones, with less need for large numbers of examples.
We introduce a
define symbol that works just like
assign, except that it applies
to the rest of the message rather than the rest of the sentence.
A sentence of the form
define X Y means that
$X will evaluate to
Y from that
point on (unless
X is changed by another
meaning-of-life-universe-everything symbol here is entirely arbitrary, and
won’t be encoded as anything particularly meaningful in the message.
Now we can start defining and naming functions. Here’s one to square an integer.
Here’s a function to increment an integer.
Now that we have functions, we could introduce some clever definitions of true, false, and conditionals, where:
? x | ? y | ? z | x $y $z
? y | ? z | y
? y | ? z | z
This is a neat implementation, but maybe a bit confusing. So let’s
not actually commit to a type for truth values in the message yet,
but just equate them with the results of equality
Once we have truth values, we can introduce conditionals and build up to fun stuff.
One slightly sneaky thing we do is to code
$0. This could be helpful, or confusing, I’m not sure. Nothing
else in the message depends on this so it can be adjusted to taste.
Now that we spent some time looking at
false, let’s show
a way to build conditional expressions. We start with an
of the form
if CONDITION E1 E2, which evaluates to
E1 if the
If the listener is trying to map the language we are describing onto
their own system of computation, it is pretty important that
“lazy,” and completely skip evaluating the branch not taken. That
should become clear fairly soon if they were to try an “eager”
We can now define more interesting functions. Here’s the maximum of two integers:
Now the minimum of two integers:
Why should human CS students be the only ones the factorial example is inflicted on…
We continue introducing symbols related to math and logic. Now we will often be able to both define them and give examples, so the listener has multiple paths to understanding.
and, which evaluates to
true if both its two arguments are
false otherwise. We don’t talk about wbat happens if you pass it integers
or something funky. There’d be value in getting into talking about types, but
it might be a bit much just now.
or, which evaluates to
true if either of its arguments are
false otherwise. Again, we just don’t talk about what happens if you
pass in any unexpected values, like integers or functions. The message is
constructed so that the problem never comes up.
Now is an opportune moment to add
There are shorter definitions, like just negating
<, but this feels more natural?
Now we introduce our first data structure. The expression
cons X Y stores
in a pair. We can then pull
X out from the pair with
car (cons X Y), and we can
Y out from the pair with
cdr (cons X Y). Apologies for the arcane names,
they are inherited from Lisp (and they’ll be encoded as something else in the
We give a definition of
cons that is a bit funky. The
cons X Y expression
constructs a function which takes a single argument, also a function. That
argument gets called with
Y. That means to pull
X back out, we
just need to call
cons X Y with a function like
? a | ? b $a. Likewise for
Y. That is exactly what
Definitions like that can be a bit hard to think about. But the great thing is that you can apply definitions like these without initially understanding them. So if the listener wants to try them out, they can there’s an element of interactivity beyond what a plain text message could give.
define, we showed that there is a global memory, where we can associate a
symbol with a value. That’s nice, but it can be handy to separate memory from
naming. In this section we introduce
make-cell X, which creates a “cell”
of memory and puts
X in it. The cell can be read with
get! | make-cell X, or written to with
set! (make-cell-X) Y.
Lists are a handy data structure to have. We’d like to get to the point
in the message where we can make lists like this:
vector 1 4 5,
vector 77 $undefined (vector 1 2 3) 14, etc. But
vector can’t be a function in the language we’ve described up to now,
it just can’t work syntactically.
What we can do is make lists like this:
(list 3) 1 4 5,
(list 4) 77 $undefined ((list 3) 1 2 3) 14, where we manually
specify how many values are in the list.
And then we can introduce a way to transform the syntax of the language,
vector 1 4 5 gets rewritten to
(list 3) 1 4 5 prior to being
An alternative would be just to introduce some special new syntax for
lists, and give examples. If the listener finds our transformation approach
confusing, they can simply ignore it and pick the message up again once
vector is in place. But by giving the transformation, we offer a second
way to understand and experiment with the concepts being introduced.
For programming and for math, it is handy to be able to apply an element-wise transform to a list, and some kind of accumulator to pull out a summary.
Now let’s do something useful: define a special form for lists.
Just in passing, give approximate values for
A very very abbreviated introduction of complex numbers
should work through how to divide complex numbers (multiply by conjugate)
Hint at Euler’s identity
Sometimes it is nice to do a lot of assignments at once.
let ((k1 v1) (k2 v2)) body which is equivalent to
assign k1 v1 | assign k2 v2 | body.
# The following parts of the message are experimental, and not # carefully integrated with the main body
# these definitions are not quite what we want # since thinking of everything as a function requires headscratching # it would be better to use these as a parallel means of evaluation # ... for expressions