Hacker News new | past | comments | ask | show | jobs | submit login

Not gonna lie, classes, destructing, TCO, and all these "engineering optimizations" are great... but what JS really, really, really needs is some sort of way to declare decorator macros. A great use case for these macros (especially in the browser) is in dealing with those god-awful deprecation warnings any given big-enough framework will eventually start spitting out after enough usage.

Right now, framework developers use console.warn which, as a function, is usually buried in the framework, and so gives stack-traces that are entirely useless to a developer using said framework (especially if the framework wraps console.warn in some way). A good clean way of declaring macros will allow JS frameworks to not be cancerous to maintain by making the stack-trace for deprecated user-code very easy to spot and correct.

And unlike features such as classes, generators, symbols, and even TCO that are reasonably achievable through clever engineering, macros flat-out have to be special-formed in. But their utility in making JS a much more maintainer-friendly language would go a long way to reducing the misery of us plebeian js users.




You mean like the ES7 decorators proposal[1], or something else?

[1] https://github.com/wycats/javascript-decorators


But decorators are just syntactic sugar around functions. You can have them now with;

    var deprecated = function(fn) {
       console.warn("Deprecated!");
       fn.apply(this, arguments);
    };
then

    var oldMethod = deprecated(function() {
    });
In ES7 you'll be able to call decorators with the new syntax:

    @deprecated
    function oldMethod {
    }
But nothing stopping you writing modular code now. The complaint about 'I have to write console.warn everywhere' seems to have an obvious answer; 'no you don't'.

As for other issues with ES6+7, the new syntax trades a few characters for a lack of clarity about what is actually happening.


Thanks for writing it out, but you've actually illustrated exactly my complaint. When you call oldMethod console.warn will spit out the line number of the wherever in your framework you have the

    var deprecated = function(fn) {
       console.warn("Deprecated!");
       fn.apply(this, arguments);
    };
declared... but you (as the user of a framework) still have no real idea where the actual function you shouldn't be calling (the fn) lives in your code (especially since the function can be anonymous)... you just know that the framework is telling you you're using a deprecated function somewhere in the code you wrote.

What I really want, and what can't be achieved with your purely in-language solution (and it really is a great solution considering the constraints), is a special form for things like @deprecated such that it straight-up can capture not only the function it's decorating, but also meta-data about the function (e.g. where it's declared, the caller / callee, etc.)


I was responding to the person responding to you mostly, but thanks for clarifying, I'd not taken your issue seriously in my reply.

Having just a deprecated macro seems very narrow and special case to me.

Something like FF's getSource would work.

    var deprecated = function(fn) {
       console.warn("Function "+fn.name+" deprecated (at "+fn.getSource()+")");
       fn.apply(this, arguments);
    };
but obv. isn't useful in real code at the moment because it is FF-only (afaik).

I'm generally quite nervous of 'special forms' in languages that don't allow you to define them yourself. Part of why scheme is so powerful is that most of it can be implemented in the same tools it gives you. I'd like to see that approach.


That's what a debugger (or a stack trace) is for. Who debugs just by line numbers anymore?




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: