Sorry that this was unclear in the meta message. The helper function
is normative in the sense that it defines the functionality, eg in the
order of operations on a data structure. But it is not visible, not
part of the api, and a real implementation does not reserve the helper
namespace. Ditto for informative functions but their prose description
gives the implementation more room for variation. --lars
On 2/29/08, Michael O'Brien <[EMAIL PROTECTED]> wrote:
> A general spec question about helper methods and the informative namespace?
>
> My presumption that both these are not part of the normative spec.
> Implementations may choose to implement the functionality without a helper
> method and without the specific informative elements. Is this correct?
>
> If so, then reading:
>
> "The iterator protocol makes use of a helper method iterate which first
> collects the values that will be returned by the iterator methods and then
> returns an object that provides the correct next method: "
>
> really means that an implementation could use the helper method iterate as
> the RI does. If not, it must provide equivalent functionality.
>
> Am I reading the meaning of helper and informative correctly?
>
> Michael
>
>
> Lars Hansen wrote:
> I'm enclosing the draft for the Map class. Please comment.
>
> --lars
>
> ________________________________
>
> The class Map
> FILE: spec/library/Map.html
> DRAFT STATUS: DRAFT 1 - 2008-02-29
> IMPLEMENTATION STATUS: ES4 RI
> TEST CASE STATUS: Unknown
> REVIEWED AGAINST ES3: N/A
> REVIEWED AGAINST ERRATA: N/A
> REVIEWED AGAINST BASE DOC: N/A
> REVIEWED AGAINST PROPOSALS: YES
> REVIEWED AGAINST CODE: YES
> The class Map is a parameterized, dynamic, non-final, direct subclass of
> Object that provides a reliable, efficient, mutable, and iterable map from
> keys to values. Keys and values may be of arbitrary types.
> A Map is realized as a hash table. When the Map is constructed the caller
> may provide specialized functions that compare keys and compute hash values
> for keys.
> Synopsis
> The class Map provides the following interface:
> __ES4__ dynamic class Map.<K,V>
> {
> public function Map(equals: function = (function(a,b) a === b),
> hashcode: function = intrinsic::hashcode) …
>
> static meta function invoke(object: Object): Map.<EnumerableId,*> …
> static public const length = 2;
>
> intrinsic function size() : uint …
> intrinsic function get(key: K) : V …
> intrinsic function put(key:K, value:V) : void …
> intrinsic function has(key:K) : boolean …
> intrinsic function remove(key:K) : boolean …
>
> iterator function get(deep: boolean = false) :
> iterator::IteratorType.<K> …
> iterator function getKeys(deep: boolean = false) :
> iterator::IteratorType.<K> …
> iterator function getValues(deep: boolean = false) :
> iterator::IteratorType.<V> …
> iterator function getItems(deep: boolean = false) :
> iterator::IteratorType.<[K,V]> …
>
> private const equals : function = …
> private const hashcode : function = …
> private var population : uint = …
> }
> The Map prototype object provides these direct properties:
> size: function () …
> get: function (key) …
> put: function (key, value) …
> has: function (key) …
> remove: function (key) …
> Methods on the Map class object
> new Map.<K,V>( equals=…, hashcode=… )
> Description
> The Map constructor creates a new map for key type K and value type V.
> The optional equals argument is a function that compares two keys and
> returns true if they are equal and false if they are not. This function must
> implement a reflexive, transitive, and symmetric relation, and equals(k1,k2)
> must be constant for any two actual keys k1 and k2. The default value for
> equals is a function that compares the two keys using the === operator.
> The optional hashcode argument is a function that takes a key and returns a
> numeric code for it. This code may be used to find associations more quickly
> in the map. Two calls to the hashcode function on the same key value must
> return the same numeric code, and the hashcode function must always return
> the same numeric code for two objects that compare equal by the equals
> function. The default value for hashcode is the intrinsic global function
> hashcode.
> NOTE The constraint that equals and hashcode return constant values does
> not apply to key values that are not in a Map nor referenced from an
> activation of any method on Map.
> NOTE There is no requirement that the values returned from hashcode for
> two unequal keys must be different.
> Implementation
> The Map constructor initializes the Map object by saving its parameters in
> private storage and initializing the count of the number of associations in
> the table to zero.
> public function Map(equals /*: function*/ = (function (x,y) x === y),
> hashcode /*: function*/ = intrinsic::hashcode)
> : equals = equals
> , hashcode = hashcode
> , population = 0
> {
> }
> FIXME (Ticket #153) The parameters to the Map constructor should be
> constrained to be function, but not any more than that (because that would
> be bad UI for scripts). Currently the RI does not support function as a type
> annotation, so the current implementation of the constructor is
> unconstrained.
> Map( object )
> Description
> When the Map class object is called as a function, it creates a new Map
> object from EnumerableId to *, populating the new Map object with the own
> properties of object.
> Returns
> The Map class object called as a function returns a new Map object.
> Implementation
> static meta function invoke(object: Object): Map.<EnumerableId,*> {
> let d = new Map.<EnumerableId,*>;
> for (let n in object)
> if (object.intrinsic::hasOwnProperty(n))
> d.put(n, object[n]);
> return d;
> }
> FIXME (Tickets #247, #289, and e-mail discussion.) This method may
> change if we change the meaning of statics in parameterized classes: the map
> would be to the type V instead of to *.
> Methods on Map instances
> size ( )
> Returns
> The intrinsic method size returns the number of associations in the map.
> Implementation
> intrinsic function size() : uint
> population;
> get ( key )
> Returns
> The intrinsic method get returns the value associated with key, or null if
> there is no such association.
> Implementation
> intrinsic function get(key: K) : V {
> let probe = informative::find(key);
> return probe ? probe.value : null;
> }
> The informative function find searches for key in the Map and returns an
> object containing at least the properties key and value if the association
> was found, or otherwise null. (The returned object is part of the Map data
> structure, and writing to it updates the association in the Map.)
> informative function find(key: K): like { key: K, value: V } …
> put ( key, value )
> Description
> The intrinsic method put creates an association between key and value, or
> overwrites an existing association if there is one.
> Returns
> The put method returns nothing.
> Implementation
> intrinsic function put(key:K, value:V) : void {
> let probe = informative::find(key);
> if (probe)
> probe.value = value;
> else {
> ++population;
> informative::insert(key, value);
> }
> }
> The informative function insert adds a new association between key and
> value to the Map.
> informative function insert(key: K, value: V): void …
> has ( key )
> Returns
> The intrinsic method has returns true if there exists an association for
> key, or false otherwise.
> Implementation
> intrinsic function has(key:K) : boolean {
> let probe = informative::find(key);
> return probe ? true : false;
> }
> remove ( key )
> Description
> The intrinsic method remove removes any association for key.
> Returns
> The remove method returns true if there was an association for key, or false
> otherwise.
> Implementation
> intrinsic function remove(key:K) : boolean {
> let probe = informative::find(key);
> if (probe) {
> --population;
> informative::eject(probe);
> return true;
> }
> return false;
> }
> The informative function eject removes the association for key from the
> Map.
> informative function eject(box: like { key: K, value: V }): void …
> Iteration protocol on Map instances
> The iterator protocol makes use of a helper method iterate which first
> collects the values that will be returned by the iterator methods and then
> returns an object that provides the correct next method:
> helper function iterate.<T>(f: function(*,*,*):*) {
> let a = [];
> informative::allElements(function (k,v) { f(a,k,v) });
> return {
> next: let (i=0, limit=a.length)
> function () : T {
> if (i < limit)
> return a[i++];
> throw iterator::StopIteration;
> }
> };
> }
> The informative function allElements calls its function argument on every
> key/value pair in the Map:
> informative function allElements(fn: function): void …
> The iterator methods getKeys, getValues, and getItems return iterator
> objects that iterate over keys, values, and key/value pairs, respectively.
> The iterator method get iterates over keys (like getKeys).
> Implementation
> iterator function getKeys(deep: boolean = false) :
> iterator::IteratorType.<K>
> helper::iterate.<K>(function (a,k,v) { a.push(k) });
>
> iterator function getValues(deep: boolean = false) :
> iterator::IteratorType.<V>
> helper::iterate.<V>(function (a,k,v) { a.push(v) });
>
> iterator function getItems(deep: boolean = false) :
> iterator::IteratorType.<[K,V]>
> helper::iterate.<[K,V]>(function (a,k,v) { a.push([k,v]) });
>
> iterator function get(deep: boolean = false) : iterator::IteratorType.<K>
> iterator::getKeys(deep);
> Methods on the Map prototype object
> The methods on the Map prototype object are constrained to being called on
> instances of Map. They all delegate to the corresponding intrinsic method on
> their this object.
> prototype function size(this: Map.<*,*>)
> this.intrinsic::size();
>
> prototype function get(this: Map.<*,*>, key)
> this.intrinsic::get(key);
>
> prototype function put(this: Map.<*,*>, key, value)
> this.intrinsic::put(key, value);
>
> prototype function has(this: Map.<*,*>, key)
> this.intrinsic::has(key);
>
> prototype function remove(this: Map.<*,*>, key)
> this.intrinsic::remove(key);
>
> ________________________________
>
> _______________________________________________
> Es4-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es4-discuss
>
_______________________________________________
Es4-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es4-discuss