Clojure Tutorial: misc notes
This page is WORK IN PROGRESS.
Rich Hickey fanclub https://github.com/tallesl/Rich-Hickey-fanclub
Clojure Transducer
saved for later reading.
ISeq is a interface
- https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java
- https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IPersistentCollection.java
- https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Seqable.java
〔Inside Clojure's Collection Model By Alex Miller. At http://insideclojure.org/2016/03/16/collections/ , accessed on 2016-03-17〕
java's class tree and interface tree and their inter-connections is really overwhelming
Clojure Doc Convention
clojure doc uses lots conventions, but As far as i know they are not explained. (in contrast, racket scheme lisp doc also has lots conventions, but they are more logically sound, and, explicitly explained.)
here's a example of clojure doc:
Usage: (fn name? [params*] exprs*) (fn name? ([params*] exprs*) +)
?
means optional.*
means 0 or more.+
means 1 or more.
Usage: (every-pred p) (every-pred p1 p2) (every-pred p1 p2 p3) (every-pred p1 p2 p3 & ps)
& some
means 0 or more args.
- clojure.core - Clojure v1.8 API documentation#clojure.core/fn
sort in clojure
sort a array/list
(def xx [7 3 1 8]) (sort xx ) ; (1 3 7 8) (sort (fn [a b] (> a b)) xx) ; (8 7 3 1)
clojure.core/sort
what happens when you use “sort” on a map data type?
(def xx {:b 4, :a 1, :c 2, :d 3 }) xx ; {:c 2, :b 4, :d 3, :a 1} (sort xx) ; ([:a 1] [:b 4] [:c 2] [:d 3])
review function multi-arity
clojure.core/reduce
clojure.core/filter
clojure.core/some
clojure.core/every?
(time expr)
-
Evaluates expr and prints the time it took. Returns the value of expr.
clojure.core/time
def
can be used without value, that is, just declare.
clojure.core/def
bind
is for binding.
clojure.core/bind
misc Clojure notepad
;; load the file yy.clj in directory xx (load "xx/yy")
;; compile the file yy.clj (compile 'xx.yy)
clojure.core/load
clojure.core/compile
Clojure compiles to the directory stored in *compile-path*
. Default value is "classes"
(relative to current directory.)
clojure.core/*compile-path*
see also: http://clojure.org/compilation
clojure.core/-main
clojure.core/eval
Clojure or lein by default runs a function named -main
.
In lein, you can specify in the defproject file in key :main
gorilla-repl notes
rendering process steps
- get expression, send to Clojure to eval.
- turn the
*out*
(or some like that) into a presentation X - turn X into JSON and send to browser. browser turn this into DOM.
this function gorilla-renderable.core/render
is the main one. Like pr
for repl, but for gorilla-repl.
gorilla-renderable.core/render
is the sole function in “Renderable” protocol. (
http://clojure.org/protocols
)
clojure.core/*out*
〔Rich Hickey Q&A By Michael Fogus. At http://codequarterly.com/2011/rich-hickey/, accessed on 2014-11-21〕
What is Clojure edn?
edn is “extensible data notation”.
edn has Clojure's lisp syntax. edn is to Clojure as JSON is to JavaScript.
edn home at https://github.com/edn-format/edn
to understand clojure in depth, the best is Rich Hickey's “Reference Documentation” essays
http://clojure.org/documentation
Any programing tutorial that mention patterns, agile, idioms, koan, ninja, zen, tao, monk, cartoons, mentions of Martin Fowler, needs to be garbage collected.
clojure problem: string not in core
string manipulation is the most important element in modern programing. This is the first thing you teach to beginners, about any language.
But with Clojure, it's not core part of the language. You need to load it as a lib, or, goto Java's string stuff.
Try to tell it to beginners. You either face the clojure namespace complexity, or dealing with one bag of the Java interoperation complexity.
PS: actually, just prefix the namespace. For example, (clojure.string/upper-case "xyz")
.
One Weird Annoyance About Clojure: Java
one annoying thing about Clojure is that it runs on Java Virtual Machine. Clojure is actually a so-called hosted language, and this is by spec. (and JavaScript is a hosted language too. 〔see JavaScript Tutorial: Understand JavaScript in Depth〕).
This practically means is that, Clojure isn't a “fixed” language. For example, when it's running on JVM, its regex is Java syntax, its string functions are Java language's string methods. When it runs in JavaScript world (as ClojureScript do), its regex is JavaScript's regex. 〔see JavaScript Regex Syntax〕
But, that's not all. The MOST annoying thing is that, you actually need to know a lot about stinking Java in order to do any real world work with Clojure. (don't let any hacker type fanatics tell you otherwise) You need to know Java class/object system, its package system, its namespace scheme, Java Virtual Machine system, its compilation cycle, its tools and achive files. Even the official Clojure documentation, outright simply say things like “returns a Java xyz object.” with no further explanation, in lots of places.
it is not to be taken lightly, that when you learn Clojure, you actally need to gradually understand a lot about Java ecosystem too.
but at least, thank god, it's a lisp that has industrial value, and is a Java replacement.
clojure parser instaparse, and excellency of clojure docs
A clojure parser lib, instaparse: https://github.com/Engelberg/instaparse, seems to be the topnotch parser. Instaparse is written by [2014-11-15 Mark Engelberg ] ( https://github.com/Engelberg ) .
It has excellent tutorial too. Clear, to the point.
- No juvenile unix humor.
- No puerile perl drivel. 〔see Perl Documentation: the Key to Perl〕
- No verbosity plus propaganda as GNU documentation, for example, 〔see Problems of Emacs's Manual〕
- No academic mumbo-jumbo, a la Haskell's documentation. 〔see Idiocy of Computer Language Docs: Unix, Python, Perl, Haskell〕
so far i've seen, clojure community's doc is top-notch. The official documentation is excellent. The lib/build manager Leiningen's documentation is excellent. 〔see Clojure Leiningen Tutorial〕 And now the instaparse documentation is excellent.
it appears, a language's community pretty much follows the style of its leader. In this case, it's Rich Hickey. You can see Hickey's writings, his documentation style, in several essays titled “Reference Documentation” at http://clojure.org/documentation. They are, concise, to the point.
meanwhile, python's documentation are pretentious garbage, following Guido's style. Here's a typical one: Python, Lambda, Guido: is Language Design Just Solving Puzzles?
and perl's drivels are derived from Larry Wall's drivel. Here's a sample: Perl Documentation: the Key to Perl
for much more, see doc by dummies, Technical writing at its worst
Clojure doc need cross-links, and example for some functions. 3rd party docs notwithstanding. For example, reading about some->
, what the hell is “thread”? no link to ->
, and no example. Clojure Tutorial
.
looks like Clojure solved another lisp problem:piping functions (-> expr1 expr2 …)
but Clojure calls it “threading”. LISP Syntax Problem of Piping Functions
persistent data structure
learned something new: persistent data structure, as in Clojure. (it's not “saved to disk”)
In computing, a persistent data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (visibly) update the structure in-place, but instead always yield a new updated structure. (A persistent data structure is not a data structure committed to persistent storage, such as a disk; this is a different and unrelated sense of the word “persistent.”)
A data structure is partially persistent if all versions can be accessed but only the newest version can be modified. The data structure is fully persistent if every version can be both accessed and modified. If there is also a meld or merge operation that can create a new version from two previous versions, the data structure is called confluently persistent. Structures that are not persistent are called ephemeral.[1]
These types of data structures are particularly common in logical and functional programming, and in a purely functional program all data is immutable, so all data structures are automatically fully persistent.[1] Persistent data structures can also be created using in-place updating of data and these may, in general, use less time or storage space than their purely functional counterparts.
While persistence can be achieved by simple copying, this is inefficient in CPU and RAM usage, because most operations make only small changes to a data structure. A better method is to exploit the similarity between the new and old versions to share structure between them, such as using the same subtree in a number of tree structures. However, because it rapidly becomes infeasible to determine how many previous versions share which parts of the structure, and because it is often desirable to discard old versions, this necessitates an environment with garbage collection.
source: Wikipedia Persistent data structure
Clojure is one big copy of Wolfram Language
Clojure is one big copy of Wolfram Language (aka Mathematica), even down to many function names (those sequence functions).
Of course, it is a inferior copy.
- It provides many “reader” level syntax sugars, but not a complete syntax layer meta-expression as Wolfram Language. 〔see Wolfram Language〕
- It provides a cleaned up lisp macros, but no comprehensive term-rewriting system called pattern matching.
- It has a linear command line interface (of which the hacker idiots calls REPL), but not a Notebook (For example, gorilla-repl is trying to provide. 〔see Interactive Clojure Notebook: gorilla-repl〕)
- It lacks integrated plotting/graphics. (again, gorilla-repl tries)
- Its syntax is nested structure, but not the source code file. Mathematica, the entire source code file (notebook) is one sexp, and can be programed.
- Clojure doesn't include a renderer, for example, relies on markdown, HTML, TeX, etc extra to write/process docs. Mathematica, it's part of the language, render/typeset document/presentation or math formulas more complex than TeX, in real time, and automatically, no need to learn special syntax. 〔see Math Typesetting, Mathematica, MathML〕
- Clojure now does fractions and infinite precision arithemitcs automatically, but lacks the thousands functions for doing math, such as integration, derivative, Solve equations, matrix, ….
Google Plus discussion https://plus.google.com/+XahLee/posts/3ae5GMdj7At