Random Sine Wave Flowers Made With turtleSpaces Logo

This simple yet attention-grabbing Logo procedure is a real visual treat, creating random three-dimensional ‘flowers’ based on the sine function. This could spice up a math class or just provide a brief introduction to sine waves in general.

The procedure makes use of the move primitive, which allows the turtle to move based on an arbitrary number of degrees away from its current heading, on the X and Y planes. When combined with the sine function, it produces these interesting ‘natural’ 3D designs.

Live model view – click and drag to rotate
TO randomflower
  clearscreen randompencolor
  ;clear the screen and select a random
  ;pen color
  
  dountil and 200 < abs (:x - :y) 200 < abs (:y - :x) [
    make "x random 2000 make "y random 2000
  ]
  ;set :x and :y containers to a random value between 0 and 2000
  ;BUT make sure they aren't within 200 of each other.
  ;The results in that range aren't aesthetically pleasing.
  
  repeat 3600 [
    ;we move down a tenth of a degree each iteration, so to form
    ;a complete 'circle' we need 3600 repetitions.
    
    move 0.5 {:x * sin repcount :y * sin repcount}
    ;the move primitive takes a number of turtle steps as its
    ;first argument, and then either a single degree value (X)
    ;or a list of two values (X and Y), which turn the turtle
    ;the specified number of degrees on each plane.
    
    ;In the case of this example, we're passing a multiple of
    ;:x and :y based on the sine of the current interation
    ;(repcount). This produces the 'flower' effect.
    
    down 0.1
  ]
END

You could put a wait into the loop so that students can see the process a bit more clearly.

Don’t forget that you can click and drag the view to orbit around the model, click with both buttons and drag to ‘pan’ the orbit point, and use the mouse wheel (or right-click and drag up and down) to zoom in and out.

Children can pick their favourites and share them with the class!

This is the flower listing as seen in the turtleSpaces application editor

PS Adding the following two lines into the repeat 3600 loop can add a little ‘pizzaz’ in the form of frags, ‘fragments’ (think of a broken mirror) or triangles made of three arbitrary points. The frag primitive creates a triangle from the last three points the turtle has stopped at, while pin and pinfrag drop ‘pins’ at points you choose and generate triangles from the last three of those pin points respectively. When combined with the sine flower procedure they add a bit of ornamentation. Just remember to setfillcolor!

    if 0 = remainder repcount 10 [pin] 
    if 0 = remainder repcount 30 [pinfrag]

Thanks for reading! Please let us know how you go at integrating turtleSpaces into your classroom’s studies. E-mail us at help@turtlespaces.org 

Past and Future Turtles: The Evolution of the Logo Programming Language (Part 1)

When I was a young child, one of my best friends was a turtle.

Not a real turtle, although that would have been fun, but a virtual one. My turtle lived inside of an Apple II, an early 8-bit computer, at my elementary school.

When I first met her, my turtle, she didn’t do much. She just sat there. It didn’t take long for me to realize that in order to get her to do something, I would need to prompt her. To do this, there was a literal prompt on the screen, beckoning me to type something.

?

And so I typed FORWARD, thinking that this should, obviously, move the turtle forward.

NOT ENOUGH INPUTS TO FORWARD

Undeterred, I revised my input to FORWARD 10, just picking an arbitrary number. Although I was only six years old, I deduced that FORWARD needed a quantity, quantities were numbers and well, ten was a good start.

And hooray, the turtle moved! I was in love with my turtle from that moment on. I learned that she could also move BACK, and turn LEFT and RIGHT. I didn’t know what degrees were when I first met my turtle, but by the time I finished our first session together, I did!

Seymour Papert in 1971

That afternoon in 1981, I had learned some of a programming language called Logo. The father of Logo was a mathematician and philosopher named Seymour Papert. Interested in learning how to improve mathematics education in young children, in the early 1960s, he had studied under Jean Piaget, a Swiss psychologist who championed a philosophy of learning known as constructivism.

When children are given new information, for example, that a full turn is made up of 360 degrees, they are likely to only accept that information if they already have the underlying understanding required, such as that a turn can be divided in half, quarters and so on, down to 360ths. Or even the concept of a number as high as 360 can exist in the first place.

Otherwise, they are likely to either misinterpret the new information to fit their current understanding (“I only understand numbers as high as 100, and so they must mean 100”) or will simply ignore it, with a silent internal ‘syntax error’.

This can improve if a) the teacher explains numbers up to 360, b) the teacher explains division and then finally c) the teacher explains that when you spin around, you are making a circle (hold out your arm! The point of your finger draws a circle when you spin) and if you spin around halfway, you’re moving 180 degrees and so on.

This may still not be enough. If the child fails to understand a, b and / or c, they still won’t understand it.

However, if the child is able to actively explore these concepts in an environment that has some measure of feedback, the likelihood of their gaining understanding improves. For example, if the teacher suggests they turn randomly, and the teacher tells them how far they have turned each time they do it, they will soon learn that if they turn halfway, they have turned 180 degrees. They will learn that a full turn is 360 degrees. They will understand that the next number after 100 is 101, and hence the next number after 200 is 201. And so on.

This is what Papert learned under Piaget. But obviously, while desirable it’s not practical for each child to have an adult giving them feedback on everything they do until they understand it. The world just doesn’t (and probably will never have) a 1:1 student to teacher ratio. This was a problem Piaget and Papert simply couldn’t surmount.

But in the early 1960s, a new technology was emerging, one that Papert realized could remove his roadblock – the computer.

Computers did not tire, they did not lose patience. Although at that time large and small in number, it was not hard for Papert to see the future, a future where schools were full of terminals connected to computers, one for each child, with which the students could explore ‘mathland’, a simple environment where mathematical concepts could be demonstrated through trial and error. The more input students provided, and the more output they absorbed, the sooner they would grasp concepts. Computers seemed a perfect fit for the task of educating children using constructivist principles.

In 1961, Papert had met an American, Marvin Minsky, at a conference in England. They presented papers that were surprisingly similar, and connected as a result. So, powered by his idea of using computers to teach children, in 1964, Papert went to the US, and joined Minskey’s Artificial Intelligence Group, a team of researchers at the Massachusetts Institute of Technology (MIT).

Papert was impressed with the technology-centric culture at MIT, and attitude that everyone had the potential to learn anything they wanted to, a position Papert shared. The students under Minsky and Papert had free rein to work on whatever they wanted, encouraging experimentation and the practical testing of even the most wild theories. Papert saw how his students, when encouraged, would learn great amounts of knowledge on their own, and collaborate with others to get past roadblocks they encountered in their pursuits. At MIT these students were known as ‘hackers’.

One of these hackers, Daniel Bobrow, graduated and got a job at a research and development (R&D) firm called Bolt, Beranek and Newman. In the mid-1960s they had started exploring computer technologies, and their potential. Bobrow became head of their new Artificial Intelligence group. There, he met Wally Feurzeig, who was leading BBN’s education group. The space race had encouraged the US government to find ways of improving math education in schools, and BBN was hoping to find a solution. They had already developed ‘time-sharing’ technology which allowed a mainframe computer to be used by many people at the same time, they just needed software to run on it that children could use to learn.

Bobrow brought in Papert and introduced him to Feurzeig, and the three discussed the idea of developing a computing language for children, Papert’s Mathland. Around that time, BBN had a visitor who demonstrated a new programming language called BASIC. Rather than using memory addresses, BASIC used line numbers to track execution, and named variables that transparently linked to memory addresses. These abstractions made it much easier for non-computer scientists to create computer programs.

BBN’s researchers created a version of BASIC they called Telcomp, which Feurzeig modified to include strings, and called Stringcomp. BBN trialed Stringcomp (using teletypes, typewriters connected to a remote computer) in eight elementary and junior high-school classrooms in 1966. That year, Minsky’s assistant at MIT, Cynthia Solomon, joined Feurzeig’s team at MIT.

Seymour Papert at Muzzey Junior High School in 1966

After Papert visited these classrooms and saw the interaction between children and Stringcomp, he became convinced that BASIC was not the answer, and that a new language would need to be written, one more suited to learning.

Importantly, the new language would need to more adequately demonstrate how the computer came to its conclusions. Papert felt that due to computers’ requirements for literal instruction, children would be able to see how the computer ‘thought’ and realize that was how they themselves also thought, helping them break down problems into smaller elements the way a computer would when it solved them. Thus, the new language would serve a dual purpose, both teaching mathematics, and how mathematics are solved.

BASIC was too monolithic in its command-based structure, and those ‘smaller parts’ could not be shown to its users, happening behind the scenes and out of sight.

And so, the new language would both need to be able to accomplish what one could accomplish in BASIC, while doing so using smaller steps that could be inspected by novice programmers. But to avoid needless and redundant repetition of code, these steps would need to be able to be reused. Because of the philosophy behind it, Wally Feurzeig christened the new language ‘Logo’, derived from Logos, the greek word for ‘thought’.

Minsky, Papert and Solomon had a number of discussions about how Logo would work. Solomon had learned some of the Lisp programming language (a language where all code and data are written in the form of expressions and lists, the name Lisp short for LISt Processing) while Minsky’s assistant, and she appreciated its power for manipulating English language strings, which she recognized could be used as a method by which students could observe the effects of computer code on recognizable data, or data that they created themselves.

It also probably didn’t hurt that Lisp had been invented by the same BBN employee (and MIT alumnus) that had developed its time-sharing system. And so, it was decided that the new language would be a variant of Lisp.

However, Lisp had some drawbacks in terms of its use with younger coders. It had an extreme reliance on structure, using an intricate array of parentheses which often led to errors that were hard to resolve (leading to nicknames Lost in Stupid Brackets and Lots of Irritating Superfluous Parentheses). Its interpreter was also bulky, and not interactive, like BASIC.

In designing Logo, Papert, Minsky and Solomon took the expression, list and string elements of Lisp, removing much of the need for brackets by making assumptions about syntax parsing and inputs, and later allowing for the ‘stacking’ of what they called ‘primitives’ (functions which may or may not resolve to a value) on a single line, such that you could type:

PRINT SUM 4 4

and the computer would output 8, or:

TYPE 1 TYPE 2 TYPE 3

and the computer would output 123.

Lists allowed for the string manipulation Solomon had been hoping for:

(PRINT PICK [RED GREEN BLUE] PICK [DOG CAT BOAT])

BLUE BOAT

RED DOG

GREEN CAT

etc.

Logo was a lot more BASIC-like in its syntax and usage, while allowing for many features BASIC did not, such as the ability to create ‘procedures’, lists of primitives that could be named, and executed just like any other primitive, such as:

TO BOX

   REPEAT 4 [
      FORWARD 10
      RIGHT 90
   ] 

END

which could be executed simply by typing:

BOX

but even better:

TO POLY :SIDES :SIZE

   REPEAT :SIDES [
      FORWARD :SIZE
      RIGHT 360 / :SIDES
   ]

END

the colon indicating a variable or container for storing a value.

POLY 4 10

would re-create our box, but the user could provide any desired values, like SUM. This satisfied Papert’s need to have both the ability to demonstrate computer problem-solving in smaller chunks, while also allowing for the reuse of code. Students could create the BOX or POLY procedures themselves, then use them in other procedures. A picture would form in their minds of the hierarchy of execution, and they would understand better how the computer, and they themselves, thought.

Except that we are getting ahead of ourselves with BOX and POLY, because in the beginning Logo did not have a turtle! When Logo was initially trialled in a seventh-grade classroom (in 1968 at Muzzey Junior High School in Lexington, Massachusetts), students were using the same teletypes the Stringcomp trial had used, and they used Logo to manipulate lists and strings rather than a turtle. Which worked quite well to engage students who were strong in English, but failed to engage those who were not.

Cynthia Solomon (left) and Seymour Papert (right) at Muzzey Junior High in 1966

Also, on the teletype math was still just numbers, regardless of the more elegant way Logo could break down mathematical equations. Kids who didn’t ‘get’ numbers still didn’t get numbers! Papert craved some sort of graphical representation, but the technology at the time strongly precluded that. And so, towards the end of the trial, he had the idea of creating a physical robot, one that could move about on the floor, and draw out graphical representations of mathematic output.

Papert and Solomon left BBN and headed back to MIT, where they formed the Logo Group. In England, two robots had been developed that could wander about a space, their inventor dubbing them ‘tortoises’. The Logo Group developed their own robots, calling them turtles. Having access to expensive display hardware, they also developed a virtual turtle, one that lived on the computer screen.

They added primitives to Logo to control the turtle: FORWARD, BACK LEFT, RIGHT. And they discovered that Papert had been right – children took to the turtle, the turtle allowing Logo users to have a perspective inside the computer, that of the turtle, rather than depending on an understanding of abstract concepts of code paths or numbers. The procedural structure of Logo meant the turtle could be ‘taught’: taught how to draw a square, taught how to draw a polygon, creating them inside of its environment, interacting it and shaping it like a child scrawling on the wall of their bedroom.

The turtle allowed for an empathetic bond to form between it and the child, giving the child a dual sense of accomplishment when the turtle succeeded at what the child told it to do – both because the child correctly instructed the turtle, and the turtle successfully carried out those instructions, the result of the latter the evidence of the former. The child could also ‘think like the turtle’ when developing procedures and debugging, moving about the room as the turtle would, figuring out roughly what they needed the turtle to do, and then refining their program as needed.

An early Logo video display

While Logo’s string and list facilities are impressive, it is fair to say the turtle made Logo. Both the physical and virtual turtles were used by fifth graders at the Bridge School in Lexington in a trial during 1970 and 1971. But both robots and video terminals were expensive in the 1970s, and schools hadn’t widely adopted computer terminals; as such, there was no widespread use of Logo in the 1970s.

However, the emergence of the home computer market in the late 1970s provided an opportunity for Logo to reach a wider segment of the population. In 1980, Minskey, Papert, Solomon and two Canadians founded Logo Computer Systems Inc. (LCSI) and  in 1981 they published a version of Logo for the Apple II computer, which I booted up and met Seymour, Cynthia and Marvin’s turtle for the first time.

They would have been very happy I learned about degrees (and other things) from their turtle!

But where did Logo go from there? Tune in next time!

In the meantime, try our weblogo… or read the Hacker News discussion!

One-A-Day: Qtips

Today’s example is short but sweet. It creates a design made out of a bunch of qtip-like ‘sticks’ with balls on the ends.

It is a design made out of ‘almost squares’ (four sides each at an 85 degree angle to each other). The turtle then turns right 5 degrees, and slides left 20 before continuing to the next almost-square.

Each side of the almost-square is coloured based on its iteration in the almost-square loop, and the fill colour of the balls is set to match. Also, each iteration is raised an amount relative to its iteration, creating a pleasing 3D effect.

Click here to open the project in the viewer or open it in the webLogo IDE

TO qtips
  hideturtle
  clearscreen
  repeat 24 [
    repeat 4 [
      penup 
      setz repcount * 3 
      ;raise up the turtle based on the loop count
      pendown 
      setpencolor 10 + repcount
      ;set the pen color based on the loop count
      setfillcolor pencolor 
      ;for the spheres
      icosphere 2 
      rope 100 
      ;a rope is a cylinder-based line
      icosphere 2 
      right 85
    ] 
    right 5 
    penup
    slideleft 20 
    pendown
  ]
END

One-a-Day: FRAG

The FRAG primitive creates a filled shape out of the current turtle position and her last two positions. For example:

FD 100 RT 90 FD 100 FRAG

will create a triangle.

While turtleSpaces has a variety of shape primitives, sometimes you need to create an arbitrary shape, and FRAG aids you in this.

Take this example, which draws a star:

TO star
  repeat 4 [
    forward 100
    right 170
    forward 86
    frag
    left 70
    forward 86
    right 170
    forward 100
    frag
    right 180
  ]

We can change the number of sides the star has by changing the number of repeats and fiddling with the values a bit:

TO star2
  repeat 5 [
    fd 100 rt 170
    fd 86 frag
    lt 88 fd 86
    rt 170 fd 100
    frag rt 180
  ]
END

First, let’s change our star procedures so they can take a :size parameter, like so:

TO star1 :size
  repeat 4 [
    fd 100 * :size
    rt 170
    fd 86 * :size
    frag
    lt 70
    fd 86 * :size
    rt 170
    fd 100 * :size
    frag
    rt 180
  ]
END

In this case, :size is a ratio, that is, 0.5 will make a star half the size, and 2 will make a star twice the size of the default.

You can change the color of the star using the SETFILLCOLOR primitive, or set a random fill color with RANDFC.

The following procedures create a sky full of stars:

TO star1 :size
  repeat 4 [
    fd 100 * :size
    rt 170
    fd 86 * :size
    frag
    lt 70
    fd 86 * :size
    rt 170
    fd 100 * :size
    frag
    rt 180
  ]
END

TO star2 :size
  repeat 5 [fd 100 * :size rt 170 fd 86 * :size frag lt 88 fd 86 * :size rt 170 fd 100 * :size frag rt 180]
END

TO star3 :size
  repeat 6 [fd 100 * :size rt 170 fd 86 * :size frag lt 100 fd 86 * :size rt 170 fd 100 * :size frag rt 180]
END

TO star4 :size
  repeat 7 [fd 100 * :size rt 170 fd 86 * :size frag lt 108.625 fd 86 * :size rt 170 fd 100 * :size frag rt 180]
END

TO star5 :size
  repeat 8 [fd 100 * :size rt 170 fd 86 * :size frag lt 115 fd 86 * :size rt 170 fd 100 * :size frag rt 180]
END

TO stars
  reset cam:setposition [0 0 0]
  cam:fixate [0 0 0]
  cam:setviewpoint [0 0 0]
  cam:newworker [forever [up 0.1 lt 0.1 rr 0.1 wait 1]]
  repeat 200 [
    pu home randori fd 400 + random 1000 up 90
    lt random 60 pd randpc randfc randfs randps
    make "size (10 + random 90) / 100
    run {pick [star1 star2 star3 star4 star5] :size}
  ]
  
END

Type STARS and press Enter to see the stars!

FRAG’s sister, SHARD creates a three-dimensional FRAG with depth beneath it. This depth is supplied as a parameter, in turtle-units, eg. SHARD 5. Try replacing FRAG with SHARD 5 in one of your star procedures and see what happens! (You’ll need to drag the camera around to see the sides of the star)

Myrtlebot: A turtleSpaces Twitter Bot

Don’t want to download the turtleSpaces client just yet? Well, you can take turtleSpaces for a bit of a spin using Myrtlebot, our turtleSpaces Twitter Bot! Myrtlebot executes whatever Logo code (not procedures yet) you tweet at her, and then returns an image of the results. In the future, we plan to allow for the recording of movies, but for now it’s just a still image. If your code runs for more than 60 seconds, it will be cut off at the 60 second mark.

Head on over to Twitter and check it out!

We’ve created a number of ‘short codes’ for various graphics primitives so that you can put more into a tweet. Here are the new ‘short codes’ (along with the typical logo rt, lt, fd, bk, up, dn etc.) See the documentation for a fuller description of each primitive:

AB = AMIGABALL
ABO = AMIGABALLOID
CAM = CURRENT CAMERA TURTLE
CB = CUBE
CBO = CUBOID
CC = CUTCONE
CCO = CUTCONOID
CCOS = CUTCONOIDSLICE
CCS = CUTCONESLICE
CF = CUTFUNNEL
CFO = CUTFUNNELOID
CFOS = CUTFUNNELOIDSLICE
CFS = CUTFUNNELSLICE
CIR = CIRCLE
CN = CONE
CNO = CONOID
COSL = CONOIDSLICE
CSL = CONESLICE
CSO = CUTSPHEROID
CSOS = CUTSPHEROIDSLICE
CSP = CUTSPHERE
CSS = CUTSPHERESLICE
CY = CYLINDER
CYA = CYLINDERARC
CYAS = CYLINDERARCSLICE
CYO = CYLINDROID
CYOA = CYLINDROIDARC
CYOAS = CYLINDROIDARCSLICE
CYOS = CYLINDROIDSLICE
CYS = CYLINDERSLICE
DCC = DUOCUTCONOID
DCFO = DUOCUTFUNNELOID
DCO = DUOCYLINDROID
DIVP = DIVISORP
DM = DOME
DMO = DOMOID
DOD = DODECAHEDRON
DODO = DODECAHEDROID
DTO = DUOTUBOID
ELL = ELLIPSE
FIX = FIXATE
FU = FUNNEL
FUO = FUNNELOID
FUOS = FUNNELOIDSLICE
FUS = FUNNELSLICE
HD = HEADING
ICD = ICOSPHEROID
IT = ITEM
NTWS = NOTWOSIDED
OCT = OCTAHEDRON
OCTO = OCTAHEDROID
PK = PICK
POPT = POPTURTLE
PRI = PRISM
PS = POLYSPOT
PT = PITCH
PUSHT = PUSHTURTLE
PY = PYRAMID
PYO = PYRAMOID
QD = QUAD
QUO = QUOTIENT
RBG = RANDBG
RBS = RANDBS
RCT = REPCOUNT
RD = RANDOM
RE = REMAINDER
RFC = RANDFC
RFS = RANDFS
RO = ROLL
RP = ROPE
RPA = REPABOVE
RPC = RANDPC
RPS = RANDPS
RPT = REPEAT
SBDS = SETBOUNDS
SBG = SETBG
SBS = SETBS
SFC = SETFC
SFS = SETFS
SHD = SETHEADING
SISI = SETICOSPHEREITERATIONS
SKF = SKEWFISO
SKI = SKEWISO
SKP = SKEWPYRAMID
SKPO = SKEWPYRAMOID
SKQ = SKEWQUAD
SKR = SKEWRECT
SKT = SKEWTRAPEZOID
SKTR = SKEWTRAPERECT
SKV = SKEWVOXELOID
SKVO = SKEWTRAPEVOXELOID
SMW = SETMARKERWIDTH
SP = SPOT
SPC = SETPC
SPD = SPHEROID
SPDS = SPHEROIDSLICE
SPH = SPHERE
SPHS = SPHERESLICE
SPI = SETPITCH
SPN = SETPOSITION
SPO = SETPOS
SPS = SETPS
SPW = SETPENWIDTH
SSA = SETSPHEROIDAXIS
SQ = SQUARE
SRO = SETROLL
SSPD = SETSPEED
STD = SETTYPEDEPTH
STDE = SETTYPEDELAY
STF = SETTYPEFONT
STFI = SETTYPEFILLED
STR = SETTYPESTRETCH
STS = SETTYPESIZE
TB = TUBE
TBA = TUBEARC
TBAS = TUBEARCLICE
TBO = TUBOID
TBOA = TUBOIDARC
TBOAS = TUBOIDARCSLICE
TBOS = TUBOIDSLICE
TBS = TUBESLICE
TH = TETRAHEDRON
THO = TETRAHEDROID
TR = TORUS
TRE = TRAPERECT
TRI = TRIANGLE
TRO = TOROID
TROS = TOROIDSLICE
TRS = TORUSSLICE
TVO = TRAPEVOXELOID
TWS = TWOSIDED
TZ = TRAPEZOID
VX = VOXEL
VXO = VOXELOID

Examples: Turtle Art

Logo is great for creating art! And 3D Logo makes it even better.

Many of these Logo artworks were inspired by examples created by Seymour Papert’s daughter Artemis Papert using the two-dimensional block-based TurtleArt application developed by LCSI Logo developer Brian Silverman. We’re grateful for both of their efforts in advancing Logo over the past several decades!

TO adobo
  reset setpenwidth 5 definecolor 16 [0 0 0]
  setpc 16 setbg 1 setbs 12 pu
  repeat 9 [
    repeat 10 [
      setpos {-120 + 20 * repcount -120 + 20 * repabove 1}
      setz -2 + 0.01 * random 400
      setfc pick [8 9 13]
      setfs -13 + random 10
      setheading -5 + random 11
      square 40 box 40
    ]
  ]
END

TO brush
  reset setbg 8
  setpenwidth 5 setbs 11
  
  repeat 300 [
    setpc pick [1 8 9 11]
    setps -10 + random 20
    pu
    setpos {-200 + random 400 -100 + random 200}
    rt random 360 pd
    repeat 20 + random 50 [
      make "stroke 30 + random 150
      fd :stroke rt -0.5 + 0.1 * random 10
      bk :stroke + random 2 lt -0.5 + 0.1 * random 10
    ]
    ra 0.01
  ]
END




TO bundles
  reset randbg
  repeat 40 [
    pu setpos {-200 + random 400 -100 + random 200}
    setpenwidth 4  pd
    lt random 360
    make "head heading
    repeat 2 [
      randpc
      repeat 90 [
        make "stroke 50 + random 5
        setps -10 + random 20
        fd :stroke
        bk 2 * :stroke
        fd :stroke
        rt 0.1 * random 20
        up -2 + (0.1 * random 40)]
      setheading :head
    ]
  ]
END



TO burst
  reset  pu
  make "colors {yellow orange red magenta blue}
  repeat 5 [
    setpc item repcount :colors
    setmarkerwidth repcount
    make "count repcount
    repeat 50 [
      rt random 360 mark :count * (20 + random 10)
      setpos [0 0]] lo repcount
  ]
END

TO caduceus
  reset  setpenwidth 5 pu
  repeat 4 [
    setpc item repcount [13 9 1 8]
    ra repcount * 2
    bk 120 pd
    repeat 100 [
      fd 1.4 + 0.1 * repabove 1
      rt 7.5 * sin 270 + 10 * repcount
    ]
    repeat 75 [
      fd 2.5 + 0.5 * repabove 1
      lt 0.5 * repcount
    ]
    pu home rr 180 * repcount
  ]
END

TO cards
  reset  pu
  repeat 1000 [
    setpos {-200 + random 400 -100 + random 200}
    rt random 360
    make "sizex 10 + random 20
    make "sizey 10 + random 20
    setfc 2 setfs 13
    quad :sizex + 2 :sizey + 2
    sr 1 fd 1 ra 0.01
    setfc pick [2 3 7 14]
    setfs -5 + random 10
    quad :sizex :sizey
    ra 0.01
  ]
END


TO citylights
  reset pu  setbg 2 setbs 10
  repeat 200 [
    setpos {-200 + random 400 -100 + random 200}
    rt random 360 make "size 20 + random 50
    setfc pick [1 9 13 7] lo 0.01
    until :size = 0 [
      randfs spot 0.05 * :size
      fd 5 lo 0.01 dec "size
    ]
  ]
END


TO dotcube
  cs seticosphereiterations 1 pu
  repeat 9 [
    repeat 9 [
      repeat 9 [
        setposition {-100 + 20 * repabove 2 -100 + 20 * repabove 1 -100 + 20 * repcount}
        setfc repabove 1 setfs repcount ico 2
      ]
    ]
  ]
END

TO dotspiral
  Reset setbg 13 setfc 9 cs
  repeat 1400 [
    pu fd repcount / 10
    spot repcount / 250
    rt 35
  ]
END


TO fireworks
  cs setpenwidth 5
  repeat 60 [
    pu home
    rt random 360
    randpc pd
    fd 30 + random 50
    repeat 50 [
      run pick [[pu][pd]]
      fd 2]
  ]
END

TO fish
  reset wrap
  setbounds [-180 -120 180 120]
  setbg 1 setbs 12
  pu setpos [-170 75]
  repeat 12 [
    setpenwidth 4 rt 44.5
    repeat 10 [
      sl 1
      repeat 3 [
        setpc item repcount [13 1 13]
        if repcount = 2 [ra 0.2]
        if repcount = 3 [lo 0.2]
        pd fd 50 pu bk 50 pu sr 1
      ]
      sl 2 rt 10
    ]
    setfc 1 ico 1 st
    lt 54.5 sr 13 fd 60
    lt 90
  ]
END

TO gaia
  reset setbg 2 setpenwidth 5  setpc 1
  repeat 5 [
    setpc item repcount [8 1 9 13 15]
    setorigin {0 0 2 * repcount}
    repeat 20 [
      pu home pd rt repcount * 18
      repeat 80 [
        fd 0.9 + ((repabove 2) * 0.1)
        rt 8 * sin (repcount * 8)
      ]
      lt 7.5
      repeat 5 [
        fd 20 pu bk 20 rt 15 pd
      ]
    ]
  ]
END


TO gradient
  cs pu
  repeat 30 [
    setfs -15 + repcount quad repcount 200 lo 0.01 sl 0.5
  ]
END

TO gridart
  reset
  randbg
  randfc
  pu
  
  setpos [-210 113]
  repeat 31 [
    for [i 1 57] [
      spot 3.5 * sin ((:i + repcount) * 2)
      sr 7.5
    ]
    sl 57 * 7.5
    bk 7.5
  ]
END

TO gridartico
  cs
  seticosphereiterations 1
  pu
  
  setpos [-210 113]
  repeat 31 [
    for [i 1 57] [
      ico 3.5 * sin ((:i + repcount) * 2)
      sr 7.5
    ]
    sl 57 * 7.5
    bk 7.5
  ]
END

TO gridartshade
  reset randbg randfc pu
  setpos [-210 113]
  repeat 31 [
    for [i 1 57] [
      setfs int (10 * (sin ((:i + repcount) * 2)))
      spot 3.5
      sr 7.5
    ]
    sl 57 * 7.5 bk 7.5
  ]
END

TO gridartwave :size
  cs
  seticosphereiterations 1
  pu
  
  setpos [-210 113]
  repeat 31 [
    for [i 1 57] [
      make "sin 3.5 * sin ((:i + repcount) * 2)
      ra :size * :sin
      ico :sin
      lo :size * :sin
      sr 7.5]
    sl 57 * 7.5
    bk 7.5
  ]
END

TO guessing
  Reset setspeed 5 setbg 9 setbs 3 setpenwidth 5
  repeat 8 [
    pu home ra repcount rt repcount * 45 pd
    repeat 22 [
      if repcount < 4 [
        setpc 8 setps 9 - (3 * repcount)] [
        setpc 13 setps (penshade - 1) + random 3
      ]
      repeat 360 [fd 1 - (0.015 * repabove 1) rt 1]
      pu sr 0.02 pd
    ]
  ]
END



TO heat
  cs pu
  repeat 10 [
    setfc pick [1 9 13]
    setpos {-170 + (repcount * 30) -120}
    up 90
    repeat 80 [
      cylinder 0.1 * repcount 1.6 10
      sr sin (repcount * 10)
      lo 1.5
    ]
    repeat 80 [
      cylinder 0.1 * (80 - repcount) 1.6 10
      sr sin ((80 + repcount) * 10)
      lo 1.5
    ]
    dn 90
  ]
END

TO heat2
  cs pu
  repeat 10 [
    setfc pick [1 9 13]
    setpos {-170 + (repcount * 30) -120}
    up 90
    repeat 80 [
      cylinder 0.1 * repcount 1.6 10
      sr sin (repcount * 10)
      lo 1.5
    ]
    repeat 80 [
      cylinder 0.1 * (80 - repcount) 1.6 10
      sr sin ((80 + repcount) * 10)
      lo 1.5
    ]
    dn 90 rr 180
  ]
END

TO hedgehog
  reset  setfc 1 pu ra 1 spot 20 setpc 13
  repeat 36 [
    home dropanchor tether pullout 18
    orbitleft repcount * 10 rt 225
    setmarkerwidth 0.1 * random 20
    mark 30 + random 80
  ]
END

TO funnybird :col1 :col2
  rl 90 setfc :col1 icospheroid 20 0.5
  pu rr 90 fd 5 sr 12 lt 30
  cylindroidarc 10 15 20 30 10 0.3
  fd 10 sr 15 ra 2
  setfc :col2 ico 3 lo 3.5 ico 3 ra 1.75
  bk 10 dn 90 lt 90
  domoid 10 8 20 0.3 fd 30 sl 7 rt 90
  icospheroid 8 2 fd 14
  icospheroid 8 2 bk 7 rr 30 rr 10 up 10
  cylinder 2 35 20 lo 40 rr 180 lt 90 dn 10
  domoid 7 10 10 0.5 oval 3.5 7 up 10 rt 90
  rl 180 ra 35 dn 20 rl 20
  cylinder 2 35 20 lo 40 rr 180 lt 90 up 10
  domoid 7 10 10 0.5 oval 3.5 7
END

TO hiding
  reset setpenwidth 5 pu
  sl 30 funnybird 1 9 home
  ra 20 rr 180 sl 30 up 10
  funnybird 13 8 rl 180 fd 20
  sr 20 spot 100 sl 40 up 90
  rl 90 sl 60 pd setpc 13
  pushturtle
  repeat 50 [
    popturtle
    pushturtle
    pu sr repcount * 2
    pd lt -10 + random 30
    setpc pick [8 9 13]
    setfs -10 + random 20
    raise -2 + random 6
    repeat 70 + random 30 [fd 1 rt 0.7]
  ]
  ht
END



TO icicles
  reset pu up 90
  repeat 20 [
    setpos {-210 + (20 * repcount) 115}
    make "size 20 + random 15 randfc
    repeat :size [
      cylinder 0.2 * (:size - repcount) 0.6 + (:size / 5) 20
      ra 0.5 + (:size / 5)
    ]
  ]
END

TO moon
  reset lt 120
  repeat 180 [fd 1 rt 1]
  rt 150
  repeat 180 [fd 0.774 lt 0.676]
  pu fd 30 pd
  repeat 3 [
    repeat 5 [
      fd 20 bk 40 fd 20 rt 36
    ]
    pu rt 180 sl 40 fd 40 pd
  ]
  ht
END

TO needles
  reset
  repeat 5 [
    repeat 10 [
      pu setpos {-240 + 80 * repabove 1 126 - repcount * 23}
      pushturtle rr 90 up -15 + random 30 randfc
      cylinder 1 30 10 rr 180 cylinder 1 30 10 popturtle
    ]
  ]
END


TO nest
  reset setspeed 1
  repeat 3 [
    setpc item repcount [9 8 4]
    repeat 18 [
      pu home raise 2 * repabove 1
      rt 7 * repabove 1 rt repcount * 20
      setps -5 up 10 pd
      mark 50 + 2 * repabove 1
      repeat 4 [
        setps penshade + 2
        repeat 90 [
          pu bk 0.1 pd mark 0.2 + 0.1 * repabove 1
          rt 2 up 1
        ]
        setpenshade penshade + 1
        repeat 90 [
          pu bk 0.1 pd
          mark 0.2 + 0.1 * repabove 1
          lt 2 up 1
        ]
      ]
    ]
  ]
  setfc 7 pu home ra 17 icospheroid 10 2 ht
END



TO notnot
  reset pu sl 10 lt 40 setpc 15 setbg 1
  setmarkerwidth 10 repeat 360 [
    mark 1.1 bk 0.1 lt 1
  ]
  lt 90 mark 115 home sr 90 fd 25 rt 40
  repeat 360 [
    mark 0.8 bk 0.1 lt 1
  ]
  lt 90 mark 80
END


TO orangepeel
  reset setpenwidth 8 setbs 3
  setbg 13 setpc 9 setps 0
  repeat 5 [
    pu home
    setpos {-240 + repcount * 50 113}
    rt 100
    repeat 10 [
      sr 1.5 fd 1 pd setps -5 + repcount
      repeat 100 [
        if divisorp 10 repcount [
          setps penshade + 1
        ]
        fd 2.75 rt repcount
      ] lt 10
    ]
  ]
END

TO patio
  cs pu setpos [-87.5 85] setfc 13
  repeat 5 [
    repeat 6 [
      setfillshade -10 + random 21
      make "offset random 10
      lt 50 - :offset
      polyspot 20 4
      rt 50 - :offset
      sr 35
    ]
    sl 210 bk 35
  ]
END

TO peaks
  reset  ht pu bk 125 setbg 2
  repeat 3 [
    setfs 0 setfc 13
    fiso 100 250
    setfc 7 setfs repcount * 3
    ra 0.1
    fiso 75 200
    sl 120 lo 50 bk 30
  ]
  home bk 125 sr 120 lo 50 bk 30
  repeat 2 [
    setfc 13 setfs 0 fiso 100 250
    setfs 3 + repcount * 3
    setfc 7 ra 0.1 fiso 75 200
    sr 120 lo 50 bk 30
  ]
  setpenwidth 5 home setpos [140 80]
  setpc 13
  repeat 36 [
    pd fd 35 pu bk 35 rt 10
  ]
END


TO pinwheel
  reset twosided
  pu setbg 2
  setfc 14 setpc 7
  repeat 2 [
    setpc item repcount [7 11]
    setfc item repcount [14 13]
    pu home rt repcount * 45
    bk 10
    repeat 100 [
      fd 40 + repcount * 1.2
      lt 90 fd 10 lt 92 fd 10
      frag lt 90
    ]
  ]
END

TO postits
  reset pu
  repeat 10 [
    repeat 10 [
      setpos {-120 + 20 * repcount -120 + 20 * repabove 1}
      randfc
      setheading -5 + random 11
      square 20 ra 0.1
    ]
  ]
END


TO rainbow
  reset setpenwidth 10  pu sl 225 bk 125 lt 10 pd
  repeat 500 [
    foreach "col {red orange yellow green blue lightblue magenta} [
      setpc :col fd 0.5 * (0.1 * (10 + repcount))
    ]
    pu bk (0.5 * (7 * (0.1 * (10 + repcount))))
    sr 1 fd 0.2 * (sin (0.5 * (repcount + 100)))
    pd
  ]
END

TO redonpink
  reset setpc 1 setbg 11 setbs -5
  pu setfc 1
  repeat 1000 [
    setpos {-220 + random 440 -120 + random 240}
    ra 0.001 setfo 50 setfs -15 + random 10
    spot 5 + random 5
  ]
  setorigin [-50 -30 2]
  repeat 16 [
    setmarkerwidth 3 home dropanchor
    pullout 10 orbitleft repcount * 22.5
    rt 180
    repeat 70 [
      setmarkerwidth markerwidth - 0.02
      bk 0.1 mark 1 rt 2
    ]
    repeat 70 [
      setmarkerwidth markerwidth - 0.02
      bk 0.1 mark 2 lt 2
    ]
  ]
END


TO roses
  reset setpenwidth 5
  repeat 3 [
    pu setpos {-190 + (repcount * repcount) * 30 -90 + repcount * 50}
    pd make "size 0.05 * (repcount / 2)
    setpc item repcount [1 9 13]
    repeat 9 [
      repeat 100 [
        fd repcount *  :size rt 10
      ]
    ]
  ]
END


TO slats
  reset
  setorigin [-260 -120]
  repeat 23 [
    pu setps -7 + repcount
    home sr 20 * repcount
    setmarkerwidth 18 rt 10
    mark 250
  ]
END


TO slats2
  reset
  setorigin [-260 -120]
  repeat 23 [
    pu setps -7 + repcount
    home setpc pick [8 9 13]
    sr 20 * repcount
    setmarkerwidth 18 rt 10
    mark 250
  ]
END

TO snake
  CS PU RANDFC
  BK 110 UP 90
  repeat 80 [
    cylinder 0.1 * repcount 1.6 10
    sr sin (repcount * 10)
    lo 1.5
  ]
  repeat 60 [
    cylinder 0.1 * (80 - repcount) 1.6 10
    sr sin ((80 + repcount) * 10)
    lo 1.5
  ]
  DN 90 RT 60 ICOSPHEROID 5 2 SL 7 FD 3
  RANDFC ICO 1 BK 6 ICO 1 HT
END

TO snakes
  CS PU RANDFC
  repeat 10 [
    home setpos {-170 + (repcount * 30) -110}
    up 90 repeat 80 [
      cylinder 0.1 * repcount 1.6 10 sr sin (repcount * 10) lo 1.5
    ]
    repeat 60 [
      cylinder 0.1 * (80 - repcount) 1.6 10
      sr sin ((80 + repcount) * 10) lo 1.5
    ]
    DN 90 RT 60 ICOSPHEROID 5 2 SL 7 FD 3
    RANDFC ICO 1 BK 6 ICO 1
  ]
  HT
END

TO solar
  reset  repeat 5 [
    setpc item repcount [1 8 9 13 15]
    repeat 18 [
      pu home raise 2 * repabove 1
      rt repabove 1 rt repcount * 20
      setps 0 pd mark 50
      repeat 5 [
        setps penshade + 1
        repeat 90 [
          mark 0.2 + 0.1 * repabove 1 rt 2
        ]
        setpenshade penshade + 1
        repeat 90 [
          mark 0.2 + 0.1 * repabove 1 lt 2
        ]
      ]
    ]
  ]
END

TO solar2
  reset setspeed 5
  repeat 5 [
    setpc item repcount [1 8 9 13 15]
    repeat 18 [
      pu home raise 2 * repabove 1
      rt 3 * repabove 1
      rt repcount * 20
      setps 0 pd
      mark 50
      repeat 5 [
        setps penshade + 1
        repeat 90 [
          mark 0.2 + 0.1 * repabove 1 rt 2
        ]
        setpenshade penshade + 1
        repeat 90 [
          mark 0.2 + 0.1 * repabove 1 lt 2
        ]
      ]
    ]
  ]
END


TO solar3
  reset           setspeed 5
  repeat 5 [
    setpc item repcount [1 8 9 13 15]
    repeat 18 [
      pu home raise 2 * repabove 1
      rt 4 * repabove 1
      rt repcount * 20 setps 0
      pd mark 50
      repeat 5 [
        setps penshade + 1
        repeat 90 [
          mark 0.2 + 0.1 * repabove 1
          rt 2
        ]
        setpenshade penshade + 1
        repeat 90 [
          mark 0.2 + 0.1 * repabove 1 lt 2
        ]
      ]
    ]
  ]
END

TO sparks
  reset setpenwidth random 10
  randbs randbg
  repeat 5 [
    pu setposition {-200 + random 400 -100 + random 200 -100 + random 100}
    setorigin position randpc randps
    repeat 30 [
      rt random 360 pd
      while (and xpos < 300 xpos > -300 ypos < 180 ypos > -180) [fd 1 lt 0.2]
      pu home
    ]
  ]
END

TO spiralart
  reset
  snappy:pullin 100
  pu
  randbg
  sl 40
  rr 90
  bk 10
  repeat 2 [
    randfc
    repeat 2800 [
      tube 2 repcount / 400 6
      lo repcount / 500
      up 2
    ]
    pu home
    fd 10 sr 40 rl 90
  ]
  ht
END


TO spirallights
  reset  setpenwidth 5
  repeat 5 [
    make "ypos 130 - (40 * repcount)
    randpc
    repeat 10 [
      pu setpos {-220 + (40 * repcount) :ypos}
      pd
      repeat 100 [
        setps -10 + int (repcount / 5)
        fd repcount / 10 rt 30
      ]
    ]
  ]
END

TO spirallightsorange
  reset  setbg 8
  setbs 13 setpenwidth 5
  repeat 5 [
    make "ypos 130 - (40 * repcount)
    repeat 10 [
      pu setpc pick [1 8 9 13]
      setpos {-220 + (40 * repcount) :ypos}
      pd
      repeat 100 [
        setps -10 + int (repcount / 5)
        fd repcount / 10
        rt 30
      ]
    ]
  ]
END


TO spirallightsorange3d
  reset  setbg 8 setbs 13
  setpenwidth 5
  repeat 5 [
    make "ypos 130 - (40 * repcount)
    repeat 10 [
      pu setpc pick [1 8 9 13]
      setposition {-220 + (40 * repcount) :ypos 0}
      pd
      repeat 100 [
        setps -10 + int (repcount / 5)
        fd repcount / 10 rt 30 dn 2
      ]
    ]
  ]
END

TO splash
  reset setspeed 5 setpenwidth 5
  repeat 144 [
    pu home rt repcount * 2.5 dn 75 pd
    repeat 400 [
      up 5 * (sin (repcount * 4))
      setps -15 + (repcount / 12)
      fd .4
    ]
  ]
  pu home
END

TO splash2
  reset setspeed 5 setpenwidth 5
  repeat 144 [
    pu home rt repcount * 2.5 dn 75 pd
    repeat 400 [
      up 5 * (sin (repcount * 4))
      rt sin repcount
      setps -15 + (repcount / 12)
      fd .4
    ]
  ]
  pu home
END

TO splash3
  reset setspeed 5 setpenwidth 5
  repeat 144 [
    pu home rt repcount * 2.5 dn 75 pd
    repeat 400 [
      up 5 * (sin (repcount * 4))
      rt sin repcount
      rr sin repcount
      setps -15 + (repcount / 12)
      fd .4]
  ]
  pu home
END

TO splash4
  reset setspeed 5 setpenwidth 5 setpc 1
  repeat 144 [
    pu home rt repcount * 2.5 dn 75 pd
    repeat 400 [
      up 5 * (sin (repcount * 4))
      rt sin repcount
      rr sin repcount * 2
      setps -15 + (repcount / 12)
      fd .4]
  ]
  pu home
END

TO spotwave
  cs  pu
  repeat 32 [
    setpos {-220 205 - (repcount * 10)}
    repeat 45 [
      setfc pick [2 3 5 6 7 10 14 15]
      spot 5 sr 10
      fd -2 + sin (repcount * 10)
    ]
  ]
END


TO stickman :size
  lt 45 setmarkerwidth :size / 3
  repeat 2 [
    lt 90 mark :size * 5 spot :size
    bk :size * 5] lt 135 mark :size * 2
  lt 45 repeat 2 [
    mark :size * 5 spot :size bk :size * 5 rt 90
  ]
  lt 135 mark :size * 5
  spot :size * 2 pu bk :size * 10
END

TO stickmen
  reset pu sl 80 fd 20
  repeat 3 [
    randfc setpc fillcolor
    stickman repcount * 3
    pu sr 80 ra 20
  ]
END

TO stormy
  reset  pu setpos [-230 -120]
  repeat 8 [
    setpc item repcount [2 6 7 14 1 8 9 13]
    repeat 160 [
      pushturtle rt 45 bk random 20
      randps mark 50 + random 20
      popturtle pu
      sr 2.5 + random 5 ra 0.01
    ]
    ra 0.1 pu
    setpos {-230 -120 + repcount * 30}
  ]
END

TO swirl
  reset pu bk 20 sr 40 setpc 1
  setbg 13 setbs -10 setorigin position pd
  repeat 12 [
    repeat 30 [
      setropewidth 6.1 - (repcount / 5)
      rope 4 bk 0.2 rt 6 bk 0.2
    ]
    pu home rt repcount * 30 pd
  ]
  ht
END


TO thicket3
  reset  setbg 2 setpenwidth 5  setpc 1
  repeat 8 [
    setpc item repcount [8 1 9 4 12 13 14 15]
    repeat 20 [
      pu setposition {-200 + (repcount * 20) 0 5 + repabove 1}
      up 25 pd
      repeat 80 [
        fd 0.9 + ((repabove 2) * 0.1)
        rt 8 * sin (repcount * 8)
      ]
      lt 7.5
      repeat 5 [
        fd 20 pu bk 20 rt 15 pd
      ]
    ]
  ]
END

TO twomoons
  reset
  setorigin [-23 -23 0]
  repeat 2 [
    setpc item repcount [7 2]
    repeat 36 [
      pu home dropanchor
      pullout 10 * repabove 1
      orbitleft repcount * 10
      rt 180 pd
      if oddp repcount [fd 40 * repabove 1] [fd 20 * repabove 1]
    ]
    setorigin [30 30 -20]
  ]
END


TO vase
  reset setpenwidth 5  pu fd 50 sl 50 pd rt 135
  repeat 40 [fd 1 rt 2]
  repeat 125 [fd 1 lt 1]
  lt 5 quad 80 220 rt 180 rr 180
  quad 80 220 rr 180 rt 185
  repeat 125 [fd 1 lt 1]
  repeat 40 [fd 1 rt 2]
  pu home bk 70 lt 15 setpc 15
  repeat 6 [
    pushturtle pd fd 150 + random 20
    setfc pick [1 8 9 11] ra 0.1
    spot 5 popturtle rt 6
  ]
END


TO weave
  reset  wrap
  repeat 30000 [
    fd 1 rt
    sin repcount
    if divisorp 1000 repcount [randpc]
  ]
END

TO zig
  reset  setbg pick [1 8 9 13]
  setbs 10 setpenwidth 10
  repeat 200 [
    ra 0.1 pu
    setpos {-220 + random 440 -120 + random 240}
    rt random 360 setpc pick [1 8 9 13]
    setps -15 + random 10
    repeat 50 [
      pd fd 50 + random 3 lt random 3 bk 50 + random 3
      rt random 3 setps penshade + (-1 + random 3)
    ]
  ]
  pu setpos [-100 -50]
  setheading 300 pd setpc 1
  setps 5 ra 1
  repeat 15 [
    bk 0.2 fd 20 rt 140
    bk 0.2 fd 20 lt 132.5
  ]
END


TO zigzag
  reset setbg 8 setbs 0 setpenwidth 5
  
  repeat 360 [
    pu home pd rt repcount * 1 lt 45
    setpc pick [1 5 7 9]
    repeat 20 [
      fd repcount rt 90
      fd repcount lt 90
    ]
  ]
END

TO zigzag3d
  reset setbg 8 setbs 0 setpenwidth 5
  repeat 360 [
    pu home pd rt repcount * 1
    lt 45 up 45 setpc pick [1 5 7 9]
    repeat 20 [
      fd repcount rt 90 fd repcount lt 90
    ]
  ]
END

Introducing turtleSpaces, a Logo environment for everyone

After a year of work, we are pleased to make available to the public our new Logo interpreter, turtleSpaces.

turtleSpaces implements the Logo programming language inside of the OpenGL 3D graphics environment, allowing you to use turtles to construct 3D models and create animations, simulations and games.

We initially implemented a version of Apple Logo II in our microM8 Apple II emulator to make it easier to use for our younger users, and because microM8 itself uses OpenGL to render the Apple II’s graphics (also in 3D) we added some rudimentary 3D commands to it (up, down, rollleft, rollright, etc.)

We received positive feedback from our users and decided to seperate the Logo interpreter from microM8 and work to grow its potential more broadly.

Why Logo?

Logo’s benefits for learning how to code are many and varied, but before we explore them, it might be better to address the concerns many have with it first, and get them out of the way.

Why not Logo?

Logo’s problems are mainly historical. In the late 1970s there was great excitement among some quarters regarding the potential benefits of teaching children computer programming. Logo was designed around this time to be an as easily-accessible programming language as could be achieved given the technology of the era, which was not very advanced and led to extreme tradeoffs between usability and practicality. In short, Logo was still difficult to use, while not being useful for very much.

Despite this, evangelists (including and mainly Logo’s co-architect Seymour Papert) still made a big deal of Logo, and attempted (and for a time largely succeeded) to gain its widespread use in education, engaging in a great deal of publicity and the making of overstated promises about its potential to turn every child who used it into a little genius. To make matters worse, Papert’s constructivist philosophy dictated that children be allowed to ‘explore’ Logo at their own whim, which while valid on its face (and is something we encourage with turtleSpaces!) was impractical in the context of the crude interpreters that were made available at the time, which were slow, unforgiving, low-resolution and had limited built-in tools, resources and examples.

To make any use of it, you really had to read the manual, but since reading the manual ran counter to Papert’s philosophy, many kids just figured out how to move the turtle forward and turn, and that was about it. Studies were done that showed some initial tutorial-based hand-holding was required, and improvements needed to be made in the user interface, and while later versions of Logo did attempt to correct these shortcomings, by that time the initial enthusiasm for Logo amongst educators had died out, and they were somewhat jaded to the concept in general.

Logo appeared too early, and pushed too hard.

In response, ‘blocks’-based versions of Logo appeared such as Scratch, which attempted to make a subset of commands and their parameter requirements obvious to young coders, who could ‘snap’ them together in the correct order and change default parameters and witness their effects. While useful perhaps in the near-term (and to be clear, we are in the process of implementing a blocks-style mode in turtleSpaces, so we agree they are not without value as an early introduction to Logo), these reduced the very valuable concept of the Turtle to little more than a gimmick, and they nobbled the potential of the Logo language they were based on so much as to make greater exploration of the language largely impossible in the context of their environments.

They were, and are, ‘dead ends‘, and this causes some concern to parents and educators, many of whom are reluctant to use them.

That isn’t to say there weren’t and aren’t other full-Logo interpreters also out there. There were and are, but they have also faced difficulty. First, they’ve tended to rely heavily on the host operating system’s user interface, which was a popular direction to go in the late 1990s and early 2000s, but not so much recently. MicroWorlds Logo, for example, allowed the user to create buttons and load images, and so forth. But the programs users created were very much restricted to their environments, and those environments were still very much oriented towards children. And this trend continued, making for very limited experiences.

As a result, given today’s cross-platform, limited UI landscape these have not aged well. Other developers implemented variants of Logo (such as NetLogo) designed for simulations, such as ant colonies or viruses. But these are largely targeted toward college students, and many of their mechanisms are in our opinion convoluted and counter-intuitive and not at all suitable for children.

Logo for children was simply a victim of being in the wrong place at the wrong time, and its stunted evolution reflected that. But there’s nothing wrong and a lot very right with Logo, and studies of the language itself have shown that. Its functional nature is fairly easy to grasp, the immediate feedback you get from the turtle promotes exploration and learning, and it is powerful enough to become a go-to language for someone even as an adult, if there was a Logo environment that was flexible enough to be useful for a broader audience, and could occupy that middle ground.

So we thought, “Why couldn’t we find that middle ground? We have the technology! Why don’t we go back to where it all started and work forward from there?”

I’d like to definitively state that we have succeeded in our task, but I’ll more tentatively say that we’re well into working on it. Here’s what we have accomplished so far:

  • A full re-implementation of the LCSI Apple Logo II primitive (command) set
  • The addition of a few hundred useful primitives from other Logos and programming languages (including some of our own invention), such as multiple turtles and threading, loops and math functions, retro-styled music and sound, turtle models, gamepad and image placement primitives
  • Several hundred primitives related to the 3D environment, including a wide variety of shapes, positional and vector based functions and tools, and Minecraft-inspired pixelated color schemes
  • An improved while retro-inspired interface that is able to easily get out of the way – no tiny window into the Logo world, no large obtrusive text areas that you can’t get rid of. You can make a program and execute it full screen just like any other game you might buy or download.
  • Written in Go so it’s cross-platform (Windows, macOS and Linux) with the potential for mobile platforms
  • Lots and lots of other smaller things that make the whole experience fun, engaging, productive and straightforward that I can’t even begin to mention.

Here’s a list of some big-ticket items that still need to happen (in no particular order):

  • Raspberry Pi, iOS and Android support, in particular for running turtleSpace apps
  • Stand-alone, distributable app generation for mobile and desktop
  • Private “Classes” that groups of students can join, whose progress can be viewed and monitored by their facilitators / teachers, who can share content between their students
  • Multi-user, multi-player capabilities so that users can design, code and play together
  • API to support control by other applications such as IDEs and tutorials
  • The ability to connect and interact with the outside world
  • 3D model import / export so that users can 3D print their creations, or use them in other 3D environments or vice-versa
  • Terrain and more complex shape design tools
  • In-environment tutorials, badges, achievements and so forth to encourage exploration
  • ‘Blocks’-based entry mode to support younger learners
  • Command-line version without the OpenGL baggage, but with internal FauxGL rendering support to enable image output
  • Refactoring and optimization!
  • A whole bunch more primitives!
  • Finally, and most importantly, to make Logo the relevant all-purpose language it was always meant to be

So, a long way to go. But a good start. Hope to see you around turtleSpaces soon!