Illiterate Blogging with Klipse

Who am I?

  • A mathematician
  • A coder
  • A pragmatic theorist
  • A freak of interactivity
  • Founded Audyx in 2013 - an Audiology Startup with 30K LOCs in Clojurescript
  • Author of Klipse
KLIPSE
  • A Web consultant: Full-Stack, clojure{,script}, ruby{, on rails}, javascript, react
me

Agenda

  • How programmers traditionnaly tell stories?
  • Problems with the traditional approach
  • What is Illiterate blogging?
  • Examples of Illiterate blogging
  • Languages supported by Klipse
  • What’s in it for you?
  • Live blogging session

Two types of programmers - type 0

  • Programmers of type 0 love code
  • Programmers of type 0 are very smart
  • Programmers of type 0 share their ideas in github repos
Mark Engelberg: Code for Clojure Conj 2015 talk about using automatas to solve riddles

Two types of programmers - type 1

  • Programmers of type 1 love words
  • Programmers of type 1 express themselves very well
  • Programmers of type 1 share their ideas in blog posts
Dr. Axel Rauschmayer: EcmaScript proposal: Object.entries() and Object.values()

Naming

  • How would you call programmers of type 0 and 1?
  • What type of programmer are you?

Regular Programmers of type 0

How do regular programmers of type 0 tell stories?

They write code.

code

Good Programmers of type 0

How do good programmers of type 0 tell stories?

They write code and comments.

code

Excellent Programmers of type 0

How do excellent programmers of type 0 tell stories?

They write code, comments and tests.

code

All Programmers of type 0

How do all programmers of type 0 make their code interactive?

They encourage the reader to try it at the REPL

code

Regular Programmers of type 1

How do regular programmers of type 1 tell stories?

They write their ideas in a natural language.

code

Good Programmers of type 1

How do good programmers of type 1 tell stories?

They write static code snippets in a programming language.

code

Excellent Programmers of type 1

How do excellent programmers of type 1 tell stories?

They add pictures to illustrate their ideas.

code

All Programmers of type 1

How do all programmers of type 0 make their code interactive?

They include the result of the evaluation inside their static code snippets.

code

The problems from the readers perspective

Problem 0: Readers are not as smart familiar with the concepts as the blog author.

They cannot digest complex code just by meditating at it.
They need to interact with it.

Problem 1: Readers are lazy.
Nobody is going to clone your github repo to interact with the code you have linked to in your blog post.

Problem Fact 2: Readers are kids.
They love to play.

The solution

Illiterate blogging with Klipse

Literate Programming: Embedding of natural language sentences in a program.

Illiterate Blogging: Embedding of interactive code snippets in a blog post.

Klipse demo

Klipse: How does it work?

The klipse plugin is a javascript tag that transforms static code snippets of an html page into live and interactive snippets:

  • Live: The code is executed in your browser
  • Interactive: The reader can modify the code and it is evaluated as she types

The code evaluation is done in the browser: no server is involved at all!

  • The code snippets are put in dom elements with a class of your choice.
  • Code snippets of different languages must have different classes.
  • The classes are passed to the klipse_settings object.
  • You can configure the settings of each Klipse snippet by setting data- attributes.

More details in Klipse README.

Klipse: Main features

  • code is evaluated as you type (configurable)
  • supports many languages: clojure, javascript (es7, jsx, react), ruby, python, brainfuck, scheme…​
  • clojurescript transpilation
  • environment is shared between code snippets
  • hidden code snippets
  • snippet preamble
  • pretty printing
  • code evaluation in a loop
  • load code from a github gist
  • interacting with the DOM
  • the CodeMirror editor is configurable: options and CSS

Klipse: code is evaluated as you type

Zero-delay between the trial and the result is key for creativity.





[1,2,3].map(x => x + 1)

$("#container-1")
.css({color: 'white',
       backgroundColor: 'blue',
      padding: '10px',
      fontSize: '50px'})
.text("Hello World")

Klipse: environment is shared between Klipse snippets

A blog post is a story.

The different elements of the stories need to be connected together.

Let’s see how to write a Hello World function in Clojure:

(defn hello [name]
  (str "hello " name "\n"))

And now, let’s see how to use this function:

(hello "Klipse")

☕You can embed a jsfiddle or a codepen in a blog post with an <iframe>.
But you cannot share neither the code nor the data between the iframes.

Hiding some details from the reader

Less is more

You don’t want to confuse your readers with technical details that are not revelant to the main idea of your article.

But you need this (irrelevant) code to let the other parts of the code run properly.

Two mechanisms for hiding code from the reader but not from Klipse:

  • A hidden Klipse snippet
  • data-preamble

You can hide a snippet using CSS

<pre class="hidden"><code class="clj">
(def irrelevant-constant
42)
</code></pre>

There is a hidden Klipse snippet just above me

We can use the hidden code in subsequent Klipse snippets:

irrelevant-constant

We can hide part of the Klipse snippet’s code using data-preamble.

<pre><code class="clj" data-preamble="(def random-num  (rand))">
random-num
</code></pre>

random-num

Warning

Are you ready for a journey into the wonderland of programming languages?

qr code
journey

Klipse: javascript

Demonstrate EcmaScript 2017 features before they are available in the browser

const cond = true;
const obj = {
  ...(cond ? {a: 1} : {}),
  b: 2,
};
obj

ES2017 code is transpiled by babel-standalone.

console.log is redirected to the result box

console.log("Hello World!")
3 + 4

Let’s escape the callback hell!
async and await in action


async function sleep(ms = 0) {
  return new Promise(r => setTimeout(r, ms));
}

async function run() {
  console.log("Before: " + (new Date()).toString());
  await sleep(1000);
  console.log("After:  " + (new Date()).toString());
}

run();

Klipse: javascript with DOM

Klipse is 100% client side.
You can interact with the page that contains the Klipse snippets.

$('#container-1345')
  .css({color: 'white',
        backgroundColor: 'green',
        padding: '10px',
        fontSize: '50px'})
  .text("Hello World")
1

Each Klipse snippet is bound to a container accessible through window.klipse_container with id window.klipse_container_id.

$(klipse_container)
  .css({color: 'white',
        backgroundColor: 'blue',
        padding: '10px',
        fontSize: '50px'})
  .text("I am the container bound to the Klipse snippet just above me")
1

Klipse: react.js and JSX

JSX is a language for writing react components almost in HTML

It is transpiled into plain javascript

const element = <h1>Hello, world!</h1>;

We can mix static and dynamic pieces of code

<p style= {{color:"blue"} }>Hello, world -- 14*3={14*3}!</p>

Let’s leverage the functional power of javascript

<div>
  {[1,2,3].map(i =>
               <p style= {{color:"blue"} }>Hello, world -- 14*{i}={14*i}!</p>
              )}
</div>

JSX code is transpiled by babel-standalone.

Learn more about JSX in this interactive JSX tutorial.

Klipse: Ruby

Simple stuff

[1,2]*10

Let’s have some real fun!!!
How would you call this piece of ruby code?

->(f){
  f[f]
  }[->(func){
    ->(n) { n == 0 ? 1 : n * func[func][n-1]}
    }][19]

The evaluation of ruby code in the browser is powered by Opal.

Klipse: Scheme

Scheme

(let ((a 1)
      (b 2))
  (cdr (list a b a b)))

Let’s enjoy a bit of code from SICP: Recursion vs. Iteration.

Factorial implemented with recursion

(define (factorial-rec n)
  (if (= n 1)
      1
      (* n (factorial-rec (- n 1)))))

(factorial-rec 50000)

No stack overflow because BiwaScheme is smart.

Factorial implemented with iteration (a.k.a tail-call recursion)

(define (factorial-iter n)
  (fact-iter-inner 1 1 n))

(define (fact-iter-inner product counter max-count)
  (if (> counter max-count)
      product
      (fact-iter-inner (* counter product)
                 (+ counter 1)
                 max-count)))

(factorial-iter 5)

Learn more about scheme in this Interactive overview of Scheme’s semantics.
The evaluation of scheme code in the browser is powered by BiwaScheme.

Klipse: Scheme - fun with car and cdr

Who wants to share a fun piece of code with car and cdr?

Quines

A quine is a program that evaluates to its own source.

In a sense, a quine is a fixed point of Klipse.

hands

Quines in clojure

Let’s find a unary function f and an argument x such that such that (f x) is exactly (f x).

It’s not hard to guess that this is going to involve self-referentiality. Therefore a good guess for x is 'f.

(defn f [x] '(f 'f))
(f 'f)

Let’s find a way to reference f without using f explicitely.

(def x 'f)
x
(list 'quote x)

To get from x to (f 'f), we do:

(list x (list 'quote x))

So let’s improve f:

(defn f [x] (list x (list 'quote x)))
(f 'f)

Now if we replace f by its definition, we get our quine:

((fn [x] (list x (list 'quote x))) '(fn [x] (list x (list 'quote x))))

Klipse: Brainfuck

Brainfuck is an esoteric language with only 8 characters.

It helps to understand what is a Turing machine

+++++++++++++++++++++++++++++++++ Increment 33 times
.
+++++++++                         Increment 9 times
.
>>                                Move forward twice

Addition of two numbers

+++++++    put 7 on cell #0
>          move to cell #1
+++        put 3 on cell # 1
<          move to cell #0
[->+<]     dec cell #0 and inc cell #1 until cell #0 is 0
>          move to cell #1
.          output cell #1

Hello World

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>

Eval

[in: ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.!]

>>>>+[->>>++>+>+++++++[<++++>>++<-]++>>+>+>+++++[>++>++++++<<-]+>>>,<++[[>[->>]<[>>]<<-]<[<]<+>>[>]>[<+>-[[<+>-]>]<[[[-]<]++<-[<+++++++++>[<->-]>>]>>]]<<]>[-]+<<[--[[-]>>-<<<+>]>>[-<<<<[>+<-]+<<+[->[<+>>>>>>+<<<<<-]<[>+<-]>>>>>>>+<[-[-[-[-[-[-[-[-[[-]>-<]>[-<<+++++++>>]<]]]>[-]<]>[-<<+++>>]<]>[-<<+>>]<]>[-]<]>[-<<<<<<<+>>>>>>>]<]>[-]<<<<<]>>>[<<+>>-]<+<[-[-[-[-[-[-[-[-[-[-[[-]>-<<<[-]<<+>>]]]]>[-]<]>[-<<<[-]<<+++++++>>>]<]]]>[-]<]>[-<<<[-]<<+++++++>>>]<]]>[-]<<<<<<[-]>>[-<<<[>+>>+<<<-]>[<+>-]>>[-[-[[-]>>]>[<<[<+>>+<-]>[<+>-]+<<-[-[-[-[-[-[-[-[-[-[-<+>]<+++++++++++++>>[-]>->-<<]]]>>[->>>>>]<<]>>[-<<<++++++++++++>>[-]>>-]<<]>>[->>>>>]<<]>>[-<<<+++++++++++>>[-]>>-]<<]>>[-<<<++++++++++>>[-]>>-]<<]]>>[->>>>>]<<]<]]>[>>]<<<]>>+>>>]<<]>>[->+>]<<<]<<[<<]>>[[<+>>+<-]+<-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[->->>[>>]>>[>>]<[<-<<-<]<[<<]<<[<<]<]>[->>[>>]>>[>>]<[>+>>+>]<[<<]<<[<<]]<]>[->>[>>]>>[>>]<[-]<[<<]<<[<<]]<]>[->>[>>]>>[>>]<[<-<]<[<<]<<[<<]]<]>[->>[>>]>>[>>]<[>+>]<[<<]<<[<<]]<]>[->>[>>]>>[>>]<<-<<-<<[<<]<<[<<]]<]>[->>[>>]>>[>>]+>>+[<<]<<[<<]]<]>[->>[>>]>>[>>]<++<[<<]<<[<<]]<]>[->>[>>]>>[>>]<+<[<<]<<[<<]]<]>[->>[>>]>>[>>]<,<[<<]<<[<<]]<]>[->>[>>]>>[>>]<-<[<<]<<[<<]]<]>[->>[>>]>>[>>]<.<[<<]<<[<<]]<]>[->>[>>]>>[>>]<<-<<[<<]<<[<<]]<]>[->>[>>]>>[>>]+[<<]<<[<<]]<]>[->>[>>]>>[>>]<[>+>>+<<<-]>[<+>-]>>[<<+>>[-]]+<<[>>-<<-]>>[<<+>>>>+<<-]>>[<<+>>-]<<[>>+<<-]+>>[<<->>-]<<<<[-<<[<<]<<[<<]<<<<<++>>]>>[-<<<<<<[<<]<<[<<]<]>]<]>[->>[>>]>>[>>]<[>+>>+<<<-]>[[<+>-]>>[-]+<<]>>[<<+>>>>+<<-]>>[<<+>>-]<<[>>+<<-]+>>[<<->>-]<<<<[-<<[<<]<<[<<]<<<<<+>>]>>[-<<<<<<[<<]<<[<<]<]>]>[<+>-]<<<<<<[>>+<<-[->>->>+[>>>[-<+>>+<]+<-[-[[-]>-<]>[-<<<+>>>]<]>[-<<<->>>]>[-<+>]<<<<[>>+<<-]>>]<<<<<<]>>[-<<+[>>>[-<+>>+<]+<-[-[[-]>-<]>[-<<<->>>]<]>[-<<<+>>>]>[-<+>]<<<<[<<+>>-]<<]]]>>>>>>>]

Klipse: Lua (implemented in WebAssembly)

function hello(s)
  print("Hello " .. s)
end

print("Hello " .. "World!")

The evaluation of lua code in the browser is powered by wasm_lua.

Klipse: Python

Python

print([x + 1 for x in range(10)])

Python Turtle

import turtle

t = turtle.Turtle()

for i in range(4):
	t.forward(150)
	t.left(90)

You can even draw fractals with the python turtle.

The evaluation of python code in the browser is powered by Skulpt.

Klipse: The integration

All the details are in Klipse README

Survey

  • How many people are bloggers?
  • How many people have a github repository?
  • Are you a programmer of type 0 or type 1?
  • How many people read blogs?

What’s in it for you?

KLIPSE
  • Share the world about code interactivty with your friends
  • Write an interactive blog post: It’s the best way to learn a topic and it’s really fun!
  • Klipsify a tutorial, a scientific paper, a blog post…​
  • Klipsify your library documentation

Questions

questions

Enough words

Let’s write our first illiterate blog post together

collaboration

powered by Klipse /