Roman Liutikov
front-end web dev
Slides link
https://slides.com/roman01la/code-transformation-for-fun-and-profit/live
your
native
language
your
native
language
AST
AST
CODE
CODE
(Abstract Syntax Tree)
const c = a + b;
const a = 1; const b = 2; const c = a + b;
(evaluating constant expressions at compile time)
Input
const c = 3;
Output
const add = (a, b) => a + b; const c = add(1, 2);
(replaces a function call site with the body of that function)
Input
const c = 1 + 2;
Output
for (let i = 0; i < 3; i++) {
console.log(i);
}
(replaces a loop with a sequence of expressions)
Input
console.log(0);
console.log(1);
console.log(2);
Output
class Button extends Component {
render() {
const { label, onClick } = this.props;
return (
<button onClick={onClick}>
{label}
</button>
);
}
}
const Button = (props) => {
const { label, onClick } = props;
return (
<button onClick={onClick}>
{label}
</button>
);
}
[0 1 2] |> map(inc) |> filter(odd) // [1, 3]
#[1, 2, 3] > Immutable.List([1, 2, 3])
#{1, 2, 3} > Immutable.Set([1, 2, 3])
const getFileNames = (dir) => {
if (__prepack) {
return getFileNamesFrom(dir);
}
}
const files = getFileNames('./');
const files = [ "img1.png", "data.json" ];
via domain specific optimization
(macros)
(runs code in Node.js at compile-time)
const files = preval`
module.exports = getFilesFrom("./");
`;
const files = [ "img1.png", "data.json" ];
import css from "css.macro";
const styles = css`
color: black;
font-size: ${base * 2}
`;
(input)
const styles = css("css-63457", {
fontSize: base * 2
});
(output)
const Counter = ({ text }, { theme }, { val } = { val: 0 }, setState) => (
<div className={theme}>
<h1>{text}</h1>
<div>
<button onClick={() => setState({ val: val - 1 })}>-</button>
<span>{val}</span>
<button onClick={() => setState({ val: val + 1 })}>+</button>
</div>
</div>
);
By Roman Liutikov