Upgrade to Pro — share decks privately, control downloads, hide ads and more …

You Won’t Believe This One Weird Way to Rewrite Closures

You Won’t Believe This One Weird Way to Rewrite Closures

Closures are undoubtedly the most powerful feature JavaScript inherited from its Lisp forbears. But would JS be so powerful… without them?

We’ll reimplement closures entirely from scratch without the convenience of native local variables or function parameters. Entirely in JavaScript. Using prototypal inheritance, some clever hat-tips from graphics programming, amnesic function bodies, and this one weird global variable.

https://github.com/nybblr/closures

Jonathan Lee Martin

May 27, 2015
Tweet

More Decks by Jonathan Lee Martin

Other Decks in Programming

Transcript

  1. You won’t believe
    this one weird way
    to rewrite closures.
    TL;DR waste of nanoseconds
    { };

    View Slide

  2. This talk on #JS
    will restore your
    faith in closures!
    A.K.A.
    { };

    View Slide

  3. One weird Nerd.
    Jonathan Martin
    We Teach. We Develop. We Write.

    View Slide

  4. closure() ===
    scope + statements;

    View Slide

  5. They survived w/o
    closures, and the
    results are shocking!

    View Slide

  6. FORTRAN 77: 501 FORMAT(3I5)

    602 FORMAT("NORMAL END")

    603 FORMAT("INPUT ERROR OR ZERO VALUE ERROR")

    INTEGER A,B,C

    10 READ(5,501,END=50,ERR=90) A,B,C

    IF(A=0 .OR. B=0 .OR. C=0) GO TO 90

    S = (A + B + C) / 2.0

    AREA = SQRT( S * (S - A) * (S - B) * (S - C))
    WRITE(6,601) A,B,C,AREA

    GO TO 10

    50 WRITE(6,602)

    STOP

    90 WRITE(6,603)

    STOP

    END
    {

    View Slide

  7. x86 Assembly: section .data

    str: db 'Hello world!', 0Ah

    str_len: equ $ - str


    section .text

    global _start


    _start:

    mov eax, 4

    mov ebx, 1


    mov ecx, str

    mov edx, str_len

    int 80h


    mov eax, 1

    mov ebx, 0

    int 80h
    {

    View Slide

  8. Ruby: class Dog

    def bark

    puts "Bowowowow!"

    end

    end


    Cat = Class.new

    Cat.send(:define_method,

    :bark, Dog.instance_method(:bark))

    # => TypeError: bind argument
    must be a subclass of Dog


    Cat.new.bark

    # => NoMethodError: undefined method
    `bark' for Cat:Class
    {

    View Slide

  9. Convert a method to a lambda in Ruby:
    lambda(&method(:events_path))
    OR JUST USE JAVASCRIPT.
    @deisinger


    View Slide

  10. This stay-at-home
    developer built his
    own closures!

    View Slide

  11. Do these 5 things
    every line.
    function params, var, variable assignment
    function memoization
    one global variable
    amnesic function bodies
    shortcut local variables





    View Slide

  12. Use this code, never
    run slow #JS again!
    var local = 'Variable';
    console.log(local);
    var func = function(arg1, arg2, arg3) {

    // ...

    };

    View Slide

  13. Use this code, never
    run slow #JS again!
    s('local', 'Variable');
    console.log(g('local'));
    f('func', ['arg1', 'arg2', 'arg3'], function(){

    // ...

    });



    View Slide

  14. Your code can look…
    var outer = function (x, y) {

    var inner = function (x, z) {

    return [x, y, z];

    };

    return inner;

    };


    console.log(outer(1,2)(3,4));

    View Slide

  15. …like this!
    f('outer', ['x', 'y'], function () {

    f('inner', ['x', 'z'], function () {

    return [g('x'), g('y'), g('z')];

    });

    return g('inner');

    });


    console.log(g('outer')(1,2)(3,4));

    View Slide

  16. These 70 lines will
    blow your mind. Ruby
    developers HATE IT!

    View Slide

  17. He wrote a transpiler.
    What happens next
    will make you weep.
    github.com/nybblr/closures

    View Slide

  18. View Slide

  19. Prototype-destroying
    developer is the most
    satisfying thing you’ll
    see today!
    The Future™
    { };

    View Slide

  20. Thanks!
    @nybblr

    View Slide