14. Pragmatic Parentheses!
• Don’t commit to a syntax
• Don’t spend time budget on syntax
• Open to extension
• Metaprogramming and serialization for free!
23. Strict 2-3 Finger Trees
• 4 digits: 0, 1, 2, 3
• Positional AND symmetric
• 2n+1 digits
• dk, k ≤ n has weight 2k, k ≥ n has weight 22n-k
• 0 and 1 only allowed for the most significant digit
24. Inc by the right
0
1
2
3
202
203
212
213
222
223
232
233
22022
22023
22032
22033
22122
22123
25. Dec by the left
22123
33023
23023
32023
22023
333
233
323
223
313
213
303
203
202
3
2
1
0
27. Dynamic + Persistent
• Low ceremony modeling:
• easily map external data to internal values
• 1:1 most of the time
• one model end-to-end
• or several identical ones…
28. Evolution
• As you gain knowledge
• Introduce layers
• Recursive process
• Models for each layer may diverge
• Converters are enough
• Must Ignore semantics
29. Loose Coupling
• Sharing values ≠ sharing mutable objects
• Sharing schemas ≠ sharing classes
• Coupling is caused by behavior and mutability
• Dumber is better
30. Who Needs Encapsulation?
• When things can’t change, why continuously check
invariants?
• Use validators to enforce invariants
• Safe publication
• How a value is built is of no importance
31. Beware of Postel’s Law
Be conservative in what you send, be liberal in what
you accept.
This defines de facto validity
Hard to reverse-engineer, not declarative enough
32. Modularity
• Easily serializable values (map, vectors etc.)
• Low coupling
• Allows for an easier transition from internal module
to external service
34. Data as API
• Blind spots
• process must be agreed upon out of band
• process is closed
• coupling to a version of the process
• Bring objects and behavior back!
35. Who needs objects?
• We have closures! (or the other way round)
• Let’s put closures in the map!
• But closures don’t print!
• Pesky behaviors…
36. How do you call a system
that sends data and
process in-band?
38. Data+Process=HTML
• Content is data
• Links and forms define processes
• Javascript too but is beyond the Turing horizon
39. Anatomy of a Form
<form action="http://example.org/xyz" method=post>
<input type=hidden name=secret value="0xDECAF">
<label>First name: <input name=fname></label>
</form>
40. Anatomy of a Form
Function pointer
<form action="http://example.org/xyz" method=post>
<input type=hidden name=secret value="0xDECAF">
<label>First name: <input name=fname></label>
</form>
41. Anatomy of a Form
Function pointer
Invocation
Protocol
impl.
<form action="http://example.org/xyz" method=post>
<input type=hidden name=secret value="0xDECAF">
<label>First name: <input name=fname></label>
</form>
42. Anatomy of a Form
Function pointer
Invocation
Protocol
impl.
<form action="http://example.org/xyz" method=post>
<input type=hidden name=secret value="0xDECAF">
<label>First name: <input name=fname></label>
</form>
Closed over
environment
44. Hypermedia API?
• Cambrian explosion (HAL, Siren, Uber…) but no
uptake
• A good starting point may be to look at closures
that are good form candidates
• named arguments
• partials
• arguments shuffling/renaming
45. What’s to be gained?
• Not only you get data as usual
• That you can manipulate as you wish from your
side of the fence
• But you also get dynamic introspection of the other
side!
46. Let’s pretend it exists
{:todos
[{:desc "Invoice Client XXX"
:mark-as-done (form-inspired-serialization-goes-here)
:delete (form-inspired-serialization-goes-here)}
{:desc "Work on Enliven"
:mark-as-done (form-inspired-serialization-goes-here)
:delete (form-inspired-serialization-goes-here)}]
:create (form-inspired-serialization-goes-here)}
• all closures are lifted out of the data and mapped
by names to generic functions
• names should be namespaced and shared
47. Benefits
• Coupling between producer and consumer is now
only an agreements on names and schemas
• The process is dynamic
• REPL experience
• Worth exploring: closures as arguments
48. Abusive Simplifications
• Using closure for endpoint is an abuse
• HTTP or synchronicity are not required
• May apply to a messaging system
• as long as some fns are adressable
50. Sequences
• Iteration model
• Should not be confused with collections
• or only very locally
• The (original) way to compose computations
51. Indices are a smell
• Indices may look efficient
• but that’s only because we picked data structures
for which they are
52. Pet peeve: strings
• Strings as chunks of 16 bits chars
• Waste of space because many code points < 256
• chars are not even characters…
• Forces you to copy and decode bytes to chars
53. Pet peeve: strings
• An abstraction with cursors (local moves/searches)
but no indexed lookup
• Would allow to deal with encoded UTF-8 directly
• AFAIK all algorithms that requires indexed lookup
(eg Boyer Moore) could work on bytes and be
composed with encoding
54. Enliven
• Work in progress templating library
• I explored composing the encoding with the
template: static parts are precomputed as bytes,
possibly in direct ByteBuffers
• I even tried composing with gzip
55. GZON
• Directly emits compressed JSON
• Avoids repeated conversions and writes of
commons expressions (constants, field names,
templates values)
• Avoids having to find repetitions right after having
emitted them
• Coming to Github soon
56. Towards Efficiency
• By avoiding unnecessary copies and allocations
• By composing/merging computations
57. In Clojure too
• Sequences
• Chunked sequences
• Reducers
• Transducers
61. Short-circuiting and/or
• Refactor with care!
• Swapping two expressions may:
• Cause exceptions
(and (not= x 0) (/ 1 x))
• Change the returned value
(and (pred x) (lookup x))
63. Regexes
=> (re-seq #"a|ab" "abababab")
("a" "a" "a" "a")
• Choice is ordered
• You can’t locally fix a regex
64. CFG vs RDP
• L ::= "a" L "a" | "a"
• Which strings are matched?
65. CFG vs RDP
• L ::= "a" L "a" | "a"
• Which strings are matched?
• CFG: any string of 2N+1 "a"s
• RDP: any string of 2^N-1 "a"s
66. CFG vs RDP
• L ::= "a" | "a" L "a"
• Which strings are matched?
67. CFG vs RDP
• L ::= "a" | "a" L "a"
• Which strings are matched?
• CFG: any string of 2N+1 "a"s
• RDP: just "a"
68. miniKanren/core.logic
• Depending on the ordering of your disjunctions and
conjunctions...
• ...your program may run endlessly without ever
returning a single answer
• Defaults fixed for disjunction in the draft of the
Reasoned Schemer 2nd edition and in core.logic
• Fair conjunction is harder
• ASP (Answer Set Programming) is really pure
69. ACId is declarative
• Associative
• Ordering is not execution
• Commutative
• Accidental ordering should not matter
• Idempotent
• Factorisation as an optimisation
70. ACId in practice
• I designed Enliven following ACId principles
• Easier to reason about a template than with Enlive
• Way faster: as fast as print
• Point-free
71. Misc
• Local state is the danger, global state is fine
• Nano VMs are fun