Skip to content

Instantly share code, notes, and snippets.

@gerardpaapu
Created July 3, 2012 04:03
Show Gist options
  • Save gerardpaapu/3037609 to your computer and use it in GitHub Desktop.
Save gerardpaapu/3037609 to your computer and use it in GitHub Desktop.
An example of chitchat code and the javascript it compiles to
;;; OrderedSet
;;; ----------
;;;
;;; A Collection class that wraps an Array.
;;; It maintains immutability, an order, and
;;; does not contain duplicates
;;;
;;; Items of the Ordered Set should implement 'Ord'
(class OrderedSet
(constructor (items, ordered, distinct)
(set this:items (or items #[]))
;; ensure the qualities of the ordered set in this.items
;; call uniquify! unless the items are known to be distinct
;; call sort! unless the items are known to be sorted
(if distinct.isFalse? (this uniquify!)
ordered.isFalse? (this sort!)))
(method (contains? needle)
(this:items contains? needle))
(method (asArray)
;; return a clone so that clients don't
;; mutate our internal array
this:items.cloneArray)
(method (slice a b)
(this:items slice a, b))
(method (nth i)
this:items.[i])
(method (length)
this:items.length)
(method (concat ls)
(let [;; ls can be an OrderedSet or an Array
(items (if (ls isAn OrderedSet) ls.items
(ls isAn Array) ls))
;; items that don't exist in the destination
(new-items (ls filter ^(this contains #0) this))]
;; return the same OrderedSet unless there are new items
(if new-items.isEmpty?
this
(OrderedSet new (this:items concat new-items) true))))
(method (sort!)
;; sort it by passing the messages '>' and '<'
;; The default implementation on Object is to
;; use the builtin javascript operators '>' and '<'
(this:items sort ^(if (#0 > #1) MORE
(#1 < #0) LESS
EQUAL)))
(method (uniqify!)
;; Ensure that this.items is distinct
(set this:items
(this:items reduce ^[out, item] (if (out contains? item)
out
(out concat item))
#[]))))
(set exports:OrderedSet OrderedSet)
OrderedSet = function(items, ordered, distinct) {
this["items"] = items || [];
if (_passMessage(distinct, "isFalse?")) {
_passMessage(this, "uniquify!");
} else {
if (_passMessage(ordered, "isFalse?")) {
_passMessage(this, "sort!");
}
}
};
OrderedSet["prototype"]["contains?"] = function(needle) {
return _passMessage(this["items"], "contains?", [ needle ]);
};
OrderedSet["prototype"]["asArray"] = function() {
return _passMessage(this["items"], "cloneArray");
};
OrderedSet["prototype"]["slice"] = function(a, b) {
return _passMessage(this["items"], "slice", [ a, b ]);
};
OrderedSet["prototype"]["nth"] = function(i) {
return _passMessage(this["items"], i);
};
OrderedSet["prototype"]["length"] = function() {
return _passMessage(this["items"], "length");
};
OrderedSet["prototype"]["concat"] = function(ls) {
return function() {
var items, new_dash_items;
items = _passMessage(ls, "isAn", [ OrderedSet ]) ? _passMessage(ls, "items") : _passMessage(ls, "isAn", [ Array ]) ? ls : null;
new_dash_items = _passMessage(ls, "filter", [ function() {
return _passMessage(this, "contains", [ arguments[0] ]);
}, this ]);
return _passMessage(new_dash_items, "isEmpty?") ? this : _passMessage(OrderedSet, "new", [ _passMessage(this["items"], "concat", [ new_dash_items ]), true ]);
}["apply"](this, typeof arguments != "undefined" ? arguments : []);
};
OrderedSet["prototype"]["sort!"] = function() {
return _passMessage(this["items"], "sort", [ function() {
return _passMessage(arguments[0], ">", [ arguments[1] ]) ? MORE : _passMessage(arguments[1], "<", [ arguments[0] ]) ? LESS : EQUAL;
} ]);
};
OrderedSet["prototype"]["uniqify!"] = function() {
return this["items"] = _passMessage(this["items"], "reduce", [ function(out, item) {
return _passMessage(out, "contains?", [ item ]) ? out : _passMessage(out, "concat", [ item ]);
}, [] ]);
};
exports["OrderedSet"] = OrderedSet;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment