Swearjure

Table of Contents

1 Swearjure    slide titleslide

Gary Fredericks

(#((% (+(*))) %)
 [(+ (*)(*)(*)(*)(*)(*)(*)) ; input == 7
  #(({(+) (% (+(*)(*)))} (% (+))
     (% (+(*)(*)(*)))) %)
  #({} % (+(*)))
  #(* ((% (+(*)))
       [(- (% (+)) (+(*)))
        (% (+(*)))
        (% (+(*)(*)))
        (% (+(*)(*)(*)))])
      (% (+)))]) ; => 5040

1.1 Notes    notes

So Swearjure is the subset of clojure that does not contain alphanumeric characters. It is surprisingly difficult to do very much with it, but there are a lot of tricks that mostly involve the Reader and using data structures as functions.

On the screen we have an implementation of the factorial function.

1.2 Primary Researchers    slide


Tim McCormack

Jean Niklas L'orange

1.3 Constants    slide

1.3.1 Positive Integers    slide

(*) ;; => 1

(+ (*) (*)) ;; => 2

(* (+ (*)(*))
   (+ (*)(*)(*))
   (+ (*)(*)(*)(*)(*)(*)(*)))
;; => 42

1.3.2 Negative Integers and Ratios    slide

(- (+ (*) (*) (*))) ;; => -3

(/ (+ (*) (*))
   (+ (*) (*) (*))) ;; => 2/3

1.3.3 Floats?    slide center

No known solution.

1.3.4 true / false / nil    slide bigcode

(= :+)    ;; => true
(= :+ :-) ;; => false
({} :+)   ;; => nil

1.4 Data Structures    slide

1:  (def x 42) (def xs '(0 1 2))
2:  ;; construct a list:
3:  `(~x ~@xs) ;; => (42 0 1 2)
4:  ;; concat two lists:
5:  `(~@xs ~@xs) ;; => (0 1 2 0 1 2)
6:  ;; convert to a vector:
7:  `[~@xs] ;; => [0 1 2]
8:  ;; nth
9:  (`[~@xs] (+ (*) (*))) ;; => 2

1.5 Functions    slide

1.5.1 Function Literal Toolbox    slide bigcode oneliner

#(...)
  • Can't use fn, defn, etc
  • Can only refer to % and %&
    • (not %2, %3, etc)
  • Can't nest expressions

1.5.2 The Literal Problem    slide

How can a function return a data structure literal?

1:  #([1 2 %])          ;; doesn't work
2:  
3:  (fn [%] [1 2 %])    ;; works, but illegal
4:  
5:  #(identity [1 2 %]) ;; works, but illegal
6:  
7:  #([[1 2 %]] (+))    ;; works, and legal!

1.5.3 Common clojure.core Functions    slide

 1:  (def inc #(+ % (*)))
 2:  (def dec #(- % (*)))
 3:  (def identity #([%] (+)))
 4:  
 5:  (def boolean #({false false nil false} % true))
 6:  (def boolean #({(= :+ :-)
 7:                  (= :+ :-),
 8:                  (:+ :-)
 9:                  (= :+ :-)}
10:                 % (= :+)))

1.5.4 Control Flow, Recursion, etc.    slide

Use a function table

 1:  ((fn [ft n]
 2:     ((ft :fact) ft n)) ; Call factorial with all fns and n
 3:  
 4:   {:fact (fn [ft n]
 5:            (let [f-to-call ({0 :is-zero} n :recurse)]
 6:              ((ft f-to-call) ft n)))
 7:    :is-zero (fn [ft n] 1) ; return 1
 8:    :recurse (fn [ft n]    ; recurse by calling :fact
 9:               (* n ((ft :fact) ft (- n 1))))}
10:    6)

1.5.5 Control Flow, Recursion, etc. 2    slide

Simulating if

 1:  ;; Equivalent to #(if (< % 5) (+ % 7) (- % 5))
 2:  
 3:  ((fn [ft n]
 4:     ((ft :main) ft n))
 5:  
 6:   {:main (fn [ft n] ((ft ({false :falsy true :truey} (< n 5)))
 7:                      ft n))
 8:    :truey (fn [ft n] (+ n 7))
 9:    :falsy (fn [ft n] (- n 5))}
10:    6) ;; => 1

1.5.6 Control Flow, Recursion, etc. 3    slide

The function table tactic eats the stack.

1.6 Curiosities    slide

1.6.1 hash-map    slide bigcode

;; NB: Does not accept 0 args
(def hash-map
  #(`[{~% ~@%&}] (+)))

1.6.2 Getting a Gensym    slide bigcode

Always returns the same symbol

(#('%& '%& '%&))
;; => rest__1206#

1.6.3 rest    slide littlecode

(#(((% (+(*))) (+)) %)
 [[:a :b :c :d :e] ;; input
  [#(({[] ((% (+(*))) (+(*)))}
      (% (+))
      ((% (+(*))) (+(*)(*))))
     [(% (+)) (% (+(*)))])
   #({} %& [])
   #(((% (+(*))) (+(*)(*)(*)))
     [(% (+)) (% (+(*))) [(+(*)) []]])
   #(({(% (+)) ((% (+(*))) (+(*)(*)(*)(*)))}
      `[~((% (+)) (+))
        ~@((% (+(*)(*))) (+(*)))]
      ((% (+(*))) (+(*)(*)(*)(*)(*))))
     [(% (+)) (% (+(*))) (% (+(*)(*)))])
   #((% (+(*)(*))) (+(*)))
   #(((% (+(*))) (+(*)(*)(*)))
     [(% (+)) (% (+(*))) [(+ (+(*)) ((% (+(*)(*))) (+)))
                   `[~@((% (+(*)(*))) (+(*)))
                     ~((% (+)) ((% (+(*)(*))) (+)))]]])]])
;; => [:b :c :d :e]

1.7 Completeness    slide

1.7.1 Turing Complete?    slide

Reduction to lambda calculus is difficult because we effectively don't have closures.

1.7.2 Turing Complete: The SKI Calculus    slide center

This slide has been left as an exercise for the reader.

1.7.3 Clojure Complete?    slide

Hardly. Missing:

  • Expressions for:
    • Arbitrary strings, symbols, keywords
    • Floating point numbers
  • Interop of any sort
  • partial and apply
  • def, recur, throw, catch, …
  • Nearly everything really

1.8 Swearjure    slide firstcenter

"Inescapeably useless, surprisingly powerful."

Future Work

  • Actually implement SKI Calculus
  • Efficient algorithm for finding smallest representation of an integer
  • Smallest alphanumeric preamble that would make Swearjure clojure-complete

1.8.1 Notes    notes

So we're led to the inescapeable conclusion that despite being surprisingly powerful, Swearjure is fundamentally useless.

If you're interested in pushing the limits of humanity's knowledge in this exciting field, I've listed several avenues you could pursue.

Also if you have ideas for ways we can sneak swearjure-empowering commits past Rich, let me know.

Thank you very much.

2 Export Metastuff

Date: 2013-03-16T17:07-0500

Author: Gary Fredericks

Org version 7.9.3f with Emacs version 24

Validate XHTML 1.0