Initial check-in
[dygraphs.git] / mochikit_v14 / doc / rst / MochiKit / Base.rst
1 .. title:: MochiKit.Base - functional programming and useful comparisons
2
3 Name
4 ====
5
6 MochiKit.Base - functional programming and useful comparisons
7
8
9 Synopsis
10 ========
11
12 ::
13
14     myObjectRepr = function () {
15         // gives a nice, stable string representation for objects,
16         // ignoring any methods
17         var keyValuePairs = [];
18         for (var k in this) {
19             var v = this[k];
20             if (typeof(v) != 'function') {
21                 keyValuePairs.push([k, v]);
22             }
23         };
24         keyValuePairs.sort(compare);
25         return "{" + map(
26             function (pair) {
27                 return map(repr, pair).join(":");
28             },
29             keyValuePairs
30         ).join(", ") + "}";
31     };
32
33     // repr() will look for objects that have a repr method
34     myObjectArray = [
35         {"a": 3, "b": 2, "repr": myObjectRepr},
36         {"a": 1, "b": 2, "repr": myObjectRepr}
37     ];
38
39     // sort it by the "a" property, check to see if it matches
40     myObjectArray.sort(keyComparator("a"));
41     expectedRepr = '[{"a": 1, "b": 2}, {"a": 3, "b": 2}]';
42     assert( repr(myObjectArray) == expectedRepr );
43
44     // get just the "a" values out into an array
45     sortedAValues = map(itemgetter("a"), myObjectArray);
46     assert( compare(sortedAValues, [1, 3]) == 0 );
47
48     // serialize an array as JSON, unserialize it, expect something equivalent
49     myArray = [1, 2, "3", null, undefined];
50     assert( objEqual(evalJSON(serializeJSON(myArray)), myArray) );
51
52
53 Description
54 ===========
55
56 :mochiref:`MochiKit.Base` is the foundation for the MochiKit suite.
57 It provides:
58
59 -   An extensible comparison facility
60     (:mochiref:`compare`, :mochiref:`registerComparator`)
61 -   An extensible programmer representation facility
62     (:mochiref:`repr`, :mochiref:`registerRepr`)
63 -   An extensible JSON [1]_ serialization and evaluation facility
64     (:mochiref:`serializeJSON`, :mochiref:`evalJSON`,
65     :mochiref:`registerJSON`)
66 -   A simple adaptation facility (:mochiref:`AdapterRegistry`)
67 -   Convenience functions for manipulating objects and Arrays
68     (:mochiref:`update`, :mochiref:`setdefault`, :mochiref:`extend`, etc.)
69 -   Array-based functional programming
70     (:mochiref:`map`, :mochiref:`filter`, etc.)
71 -   Bound and partially applied functions
72     (:mochiref:`bind`, :mochiref:`method`, :mochiref:`partial`)
73
74 Python users will feel at home with :mochiref:`MochiKit.Base`, as the
75 facilities are quite similar to those available as part of Python and
76 the Python standard library.
77
78
79 Dependencies
80 ============
81
82 None.
83
84
85 Overview
86 ========
87
88 Comparison
89 ----------
90
91 The comparators (operators for comparison) in JavaScript are deeply
92 broken, and it is not possible to teach them new tricks.
93
94 MochiKit exposes an extensible comparison facility as a simple
95 :mochiref:`compare(a, b)` function, which should be used in lieu of
96 JavaScript's operators whenever comparing objects other than numbers
97 or strings (though you can certainly use :mochiref:`compare` for
98 those, too!).
99
100 The :mochiref:`compare` function has the same signature and return
101 value as a sort function for ``Array.prototype.sort``, and is often
102 used in that context.
103
104 Defining new comparators for the :mochiref:`compare` function to use
105 is done by adding an entry to its :mochiref:`AdapterRegistry` with the
106 :mochiref:`registerComparator` function.
107
108
109 Programmer Representation
110 -------------------------
111
112 JavaScript's default representation mechanism, ``toString``, is
113 notorious for having terrible default behavior. It's also very unwise
114 to change that default, as other JavaScript code you may be using may
115 depend on it.
116
117 It's also useful to separate the concept of a "string representation"
118 and a "string representation for programmers", much like Python does
119 with its str and repr protocols.
120
121 :mochiref:`repr` provides this programmer representation for
122 JavaScript, in a way that doesn't require object prototype hacking:
123 using an :mochiref:`AdapterRegistry`.
124
125 Objects that implement the repr protocol can either implement a
126 ``.repr()`` or ``.__repr__()`` method, or they can simply have an
127 adapter setup to generate programmer representations. By default, the
128 registry provides nice representations for ``null``, ``undefined``,
129 ``Array``, and objects or functions with a ``NAME`` attribute that use
130 the default ``toString``. For objects that ``repr`` doesn't already
131 understand, it simply defaults to ``toString``, so it will integrate
132 seamlessly with code that implements the idiomatic JavaScript
133 ``toString`` method!
134
135 To define a programmer representation for your own objects, simply add
136 a ``.repr()`` or ``.__repr__()`` method that returns a string. For
137 objects that you didn't create (e.g., from a script you didn't write,
138 or a built-in object), it is instead recommended that you create an
139 adapter with :mochiref:`registerRepr`.
140
141
142 JSON Serialization
143 ------------------
144
145 JSON [1]_, JavaScript Object Notation, is a widely used serialization
146 format in the context of web development. It's extremely simple,
147 lightweight, and fast. In its essence, JSON is a restricted subset of
148 JavaScript syntax suitable for sending over the wire that can be
149 unserialized with a simple eval. It's often used as an alternative to
150 XML in "AJAX" contexts because it is compact, fast, and much simpler
151 to use for most purposes.
152
153 To create a JSON serialization of any object, simply call
154 :mochiref:`serializeJSON()` with that object. To unserialize a JSON
155 string, simply call :mochiref:`evalJSON()` with the serialization.
156
157 In order of precedence, :mochiref:`serializeJSON` coerces the given
158 argument into a JSON serialization:
159
160 1.  Primitive types are returned as their JSON representation:
161     ``string``, ``number``, ``boolean``, ``null``.
162 2.  If the object has a ``__json__`` or ``json`` method, then it is
163     called with no arguments. If the result of this method is not the
164     object itself, then the new object goes through rule processing
165     again (e.g. it may return a string, which is then serialized in
166     JSON format).
167 3.  If the object is ``Array``-like (has a ``length`` property that is
168     a number, and is not a function), then it is serialized as a JSON
169     array.  Each element will be processed according to these rules in
170     order.  Elements that can not be serialized (e.g. functions) will
171     be replaced with ``undefined``.
172 4.  The ``jsonRegistry`` :mochiref:`AdapterRegistry` is consulted for
173     an adapter for this object. JSON adapters take one argument (the
174     object), and are expected to behave like a ``__json__`` or
175     ``json`` method (return another object to be serialized, or
176     itself).
177 5.  If the object is ``undefined``, a ``TypeError`` is thrown. If you
178     wish to serialize ``undefined`` as ``null`` or some other value, you
179     should create an adapter to do so.
180 6.  If no adapter is available, the object is enumerated and
181     serialized as a JSON object (name:value pairs). All names are
182     expected to be strings.  Each value is serialized according to
183     these rules, and if it can not be serialized (e.g. methods), then
184     that name:value pair will be skipped.
185
186
187 Adapter Registries
188 ------------------
189
190 MochiKit makes extensive use of adapter registries, which enable you
191 to implement object-specific behaviors for objects that you do not
192 necessarily want to modify, such as built-in objects. This is
193 especially useful because JavaScript does not provide a method for
194 hiding user-defined properties from ``for propName in obj``
195 enumeration.
196
197 :mochiref:`AdapterRegistry` is simply an encapsulation for an ordered
198 list of "check" and "wrap" function pairs. Each
199 :mochiref:`AdapterRegistry` instance should perform one function, but
200 may have multiple ways to achieve that function based upon the
201 arguments. One way to think of it is as a poor man's generic function,
202 or multiple dispatch (on arbitrary functions, not just type!).
203
204 Check functions take one or more arguments, and return ``true`` if the
205 argument list is suitable for the wrap function. Check functions
206 should perform "cheap" checks of an object's type or contents, before
207 the "expensive" wrap function is called.
208
209 Wrap functions take the same arguments as check functions and do some
210 operation, such as creating a programmer representation or comparing
211 both arguments.
212
213
214 Convenience Functions
215 ---------------------
216
217 Much of :mochiref:`MochiKit.Base` is there to simply remove the grunt
218 work of doing generic JavaScript programming.
219
220 Need to take every property from one object and set them on another?
221 No problem, just call :mochiref:`update(dest, src)`! What if you just
222 wanted to update keys that weren't already set? Look no further than
223 :mochiref:`setdefault(dest, src[, ...])`.
224
225 Want to return a mutable object, but don't want to suffer the
226 consequences if the user mutates it? Just :mochiref:`clone(it)` and
227 you'll get a copy-on-write clone. Cheaper than a copy!
228
229 Need to extend an ``Array`` with another array? Or even an
230 ``Array``-like object such as a ``NodeList`` or the special
231 ``arguments`` object? Even if you need to skip the first few elements
232 of the source ``Array``-like object, it's no problem with
233 :mochiref:`extend(dstArray, srcArrayLike[, skip])`!
234
235 Wouldn't it be convenient to have all of the JavaScript operators were
236 available as functions somewhere? That's what the
237 :mochiref:`operators` table is for, and it even comes with additional
238 operators based on the :mochiref:`compare` function.
239
240 Need to walk some tree of objects and manipulate or find something in
241 it?  A DOM element tree perhaps? Use :mochiref:`nodeWalk(node,
242 visitor)`!
243
244 There's plenty more, so check out the `API Reference`_ below.
245
246
247 Functional Programming
248 ----------------------
249
250 Functional programming constructs such as :mochiref:`map` and
251 :mochiref:`filter` can save you a lot of time, because JavaScript
252 iteration is error-prone and arduous. Writing less code is the best
253 way to prevent bugs, and functional programming can help you do that.
254
255 :mochiref:`MochiKit.Base` ships with a few simple Array-based
256 functional programming constructs, namely :mochiref:`map` and
257 :mochiref:`filter`, and their "extended" brethren, :mochiref:`xmap`
258 and :mochiref:`xfilter`.
259
260 :mochiref:`map(func, arrayLike[, ...])` takes a function and an
261 ``Array``-like object, and creates a new ``Array``. The new ``Array``
262 is the result of ``func(element)`` for every element of ``arrayLike``,
263 much like the ``Array.prototype.map`` extension in Mozilla. However,
264 :mochiref:`MochiKit.Base` takes that a step further and gives you the
265 full blown Python version of :mochiref:`map`, which will take several
266 ``Array``-like objects, and calls the function with one argument per
267 given ``Array``-like, e.g.::
268
269    var arrayOne = [1, 2, 3, 4, 5];
270    var arrayTwo = [1, 5, 2, 4, 3];
271    var arrayThree = [5, 2, 1, 3, 4];
272    var biggestElements = map(objMax, arrayOne, arrayTwo, arrayThree);
273    assert( objEqual(biggestElements, [5, 5, 3, 4, 5]) );
274
275 :mochiref:`filter(func, arrayLike[, self])` takes a function and an
276 ``Array``-like object, and returns a new ``Array``.  This is basically
277 identical to the ``Array.prototype.filter`` extension in
278 Mozilla. self, if given, will be used as ``this`` in the context of
279 func when called.
280
281 :mochiref:`xmap` and :mochiref:`xfilter` are just special forms of
282 :mochiref:`map` and :mochiref:`filter` that accept a function as the
283 first argument, and use the extra arguments as the ``Array``-like. Not
284 terribly interesting, but a definite time-saver in some cases.
285
286 If you appreciate the functional programming facilities here, you
287 should definitely check out :mochiref:`MochiKit.Iter`, which provides
288 full blown iterators, :mochiref:`MochiKit.Iter.range`,
289 :mochiref:`MochiKit.Iter.reduce`, and a near-complete port of Python's
290 itertools [2]_ module, with some extra stuff thrown in for good
291 measure!
292
293
294 Bound and Partial Functions
295 ---------------------------
296
297 JavaScript's method-calling special form and lack of bound functions
298 (functions that know what ``this`` should be) are one of the first
299 stumbling blocks that programmers new to JavaScript face. The
300 :mochiref:`bind(func, self)` method fixes that right up by returning a
301 new function that calls func with the right ``this``.
302
303 In order to take real advantage of all this fancy functional
304 programming stuff, you're probably going to want partial
305 application. This allows you to create a new function from an existing
306 function that remembers some of the arguments.  For example, if you
307 wanted to compare a given object to a slew of other objects, you could
308 do something like this::
309
310     compareWithOne = partial(compare, 1);
311     results = map(compareWithOne, [0, 1, 2, 3]);
312     assert( objEqual(results, [-1, 0, 1, 1]) );
313
314 One of the better uses of partial functions is in
315 :mochiref:`MochiKit.DOM`, which is certainly a must-see for those of
316 you creating lots of DOM elements with JavaScript!
317
318
319 API Reference
320 =============
321
322 Errors
323 ------
324
325 :mochidef:`NotFound`:
326
327     A singleton error raised when no suitable adapter is found
328
329     *Availability*:
330         Available in MochiKit 1.3.1+
331
332
333 Constructors
334 ------------
335
336 :mochidef:`AdapterRegistry`:
337
338     A registry to facilitate adaptation.
339
340     All ``check``/``wrap`` function pairs in a given registry should
341     take the same number of arguments.
342
343     *Availability*:
344         Available in MochiKit 1.3.1+
345
346
347 :mochidef:`AdapterRegistry.prototype.register(name, check, wrap[, override])`:
348
349     ``name``:
350         a unique identifier used to identify this adapter so that it
351         may be unregistered.
352
353     ``check``:
354         function that should return ``true`` if the given arguments
355         are appropriate for the ``wrap`` function.
356
357     ``wrap``:
358         function that takes the same parameters as ``check`` and does
359         the adaptation.  Every ``wrap``/``check`` function pair in the
360         registry should have the same number of arguments.
361
362     ``override``:
363         if ``true``, the ``check`` function will be
364         given highest priority. Otherwise, the lowest.
365
366     *Availability*:
367         Available in MochiKit 1.3.1+
368
369
370 :mochidef:`AdapterRegistry.prototype.match(obj[, ...])`:
371
372     Find an adapter for the given arguments by calling every ``check``
373     function until one returns ``true``.
374
375     If no suitable adapter is found, throws :mochiref:`NotFound`.
376
377     *Availability*:
378         Available in MochiKit 1.3.1+
379
380
381 :mochidef:`AdapterRegistry.prototype.unregister(name)`:
382
383     Remove a named adapter from the registry
384
385     *Availability*:
386         Available in MochiKit 1.3.1+
387
388
389 :mochidef:`NamedError`:
390
391     Convenience constructor for creating new errors
392     (e.g. :mochiref:`NotFound`)
393
394     *Availability*:
395         Available in MochiKit 1.3.1+
396
397
398 Functions
399 ---------
400
401 :mochidef:`arrayEqual(self, arr)`:
402
403     Compare the arrays ``self`` and ``arr`` for equality using
404     ``compare`` on each element. Uses a fast-path for length
405     differences.
406
407     *Availability*:
408         Available in MochiKit 1.3.1+
409
410
411 :mochidef:`average(lst[, ...])`:
412
413     This function is an alias of :mochiref:`mean()`.
414
415     *Availability*:
416         Available in MochiKit 1.3.1+
417
418
419 :mochidef:`bind(func, self[, arg, ...])`:
420
421     Return a copy of ``func`` bound to ``self``. This means whenever
422     and however the returned function is called, ``this`` will always
423     reference the given ``self``. ``func`` may be either a function
424     object, or a string. If it is a string, then ``self[func]`` will
425     be used, making these two statements equivalent::
426
427         bind("method", self);
428         bind(self.method, self);
429
430     Calling :mochiref:`bind(func, self)` on an already bound function
431     will return a new function that is bound to the new ``self``! If
432     ``self`` is ``undefined``, then the previous ``self`` is used.  If
433     ``self`` is ``null``, then the ``this`` object is used (which may
434     or may not be the global object). To force binding to the global
435     object, you should pass it explicitly.
436
437     Additional arguments, if given, will be partially applied to the
438     function. These three expressions are equivalent and return
439     equally efficient functions (:mochiref:`bind` and
440     :mochiref:`partial` share the same code path):
441
442     - :mochiref:`bind(oldfunc, self, arg1, arg2)`
443     - :mochiref:`bind(partial(oldfunc, arg1, arg2), self)`
444     - :mochiref:`partial(bind(oldfunc, self), arg1, arg2)`
445
446     *Availability*:
447         Available in MochiKit 1.3.1+
448
449
450 :mochidef:`bindMethods(self)`:
451
452     Replace all functions ``meth`` on ``self`` with
453     :mochiref:`bind(meth, self)`.  This emulates Python's bound
454     instance methods, where there is no need to worry about preserving
455     ``this`` when the method is used as a callback.
456
457     *Availability*:
458         Available in MochiKit 1.3.1+
459
460
461 :mochidef:`camelize(str)`:
462
463     Converts hyphenated strings to camelCase::
464
465         assert( camelize("border-left") == "borderLeft" );
466
467     *Availability*:
468         Available in MochiKit 1.4+
469
470
471 :mochidef:`clone(obj)`:
472
473     Return a new object using ``obj`` as its prototype. Use this if
474     you want to return a mutable object (e.g. instance state), but
475     don't want the user to mutate it. If they do, it won't have any
476     effect on the original ``obj``.
477
478     Note that this is a shallow clone, so mutable properties will have
479     to be cloned separately if you want to "protect" them.
480
481     *Availability*:
482         Available in MochiKit 1.3.1+
483
484
485 :mochidef:`compare(a, b)`:
486
487     Compare two objects in a sensible manner. Currently this is:
488
489     1.  ``undefined`` and ``null`` compare equal to each other
490     2.  ``undefined`` and ``null`` are less than anything else
491     3.  If JavaScript says ``a == b``, then we trust it
492     4.  comparators registered with registerComparator are used to
493         find a good comparator. Built-in comparators are currently
494         available for ``Array``-like and ``Date``-like objects.
495     5.  Otherwise hope that the built-in comparison operators do
496         something useful, which should work for numbers and strings.
497     6.  If neither ``a < b`` or ``a > b``, then throw a ``TypeError``
498
499     Returns what one would expect from a comparison function:
500
501     +-----------+---------------+
502     | Value     | Condition     |
503     +-----------+---------------+
504     | ``0``     | ``a == b``    |
505     +-----------+---------------+
506     | ``1``     | ``a > b``     |
507     +-----------+---------------+
508     | ``-1``    | ``a < b``     |
509     +-----------+---------------+
510
511     *Availability*:
512         Available in MochiKit 1.3.1+
513
514
515 :mochidef:`compose(f1, f2, ..., fN)`:
516
517     Return a new function as the combination of the given function
518     arguments, equivalent to ``f1(f2(arguments))``.
519
520     *Availability*:
521         Available in MochiKit 1.4+
522
523
524 :mochidef:`concat(lst[, ...])`:
525
526     Concatenates all given ``Array``-like arguments and returns
527     a new ``Array``::
528
529         var lst = concat(["1","3","5"], ["2","4","6"]);
530         assert( lst.toString() == "1,3,5,2,4,6" );
531
532     *Availability*:
533         Available in MochiKit 1.3.1+
534
535
536 :mochidef:`counter(n=1)`:
537
538     Returns a function that will return a number one greater than
539     the previous returned value, starting at ``n``. For example::
540
541         nextId = counter()
542         assert( nextId() == 1 )
543         assert( nextId() == 2 )
544
545     For an iterator with this behavior, see
546     :mochiref:`MochiKit.Iter.count`.
547
548     *Availability*:
549         Available in MochiKit 1.3.1+
550
551
552 :mochidef:`extend(self, obj, skip=0)`:
553
554     Mutate the array ``self`` by extending it with an ``Array``-like
555     ``obj``, starting from index ``skip``. If ``null`` is given as the
556     initial array, a new one will be created.
557
558     This mutates *and returns* ``self``, be warned.
559
560     *Availability*:
561         Available in MochiKit 1.3.1+
562
563
564 :mochidef:`evalJSON(aJSONString)`:
565
566     Unserialize a JSON [1]_ represenation of an object.
567
568     Note that this uses the ``eval`` function of the interpreter, and
569     therefore trusts the contents of ``aJSONString`` to be safe.  This
570     is acceptable when the JSON and JavaScript application originate
571     from the same server, but in other scenarios it may not be the
572     appropriate security model. Currently, a validating JSON parser is
573     beyond the scope of MochiKit, but there is one available from
574     json.org [1]_.
575
576     *Availability*:
577         Available in MochiKit 1.3.1+
578
579
580 :mochidef:`filter(fn, lst)`:
581
582     Returns a new ``Array`` composed of all elements from ``lst``
583     where ``fn(lst[i])`` returns a true value.
584
585     If ``fn`` is ``null``, ``operator.truth`` will be used.
586
587     *Availability*:
588         Available in MochiKit 1.3.1+
589
590
591 :mochidef:`findValue(lst, value, start=0, end=lst.length)`:
592
593     Finds the index of ``value`` in the ``Array``-like object ``lst``
594     using :mochiref:`compare`. The search starts at the index
595     ``start``, and ends at the index ``end - 1``. If ``value`` is not
596     found in ``lst``, it will return ``-1``.
597
598     For example::
599
600         assert( findValue([1, 2, 3, 2, 1], 2) == 1 )
601         assert( findValue([1, 2, 3, 2, 1], 2, 2) == 3 )
602
603     *Availability*:
604         Available in MochiKit 1.3.1+
605
606
607 :mochidef:`findIdentical(lst, value, start=0, end=lst.length)`:
608
609     Finds the index of ``value`` in the ``Array``-like object ``lst``
610     using the ``===`` operator. The search starts at the index
611     ``start``, and ends at the index ``end - 1``. If ``value`` is not
612     found in ``lst``, it will return ``-1``.
613
614     You should use this function instead of :mochiref:`findValue` if
615     ``lst`` may be comprised of objects for which no comparator is
616     defined and all you care about is finding an identical object
617     (e.g. the same instance), or if ``lst`` is comprised of just
618     numbers or strings and performance is important.
619
620     For example::
621
622         assert( findIdentical([1, 2, 3, 2, 1], 2) == 1 )
623         assert( findIdentical([1, 2, 3, 2, 1], 2, 2) == 3 )
624
625     *Availability*:
626         Available in MochiKit 1.3.1+
627
628
629 :mochidef:`flattenArguments(arg[, ...])`:
630
631     Given a bunch of arguments, return a single ``Array`` containing
632     all of those arguments. Any ``Array``-like argument will be extended
633     in-place, e.g.::
634
635         compare(flattenArguments(1, [2, 3, [4, 5]]), [1, 2, 3, 4, 5]) == 0
636
637     *Availability*:
638         Available in MochiKit 1.3.1+
639
640
641 :mochidef:`flattenArray(lst)`:
642
643     Return a new ``Array`` consisting of every item in lst with ``Array``
644     items expanded in-place recursively. This differs from 
645     :mochiref:`flattenArguments` in that it only takes one argument and
646     it only flattens items that are ``instanceof Array``.
647
648         compare(flattenArray([1, [2, 3, [4, 5]]]), [1, 2, 3, 4, 5]) == 0
649
650     *Availability*:
651         Available in MochiKit 1.4+
652
653
654 :mochidef:`forwardCall(name)`:
655
656     Returns a function that forwards a method call to
657     ``this.name(...)``
658
659     *Availability*:
660         Available in MochiKit 1.3.1+
661
662
663 :mochidef:`isArrayLike(obj[, ...])`:
664
665     Returns ``true`` if all given arguments are ``Array``-like (have a
666     ``.length`` property and ``typeof(obj) == 'object'``)
667
668     *Availability*:
669         Available in MochiKit 1.3.1+
670
671
672 :mochidef:`isDateLike(obj[, ...])`:
673
674     Returns ``true`` if all given arguments are ``Date``-like (have a
675     ``.getTime()`` method)
676
677     *Availability*:
678         Available in MochiKit 1.3.1+
679
680
681 :mochidef:`isEmpty(obj[, ...])`:
682
683     Returns ``true`` if all the given ``Array``-like or string
684     arguments are empty ``(obj.length == 0)``
685
686     *Availability*:
687         Available in MochiKit 1.3.1+
688
689
690 :mochidef:`isNotEmpty(obj[, ...])`:
691
692     Returns ``true`` if all the given ``Array``-like or string
693     arguments are not empty ``(obj.length > 0)``
694
695     *Availability*:
696         Available in MochiKit 1.3.1+
697
698
699 :mochidef:`isNull(obj[, ...])`:
700
701     Returns ``true`` if all arguments are ``null``.
702
703     *Availability*:
704         Available in MochiKit 1.3.1+
705
706
707 :mochidef:`isUndefinedOrNull(obj[, ...])`:
708
709     Returns ``true`` if all arguments are undefined or ``null``
710
711     *Availability*:
712         Available in MochiKit 1.3.1+
713
714
715 :mochidef:`itemgetter(name)`:
716
717     Returns a ``function(obj)`` that returns ``obj[name]``
718
719     *Availability*:
720         Available in MochiKit 1.3.1+
721
722
723 :mochidef:`items(obj)`:
724
725     Return an ``Array`` of ``[propertyName, propertyValue]`` pairs for
726     the given ``obj`` (in the order determined by ``for propName in
727     obj``).
728
729     *Availability*:
730         Available in MochiKit 1.3.1+
731
732
733 :mochidef:`keyComparator(key[, ...])`:
734
735     A comparator factory that compares ``a[key]`` with ``b[key]``.
736     e.g.::
737
738         var lst = ["a", "bbb", "cc"];
739         lst.sort(keyComparator("length"));
740         assert( lst.toString() == "a,cc,bbb" );
741
742     *Availability*:
743         Available in MochiKit 1.3.1+
744
745
746 :mochidef:`keys(obj)`:
747
748     Return an ``Array`` of the property names of an object (in the
749     order determined by ``for propName in obj``).
750
751     *Availability*:
752         Available in MochiKit 1.3.1+
753
754
755 :mochidef:`listMax(lst)`:
756
757     Return the largest element of an ``Array``-like object, as
758     determined by :mochiref:`compare`. This is a special form of
759     :mochiref:`listMinMax`, specifically
760     :mochiref:`partial(listMinMax, 1)`.
761
762     *Availability*:
763         Available in MochiKit 1.3.1+
764
765
766 :mochidef:`listMin(lst)`:
767
768     Return the smallest element of an ``Array``-like object, as
769     determined by :mochiref:`compare`. This is a special form of
770     :mochiref:`listMinMax`, specifically
771     :mochiref:`partial(listMinMax, -1)`.
772
773     *Availability*:
774         Available in MochiKit 1.3.1+
775
776
777 :mochidef:`listMinMax(which, lst)`:
778
779     If ``which == -1`` then it will return the smallest element of the
780     ``Array``-like ``lst``. This is also available as
781     :mochiref:`listMin(lst)`.
782
783     If ``which == 1`` then it will return the largest element of the
784     ``Array``-like ``lst``. This is also available as
785     :mochiref:`listMax(list)`.
786
787     *Availability*:
788         Available in MochiKit 1.3.1+
789
790
791 :mochidef:`map(fn, lst[, ...])`:
792
793     Return a new array composed of the results of ``fn(x)`` for every
794     ``x`` in ``lst``.
795
796     If ``fn`` is ``null``, and only one sequence argument is given the
797     identity function is used.
798
799         :mochiref:`map(null, lst)` -> ``lst.slice()``;
800
801     If ``fn`` is not ``null`` and more than one sequence argument is
802     given, then one element from each sequence is used to build the
803     argument list for ``fn``.
804
805         :mochiref:`map(fn, p, q, ...)`
806             ->  ``[fn(p[0], q[0], ..), fn(p[1], q[1], ...), ...]``
807     
808     If ``fn`` is ``null``, and more than one sequence is given as
809     arguments, then the ``Array`` function is used, making it
810     equivalent to :mochiref:`MochiKit.Iter.zip`.
811
812         :mochiref:`map(null, p, q, ...)`
813             -> :mochiref:`MochiKit.Iter.zip(p, q, ...)`
814             -> ``[[p0, q0, ...], [p1, q1, ...], ...];``
815
816     *Availability*:
817         Available in MochiKit 1.3.1+
818
819
820 :mochidef:`mean(lst[, ...])`:
821
822     Returns the arithmetic mean (average) of the argument list, or an array.
823     This function applies :mochiref:`flattenArguments()` to the argument list.
824
825     *Availability*:
826         Available in MochiKit 1.4+
827
828
829 :mochidef:`median(lst[, ...])`:
830
831     Returns the median of the argument list, or an array. This function
832     applies :mochiref:`flattenArguments()` to the argument list.
833
834     *Availability*:
835         Available in MochiKit 1.4+
836
837
838 :mochidef:`merge(obj[, ...])`:
839
840     Create a new instance of ``Object`` that contains every property
841     from all given objects. If a property is defined on more than one
842     of the objects, the last property is used.
843
844     This is a special form of :mochiref:`update(self, obj[, ...])`,
845     specifically, it is defined as :mochiref:`partial(update, null)`.
846
847     *Availability*:
848         Available in MochiKit 1.3.1+
849
850
851 :mochidef:`method(self, func, ...)`:
852
853     Alternate form of :mochiref:`bind` that takes the object before
854     the function. These two calls are equivalent::
855
856         bind("method", myobject)
857         method(myobject, "method")
858
859     *Availability*:
860         Available in MochiKit 1.3.1+
861
862
863 :mochidef:`methodcaller(name[, args...])`:
864
865     Return a new function that calls a method on its argument,
866     for example::
867
868         lst = map(methodcaller("toLowerCase"), ["THIS", "is", "LoWeRCaSe"]);
869         assert( lst.join(" ") == "this is lowercase" );
870
871     *Availability*:
872         Available in MochiKit 1.4+
873
874
875 :mochidef:`nameFunctions(namespace)`:
876
877     Given a ``namespace`` (object or function) with a ``NAME``
878     property, find all methods in it and give them nice ``NAME``
879     properties too (for use with :mochiref:`repr`). e.g.::
880
881         namespace = {
882             NAME: "Awesome",
883             Dude: function () {}
884         }
885         nameFunctions(namespace);
886         assert( namespace.Dude.NAME == 'Awesome.Dude' );
887
888     *Availability*:
889         Available in MochiKit 1.3.1+
890
891
892 :mochidef:`noop()`:
893
894     A function that performs no operation. Use this where you would
895     otherwise use ``(function () {})`` in order to avoid Internet
896     Explorer cyclic garbage leakage.
897
898     *Availability*:
899         Available in MochiKit 1.4
900
901
902 :mochidef:`objEqual(a, b)`:
903
904     Return ``true`` if ``compare(a, b) == 0``
905
906     *Availability*:
907         Available in MochiKit 1.3.1+
908
909
910 :mochidef:`nodeWalk(node, visitor)`:
911
912     Non-recursive generic node walking function (e.g. for a DOM).
913
914     The walk order for nodeWalk is breadth first, meaning that all
915     siblings will be visited before any children.
916
917     ``node``:
918         The initial node to be searched.
919
920     ``visitor``:
921         The visitor function, will be called as ``visitor(node)``, and
922         should return an ``Array``-like of nodes to be searched next
923         (e.g. ``node.childNodes``).  Leaf nodes may return ``null`` or
924         ``undefined``.
925
926     *Availability*:
927         Available in MochiKit 1.3.1+
928
929
930 :mochidef:`objMax(obj[, ...])`:
931
932     Return the maximum object according to :mochiref:`compare` out of
933     the given arguments. This is similar to :mochiref:`listMax`,
934     except is uses the arguments instead of a given ``Array``-like.
935
936     *Availability*:
937         Available in MochiKit 1.3.1+
938
939
940 :mochidef:`objMin(obj[, ...])`:
941
942     Return the minimum object according to :mochiref:`compare` out of
943     the given arguments. This is similar to :mochiref:`listMin`,
944     except it uses the arguments instead of a given ``Array``-like.
945
946     *Availability*:
947         Available in MochiKit 1.3.1+
948
949
950 :mochidef:`operator`:
951
952     A table of JavaScript's operators for usage with :mochiref:`map`,
953     :mochiref:`filter`, etc.
954
955
956     Unary Logic Operators:
957
958         +--------------------+--------------------------+-------------------+
959         | Operator           | Implementation           | Description       |
960         +====================+==========================+===================+
961         | ``truth(a)``       | ``!!a``                  | Logical truth     |
962         +--------------------+--------------------------+-------------------+
963         | ``lognot(a)``      | ``!a``                   | Logical not       |
964         +--------------------+--------------------------+-------------------+
965         | ``identity(a)``    | ``a``                    | Logical identity  |
966         +--------------------+--------------------------+-------------------+
967
968
969
970     Unary Math Operators:
971
972         +--------------------+--------------------------+---------------+
973         | Operator           | Implementation           | Description   |
974         +====================+==========================+===============+
975         | ``not(a)``         | ``~a``                   | Bitwise not   |
976         +--------------------+--------------------------+---------------+
977         | ``neg(a)``         | ``-a``                   | Negation      |
978         +--------------------+--------------------------+---------------+
979
980
981
982     Binary Operators:
983
984         +-------------------+-------------------+-------------------------------+
985         | Operator          | Implementation    | Description                   |
986         +===================+===================+===============================+
987         | ``add(a, b)``     | ``a + b``         | Addition                      |
988         +-------------------+-------------------+-------------------------------+
989         | ``sub(a, b)``     | ``a - b``         | Subtraction                   |
990         +-------------------+-------------------+-------------------------------+
991         | ``div(a, b)``     | ``a / b``         | Division                      |
992         +-------------------+-------------------+-------------------------------+
993         | ``mod(a, b)``     | ``a % b``         | Modulus                       |
994         +-------------------+-------------------+-------------------------------+
995         | ``mul(a, b)``     | ``a * b``         | Multiplication                |
996         +-------------------+-------------------+-------------------------------+
997         | ``and(a, b)``     | ``a & b``         | Bitwise and                   |
998         +-------------------+-------------------+-------------------------------+
999         | ``or(a, b)``      | ``a | b``         | Bitwise or                    |
1000         +-------------------+-------------------+-------------------------------+
1001         | ``xor(a, b)``     | ``a ^ b``         | Bitwise exclusive or          |
1002         +-------------------+-------------------+-------------------------------+
1003         | ``lshift(a, b)``  | ``a << b``        | Bitwise left shift            |
1004         +-------------------+-------------------+-------------------------------+
1005         | ``rshift(a, b)``  | ``a >> b``        | Bitwise signed right shift    |
1006         +-------------------+-------------------+-------------------------------+
1007         | ``zrshift(a, b)`` | ``a >>> b``       | Bitwise unsigned right shift  |
1008         +-------------------+-------------------+-------------------------------+
1009
1010
1011
1012     Built-in Comparators:
1013
1014         +---------------+-------------------+---------------------------+
1015         | Operator      | Implementation    | Description               |
1016         +===============+===================+===========================+
1017         | ``eq(a, b)``  | ``a == b``        | Equals                    |
1018         +---------------+-------------------+---------------------------+
1019         | ``ne(a, b)``  | ``a != b``        | Not equals                |
1020         +---------------+-------------------+---------------------------+
1021         | ``gt(a, b)``  | ``a > b``         | Greater than              |
1022         +---------------+-------------------+---------------------------+
1023         | ``ge(a, b)``  | ``a >= b``        | Greater than or equal to  |
1024         +---------------+-------------------+---------------------------+
1025         | ``lt(a, b)``  | ``a < b``         | Less than                 |
1026         +---------------+-------------------+---------------------------+
1027         | ``le(a, b)``  | ``a <= b``        | Less than or equal to     |
1028         +---------------+-------------------+---------------------------+
1029
1030
1031
1032     Strict Built-in Comparators:
1033
1034         +---------------+-------------------+---------------------------+
1035         | Operator      | Implementation    | Description               |
1036         +===============+===================+===========================+
1037         | ``seq(a, b)`` | ``a === b``       | Strict equals             |
1038         +---------------+-------------------+---------------------------+
1039         | ``sne(a, b)`` | ``a !== b``       | Strict not equals         |
1040         +---------------+-------------------+---------------------------+
1041
1042
1043
1044     Extended Comparators (uses :mochiref:`compare`):
1045
1046         +---------------+---------------------------+---------------------------+
1047         | Operator      | Implementation            | Description               |
1048         +===============+===========================+===========================+
1049         | ``ceq(a, b)`` | ``compare(a, b) == 0``    | Equals                    |
1050         +---------------+---------------------------+---------------------------+
1051         | ``cne(a, b)`` | ``compare(a, b) != 0``    | Not equals                |
1052         +---------------+---------------------------+---------------------------+
1053         | ``cgt(a, b)`` | ``compare(a, b) == 1``    | Greater than              |
1054         +---------------+---------------------------+---------------------------+
1055         | ``cge(a, b)`` | ``compare(a, b) != -1``   | Greater than or equal to  |
1056         +---------------+---------------------------+---------------------------+
1057         | ``clt(a, b)`` | ``compare(a, b) == -1``   | Less than                 |
1058         +---------------+---------------------------+---------------------------+
1059         | ``cle(a, b)`` | ``compare(a, b) != 1``    | Less than or equal to     |
1060         +---------------+---------------------------+---------------------------+
1061
1062
1063
1064     Binary Logical Operators:
1065
1066         +-----------------------+-------------------+---------------------------+
1067         | Operator              | Implementation    | Description               |
1068         +=======================+===================+===========================+
1069         | ``logand(a, b)``      | ``a && b``        | Logical and               |
1070         +-----------------------+-------------------+---------------------------+
1071         | ``logor(a, b)``       | ``a || b``        | Logical or                |
1072         +-----------------------+-------------------+---------------------------+
1073         | ``contains(a, b)``    | ``b in a``        | Has property (note order) |
1074         +-----------------------+-------------------+---------------------------+
1075
1076     *Availability*:
1077         Available in MochiKit 1.3.1+
1078
1079
1080 :mochidef:`parseQueryString(encodedString[, useArrays=false])`:
1081
1082     Parse a name=value pair URL query string into an object with a
1083     property for each pair. e.g.::
1084
1085         var args = parseQueryString("foo=value%20one&bar=two");
1086         assert( args.foo == "value one" && args.bar == "two" );
1087
1088     If you expect that the query string will reuse the same name, then
1089     give ``true`` as a second argument, which will use arrays to store
1090     the values. e.g.::
1091
1092         var args = parseQueryString("foo=one&foo=two", true);
1093         assert( args.foo[0] == "one" && args.foo[1] == "two" );
1094
1095     *Availability*:
1096         Available in MochiKit 1.3.1+
1097
1098
1099 :mochidef:`partial(func, arg[, ...])`:
1100
1101     Return a partially applied function, e.g.::
1102
1103         addNumbers = function (a, b) {
1104             return a + b;
1105         }
1106
1107         addOne = partial(addNumbers, 1);
1108
1109         assert(addOne(2) == 3);
1110
1111     :mochiref:`partial` is a special form of :mochiref:`bind` that
1112     does not alter the bound ``self`` (if any). It is equivalent to
1113     calling::
1114
1115         bind(func, undefined, arg[, ...]);
1116
1117     See the documentation for :mochiref:`bind` for more details about
1118     this facility.
1119
1120     This could be used to implement, but is NOT currying.
1121
1122     *Availability*:
1123         Available in MochiKit 1.3.1+
1124
1125
1126 :mochidef:`queryString(names, values)`:
1127
1128     Creates a URL query string from a pair of ``Array``-like objects
1129     representing ``names`` and ``values``. Each name=value pair will
1130     be URL encoded by :mochiref:`urlEncode`. name=value pairs with a
1131     value of ``undefined`` or ``null`` will be skipped. e.g.::
1132
1133         var keys = ["foo", "bar"];
1134         var values = ["value one", "two"];
1135         assert( queryString(keys, values) == "foo=value%20one&bar=two" );
1136
1137     Alternate form 1:
1138         :mochiref:`queryString(domElement)`
1139
1140     If :mochiref:`MochiKit.DOM` is loaded, one argument is given, and
1141     that argument is either a string or has a ``nodeType`` property
1142     greater than zero, then ``names`` and ``values`` will be the
1143     result of :mochiref:`MochiKit.DOM.formContents(domElement)`.
1144
1145     Alternate form 2:
1146         :mochiref:`queryString({name: value, ...})`
1147
1148     Note that when using the alternate form, the order of the
1149     name=value pairs in the resultant query string is dependent on how
1150     the particular JavaScript implementation handles ``for (..in..)``
1151     property enumeration.
1152
1153     When using the second alternate form, name=value pairs with
1154     ``typeof(value) == "function"`` are ignored. This is a workaround
1155     for the case where a poorly designed library has modified
1156     ``Object.prototype`` and inserted "convenience functions".
1157
1158     Values that are Array-like will be expanded as if they were multiply
1159     defined HTML elements. For example::
1160
1161         assert( queryString({a: [1,2]}) === "a=1&a=2" );
1162     
1163     Alternate form 2 (MochiKit 1.4+):
1164         :mochiref:`queryString([names, values])`
1165
1166     This form behaves identically to :mochiref:`queryString(names, values)`,
1167     except it takes both arguments as a single Array. This mirrors the
1168     return value of :mochiref:`MochiKit.DOM.formContents`.
1169
1170     *Availability*:
1171         Available in MochiKit 1.3.1+
1172
1173
1174 :mochidef:`registerComparator(name, check, comparator[, override])`:
1175
1176     Register a comparator for use with :mochiref:`compare`.
1177
1178     ``name``:
1179         unique identifier describing the comparator.
1180
1181     ``check``:
1182         ``function(a, b)`` that returns ``true`` if ``a`` and ``b``
1183         can be compared with ``comparator``.
1184
1185     ``comparator``:
1186         ``function(a, b)`` that returns:
1187
1188         +-------+-----------+
1189         | Value | Condition |
1190         +-------+-----------+
1191         | 0     | a == b    |
1192         +-------+-----------+
1193         | 1     | a > b     |
1194         +-------+-----------+
1195         | -1    | a < b     |
1196         +-------+-----------+
1197
1198         ``comparator`` is guaranteed to only be called if ``check(a,
1199         b)`` returns a ``true`` value.
1200
1201     ``override``:
1202         if ``true``, then this will be made the highest precedence
1203         comparator.  Otherwise, the lowest.
1204
1205     *Availability*:
1206         Available in MochiKit 1.3.1+
1207
1208
1209 :mochidef:`registerJSON(name, check, simplifier[, override])`:
1210
1211     Register a simplifier function for use with
1212     :mochiref:`serializeJSON`.
1213
1214     ``name``:
1215         unique identifier describing the serialization.
1216
1217     ``check``:
1218         ``function(obj)`` that returns ``true`` if ``obj`` can
1219         can be simplified for serialization by ``simplifier``.
1220
1221     ``simplifier``:
1222         ``function(obj)`` that returns a simpler object that can be
1223         further serialized by :mochiref:`serializeJSON`. For example,
1224         you could simplify ``Date``-like objects to ISO 8601 timestamp
1225         strings with the following simplifier::
1226
1227             var simplifyDateAsISO = function (obj) {
1228                 return toISOTimestamp(obj, true);
1229             };
1230             registerJSON("DateLike", isDateLike, simplifyDateAsISO);
1231
1232         ``simplifier`` is guaranteed to only be called if
1233         ``check(obj)`` returns a ``true`` value.
1234
1235     ``override``:
1236         if ``true``, then this will be made the highest precedence
1237         serialization. Otherwise, the lowest.
1238
1239     *Availability*:
1240         Available in MochiKit 1.3.1+
1241
1242
1243 :mochidef:`registerRepr(name, check, wrap[, override])`:
1244
1245     Register a programmer representation function.  :mochiref:`repr`
1246     functions should take one argument and return a string
1247     representation of it suitable for developers, primarily used when
1248     debugging.
1249
1250     If ``override`` is given, it is used as the highest priority repr,
1251     otherwise it will be used as the lowest.
1252
1253     *Availability*:
1254         Available in MochiKit 1.3.1+
1255
1256
1257 :mochidef:`repr(obj)`:
1258
1259     Return a programmer representation for ``obj``. See the
1260     `Programmer Representation`_ overview for more information about
1261     this function.
1262
1263     *Availability*:
1264         Available in MochiKit 1.3.1+
1265
1266
1267 :mochidef:`reverseKeyComparator(key)`:
1268
1269     A comparator factory that compares ``a[key]`` with ``b[key]`` in
1270     reverse.  e.g.::
1271
1272         var lst = ["a", "bbb", "cc"];
1273         lst.sort(reverseKeyComparator("length"));
1274         assert(lst.toString() == "bbb,cc,a");
1275
1276     *Availability*:
1277         Available in MochiKit 1.3.1+
1278
1279
1280 :mochidef:`serializeJSON(anObject)`:
1281
1282     Serialize ``anObject`` in the JSON [1]_ format, see `JSON
1283     Serialization`_ for the coercion rules. For unserializable objects
1284     (functions that do not have an adapter, ``__json__`` method, or
1285     ``json`` method), this will return ``undefined``.
1286
1287     For those familiar with Python, JSON is similar in scope to
1288     pickle, but it can not handle recursive object graphs.
1289
1290     *Availability*:
1291         Available in MochiKit 1.3.1+
1292
1293
1294 :mochidef:`setdefault(self, obj[, ...])`:
1295
1296     Mutate ``self`` by adding all properties from other object(s) that
1297     it does not already have set.
1298
1299     If ``self`` is ``null``, a new ``Object`` instance will be created
1300     and returned.
1301
1302     This mutates *and returns* ``self``, be warned.
1303
1304     *Availability*:
1305         Available in MochiKit 1.3.1+
1306
1307
1308 :mochidef:`typeMatcher(typ[, ...])`:
1309
1310     Given a set of types (as string arguments), returns a
1311     ``function(obj[, ...])`` that will return ``true`` if the types of
1312     the given arguments are all members of that set.
1313
1314     *Availability*:
1315         Available in MochiKit 1.3.1+
1316
1317
1318 :mochidef:`update(self, obj[, ...])`:
1319
1320     Mutate ``self`` by replacing its key:value pairs with those from
1321     other object(s). Key:value pairs from later objects will overwrite
1322     those from earlier objects.
1323
1324     If ``self`` is ``null``, a new ``Object`` instance will be created
1325     and returned.
1326
1327     This mutates *and returns* ``self``, be warned.
1328
1329     A version of this function that creates a new object is available
1330     as :mochiref:`merge(a, b[, ...])`
1331
1332     *Availability*:
1333         Available in MochiKit 1.3.1+
1334
1335
1336 :mochidef:`updatetree(self, obj[, ...])`:
1337
1338     Mutate ``self`` by replacing its key:value pairs with those from
1339     other object(s). If a given key has an object value in both
1340     ``self`` and ``obj``, then this function will be called
1341     recursively, updating instead of replacing that object.
1342
1343     If ``self`` is ``null``, a new ``Object`` instance will be created
1344     and returned.
1345
1346     This mutates *and returns* ``self``, be warned.
1347
1348     *Availability*:
1349         Available in MochiKit 1.3.1+
1350
1351
1352 :mochidef:`urlEncode(unencoded)`:
1353
1354     Converts ``unencoded`` into a URL-encoded string. In this
1355     implementation, spaces are converted to %20 instead of "+". e.g.::
1356
1357         assert( URLencode("1+2=2") == "1%2B2%3D2");
1358
1359     *Availability*:
1360         Available in MochiKit 1.3.1+
1361
1362
1363 :mochidef:`values(obj)`:
1364
1365     Return an ``Array`` of the property values of an object (in the
1366     order determined by ``for propName in obj``).
1367
1368     *Availability*:
1369         Available in MochiKit 1.4+
1370
1371
1372 :mochidef:`xfilter(fn, obj[, ...])`:
1373
1374     Returns a new ``Array`` composed of the arguments where
1375     ``fn(obj)`` returns a true value.
1376
1377     If ``fn`` is ``null``, ``operator.truth`` will be used.
1378
1379     *Availability*:
1380         Available in MochiKit 1.3.1+
1381
1382
1383 :mochidef:`xmap(fn, obj[, ...)`:
1384
1385     Return a new ``Array`` composed of ``fn(obj)`` for every ``obj``
1386     given as an argument.
1387
1388     If ``fn`` is ``null``, ``operator.identity`` is used.
1389
1390     *Availability*:
1391         Available in MochiKit 1.3.1+
1392
1393
1394 See Also
1395 ========
1396
1397 .. [1] JSON, JavaScript Object Notation: http://json.org/
1398 .. [2] Python's itertools
1399        module: http://docs.python.org/lib/module-itertools.html
1400
1401 Authors
1402 =======
1403
1404 - Bob Ippolito <bob@redivi.com>
1405
1406
1407 Copyright
1408 =========
1409
1410 Copyright 2005 Bob Ippolito <bob@redivi.com>. This program is
1411 dual-licensed free software; you can redistribute it and/or modify it
1412 under the terms of the `MIT License`_ or the `Academic Free License
1413 v2.1`_.
1414
1415 .. _`MIT License`: http://www.opensource.org/licenses/mit-license.php
1416 .. _`Academic Free License v2.1`: http://www.opensource.org/licenses/afl-2.1.php