Skip to content

Commit 3148afa

Browse files
committed
more work
1 parent eecb6a9 commit 3148afa

1 file changed

Lines changed: 187 additions & 0 deletions

File tree

content/guides/weird_characters.adoc

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,190 @@ user=> (def x "x") ; this is a comment
352352
user=> ; this is a comment too
353353
<returns nothing>
354354
----
355+
356+
357+
// =================================
358+
359+
== ` - Syntax quote
360+
361+
See `~@` (unquote splicing) and `~` (unquote) for additional information
362+
````` is the syntax quote. When used on a symbol it resolves to the symbol
363+
in the current context:
364+
[source,clojure]
365+
----
366+
user=> (def five 5)
367+
#'user/five
368+
user=> `five
369+
user/five
370+
----
371+
When used with lists (remember everything in Clojure is data) it forms a
372+
*template* for the data strucutre and won't immediately resolve it.
373+
374+
[source,clojure]
375+
----
376+
user=> (1 2 3)
377+
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/eval832 (NO_SOURCE_FILE:1)
378+
user=> `(1 2 3)
379+
(1 2 3)
380+
----
381+
You'll see this most often in teh context of macros. We can write one now:
382+
[source,clojure]
383+
----
384+
user=> (defmacro debug [body]
385+
#_=> `(let [val# ~body]
386+
#_=> (println "DEBUG: " val#)
387+
#_=> val#))
388+
#'user/debug
389+
user=> (debug (+ 2 2))
390+
DEBUG: 4
391+
4
392+
----
393+
The macro takes a single statement and wraps it in a *quoted* `let` block,
394+
evaluates and prints the result and then evaluates the body. In effect this
395+
`defmacro` call returns a quoted data structure representing the program we
396+
are writing with it. The ``` allows this to happen.
397+
398+
* http://www.braveclojure.com/writing-macros/[Clojure for the Brave and True - Writing Macros]
399+
* http://aphyr.com/posts/305-clojure-from-the-ground-up-macros[Clojure from the ground up: macros]
400+
* http://clojure.org/macros[Clojure Official Documentation]
401+
402+
== \*var-name* - Earmuffs
403+
404+
Earmuffs (a pair of asterisk bookending var names) is a *naming convention* in
405+
many LISPs used to denote *special vars*. Most commonly in Clojure this seems
406+
to be used to denote *dynamic* vars, i.e. ones that can change depending on
407+
where you are in the program. The earmuffs act as a warning that "here be dragons"
408+
and to never assume the state of the var. Remember, this is a *convention*, not a
409+
*rule*.
410+
411+
Core Clojure exampels are `\*out*` and `\*in*` which represent the standard in and
412+
out writers for Clojure.
413+
414+
* http://stackoverflow.com/questions/1986961/how-is-the-var-name-naming-convention-used-in-clojure[How is the var-name naming-convention used in clojure?]
415+
* http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/\*out*[Clojure API Docs]
416+
417+
== >!!, <!!, >! and <! - core.async channel macros
418+
419+
These symbols are channel operations in `core.async` - a Clojure/ClojureScript
420+
library for channel based asynchronous programming (specifically http://en.wikipedia.org/wiki/Communicating_sequential_processes[CSP - Communicating Sequential Processes]).
421+
422+
If you imagine, for the sake of argument, a channel is a bit like a queue that
423+
things can put stuff on and take stuff off, then these symbols support that
424+
simple API.
425+
426+
* `>!!` and `<!!` are *blocking put* and *take* respectively
427+
* `>!` and `<!`are, simply *put* and *take*
428+
429+
THe difference being the blocking version operate outside `go` blocks and block
430+
the tread they operate on.
431+
[source,clojure]
432+
----
433+
user=> (def my-channel (chan 10)) ; create a channel
434+
user=> (>!! my-channel "hello") ; put stuff on the channel
435+
user=> (println (<!! my-channel)) ; take stuff off the channel
436+
hello
437+
----
438+
The non-blocking version sneed to be executed within a `go` block, otherwise
439+
they'll throw an exception.
440+
[source,clojure]
441+
----
442+
user=> (def c (chan))
443+
#'user/c
444+
user=> (>! c "nope")
445+
AssertionError Assert failed: >! used not in (go ...) block
446+
nil clojure.core.async/>! (async.clj:123)
447+
----
448+
While the diffence between these is well outside the scope of this guide,
449+
fundamentally the `go` blocks operate and manage their own resources pausing
450+
*execution* of code without blocking threads. This makes asynchronously executed
451+
code appear to be synchronous, removing the pain of managing
452+
asynchronous code from the code base.
453+
454+
* https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj[core.async Code Walkthrough]
455+
* https://github.com/clojure/core.async/wiki[core.async Wiki]
456+
457+
== <symbol>? - Predicate Marker
458+
459+
Putting `?` at the end of a symbol is a *naming convention* common across
460+
many languages that support special characters in their symbol names. It is
461+
used to indicate that the thing is a predicate, i.e. that it *poses a question*.
462+
For example, imagine using an API that delt with buffer manipulation:
463+
[source,clojure]
464+
----
465+
(def my-buffer (buffers/create-buffer [1 2 3]))
466+
(buffers/empty my-buffer)
467+
----
468+
At a glance, how would you know if the function `empty` in this case,
469+
* Returned `true` if the passed in buffer was empty, or,
470+
* Cleared the buffer
471+
While the author could have renamed `empty` to `is-empty`, the richness of
472+
symbol naming in Clojure allows us to express intent more symbolically.
473+
[source,clojure]
474+
----
475+
(def my-buffer (buffers/create-buffer [1 2 3]))
476+
(buffers/empty? my-buffer)
477+
false
478+
----
479+
This is simply a recommended *convension*, not a *requirement*.
480+
481+
* https://github.com/bbatsov/clojure-style-guide#naming[Clojure Style Guide]
482+
483+
== <symbol>! - Unsafe Operations
484+
485+
The Clojure style guide has this to say
486+
487+
[]
488+
====
489+
The names of functions/macros that are not safe in STM transactions
490+
should end with an excalamation mark (e.g `reset!`).
491+
====
492+
You'll most commonly see this appended to function names whose purpose
493+
is to mutate state, e.g. connecting to a data store, updating an atom or
494+
closing a file stream
495+
[source,clojure]
496+
----
497+
user=> (def my-stateful-thing (atom 0))
498+
#'user/my-stateful-thing
499+
user=> (swap! my-stateful-thing inc)
500+
1
501+
user=> @my-stateful-thing
502+
1
503+
----
504+
505+
This is simply a recommended *convention* and not a *requirement*
506+
507+
* https://github.com/bbatsov/clojure-style-guide#naming[Clojure Style Guide]
508+
509+
== _ - Irrelevant var
510+
511+
When you see this used as function arguments or similar, it is a common
512+
naming convention for vars or arguments you are not interested in using.
513+
That is you don't intend to use them, so you aren't really interested in
514+
thinking of a useful name for them.
515+
516+
This is an example using the `add-watch` function that can be used to add
517+
callback style behaviour when atoms change value. Imagine, given an atom, we
518+
want to print the new value every time it changes
519+
[source,clojure]
520+
----
521+
(def value (atom 0))
522+
523+
(add-watch value nil (fn [_ _ _ new-value]
524+
(println new-value))
525+
526+
(reset! value 6)
527+
; prints 6
528+
(reset! value 9)
529+
; prints 9
530+
----
531+
`add-watch` takes four arguments, but in our case we only really care about the
532+
last argument - the new value of the atom.
533+
534+
[]
535+
====
536+
Many thanks to everyone who has contributed ideas and [the copious amounts of]
537+
spelling corrections (crikey I'm bad at speelingz - so thanks Michael R. Mayne,
538+
lobsang_ludd). I've tried to call out people who have specifically asked for
539+
things. Sorry if I've missed you.
540+
====
541+

0 commit comments

Comments
 (0)