Skip to content

Instantly share code, notes, and snippets.

@modernserf
Created May 8, 2015 21:45
Show Gist options
  • Save modernserf/3ac408fc55904a75d68b to your computer and use it in GitHub Desktop.
Save modernserf/3ac408fc55904a75d68b to your computer and use it in GitHub Desktop.
Set-oriented lisp
; TODO: infix syntax?
; Not everything is a set, but assignment is implicitly to a set.
(def foo 1)
; equivalent to
(def foo (Set 1))
(def foo 1 2)
; equivalent to
(def foo (Set 1 2))
; set items are unique
(def foo 1 1 2 3 2)
; => (Set 1 2 3)
; sets can be defined with square brackets
[1 2 3]
; equivalent to
(Set 1 2 3)
; There are literals for numbers and strings.
; Strings are always enclosed in double-quotes.
(def baz "a string")
; tuples are collections of fields with a consistent order.
; functionally equivalent to a "classic" list
; tuples have no uniqueness constraints
; there are a few syntax options for defining them.
(Tuple "foo" "bar")
#("foo" "bar")
; bareword + colon + value is equivalent to a 2-element tuple.
foo: "bar"
; tag (#) is a modifier that has a meaning similar to "quote"
; tagged barewords are strings
(def tags #foo #bar #baz)
; equivalent to
(def tags (Set "foo" "bar" "baz"))
; tagged lists are tuples
#(1 2 3)
; equivalent to
(Tuple 1 2 3)
; sets and tuples are combined to make maps
[foo: 10 bar: 20 baz: 30]
; equivalent to
(Set (Tuple "foo" 10) (Tuple "bar" 20) (Tuple) ("baz" 30))
; or indexed lists
(List foo bar baz)
; equivalent to
[0: foo 1: bar 2: baz]
; TODO: sequence as distinct from tuple?
; records are tuples with type checks and named fields.
(def Foo (Record #("name" String) #("email" String)))
; shorthand definition
(defrecord Foo name: String email: String)
; this creates a constructor for a record.
; record constructor expects a tuple
(Foo #("Alice" "[email protected]"))
; or a map
(Foo [name: "Alice" email: "[email protected]"])
; additional fields can be tacked onto a record
; this is useful for tagging
(Foo #("Fred" "[email protected]" #))
; sets are implicit here as well
; multiple items passed to a constructor make a table
(Foo #("Justin" "[email protected]")
#("Fred" "[email protected]"))
; tables support SQL-style operations
; TODO
; function arguments are not implicitly grouped into a set
(+ 2 3 4) ; => 9
(+ [2 3 4]) ; => TODO: curried function maybe? error?
; functions are implicitly mapped over their arguments
; with their results combined into a single set
(+ [2] [3 4])
; => [5, 6]
; apply (\) calls the function with each set member as an argument
(\ + [2 3 4]) ; => 9
; equivalent to
(+ 2 3 4)
; or even
(+ [2] [3] [4])
; apply also takes tuples
(\ + #(2 3 4))
; when called with a set as its only parameter, it converts it into a tuple (in no particular order)
(\ [2 3 4]) ; => #(2 3 4) maybe?
; functions
(Function [x] (+ x 5))
; functions dispatch on arity
; multiple arity
(Function [x] (+ x 5)
[x y] (+ x y 5)
; variadic : args treated as tuple
[\xs] (+ (first xs) (\ addFive (rest xs))))
; function shorthand
(def addFive {+ $ 5}
{+ $0 $1 5}
{+ (first \$) (\ addFive (rest \$))})
; note that addFive is a _set_ of functions
; TODO: fold and insert
; set operations
; union
(++ [1 2 3] [2 4 6])
; => [1 2 3 4 6]
; intersection
(&& [1 2 3] [2 4 6])
; => [2]
; difference
(-- [1 2 3] [2 4 6])
; => [1 3 4 6]
; filtering operations return the last operand for success, empty set for failure
; equivalence
(== [1 2 3] [2 3 1])
; => [2 3 1]
(== [1 2 3] [2 4 6])
; => []
; membership
; (lt, gt, lte, gte used for numeric comparators)
(< [1 2] [1 2 3])
; => [1 2 3]
(> [1 2 3] [1 2])
; => [1 2]
(< [1 2] [1 2 3] [1 2 3 4])
; equivalent to
(< (< [1 2] [1 2 3]) [1 2 3 4])
; to allow infix use as [1 2] < [1 2 3] < [1 2 3 4]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment