Clojure at Lightspeed

John Stevenson

@jr0cket

Press space to navigate through this 2-dimentional presentation

Or use the arrow keys and follow the navigation paths indicated in the bottom right corner

Abstract

Light Table demonstrates a new breed of interactive coding tools, based on Bret Victor's "Designing on Principle".

With Light Table, you can create Clojure & ClojureScript apps that run inside the development tool, giving you the ultimate fast feedback.

This session will show a new way of developing that is fast, effective and fun.

jaxlondon-logo.png

What is LightTable

A developer tool for Clojure development

A kickstarter project

Inspired by Bret Victor's talk: Inventing on Principle

Inventing on Principle

Bret's principle

Bringing ideas into the world is one of the most important things to do

  • ideas give meaning to peoples lives

creating-ideas.png

Nurturing ideas by connecting to creations

Creators need to see the affect as soon as a change is made

inventing-on-principle-interact-bounce-trace-adjust.png

Ideas start small,

need an environment where the creator can nurture and let them grow

Find a guilding Principle

Find something you believe is important, neccessary and right

http://worrydream.com/

Traditional coding approach

Has not evolved much since punch cards & teletypes

  • code > compile > run > result
  • switch between results and code
  • constantly loosing connection with the app you are creating

Classic IDE's make your eyes jump around

eclipse-counterclockwise-clojure-project.png

Applying these principles to software development

Make changes as quickly as you think of them

– understand the possibilities by interacting with your creation

-think_in_code.jpg

Interacting with your creation directly…

… more ideas flow when you have to parsing less code

Use your brain effectively

When you look at code you have to "play commputer"

  • you have to imagine in your head what each line of code does
  • you become the interpreter & runtime …

Find bugs as soon as you type them…

… instead of leaving it to the unit tests, compiler or person using the software!

Similar approaches

Seb.ly for Creative development

CreativeJS for Designers

Command Line feedback

Using zsh to show current branch & change

zsh-visualising-status-examples.png

Showing namespaces in the REPL

clojure-repl-custom-colour-text.png

Principles Driving LightTable

  • never have to look for documentation
  • files are not the best representation of code
  • editors can be anywhere and show you anything
  • trying is encouraged
  • changes produce instantaneous results
  • shine light on related pieces of code

Live Feedback

Inital concept idea: lighttable-concept-live-eval.png

Early implementation: light-table-example.png

Responsive development

lighttable-concept-game-example.png

Status of the LightTable project

Multiple language support

  • Clojure & ClojureScript
  • JavaScript, HTML, CSS
  • Python

Why is LightTable worth a look

  • easy to setup
  • fast feedback
  • results embedded in the code
  • your app is side by side in the tool (webapps & graphics)
  • a great tool for learning a language

Has LightTable met its original goals

  • Not yet…
  • Focused on a solid platform, so original goals still atainable
  • Time will tell if "the development tool" for Clojure

Getting LightTable

Install latest 5.x version from http://www.lighttable.com/

  • Linux 32bit / 64bit
  • Mac OSX
  • Windows

LightTable Features

Fast Feedback

See what your code does as you type it

  • Evaluate code in place
  • Inline docs
  • Instarepl
  • Embedded browser

Quick demo - Evaluating code

Create a new project

lein new my-project

clojure-leiningen-new-project.png

Open project in Lightable

  1. Run LightTable
  2. Open the workspace view
    • Ctrl-Space toggle workspace
  3. Add the project folder
  4. Open the src/my-project/core.clj file
    • Ctrl-o core.clj

Show the current Workspace

lighttable-workspace-key-combo.png

Add a project folder

lighttable-workspace-folder-add.png

Open a file

Open a file from any folder added to the workspace

lighttable-open-file.png

Connecting to a Clojure REPL

Starts a new REPL using the project.clj definition

lighttable-connect-keyboard-combo.png

Evaluates all the code in the opened file

lighttable-connect-evaluated-code.png

Show REPL connections

See what connections you have open

  • reset and disconnect connections

lighttable-connections-show.png

Interact with Code

Type some Clojure expressions and evaluate with Ctrl-Enter

(+ 1 2 3 4 5)
(println "Hello LightTable")
(def message "Give me fast feedback")
(apply + '(1 2 3 4 5))

Evaluate a single expression with Ctrl + Enter lighttable-eval-simple-expression.png

Evaluate all the code with Ctrl + Shift + Enter lighttable-eval-simple-expressions.png

Evaluating further

Define a message string

(def message "Give me fast feedback")

(defn welcome-message 
 "Send a persons a welcome message"
 [name]
 (str name ", " message)
)

(welcome message "JAX")

Inline Error messages

See clearly where problems are… lighttable-eval-error-message-inline-defn.png

… see when they are resolved lighttable-eval-error-message-inline-defn-fixed.png

Define another function

Lets write a simple function, with docs too!

(defn multi-me 
  "Multiple a number by itself"
  [number]
  (/ number number))

(multi-me 5)

Evaluate the function - Ctrl + Enter

  • checks the function evaluates correctly
  • make the function available to use in the current namespace

lighttable-eval-function-multi-me.png

Call the function - Ctrl + Enter

  • see the result of calling the function with a parameter
  • change the parameter and use Ctrl + Enter to re-evaluate

lighttable-eval-function-multi-me-call.png

Break the code

What if we had typed divide instead of multiply…

(multi-me 0)

lighttable-eval-error-div-by-zero.png

Calling functions not yet evaluated

Defined a function and trying to call it without evaluating it

lighttable-eval-call-function-not-evaluated.png

Evaluate the function then the call to that function lighttable-eval-order-of-eval.png

Hiding evaluation Results

Simply right click on the result you want to hide and select "Remove result"

lighttable-eval-remove-result.png

If you can see what the code is doing, do you need unit tests ?

TDD-cycle.png

Yes, unit tests are about more than testing code…

Inline docs

Show the docs

Right click on a function name

  • Right click on doc to close

lighttable-inline-docs-toggle-docs.png

lighttable-show-docs-map.png

Show docs for your own functions

lighttable-inline-docs-high-score-example.png

Code moves out of the way

[show longer function with several lines of expressions, where does the documentation appear] lighttable-inline-docs-larger-example.png

Hide the docs

Right click and select Remove result

lighttable-inline-docs-larger-example-remove.png

Toggle the docs

Ctrl + Space Toggle documentation at cursor

lighttable-inline-docs-toggle-docs.png

Instarepl

Use Instarepl to evaluate your code as you type

  • Evaluation character by character
  • Re-evaluate when ever you change code

Instarepl workflow - new idea

Advantages:

  • no project required
  • no namespace definition required
  • quick way to test out code
  • really easy way to start learning Clojure

Create a new Instarepl

lighttable-instarepl-open.png

Evauating code on the fly

Example: Adding numbers together

lighttable-instarepl-live-addition-5.png

Re-evaluate as you add more numbers

lighttable-instarepl-live-addition-10.png

Adding Instarepl to your current editor

  1. Open project in workspace
  2. Open file(s) to work on
  3. Connect the file(s) to Instarepl

Multiple REPL sessions

Choose which REPL session to connect to

lighttable-instarepl-multiple-repl-choice.png

Example: Learning Clojure Koans

Clojure Koans are a practical way to learn the language

  • use LightTable Instarepl to solve the Koans

Clone the Koans from Github

git clone https://github.com/functional-koans/clojure-koans.git

Open the Koans folder in LightTable

  1. Ctrl + Space toggle workspace
  2. Click on folder
  3. Select the Koans folder (containing project.clj)
  4. Open the first Koan (click on filename or Ctrl + o filename)
  5. Delete first line and trailing parentheses

Update the Clojure version

LightTable needs to run Clojure 1.5.1 or greater

  • edit the project.clj file

lighttable-instarepl-koans-project-clj-version-update.png

If you dont update the Clojure version, you cannot run Instarepl

lighttable-instarepl-koans-cannot-connect.png

Make the current editor an Instarepl

lighttable-instarepl-koans-make-current-editor-instarepl.png

Koans are awaiting to be solved

Each challenge shows an errors

lighttable-instarepl-koans-to-be-solved.png

Solving the Koans

lighttable-instarepl-koans-being-solved.png

All the Koans are solved

lighttable-instarepl-koans-solved.png

Connecting to your own projects

lein-light leiningen plugin

use your own projects as the context for the Instarepl

Install lein-light

In your ~/.lein/profiles.clj

{:user {:plugins [[lein-light "0.0.4"]]}}

Connecting to the REPL

cd my-project 
lein light

Ctrl-Space Add Connection

Select Clojure (remote nREPL)

Code Watches

Understanding what constructs are doing

JavaScript interaction

Embedded Browser

Driving Browser with node app

Create a node application Add any depenencies Start the node web app Open browser tab in LT Open main .js file in LT Edit main .js file and see change reflected in the browser

Interact with your application live

Works well with

  • JavaScript
  • ClojureScrpt

Browser

[still to figure out properly]

Browser external (with script tag)

[Link to threejs cube clip]

Interacting with Graphics

From the original LightTable concept: lighttable-concept-live-clojurescript-game.png

Embedded graphics is yet to come to LightTable

LightTable Basics

Commands

Ctrl-Space

Start typing the command you want LightTable pattern matches available Commands

Built in Docs

Workspace

Connections

Console output

Splitting the window

Moving tabs around

Searching for Docs

Open the language search lighttable-search-language-docs.png

Search the Clojure language for map lighttable-search-language-docs-search-map.png

Toggle full screen

Ctrl + Space toggle fullscreen

Toggle Console

Ctrl + Space toggle console

Toggle Comments

Ctrl + Space toggle comment lines

Toggle live mode

Ctrl + Space toggle live mode

Changing Fonts

Changing Skin & Themes

LightTable terminology

What is…

Eval? Eval, short for evaluation, is the act of executing code inside of a running process. This means you modify the code that is currently executing without having to restart whatever you're doing.

REPL?

Read-Eval-Print-Loop

  • enter code, evaluate that code and immediately return the result.
  • a great way to experiment and discover your language & libraries
  • allows you to evaluate code in a file to see what something does

Instarepl?

An editor that evaluates as you type

  • shows the result of an expression
  • how all the variables in your code are filled in to get that result. This
  • allows you to see data flow through your program
  • a kind of real-time debugging.
  • Results are blue
  • Variable values are purple

Client

  • a process connected to Light Table that can be sent messages
  • messages generally relate to evaluating code in that process
    • but they don't have to.
  • eg. to eval Python code, a Python process runs which talks to Light Table over TCP and acts a client for us to send code to.

Workspace

  • The group of files and folders that you are working with
  • Workspaces are saved and created automatically
  • access last 20 workspaces via "recent" button at top of the workspace tree

Behavior

Light Table's functionality is defined by functions that respond to a set of triggers.

This combination of a function and the triggers that it reacts to is called a behavior.

Behaviors serve as the way to define what Light Table does in any number of situations and operate as a very powerful settings system. Behaviors are not applied directly to objects, but rather to "tags". These tags allow you to specify behavior for kinds of things at different levels of specificity.

For example, you can apply behavior to all editors by adding a behavior to the :editor tag or to only clojure editors by adding it to the :editor.clojure tag. To modify behaviors, execute the Settings: User behaviors command.

Resources

Chris Grangers blog

LightTable.com

LightTable issue tracker

blog.jr0cket.co.uk

jr0cket.github.io

Thank you.

WIP

Interacting with Graphics

Visualising Binary search tree algorithm Visualising different search algoritms Drawing simple shapes and changing them

Creating a project from inside lighttable

can you create a new project from within lighttable, using leiningen ?

Behaviours

Showing the workspace on start up

always display the workspace panel, in user.behaviors add this behavior to the :app section:

:lt.objs.sidebar.workspace/workspace.open-on-start

Run on start

run on start behavior lets you do all kinds of clever things

It appears to follow the similar pattern to the other behaviour configs. Here's an example of one that worked for me:

{:+ {:app [(:lt.objs.app/run-on-init :toggle-console)]

If you want more than one command to run you can pass in a vector of them:

{:+ {:app [(:lt.objs.app/run-on-init [:toggle-console ….])]

Note that I had to use auto-completion within the keymap bindings file to lookup the appropriate keyword for the command, so yeah it will be nice when some in-line auto-completion help gets added, but I imagine that will come.

Defining your own customisations

Q: How do you select the current line, like ctrl+l in Sublime Text

A: add it to your keymap:

:editor {"ctrl+l" [:editor.select-line]}

Or you could use 'V' in vim mode or emacs ….

Tweakts

V0.5.16 onwards

ADDED: Clojure mode can now color (comment …) forms as comments. Use the `Clojure: Highlight comment forms as comments` behavior ADDED: `Instarepl: set start content` behavior, set it to "" to remove the intro. #827

ADDED: `App: Run commands on start` behavior to let you run whatever when LT is opened. I.e. make full screen, toggle the workspace tree, etc.

an example:

{:+ {:app [(:lt.objs.app/run-on-init :toggle-console)]

If you want more than one command to run you can pass in a vector of them:

{:+ {:app [(:lt.objs.app/run-on-init [:toggle-console ….])]

Note that I had to use auto-completion within the keymap bindings file to lookup the appropriate keyword for the command, so yeah it will be nice when some in-line auto-completion help gets added, but I imagine that will come.

Display workspace panel at startup

always display the workspace panel, in user.behaviors add this behavior to the :app section:

:lt.objs.sidebar.workspace/workspace.open-on-start

Defining your own syntax highlihting

I was able to get the proper syntax highlighting for edn files by putting the following in my user.behaviors file:

{:+ {:files [(:lt.objs.files/file-types [{:name "edn" :exts [:edn] :mime "text/x-clojurescript" :tags [:editor.clj]}])]}}

Stop the spinny cubes from spinning

`Statusbar: reset working indicator` command

Working with HTML5 video

for licensing reasons, node-webkit doesn't ship with the proprietary codecs. See this for how to add them: https://github.com/rogerwang/node-webkit/wiki/Support-mp3-and-h264-in-video-and-audio-tag

website featuring a video using simple html5 video tag:

<video width="640" height="360" id="blablaVideo" autoplay="true"> <source src="assets/blabla.mp4"> </video>

Paredit fun

Holy paredit commands Batman! I've added a few simple ones that can be composed into doing some neat things. For example with the select expression and clear selection commands you can format a parent expression, or eval it, or delete it, or … Here's an example from user keymap:

:editor {;;Eval the parent ( … ) "alt-enter" [(:paredit.select.parent "(")

:eval-editor-form

:paredit.select.clear]

;;Select the parent expression, whether that's [], {}, or () "shift-alt-s" [:paredit.select.parent]

;;Format the parent () "alt-s" [(:paredit.select.parent "(")

:smart-indent-selection

:paredit.select.clear]

;;Slurp and Barf, with less ridiculous and more intuitive names "alt-shift-." [:paredit.grow.right] "alt-shift-," [:paredit.shrink.right]}

ADDED: Basic paredit commands! `Paredit: Grow right`, `Paredit: Grow left`, `Paredit: Shrink right`, `Paredit: Shrink left`, `Paredit: Select expression`, `Paredit: Clear selection and return cursor`

Misc

Allow both {:- {:app ["key"]}} and {:- {:app {"key" [..]}}} for keymap removal

Highlight line performance issues

I turned highlight-line off by default due to the performance issues it carries with it. To turn it back on open your user behaviors and add the :lt.objs.editor/highlight-current-line behavior to the :editor tag.

connecting to remote repl - libs required

To allow LT to connect to a remote repl, you have to add in the lighttable-ops middleware. A simple project.clj looks like this:

(defproject lttest "0.1.0-SNAPSHOT"

:description "FIXME: write description"

:dependencies [[org.clojure/clojure "1.5.1"] [lein-light-nrepl "0.0.1"]]

:repl-options {:nrepl-middleware [lighttable.nrepl.handler/lighttable-ops]})

######################################### #########################################

Slide with background image

hyperlink-text

  • bulletpoint
  • dont go crazy

Sub-slide - srolls vertically from slide above

Some source code using hightlits.js

(def clojure-devs "love brackets")

Slied with code

git init

Slide with Colour - overriding the theme

I love red.

Hightliht text as a fragment of the slide

Fragments in Reveal.js

Press the "Down" key on the page or the down arrow to trigger fragments

  • Create
  • Fragment
  • At Ease

Fragment captions

#+ATTR_REVEAL: :frag
   * Create
   * Fragment
   * At Ease

Reveal.js Can Alert

Change slide style to wake up the

Presentation demo file:////home/jr0cket/projects/presentations/slides/jax-london-2013-light-table.html

Simple node

http://localhost:5000/

3d example http://threejs.org/examples/webgl_buffergeometry_particles.html

http://threejs.org/examples/#webgl_buffergeometry_particles