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. ..

Hi Claus, interesting idea. Given

The idea of {x: a, y: b, ...: c} – record extension and row
capture<http://successor-ml.org/index.php?title=Functional_record_extension_and_row_capture>
–
for structuring and destructuring comes to mind, but ES objects are a
different animal compared to ML records. For example, which properties of c are
copied into the object being initialized by {x: a, y: b, ...: c}?
enumerable? own? etc.

(from <http://wiki.ecmascript.org/doku.php?id=harmony:destructuring#issues>)

you could say

   const older_obj = { age: 2, ...: obj };

But as the note says, there are a bunch of open questions that need to be
settled before this becomes a serious candidate. We should examine how this
interacts with other aspects of extended object literals.

Hi Mark,

thanks for the pointer.

Yes, there used to be a large body of literature just on the various
ways of factoring a record operations API, mostly driven by their
use for semantics of object-oriented language variations and by
their type system difficulties ('record calculi', 'semantics of
inheritance/oo', 'typing record concatenation', ..).

Record/object extension is one of the recurring ideas, and since
it is based on record/object literals + a base record/object, most
of the design choices follow from the extended object literals.

My immediate concern is simply: given the choices already made
for Javascript object operations, why don't we have a complete set
of operations for both in-place and copying updates? The current
situation at the object level is as if JS only had '+=' and '-=', but
not '+' and '-', at the level of numbers.

As for the set of operations, JS has already chosen that updating
a non-existing property extends the object, so update and extension
are mixed in one operation. There is a separate operation for removing
properties and there are tests for the existence of properties, both
locally and in the prototype chain. If there were functional equivalents
to the imperative base operations

   obj.prop = value;
   delete obj.prop;

then one could build more complex operations from there, instead
of from scratch. delete already returns the object, but assignment
returns the value, and overloading delete to produce an object copy
if the input object is frozen would be confusing, so we need new
syntax, and object extension with extended object literals could do.

Assuming that the extended object is copied as is, modified as
specifiable by the extended object literal syntax, I'd assume

   { prop : value; ...: obj }

to be a (shallow) copy of obj, identical (including prototype and
meta properties such as frozen/configurable/..) in all but prop.

If I don't want to copy prototype or meta-properties, I'd need
to use records instead of objects, or get some help from the
extended object literal syntax.

But one shouldn't try to fit everything into the object literal
syntax, either - once it is accepted that copying objects is useful,
there could be an Object.filter operation, eg, to filter out
properties based on their meta-properties (enumerable, own, ..):

   Object.filter(predicate,obj)

would return a (shallow) copy of obj with properties filtered
according to some predicate function.

To avoid an additional operator for functional delete, one might
add a delete directive to extended object literal syntax, and have

   { delete prop; ...: obj}

be a (shallow) copy of obj, identical in all but prop.

Wouldn't that be sufficient as a baseline? If not, what is missing?

Is extended object literal syntax capable of handling this slightly
extended range of use? Btw, should there be a way to un-freeze
object copies (typical application is to make a non-frozen copy
of a frozen array, update it incrementally and in-place in a loop,
then freeze the resulting array copy for further use)?

In sum, copying object modifications are useful for programmers,
and taking them into consideration might ease the constraints
for ES language design (not everything has to fit into the simple
in-place update all-permitted-or-all forbidden scheme - copying
updates offer a third option).

Claus

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<https://mail.mozilla.org/listinfo/es-discuss>




--
   Cheers,
   --MarkM




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

Reply via email to