Kevnz
7/3/2012 - 4:03 AM

An example of chitchat code and the javascript it compiles to

An example of chitchat code and the javascript it compiles to

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;
;;; 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)