Skip to content

Instantly share code, notes, and snippets.

@kl0tl
Last active August 29, 2015 14:02
Show Gist options
  • Save kl0tl/3de5ca52e7b738d477ad to your computer and use it in GitHub Desktop.
Save kl0tl/3de5ca52e7b738d477ad to your computer and use it in GitHub Desktop.
Bound functions déclaration (aka methods)
/*
```
var foo = {
bound method() {
return this;
}
};
var method = foo.method;
method() === foo;
```
An alternative syntax allows to declare a bound function on a preexisting object
```
var foo = {};
bound foo.method() {
return this;
};
```
Unlike with Function#bind, bound functions are bound lazily upon first invocation
```
var bar = {
__proto__: foo
};
var method = bar.method;
method() === bar;
```
*/
macro function_params {
rule { ($param (,) ...) }
}
macro concise_function_expression {
rule { $params:function_params { $body ... } } => {
function $params { $body ... }
}
rule { $params:function_params => $body:expr } => {
function $params { return $body }
}
}
// cf http://stackoverflow.com/a/22414263
macro syntax2string {
rule { $syntax } => {
[makeValue(unwrapSyntax($syntax).toString(), $syntax)]
}
}
macro stringify {
case { _ ($syntax) } => {
letstx $string = syntax2string(#{$syntax});
return #{$string};
}
}
let bound = macro {
rule { $name:ident $function:concise_function_expression } => {
get $name() {
return Object.defineProperty(this, stringify($name), {
__proto__: null,
value: $function.bind(this),
writable: true,
enumerable: false,
configurable: true
}).$name;
}
}
rule { $symbol:ident (.) ... $name:ident $function:concise_function_expression } => {
Object.defineProperty($symbol (.) ..., stringify($name), {
__proto__: null,
get: function () {
return Object.defineProperty(this, stringify($name), {
__proto__: null,
value: $function.bind(this),
writable: true,
enumerable: false,
configurable: true
}).$name;
},
enumerable: true,
configurable: true
})
}
rule { $rest ... } => { bound $rest ... }
}
export bound;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment