Skip to content

davelnewton/clojure-turtle

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

clojure-turtle

clojure-turtle is a Clojure library that implements the Logo programming language in a Clojure context. Quil is used for rendering.

Logo is a simple language that is useful in introducing programming to beginners, especially young ones. Logo also happens to be a dialect of Lisp. clojure-turtle tries to maintain those beneficial aspects of Logo while using Clojure and Clojure syntax. The goal is to make learning programming and/or Clojure easier by disguising powerful concepts with fun!

Artifacts

clojure-turtle artifacts are released to Clojars.

If you are using Maven, add the following repository definition to your pom.xml:

<repository>
  <id>clojars.org</id>
  <url>http://clojars.org/repo</url>
</repository>

The Most Recent Release

With Leiningen:

[clojure-turtle "0.1.0"]

With Maven:

<dependency>
  <groupId>clojure-turtle</groupId>
  <artifactId>clojure-turtle</artifactId>
  <version>0.1.0</version>
</dependency>

Installation

First, install Leiningen.

Second, run a REPL session that has clojure-turtle loaded inside it. This can be done in a couple of ways:

Usage

Load the clojure-turtle.core namespace.

(use 'clojure-turtle.core)
; WARNING: repeat already refers to: #'clojure.core/repeat in namespace: user, being replaced by: #'clojure-turtle.core/repeat
;=> nil

The symbol repeat is overridden to behave more like the Logo function, but the Clojure core function is still available as clojure.core/repeat.

The use call will also evaluate Quil code that creates a sketch in a separate window, in which our turtle lives and operates.

forward, back, right, left

It's forward, back, right, and left as in Logo. Go forward and back by a length (in pixels). Right and left turn the turtle by an angle, in degrees. It's Clojure syntax, so 'executing commands' (function calls) are done within parenthases.

(forward 30)
;=> #<Atom@4c8829b7: {:y 29.99999999999997, :angle 90, :pen true, :x -1.3113417000558723E-6}>

(right 90)
; #<Atom@4c8829b7: {:y 29.99999999999997, :angle 0, :pen true, :x -1.3113417000558723E-6}>

repeat, all

repeat is like the Logo function, or like Clojure's repeatedly. Going from the Logo syntax to clojure-turtle's syntax for repeat, commands that are being repeated are put within parenthases notation. The square brackets that group the repeated commands are replaced with (all ... ). The equivalent of the Logo REPEAT 3 [FORWARD 30 RIGHT 90] would be

(repeat 3 (all (forward 30) (right 90)))
;=> #<Atom@4c8829b7: {:y -2.6226834249807383E-6, :angle 90, :pen true, :x -9.535951726036274E-7}>

Let's see how we can simplify this.

(def side (all (forward 30) (right 90)))
;=> #'user/side
(left 90)
;=> #<Atom@4c8829b7: {:y -2.6226834249807383E-6, :angle 180, :pen true, :x -9.535951726036274E-7}>

(repeat 4 side)
;=> #<Atom@4c8829b7: {:y -1.311341712550984E-5, :angle 180, :pen true, :x -4.76797586142362E-6}>

As you just saw above, we can take the instructions that we pass into repeat, give them a single name, and refer to that name to get the same effect.

Let's simplify further.

(def square (all (repeat 4 side)))
(left 90)
(square)

So given a named set of instructions, we can invoke the instructions by putting the name in parenthases just like we do for functions like forward, left, and repeat

(def square-and-turn (all (square) (left 90)))
(left 90)
(square-and-turn)

(left 45)
(repeat 4 square-and-turn)

penup, pendown, setxy, setheading

The turtle has a pen that it drags along where it goes, creating a drawing. We can pick the pen up and put the pen down when we need to draw unconnected lines. setxy also teleports the turtle without drawing. setheading turns the turtle in an exact direction.

(penup)
(forward 113)
(right 135)

(pendown)
(repeat 4 (all (forward 160) (right 90)))

(setxy -100 0)

(setheading 225)

clean, home

clean erases all drawing. home brings the turtle to its original position and direction.

(clean)

(home)

What next?

clojure-turtle uses Quil, which uses Processing. clojure-turtle also has the full power and fun of Clojure available to it, too.

What do you get when you enter the following?

(defn any-square
  [s]
  (repeat 4 (all (forward s) (right 90))))

(any-square 10)
(any-square 20)
(def lengths [40 50 60])
(map any-square lengths)
(defn times-2
  [x]
  (* 2 x))

(right 90)
(map any-square (map times-2 lengths))
(right 90)
(->> lengths
     (map times-2)
     (map any-square))
(defn polygon-side
  [n s]
  (forward s)
  (right (/ 360 n)))

(defn any-polygon
  [n s]
  (repeat n (all (polygon-side n s))))

(clean)
(right 180)
(any-polygon 5 20)
(def sides [6 7 8 10 12])
(def lengths (reverse [30 40 50 60 70]))
(map any-polygon sides lengths)
(defn rand-side
  []
  (forward (rand-int 50))
  (setheading (rand-int 360)))

(fn? rand-side)
(fn? side)

(clean)
(home)
(repeat 4 side)
(repeat 100 rand-side)

What possibilities exist when you incorporate the full power of Clojure? What can you create?

License

Distributed under the Apache 2 license.

Disclaimer

This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.

Dependencies

Quil is distributed under the Eclipse Public License either version 1.0 (or at your option) any later verison.

The official Processing.org's jars, used as dependencies of Quil, are distributed under LGPL and their code can be found on http://processing.org/

About

A Clojure library that implements the Logo programming language in a Clojure context

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Clojure 100.0%