Skip to content

Commit b8f235b

Browse files
committed
two-thirds
1 parent 60fe020 commit b8f235b

1 file changed

Lines changed: 163 additions & 2 deletions

File tree

content/guides/weird_characters.adoc

Lines changed: 163 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,170 @@ user=> ; this is a comment too
353353
<returns nothing>
354354
----
355355

356+
== : - Keyword
356357

357-
// =================================
358+
`:` is the indicator for a keyword which is an interned string that provides
359+
fast comparison and lower memory overhead.
360+
361+
[source,clojure]
362+
----
363+
user=> (type :test)
364+
clojure.lang.Keyword
365+
----
366+
Alternatively you can use `keyword` to create a keyword from a string
367+
[source,clojure]
368+
----
369+
user=> (keyword "test")
370+
:test
371+
----
372+
A neat thing about keywords is that they alsoe implement `IFn` and can act as
373+
functions for extracting values from maps which is very nice:
374+
[source,clojure]
375+
----
376+
user=> (def my-map { :one 1 :two 2 })
377+
#'user/my-map
378+
user=> (:one my-map) ; get the value for :one by invoking it as function
379+
1
380+
user=> (:three my-map) ; it can safely access non-keys
381+
nil
382+
user=> (:three my-map 3) ; it can return a default if specified
383+
3
384+
----
385+
386+
* http://clojure.org/data_structures#Data%20Structures-Keywords[Clojure Official Documentation]
387+
388+
== :: - Qualified keyword
389+
390+
`::` is used to fully qualify a keyword with the current namespace:
391+
[source,clojure]
392+
----
393+
user=> :my-keyword
394+
:my-keyword
395+
user=> ::my-keyword
396+
:user/my-keyword
397+
user=> (= ::my-keyword :my-keyword)
398+
false
399+
----
400+
This is useful when creating macros. If you want to ensure a macro, that calls
401+
another function in the macro namespace, correctly expands to call the function,
402+
you could use `::my-function` to refer to the fully qualified name.
403+
404+
== / - Namespace separator
405+
406+
`/` can be the division function `/`, but can also act as a separator in a
407+
symbol name to break apart the symbol name and the namespace it resides in, eg
408+
`my-namespace/utils`. this allows symbols to be fully qualified to prevent
409+
collitsions or spread.
410+
411+
* http://clojure.org/reader[Clojure Official Documentation]
412+
413+
== $ - Inner class reference
414+
415+
Used to reference inner classes and interfaces in Java. Separates the
416+
container class name and the inner class name.
417+
[source,clojure]
418+
----
419+
(:import (basex.core BaseXClient$EventNotifier)
420+
421+
(defn- build-notifier [notifier-action]
422+
(reify BaseXClient$EventNotifier
423+
(notify [this value]
424+
(notifier-action value))))
425+
----
426+
427+
`EventNotifier` is an inner interface of the `BaseXClient` class which is an
428+
imported Java class
429+
430+
* http://blog.jayfields.com/2011/01/clojure-using-java-inner-classes.html[Clojure: Using Java Inner Classes]
431+
432+
== -> ->> some-> cond-> as-> etc. - Threading macros
433+
434+
These are threading macros. Almost all of them take an initial value and
435+
*tread* this value through a number of forms. Let's imagine (for reasons unknown)
436+
we wanted to take a number, find the square root, cast it to an int, then a
437+
string and then back to an integer again. We could write it like this:
438+
[source,clojure]
439+
----
440+
user=> (Integer. (str (int (Math/sqrt 25))))
441+
5
442+
----
443+
The threading macro allows us to unravel this deep nesting:
444+
[source,clojure]
445+
----
446+
user=> (-> 25 (Math/sqrt) int str Integer.)
447+
5
448+
----
449+
Or if you prefer multiline and consistent brackettering
450+
[source,clojure]
451+
----
452+
(-> 25
453+
(Math/sqrt)
454+
(int)
455+
(str)
456+
(Integer.))
457+
----
458+
459+
What the macro does is take the value returned from each expression and push
460+
it in as the first argument to the next one.
461+
462+
`->>` (thread last) is the same, but different. Rather than push the last value
463+
in as the *first* argument, it passes it in as the *last* argument.
464+
465+
The "etc." in the title refers to the fact that there are a whole host of
466+
threading macros that perform variations on the same theme (`cond->`, `some->`,
467+
`as->` and their `->>` equivalents). There is also an entire libary,
468+
https://github.com/rplevy/swiss-arrows[swiss arrows], dedicated to the threading
469+
macros.
470+
471+
* http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/[Understanding the Clojure -> macro
472+
473+
== ~ - Unquote macro
474+
475+
See ``` (syntax quote) for additional information.
476+
477+
`~` is unquote. That is within a syntax quoted (```) block `~` will *unquote*
478+
the associated symbol, i.e. resolve it in the current context:
479+
[source,clojure]
480+
----
481+
user=> (def five 5) ; create a named ref representing the number 5
482+
#'user/five
483+
user=> five ; five will yeild its internal value
484+
5
485+
user=> `five ; syntax quoting five will fully resolve the SYMBOL
486+
user/five
487+
user=> `~five ; within a syntax quoted block ~ wil resolve the value in the current context
488+
5
489+
----
490+
This forms the meat and potatoes of creating macros which are, to be highly
491+
reductionist, functions that return blocks of syntax with parts evaluated in
492+
various contexts
493+
494+
* http://www.braveclojure.com/writing-macros/[Clojure for the Brave and True - Writing Macros]
495+
* http://aphyr.com/posts/305-clojure-from-the-ground-up-macros[Clojure from the ground up: macros]
496+
* http://clojure.org/macros[Clojure Official Documentation]
497+
498+
== ~@ - Unquote splicing macro
499+
500+
See ``` (syntax quote) and `~` (unquote) for additional information.
501+
502+
`~@` is unquote-splicing. Where unquote (`~`) deals with single values (or
503+
treats its attached item as a single item), `~@` works on lists and expands
504+
them out into multiple statements. Think of `apply` which takes a seq and expands
505+
it out as arguments to the applied function.
506+
[source,clojure]
507+
----
508+
user=> (def three-and-four (list 3 4))
509+
#'user/three-and-four
510+
user=> `(1 ~three-and-four) ; treates as a single statement produces a nested list
511+
(1 (3 4))
512+
user=> `(1 ~@three-and-four) ; expand out as seperate statements
513+
(1 3 4)
514+
----
515+
Again, this gives us a lot of power in macros.
516+
517+
* http://www.braveclojure.com/writing-macros/[Clojure for the Brave and True - Writing Macros]
518+
* http://aphyr.com/posts/305-clojure-from-the-ground-up-macros[Clojure from the ground up: macros]
519+
* http://clojure.org/macros[Clojure Official Documentation]
358520

359521
== ` - Syntax quote
360522

@@ -620,4 +782,3 @@ spelling corrections (crikey I'm bad at speelingz - so thanks Michael R. Mayne,
620782
lobsang_ludd). I've tried to call out people who have specifically asked for
621783
things. Sorry if I've missed you.
622784
====
623-

0 commit comments

Comments
 (0)