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. 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 {
  2. 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 {
  3. 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 {
  4. Do these 5 things every line. function params, var, variable

    assignment function memoization one global variable amnesic function bodies shortcut local variables ✗ ✗ ✓ ✓ ✓
  5. Use this code, never run slow #JS again! var local

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

    console.log(g('local')); f('func', ['arg1', 'arg2', 'arg3'], function(){
 // ...
 }); ⇢ ⇢ ⇢
  7. 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));
  8. …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));