User-reifiable References
Claus Reinke wrote:
Thoughts?
As noted, we're moving away from References in the language. Macros are out there but the better way: you want to abstract over syntax, not runtime lvalue semantics.
As noted, we're moving away from References in the language.
l-values as function parameters are still going to be useful, for abstractions involving assignment operators.
Macros are out there but the better way: you want to abstract over syntax, not runtime lvalue semantics.
Useful macros are going to have a lot of expressive power over syntax, which tends to go along with decreased ability to reason about code. Functions are not as simple in JS as they are in other functional languages, but it still seems advisable to do as much as possible without macros.
I've updated my infix operator gist, to include initial support for 'ref', and also to wrap operator arguments - so both assignment operators and short-circuiting operators are now possible. Unwrapping of arguments and reference objects is done explicitly in operator definitions.
https://gist.github.com/3157251
See example 6 (strawman:default_operator, .??, .??=) in
https://gist.github.com/3157251#file_sample.js
The expected output (for those who don't want to clone and run the gist) can be seen in the comments of
https://gist.github.com/3157251#file_infix.js
In this gist, the desugaring of 'ref' and infix operators corresponds to hard-coded macros, doing the things with syntax that cannot be done with functions alone. The rest is handled by function definitions and conventional code.
Until macros make it into the language, this is an easy way to play with suggested operators (factoring out the parser hacking, some of which is still TODO).
Example extract:
Operator['.??='] =
function(lhs_,rhs_){
var lhs = lhs_();
var value = lhs.deref;
return (lhs.deref = ( value!==undefined ? value : rhs_()))
};
(function(){
var x;
console.log('6(assignment x):', ref x .??= 1);
console.log('6(assignment x):', x );
}());
Output extract:
6(assignment x): 1
6(assignment x): 1
Btw, I've also added (example 7) a simple version of Allen's new strawman:define_properties_operator, '.:=' .
Claus
Context:
Problem:
I keep running into this limitation, and examples like the '??=' in strawman:default_operator show I'm not the only one. So I have looked for a workaround, and I think I've found a useful option, on which I'd like your input.
Suggestion:
The starting point is the representation of References as an object with a single getter/setter pair, so that reifying, eg.,
gives (*)
This gives us an object that can be passed around, and can be reflected back to an r-value or l-value, depending on context:
Of course, (*) is a handful, and gets worse when one tries to share computation within 'base' and 'prop' between getter and setter. No one is going to write this out by hand for every reified Reference, or read code with lots of these without struggling to see the simple intention behind the code.
The suggestion is to introduce a keyword phrase, so that
desugars to
(and similarly for the other valid Reference phrases)
Then, a user-defined assignment operator, eg. matching the strawman:default_operator's '??=', would be possible as (ignoring infix syntax and multiple evaluation of 'r' here, as those are separate issues)
The readability improvement is so extreme that I doubt anyone is using this pattern without syntax support?-)
Since reification of References happens only on request, this has no performance implications for normal operation.
Since reification is a simple desugaring, implementing and backtranslation into ES5 are not difficult.
Two questions come to mind:
1 where, exactly, does 'ref <Reference>' fit into the syntax and post-syntax checks for valid References?
2 'ref' is not reserved, what about existing code using 'ref'?
As to 2, if 'ref' is in common use as a variable (a github search [1] turns up some examples), I wouldn't mind having to import 'ref' from some standard module before using it as a keyword, or having local 'ref' declarations disable 'ref' as a keyword. That way, users can migrate away from 'ref' as a variable, but don't have to do so unless they want to use 'ref' as a keyword.
would allow progress with control abstractions in JS, without having to invoke or wait for the full complexity of macros for JS.
Without something like user-reifiable References, even simple abstractions like assignment operators remain beyond the reach of JS library coders.
Thoughts? Claus clausreinke.github.com
[1] search?q=ref&type=Code&language=JavaScript