Experimental extension ideas - Lispl-Wicht/c-logo-s GitHub Wiki
Representational Experiments (Non-Normative)
Logo's infix operators (8 June 2026)
Pedagogical potential:
Letting learners define the mapping between infix as the symbolic-relational register, and prefix as the operational-discursive register, conversion (transformation of representations) is supported, not just treatment (transformation of values).
Prefix becomes
- the canonical semantic form
- the reference shown by the system
- the hover explanation
- the fallback rendering
Infix becomes:
- a convenience
- a cultural bridge
- a representational experiment
The infix operators
^forpower,*,×or⋅forproduct,/or÷forquotient,+and-forsumanddifference,=forequalp,<and>forlesspandgreaterp,<=or≤forlessequalp,>=,≥forgreaterequalp,- and
←formake
constitute an exception to Logo's regular prefix notation.
The arithmetical and relational operators connect with the conventional notation used in mathematics class.
The assignment operator ← emphasises a physical L-value/R-value notion by
highlighting the assignment direction instead of suggesting equivalence of both
values with a = or a purely mathematical definition context with
:=. It provides an unequivocal use of the equal sign and connects with
formal CS notation, used e.g. by Donald Knuth (also adopted in R
as <-).
Note: The assignment operator or make operator is not part of the infix operator
machinery. Therefore it is not considered an infix operator in cLogos terminology.
It is syntactic sugar sui generis that resolves earlier in the reader pipeline into
the regular prefixed make call.
However, infix operators in Logo are directives (realised through defstructures in the pipeline) that are syntactic sugar over arithmetic or logic procedures. Logo's regular prefixed syntax lets instructions be read nearly as natural language sentences. This is the priority.
Infix operators introduce a relational perspective which is represented in a highly condensed symbolised form and cannot be read as an action unfolding in time. Therefore, the flow of reading is interrupted through the integration of a different semiotic register in Duval's sense.
To justify the use of infix operators beyond the connection to conventional math class customs and honour Logo's primary representation style at the same time, the following extension is debatable:
Fostering the invention of own infix symbols to support creative experiences may be possible in cLogos by making the representational shift explicit.
For this purpose the keywords infix, weight and associativity
are introduced (✅ provided in the surface normalisation, 16 June 2026) , e.g.:
to [my.sum.product infix "*+ weight 45 associativity left] :a :b
output sum :a product :a :b
end
The concrete surface syntax shown here is illustrative, not normative. But this corresponds with the underlying Common Lisp constructor:
(define-infix :sign "*+"
:weight 45
:associativity :left
:procedure (lookup-procedure "my.sum.product"))
This enables two possible calls:
print my.sum.product 4 5
print 4 *+ 5
The environment must make the presence of custom infix operators explicit and explainable. Therefore the following constraints apply:
- infix must be declared adjacent to its definition
- the editor must show the underlying procedure on hover
- infix usage must be visually marked (colour / underline)
- infix cannot override existing primitives
Thus, custom infix operators must not appear implicitly in introductory materials. Learners can invent symbols only after they understand procedures.
Custom infix operators must rely on procedures that are diadic by default, and their symbols must not consist of more than two Unicode characters.
Primitive infix operators can be modified according to their weight and associativity with the commands:
set.infix.weight "+ 70
set.infix.assoc "* "right
This enables experiments with deviating precedence rules and conflict resolution rules for the traditional operators.
Modifications of the primitive infix operators and the introduction of custom
infix operators take place in the workspace (*workspace-infix-table*). They
overshadow the stable operators in the core of the language.
INVARIANT:
←is the assignment operator and not part of the arithmetic infix operator lattice. It has fixed precedence and right associativity and cannot be overridden, shadowed, or redefined. Additional warning message: "The assignment operator does not compute values; it assigns values to variables and cannot be redefined.” But still, the error messages is:set.infix.weight/set.infix.assoc doesn't like ← as input.
Alternatives for reconciliation
As a general principle, Logo favors verbs as names for commands (procedures called for their effect), and nouns as names for operations (procedures called for their output).
Turtle Talk partially deviates from this scheme through historically grown vocabulary choices.
As a possible reconciliation, alternative names may be introduced as aliases or meta-commands, without replacing the canonical Berkeley Logo vocabulary.
Meta-commands for turtle motion
An additional command move may be introduced as a meta-command that
composes existing directional commands such as forward, backward, left,
and right.
The meaning of the second input depends on the direction:
move forward 10 ; second input is distance
move left 270 ; second input is angle
This preserves the original primitives while allowing motion to be expressed as a compositional sentence.
Meta-commands for state toggling
Another possible meta-command is toggle, used with symbolic state names:
toggle textscreen
toggle fullscreen
toggle splitscreen
Optional shorthands may be provided:
tts
ttf
tss
These forms do not replace existing commands; they provide an alternative, linguistically explicit layer.
Aliases for communicative clarity
Some commands may be complemented with aliases that emphasize communicative intent:
label→sayPrints text at the turtle’s current position.filled→paint.inTakes a color code and an instruction list describing a polygon; the effect is the filled polygon.
Explicit scope vocabulary
Alternatives for the scope-related commands:
global→globalizelocal→localize
These aliases make the effect of the command explicit, without altering semantics.
Complex numbers ✅ (enabled as core feature on 22 June 2026 in the reader pipeline)
Complex numbers may be introduced as an explicit numeric extension.
Literal notation:
c(0.0,1.4142135)
This corresponds to the Common Lisp representation:
#C(0.0 1.14142135)
and aligns naturally with vector notation used in turtle geometry.
This literal form is complemented by a constructor operation:
complex 0.0 1.4142135
which evaluates to:
c(0.0,1.4142135) ;; surface representation, internally: #C(0.0 1.4142135)
analogous to how:
int 1.3
evaluates to:
1
No implicit coercions are introduced; complex numbers remain explicit symbolic objects.
The helptext of cLogos complex can therefore be:
"COMPLEX num1 num2
(COMPLEX num1)
c(num1,num2)
outputs a complex number with num1 as the real part, and num2 as the imaginary part.
The 'c' is the special quote for complex number words which must be represented as
an ordered pair in conventional mathematical notation."
This allows to change the sqrt helptext of Berkeley Logo:
"SQRT num
outputs the square root of the input, which must be nonnegative."
to
"SQRT num
outputs the square root of the input, which can also be negative."
Programming in the Large
Utilising the concept of Microworld as meaning (July 2026)
Papert introduces Microworld as a term for "self-contained worlds [each with its own assumptions and constraints], in which certain questions are relevant and others are not" (Papert 1980, p. 117). These microworlds also enable deliberate restrictions to encourage the construction of safe cognitive spaces in which operations can be examined and internalised before new operations become open for inquiry by extending the world (p. 118-119).
Starting from this, in cLogos a microworld is not necessarily a formal system that happens to be explored. It is rather a domain of meaningful activity defined for inquiry, in which certain actions, questions, and distinctions become possible and worthwhile.
As a complementary concept, a system in Common Lisp is primarily stipulative: it begins from design, it has specifications, it provides a set of functions through which the intended interdependent rules are enacted and what belongs becomes distinguishable.
By contrast, a microworld is explicative. It is recognised retrospectively. One explores. One builds. One notices recurring structures. One begins to say: "Ah...what I have actually been exploring is..." The microworld is therefore not simply given. It emerges as an intelligible domain. So:
Systems are defined, microworlds are discovered. A system may be specified, but a microworld is recognised through inhabiting it.
In general however, this cLogos concept of microworlds describes the actual bottom-up approach of programming which is likewise characteristic
for programming in Lisp. As soon as a system is defined in Common Lisp with asdf:defsystem, the interaction with the REPL takes shape as
source text in the editor, and such explorations lead to the maturing system definition which can be
compiled as production code. Thus in this respect, microworld denotes a mindset underlying the cLogos way of bringing parts of source text together into a coherent body—at the same time it is
its complement of a Common Lisp system, yet with its special cLogos characteristics.
A microworld is declared as
declare.microworld cloud-cuckoo-land ~
"workspaces [foo bar.lala-land]
"procedures [baz.fun-isle:qux]
"variables [flip.dream-catcher:flop]
"microworlds [over-the-rainbow]
where cloud-cuckoo-land is a sample name for the microworld to explore, and the optional arguments may integrate existing workspaces,
procedures, variables, or microworlds into the new world, which comes into existence through the instruction:
load.world "cloud-cuckoo-land
The declaration does not create the conceptual microworld; it records a currently recognised coherence among existing objects and relations.
If a microworld has come into existence it can likewise be extended:
extend.microworld "cloud-cuckoo-land
"workspaces [quux]
"microworlds [mechanics]
This is recording the history of understanding during programming: once a decision is made while tinkering in the current workspace to declare the microworld emerging in the mind, a documentation process begins. The microworld becomes gradually extended with borrowed workspaces. Once the relation with another microworld is recognised, that one becomes included as well. Also just single procedures may become part of the own world under consideration.
If names of workspaces and procedures in cLogos consist of several words these parts are separated by dots, such as
do.something ; procedure
elsies.second.workspace ; workspace
If names of microworlds consist of several words those parts are separated by hyphens:
cloud-cuckoo-land
In fully-qualified names as lookup paths, the procedure name is the last constituent separated by a colon from the preceding parts. The name of the microworld is left from the colon and separated with a dot from the preceding workspace name. Thus:
second.bar.lala-land:poof
denotes procedure poof from workspace second.bar in the microworld lala-land.
Internally that procedure may be something addressable by various lookup paths like:
procedure-object-id: #<procedure 4711>
When microworlds are extended by other microworlds, the fully-qualified names foster naming hygiene. However, to treat microworlds as one namespace they can be merged:
merge.microworlds "cloud-cuckoo-land ~
"lala-land
Here, the names in lala-land are used within the namespace of cloud-cuckoo-land where then a call to
second.bar.lala-land:poof can simply become poof.
As it is good practice both in Common Lisp and in C++, as well as in other programming languages, such merging should not be the rule but the exception for good reasons. It is necessary to be certain that there will be no name conflicts, thus extending microworlds and using fully-qualified names is also recommended in cLogos.
Nonetheless: name spaces protect meanings; microworlds reveal relationships. The possibility to point to the same procedure within a workspace from different microworlds allows different views on the same object in different contexts. The extensibility of a microworld reflects a model as a world that can become sufficiently coherent to be surveyed.
In principle, when a child first encounters cLogos, perhaps
World
Turtle
Forward
Right
is already a complete world. Nothing is missing.
Later that same person enters another world.
World
Procedures
Variables
Workspaces
Later again,
World
Workspaces
Other worlds
None of these invalidate the previous one. They simply redefine what counts as "the world." This integration does not require convenient shorthands. It requires clarity about the adopted concepts as situated experiences. Furthermore, if one microworld integrates a concept from one workspace within this conceptual frame, and another does the same in another context, this may enable the learner to recognise the relation.
A microworld is a contextual graph of recognised relations over existing objects. They serve as overlays, so the underlying primary objects—the workspaces—remain untouched; what changes is the relational context in which they are understood. In this way, a microworld does not add objects; it makes relations among existing objects meaningful as a domain of inquiry.
Workspace as storage and locally bound cognitive space
The workspace in Logo is the primary cultivation space in which the interactions with the environment are stored. In cLogos this concept is generalised towards the concept of Common Lisp packages.
A workspace is the thing that exists. Therefore at startup, cLogos initially prepares a workspace for the current user and let the user enter it:
prepare "elsies.workspace
enter "elsies.workspace
Only now it is possible to declare a microworld as relational space, because existence precedes interpretation. So, cLogos continues:
declare.microworld "playing.ground ~
"workspaces [elsies.workspace]
Right now, the set of Logo primitives alone is known in this world. To become fully compatible with Berkeley Logo, the core-library must
be extended with the playing-ground:
extend.microworld "core-library ~
"microworlds [playing-ground]
For full alignment with Harvey's Logo textbooks, these worlds are merged automatically, so that the core library procedures can be called like primitives.
merge.microworld "playing-ground ~
"core-library
Now, the microworld is loaded to enact the relations:
load.microworld "playing.ground
New workspaces can be explicitly brought to existence through another call to:
prepare "another.workspace
If a workspace already exists, it can be either loaded with a microworld to situate it in a context. It can also be entered to be the active cultivation space. Or parts of it can be borrowed in another workspace:
borrow.from "elmars.workspace [foo]
The procedure foo is now accessible in elsies.workspace with the qualified name elmars.workspace:foo. If borrow.from
is called without a list, all names from the borrowed workspace become callable by their qualified names.
As a convenience, the qualified name can be altered through borrowing the workspace under a different name:
;; one procedure:
borrow.from.as "elmars.workspace [foo] "elmars:foo
borrow.from.as "second.bar.lala-land [poof] "lala:poof
;; or completely:
borrow.from.as "elmars.workspace "elmar
A workspace also allows to alter its public interface. While names in a package of Common Lisp are internal as long as they are not explicitly declared as external symbols, cLogos follows the conversed strategy: everything is public unless it is buried.
In Berkeley Logo, burying is a tool for workspace management—from the manual:
bury
BURY contentslistcommand. Buries the procedures, variables, and property lists named in the input. A buried item is not included in the lists output by CONTENTS, PROCEDURES, VARIABLES, and PLISTS, but is included in the list output by BURIED. By implication, buried things are not printed by POALL or saved by SAVE.
This is reinterpreted in cLogos as the public interface being the default. Logo assumes openness which continues across workspaces loaded in parallel.
Workspace
everything is public
unless
deliberately buried
Thus, during tinkering, it becomes part of the exploration to distinguish the auxiliary procedures constituting the implementation from those which constitute the public conceptual interface. The auxiliaries then can be buried and are only accessible from outside with the fully-qualified name containing two colons:
geometric.shapes.euclidean-perspective::polygon.helper
The UNICOM facility
cLogos will have networking capabilities. Particularly, it will provide the exchange of microworlds among users. While
load.world "cloud-cuckoo-land
loads a microworld in the local system,
unicom:fetch.world "cloud-cuckoo-land
supplies that microworld with all its dependencies from a remote universe server (in the local network or on the internet). On such
servers, microworlds can be searched:
unicom:search.world "foobar
Within this distribution facility, a microworld effectively serves as the envelope that brings together the workspaces related under its name.
Microworlds can be added to the universe:
unicom:add.to.universe "foobar
This process may have a forerun initialised with:
unicom:offer.world "foobar
This might provoke:
unicom:recognise.world "foobar ~
"suggest "review ; or "adopt
;; "vote "graft ; or "archive
A process of coordination of planning may be installed to maintain the extension of the used universe server.
Further procedures may be:
unicom:update.universe
unicom:reset.universe
These procedures may also accept inputs to distinguish different universe servers.
This facility will be defined in a workspace universe related with the microworld communication which relates further workspaces
and primitives that provide the necessary infrastructure:
prepare "universe
declare.microworld "communication
;; ...
extend.microworld "communication
"workspaces [universe]
load.microworld "communication
The standard way to use the universe workspace is then
borrow.from.as "universe.communication "unicom
Very provisional: Separated layers concerned with only one task (?)
A microworld answers: "Given these artefacts and relations, what conceptual landscape do they form?" or "Why are these things considered together?"
Does the prototype-based BLOS answer, by contrast:
"Given this object and this message, which behaviour should be found?" or "Once I have this thing, how does it behave?"
Here, procedures are looked up relative to an object which is conceptionally:
object = {
variables: {name -> value},
procedures: {name -> procedure},
parents: [object...]
}
A separate namespace layer may answer, in turn: "How do I find this thing?" or "Where does this thing belong?"
Thus, programming in the large might take place in four layers:
Workspaces
└── existence / local objects
BLOS
└── behaviour / object relations
Namespace layer
└── location / qualified identity
Microworld layer
└── meaning / conceptual relations