Created
September 19, 2010 14:05
-
-
Save jido/586791 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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