changeset 81:0f57e5c2ae82

Add notes on sequences in Clojure Next up: infinite sequences!
author IBBoard <dev@ibboard.co.uk>
date Thu, 06 Jun 2019 20:56:16 +0100
parents a83309cdf5d3
children cf7182bca068
files 6-Clojure/README.txt
diffstat 1 files changed, 25 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/6-Clojure/README.txt	Thu Jun 06 20:26:42 2019 +0100
+++ b/6-Clojure/README.txt	Thu Jun 06 20:56:16 2019 +0100
@@ -37,10 +37,10 @@
 
 Note: 0 and "" are true but nil is false, so only false and the null value are falsey.
 
-Clojure has four main data structures - lists (for code), vectors (for data), sets and maps.
+Clojure has four main data structures - lists (for code), vectors (for data), sets and maps. These are types of sequence. Other things may also be sequences (strings, file system structures, etc).
+Sequences can then be operated on with "first", "last", "rest" and "cons" (construct from head and tail) functions.
 
 You can't build a list Python style with "(1 2 3)". You need either "(list 1 2 3)" or the odd syntax "'(1 2 3)".
-Lists can then be operated on with "first", "last", "rest" and "cons" (construct from head and tail) functions.
 There are also functions like "nth" (nth <list> <0-based index>)
 
 Vectors use sequare brackets. They're like a list, but you can implicitly index them (i.e. you don't need "nth") by doing ([vector] pos) because they're treated as functions.
@@ -79,7 +79,29 @@
 
 As well as the map function, there's "apply" and "filter".
 
-Also, some helper functions exist, like "odd?".
+Also, some helper functions exist, like "odd?". Terminating in a question mark seems to be the Clojure approach to predicates. Sometimes you end up with multiple question marks:
+
+(every? number? [1 2 3 :four])
+;false
+
+not-every? and not-any? both have question marks as well. But not everything is question marked:
+
+(some nil? [1 2 nil])
+; true
+
+This seems oddly inconsistent. The footnote explains that it's because "some returns the first value that is not nil or false", so "nil?" return false for 1 and 2 and then return true for nil and so some returns it.
+It's not a predicate because "(some nil? [1 2]) returns nil, not false.
 
 Functional languages do lazy tail recursion. Unless they're Clojure, because the JVM doesn't support it. Clojure does it with a  "loop" and a "recur" function. "loop" takes x and y with initial values and a function to call. See loop_recur.clj.
 
+For loops take the form (for [val collection<, val2 collection2<, …>>] (body)), which is a bit like "for X in Collection", but doesn't look like it at first.
+Multiple val/collection pairs give nested for loops (so every val with every val2).
+
+But then for loops can take a ":when" test keyword (or :let or :while). Which is odd, because :xxx has only ever been a user atom, but this one already has meaning. And they can be mixed anywhere in the parameters and Clojure knows what to do.
+
+Reduce is more familiar: (reduce func list)
+
+(reduce + [1 2 3 4]) ; sums
+(reduce * [1 2 3 4 5]) ; factorial
+
+As well as sorting a list with (sort list) you can use a custom funcion with (sort-by function list) where "function" takes a single parameter and generates a key.
\ No newline at end of file