Javascript data structure operations: some of the APIs are imperative, some are functional, some are mixed. Having functional equivalents to all imperative data structure operations is necessary to support expression-oriented programming over constant data structures.

"imperative" here refers to operations that are designed to be used as statements, changing inputs by side-effect, while "functional" refers to operations designed to be used as expressions, leaving their inputs unchanged. A familiar example is the Array API, e.g.:

   array.concat([1])    - returns a modified copy of array, expression

   array.push(1)        - modifies array in place, "statement"

It does seem as if older API elements tend to be imperative while newer ones tend to be functional. However, not all imperative
operations have functional counterparts yet, and with increasing
focus on constant and frozen objects, the need for functional
operations is going to increase.

In particular, I have been wondering about how freezing objects
curtails what I am able to do with them. Having worked with pure
functional language for a long time, I really like the advantages of
frozen/constant objects, both for avoiding bugs and to enable
optimizations, but I'm not used to not having a full set of operations to work with such objects:

Example 1: constant functions, prototypes and toString

   The standard API for functions requires imperative operations
   for both prototypical inheritance and for string representation.

   const C() {}
   // C.prototype.toString = function() { return 'C()' }
   // C.toString = function() { return 'C()' }

Example 2: property update

   The standard API for object property update is imperative.

   const obj = Object.freeze({ age : 1, .. });
   const older_obj = // a modified copy of obj, with age : 2??

The standard APIs for these fundamental operations are imperative
and so are not available on frozen objects (this also applies to the
record strawman, for instance).

How does one achieve the effects of these operations on frozen
objects, by creating modified copies? For an expression-oriented style of programming where no object is ever modified in place, it seems one has to use a lower level API, perhaps by calling
Object.create and Object.freeze to implement some form of
Object.clone, then mixing in the update on the clone before freezing it. Or perhaps using proxies to achieve the effect..

The situation is somewhat similar to the declarative object initializers being worked on as object literal extensions, but those don't seem to help here.

What is the best way of doing functional/declarative/expression-
oriented object modification in ES5 or ES/next? Is there really an imperative-preferred flaw in the current design?

Claus


_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to