On Tue, Feb 16, 2016 at 9:38 AM, Garrett Smith <dhtmlkitc...@gmail.com> wrote: > On Mon, Feb 15, 2016 at 1:13 AM, Coroutines <corouti...@gmail.com> wrote: > >> This post might be overly wordy. Sorry. It relates to the >> functionality provided by the `with` keyword and why I think it's >> important in the future. >> >> I am currently rewriting a templating module that I think is very >> useful for it's ability to turn a function in coffeescript syntax into >> a sort of DSL - something that looks like this: >> >> template = -> >> doctype 5 >> html -> >> head -> >> title @title >> body -> >> div id: 'content', -> >> if @posts? >> for p in @posts >> div class: 'post', -> >> p p.name >> div p.comment >> form method: 'post', -> >> ul -> >> li -> input name: 'name' >> li -> textarea name: 'comment' >> li -> input type: 'submit' >> >> For those not familiar with Coffeescript, "= ->" creates a function >> with no arguments, the indented sub-block is the body of the function. >> >> All of these things essentially compile into nested functions like: >> html(head(title(this.title)) >> >> (not an exact translation) >> >> Anyway, this library/module called (ck) exploits the little-used >> `with` keyword. It creates a function like this: >> >> function (scope, template) { with (scope) { template(); } } >> >> So the template is just a series of functions that lookup within >> `scope` for a function creating HTML. The problem is this module >> (imo) wastefully creates a lot of closures to create the HTML tags. >> > > I think you'll have a lot better luck starting out like I did: Learn > HTML first. You're working on some complicated stuff there, and for > me, I always try to get simple to work. Simple and working is good! > > You cannot have too solid of a grasp of HTML. Ditto for CSS. > > When it comes to javascript, context and scope can be tricky and > confusing for those coming from other languages. > > Thank you,
With respect - for this particular project I wanted to gut it to be as small as possible. What fascinates me about this module (ck) is how it abuses lookups in the scope chain to form HTML - while similarly looking great as valid Coffeescript. It has been my aim to remove as many responsibilities from it to instead put on the user or on other libraries. I do not want this module to worry about if <lol> is a valid HTML tag - just that the tag itself is well-formed (disregarding self-closing tags). I have already removed auto-indenting the resulting HTML as that can be done with js-beautify in another part of the overall pipeline (a gulp task for instance). The frustration I'm having is that `with` is no longer in style. I can get it to work with a Proxy (as Andreas corrected for me) - but it still requires I keep a list of valid HTML tags - so the has() handler in the proxy will work correctly. The problem is the scope lookup I need is in the wrong order - I wanted it to look at the existing scope and if a function doesn't exist, then resolve it through the Proxy so it creates the closure which creates the HTML tag. Currently this is reversed - which is why I have to keep the list of HTML tags. If I could reverse it I could remove more code. I don't have the needed control over scope I want - I can't resolve through the existing scope and fallback on a Proxy to generate a function/closure as needed. That is my problem with scope. Anyway, I understand if this is not the right place to talk about my specific project problem - but I thought it would be important to start a discussion about scope. I'm lobbying to have this control someday. Again, with WebAssembly in the future to support the scoping rules of other languages that will compile to the WebAssembly AST it will have to be loosely based on what Javascript supports. Here's the non-working version of what I had in mind (forgive the coffeescript) - but it somewhat illustrates what I'm talking about with "with + Proxy" (dynamic?) scoping: require('assert').ok Proxy?, 'no Proxy!!' require 'harmony-reflect' html = '' isString = (x) -> typeof x is 'string' or x instanceof String env = new Proxy {}, # this is a problem - I can't make use of existing functions # "behind" the Proxy if I always return true (from the existing, non-with scope) has: -> true get: (_, prop) -> (attrs, body) -> makeTag prop, attrs, body makeTag = (tag, attrs, body) -> unless typeof attrs is 'object' body = attrs attrs = {} attrs = ("#{attr}=\"#{value}\"" for own attr, value of attrs when value? and value isnt false).join ' ' # intended coercion here if attrs attrs = " #{attrs}" html += "<#{tag}#{attrs}>" # if there is no body, this is a self-closing tag (the user knows HTML not us) return unless body? if isString html += body else runWithinTagger body html += "</#{tag}>" # f() creates an <f> - this is flawed. in the ck module a Function is created from the edited toString() of f: # https://github.com/blitmap/ck/blob/master/lib/ck.coffee#L82-L84 `function runWithinTagger(f) { with (env) { f(); } }` f = -> h1 'Hello', 'this header here' p 'this is a paragraph' runWithinTagger f console.log html _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss