String interpolation. Fairy tale come true

Published on August 31, 2013

String interpolation. Fairy tale come true

    Formulation of the problem


    Quite by accident, I turned from a pythonist into a JS developer, and an overwhelming load of things that did not exist in JS fell upon my fragile children's psyche. For example, there is no convenient formatting of strings. On python you can write:
    'hello, %(thing)s' % {'thing': 'world'}
    

    Or like this:
    'hello, {thing}'.format(**{'thing': 'world'})
    



    The closest analogue in JS is concatenation ( operator +), which scales very poorly with increasing line length, and even looks ugly to the limit:
    '<div class="input-append"><input type="text" name="username" '+
    'id="signup_username" placeholder="'+placeholder+'"><input '+
    'type="hidden" name="password" value="'+generated+'"><button '+
    ...
    

    If possible, I would like to avoid this.

    Jeremy Ashkenas, when developing CoffeeScript, also drew attention to this feature of JS, and by chance a dialect of PHP:
    "hello, #{document.cookie}"
    

    This is also bad, besides it works only for string literals, it will not work to load a template from a file.

    I like Ruby-like syntax in this thing, but I don’t like everything else, especially the execution of arbitrary code inside a string. Thus, the statement of the problem:
    - write a function
    - which substitutes variables into a string
    - loaded from a file
    - not PHP

    Search for a solution


    Usually in such cases, ready-made libraries are used, moreover, in NPM, according to the word template, there are more than two thousand packages.

    In fact, mustache or lodash (underscore.js) works just fine, but ... very slowly: 10-20 μs per lookup. Not the limit of dreams in any case, especially when the "advanced" functionality like loops and filters is absolutely not needed.

    But concatenation, although it looks scary, like an animal grin of collectivism, still works 10-30 times faster. Thus, we add to the statement of the problem:
    - translates into concatenation
    - and works very fast

    Now, according to this specification, you can reinvent the wheel. Because why not.

    What happened


    I got this kind of thing: Ruby-like simple string interpolation (GitHub)

    It has 9 lines of code, and it performs one million three hundred thousand substitutions per second (about 0.77 μs per substitution) on the same machine where mustache does 130 thousand , and lodash / underscore 45 thousand substitutions per second.
    var hello = fmt('hello, #{thing}')
    hello({thing: 'world'})
    // -> hello, world
    

    Conclusion: due to the rejection of the complex functions of the template engine (loops, conditional expressions), acceleration of 10-30 times was achieved compared to popular libraries without resorting to the execution of arbitrary code in the template.

    Rssi.js can be installed from npm with an obvious command npm install rssi, Bower ( bower install rssi) is also supported ; on the client side, you can use AMD (RequireJS), but you can not use it.



    Thanks for reading this not very coherent text! Write patches, gentlemen, good ones, and see you soon.