Pieter is looking at Mieke, and Mieke is looking at Jan. Pieter is married, but Jan is not. Is a married person looking at an unmarried person?
The human brain is wired to accept the first seemingly fit answer that comes to mind when considering a problem. It makes sense from an evolutionary point of view: heuristics speed up the process of finding a solution. Speed is important for survival.
Psychologists concur with philosophers in the irrelevance of logic to everyday reasoning. Decades of work on Wason’s selection task seem to confirm this. — Pascal Engels
Following Daniel Kahneman’s terminology, the brain works in two modes, system 1 and system 2. System 1 is the thinking that is fast, intuitive, and unaware of its workings. System 2 is the slow thinking able to correct system 1’s mistakes. The problem is that we often fail to recognize when we need to switch gear and slow down.
Question: When we program, do we use system 1 or system 2?
We use both. When we learn or face a difficult part of the program, we use system 2, but most of the time we’ll try to maximize system 1 and proceed fast to use what we’ve learnt, what we already know.
Civilization advances by extending the number of important operations which we can perform without thinking about them — Alfred North Whitehead
We need to be humble in the light of our shortcomings, and embrace any strategy that helps us exercice our capabilities.
Constructionism. Seminal paper: Epistemological Pluralism and the Revaluation of the Concrete, by Seymour Papert and Sherry Turkle
Desirable properties such as:
Interactive programming is the procedure of writing parts of a program while it is already active.
From within the environment provided by the REPL, you can define and redefine program elements such as variables, functions, classes, and methods; evaluate any Lisp expression; load files containing Lisp source code or compiled code; compile whole files or individual functions; enter the debugger; step through code; and inspect the state of individual Lisp objects.
Consult a paper (from 1978): Programming in an Interactive Environment: the ``Lisp'' Experience by Erik Sandewall
The kernel of the programming system must contain the following programs:
(loop (print (eval (read))))
doc
, source
in clojure.repl namespace)*data-readers*
, *default-data-reader-fn*
)*print-length*
, *print-level*
)But for the true Lisp programming experience, you need an environment, such as SLIME, that lets you interact with Lisp both via the REPL and while editing source files. — Peter Seibel, Practical Common Lisp
For instance, you don't want to have to cut and paste a function definition from a source file to the REPL or have to load a whole file just because you changed one function; your Lisp environment should let us evaluate or compile both individual expressions and whole files directly from your editor. — Peter Seibel, Practical Common Lisp
Lisp | Non-Lisp |
---|---|
SLIME (CL) | COLT (Actionscript) |
Cider (Clojure | SuperCollider (C++) |
Emacs (Lisp) | Squeak (Smalltalk) |
Geiser (Scheme) | |
Genera (Lisp Machine) |
Henceforth, the environment will be known as Cider.
You don’t want to do that.
Clojure needs to bootstrap itself inside the JVM each and every time.
Ah. Let’s see.
Cojure built-in facilities: (require ... :reload)
and (require ... :reload-all)
Some problems.
Solved by tools.namespace single API call refresh
.
The refresh
function will scan all the directories on the classpath for Clojure source files, read their ns declarations, build a graph of their dependencies, and load them in dependency order. (You can change the directories it scans with set-refresh-dirs.)
But first, it will unload (remove) the namespaces that changed to clear out any old definitions.
user=> (require '[clojure.tools.namespace.repl :refer [refresh]]) user=> (refresh) user=> (def my-app (start-my-app))
user=> (stop-my-app my-app) user=> (refresh) user=> (def my-app (start-my-app))
refresh
will destroy Vars when it reloads the namespace (even defonce
)
tools.namespace
+ Lifecycle protocol (Stuart Sierra)
http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
component
is a tiny Clojure framework for managing the lifecycle of software components which have runtime state.
A set of readymade components. The usual suspects.
Jetty | Datomic |
HTTP kit | H2 |
Aleph | Monger |
Sente | nREPL |
Neo4j | Langohr |
ElasticSearch | PostgreSQL |
Immutant | Etsy |
JVM instances proliferation. Examples: the REPL, the cljs
build, the hot-reloading process (figwheel), preprocessors, watchers….
In shell a:
$ lein repl :headless
In shell b:
$ lein trampoline cljsbuild repl-listen
Or:
$ lein figwheel
Single JVM instance.
(deftask dev "Run a restartable system in the Repl" [] (comp (watch :verbose true) (reload) ; figwheel (cljs :source-map true) ; cljsbuild (repl :server true))) ; REPL
(defsystem dev-system [:db (new-h2-database DEFAULT-MEM-SPEC) :web (new-web-server (Integer. (env :http-port)) app)])
(deftask dev "Run a restartable system in the Repl" [] (comp (environ :env {:http-port "3025" :imdb-key "xxxxx-xxxx-xxxxx-xxxxx"}) (watch :verbose true) (system :sys #'dev-system :auto-start true :hot-reload true :files ["handler.clj"]) (reload) ; equivalent to figwheel (cljs :source-map true) ; equivalent to cljsbuild (repl :server true)))
Your application updates itself automatically when editing your source code.
(require ... :reload)
(refresh}
(via (reloaded.repl/reset)
)
Garnet - a graphical toolkit for Lisp
Live coding performance in Impromptu by Andrew Sorensen.
Full Clojure programming environment in Microsoft Excel https://github.com/whamtet/Excel-REPL