Skip to content

Instantly share code, notes, and snippets.

@jido
Created September 19, 2010 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jido/586791 to your computer and use it in GitHub Desktop.
Save jido/586791 to your computer and use it in GitHub Desktop.
(defn fold [vals, seed, next, return, error]
(if (< 0 (count vals))
#(next
(first vals)
seed
(fn [result]
(fold (subvec vals 1) result next return error))
error)
#(return seed)))
(defn wrap [func]
(fn [value, return, error]
#(try
(return (func value))
(catch Exception e (error e)))))
(def ident (wrap identity))
(defrecord SimpleList [values])
(defrecord SimpleListClassInstance [instance])
(defprotocol SimpleListClassProtocol
(instance [self, return, error])
(SimpleList0 [self, return, error]))
(extend-protocol SimpleListClassProtocol SimpleListClassInstance
(instance [self, return, error] #(return (:instance self)))
(SimpleList0 [self, return, error] #(return (:instance self))))
(def SimpleListClass (new SimpleListClassInstance (new SimpleList [])))
(defprotocol SimpleListProtocol
(counts [self, return, error]
"
[int count()]
Counts the items
[return(int)] number of items in the list")
(valueAt [self, i, return, error]
"
[E valueAt(i)]
Get item at a given index
[int i] index of the item
[return(E)] value of the item
[throw(OutOfBounds)] the index is out of bounds")
(value [self, return, error]
"
[yield E value()]
Yields a value from the list
[return(E)] the value of next item in the list
[throw(EndOfYield)] when there are no more items")
(indexOf [self, item, transform, return, error]
"
[int indexOf(reference, transform)]
Get index of a given value
[T reference] the value to look for
[T transform(item) = ident] a function to apply on each item before comparing
[return(int)] index of an item in the list where transform(item) = reference
[throw(NotFound)] if no matching item is found
[throw(Exception)] if transform raises an exception")
(contains [self, item, transform, yes, no, error]
"
[fun(reference,transform->yes(),no(),throw(Exception)) contains]
Checks if the given value belongs to the list
[T reference] the value to look for
[T transform(item) = ident] a function to apply on each item before comparing
[yes()] if there is an item in the list where transform(item) = reference
[no()] otherwise
[throw(Exception)] if transform raises an exception")
(associate [self, item, i, return, error]
"
[Self associate(item, i)]
Sets the item at given index
[E item] the new value of the item
[int i] the index of the item, which can be count+1 to extend the list
[return(Self)] the updated list"))
(extend-protocol SimpleListProtocol SimpleList
(counts [self, return, error]
#(return (count (:values self))))
(valueAt [self, i, return, error]
(let [vals (:values self)]
(if (<= 1 i (count vals))
#(return (nth vals (dec i)))
#(error (new IndexOutOfBoundsException (str "Index" i "out of bounds:" vals))))))
(indexOf
[self, reference, transform, return, error]
(fold (:values self) 1
(fn [value, index, ret, error]
(transform value
(fn [valproj]
(if (= reference valproj)
#(return index)
#(ret (inc index))))
error))
(fn [_] #(error (new IndexOutOfBoundsException)))
error))
(contains
[self, reference, transform, yes, no, error]
(fold (:values self) {}
(fn [value, _, return, error]
(transform value
(fn [valproj]
(if (= reference valproj)
yes
#(return value)))
error))
(fn [_] no)
error))
(associate [self, item, i, return, error]
(let
[vals (:values self)
after (inc (count vals))]
(if (= i after)
#(return
(assoc self :values (conj vals item)))
(if (< 0 i after)
#(return
(assoc self :values (assoc vals i item)))
#(error (new IndexOutOfBoundsException (str "Index" i "out of bounds: " vals)))))))
(value [self, return, error]
(fold
(:values self)
[return, error] ;initial pair of continuations
(fn [avalue, continuation, ret, err]
(fn []
((first continuation) ;return
avalue
(fn [continue, end] #(ret [continue, end]))))) ;resume
(fn [continuation]
#((second continuation) (new IndexOutOfBoundsException))) ;end of yield
error)))
(defn logException [e] (.printStackTrace e))
(trampoline
(-> SimpleListClass (instance (fn [l]
(-> l (associate "Hello" 1 (fn [l]
(-> l (associate "World!" 2 (fn [l]
;(-> l (associate "@@@@" 3 (fn [l] ;)))
(-> l (valueAt 2 (fn [second]
(println "the second element is:" second)
(-> l (value (fn [value next]
(println "First value: " value)
(next (fn [value next]
(println "Next value: " value)
(next
(fn [value _]
(println "unexpected value! " value)
(-> l (indexOf 6 (wrap count)
(fn [position]
(println "Found six-letter word at position:" position))
(fn [_] (println "Didn't find matching word!")))))
(fn [_]
(-> l (contains "Hello" ident
#(println (:values l) "contains Hello")
#(println "not found!")
logException)))))
logException)) logException))) logException))) logException))) logException)))
logException))) ;logException)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment