An alternative quasi-literal strawman

Mike Samuel mikesamuel at gmail.com
Thu Dec 31 09:27:42 PST 2009


2009/12/31 Ash Berlin <ash_js at firemirror.com>:
>
> On 31 Dec 2009, at 06:12, Mike Samuel wrote:
>
>> I received some convincing arguments that the original quasi proposal
>> fell short as a DSL scheme.  Whether a full-fledged DSL scheme is
>> desired or not, I don't know, but I read up on scheme macros and put
>> together an alternative semantics that I hope gets the strengths in
>> flexibility and performance of scheme macros while preserving the
>> encapsulation and security goals of SES, and having a syntax that
>> should be familiar to PHP and perl users.
>>
>> It is a significantly more complex proposal so I broke the semantics
>> into three sections: free variable analysis, alpha-renaming, and
>> hygienic macros, and put together a draft implementation of each.
>>
>> The alternative proposal is at
>> http://wiki.ecmascript.org/doku.php?id=strawman:quasis-alt and that
>> page links to the two supporting documents.  At the top of each are
>> links to source code and tests.
>>
>> Even if the extra complexity is prohibitive, hopefully this
>> demonstrates that the original proposal can be extended in the future
>> should DSL support in ecmascript become a desideratum.
>>
>> cheers,
>> mike
>
> The DSL syntax  shown in the motivation is decidedly odd and un-javascripty (even for a DSL). Is that just an example of whats possible, or indicative of what is required? Picking one thing at random: the |${}| is that just to avoid parsing the contents of the block in the macro/quasi? And i guess to show delayed exec.

The requirement for a DSL syntax imposed by this scheme are:
- it is possible to identify substitution expressions within the DSL statically.


> What's with |(0, eval)('hygienicMacro')| for in all the examples? It just serves to confuse me

That's explained in semantics:

8.  (0, eval)(”hygienicMacro”): Create a CallExpression whose
MemberExpression is (6) and whose Arguments are (7). This will invoke
the eval function to bind hygienicMacro in the global scope anytime
eval(...) would function as the eval operator. IMPORTANT: If eval is
not the builtin, then this may not function properly, but in that
case, the expression constructed in (10) would not invoke the eval
operator, so hygienicMacro is not required to ensure isolation.

Basically, the double use of eval ensures that either
(1) `eval` is not the eval operator in which case hygienicMacro is not
required to ensure the security properties, OR
(2) the eval function provides a reliable path to hygienicMacro so
that it can guard against malicious inputs reaching the eval operator.


> Why does hygeienicMacro need the qfnName? Wouldn't that be qfn.name if it matters? If not then perhaps move it to the last argument, as I don't think it would be used all that often.

qfn.name would not be the correct way to reach qfn in the following example

var a = function b(...) { ... }

// In a scope far far away
a`...`

> (Just as an aside at this point, you have #Substitutions and a few others which don' link anywhere on this page)

Ah.  Thanks.  That's because I cut out the syntax which has not
changed from the original proposal.  Will fix.


> 'Quasis maintain isolation' - doens't this just make it behave like a function with different syntax than a macro? Oh no i just read it wrong, and somehow from the ten steps got the impression that it could access variables from the scope where the macro substitution occurs. Hmm wonder why..

Sorry if this was confusing.  The entire bullet point is
    Quasis maintain isolation : Only references specified in
    substitutions can reach outside the scope accessible to the quasi function.

What I was trying to convey is that the macro author has complete
control over what symbols the quasi can muck with, and does so by
specifying information they would have to even if the quasi scheme did
not have to have the security properties it does.


> deterministicAfterFirstCallJsonToJsonFn is just a form of memoization isn't it? Also |var args = Array.slice(arguments)| (yes, that is using the array generics on the ctor. I like them)

Exactly.  It just happens to be a form of memoization which should
allow interpreters to make new control structures specified via quasis
perform really well without losing the dynamism in ES code loading.

> In general as a language user rather than as somehow who might have to implement this (which I'm not, I am *just* a user) I think I like the more power this gives me, but its a very limited form of DSLs with slightly peculiar syntax. In short I like the idea, but I don't get this proposal :(

> Even more generally I'm still unconvinced by the escaping rules.

What would you like to see to move discussion of syntax forward?
I could start compiling example use cases and show how they would look
using the specified syntax and variants, but without interesting
alternative syntaxes, I'm not sure how helpful that would be.

> -ash
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>


More information about the es-discuss mailing list