@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
{
  today: {
      temperatures: [19, 18.5, 18, 18.5, 17, /* ... */]
  },
  future: [
    { high: 21, low: 13, chanceOfSnow: 0.05 },
    { high: 21, low: 14, chanceOfSnow: 0.03 },
    { high: 21, low: 16, chanceOfSnow: 0.04 },
    { high: 19, low: 16, chanceOfSnow: 0.04 },
    /* ... */
  ]
}
@phenomnominal 2020
<h2>Weather result</h2>
<h3>
    <p>Arendelle, Norway</p>
    <p>Sunday 19:00</p>
    <span>Sunny</span>
</h3>
<img alt="Sunny" src="//arendelle.info/weather/64/sunny.png">
<h3>
  19<button aria-label="°Celsius">°C</button>
</h3>
<p>Precipitation: <span>0%</span></p>
<p>Humidity: <span>75%</span></p>
<p>Wind: <span>1 m/s</span></p>
<ol>
    <li>
        <p aria-label="Sunday">Sun</p>
        <img alt="Clear" src="//arendelle.info/weather/48/sunny.png">
        <span>21</span>°
        <span>13</span>°
    </li>
    <!-- ... -->
</ol>@phenomnominal 2020
const response = await fetch('https://arendelle.info/weather.json');
const data = await response.json();
// {
//   today: {
//       temperatures: [19, 18.5, 18, 18.5, 17, /* ... */]
//   },
//   future: [
//     { high: 21, low: 13, chanceOfSnow: 0.05 },
//     { high: 21, low: 14, chanceOfSnow: 0.03 },
//     { high: 21, low: 16, chanceOfSnow: 0.04 },
//     { high: 19, low: 16, chanceOfSnow: 0.04 },
//     /* ... */
//   ]
// }
const SATURDAY = 6;
const today = new Date().getDay();
const chanceOfSnowOnSaturday = data.future[SATURDAY - today].chanceOfSnow * 100;h1 {
  // ...
}
h3 > p {
  // ... 
}
button:active,
button:hover {
  // ...
}
li:first-child {
  // ...
}@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
fs.watch
fs.link
fs.copyFile
fs.chmod
fs.access
@phenomnominal 2020
fs.writeFile
fs.mkdir
fs.readFile
@phenomnominal 2020
// snowflake.txt
                                ()
                                /\
                               //\\
                              <<  >>
                          ()   \\//   ()
                ()._____   /\   \\   /\   _____.()
                   \.--.\ //\\ //\\ //\\ /.--./
                    \\__\\/__\//__\//__\\/__//
                     '--/\\--//\--//\--/\\--'
                        \\\\///\\//\\\////
                    ()-= >>\\< <\\> >\\<< =-()
                        ////\\\//\\///\\\\
                     .--\\/--\//--/\\--/\\--.
                    //""/\\""//\""//\""//\""\\
                   /'--'/ \\// \\// \\// \'--'\
                 ()`"""`   \/   //   \/   `"""`()
                          ()   //\\   ()
                              <<  >>
                               \\//
                                \/
                                ()@phenomnominal 2020
import { promises as fs } from 'fs';
async function readSnowflake () {
  return fs.readFile('./snowflake.txt', 'utf8');
}
console.log(await readSnowflake());@phenomnominal 2020
Weaseltown:dywbabt queenelsa$ node index.js
                              ()
                              /\
                             //\\
                            <<  >>
                        ()   \\//   ()
              ()._____   /\   \\   /\   _____.()
                 \.--.\ //\\ //\\ //\\ /.--./
                  \\__\\/__\//__\//__\\/__//
                   '--/\\--//\--//\--/\\--'
                      \\\\///\\//\\\////
                  ()-= >>\\< <\\> >\\<< =-()
                      ////\\\//\\///\\\\
                   .--\\/--\//--/\\--/\\--.
                  //""/\\""//\""//\""//\""\\
                 /'--'/ \\// \\// \\// \'--'\
               ()`"""`   \/   //   \/   `"""`()
                        ()   //\\   ()
                            <<  >>
                             \\//
                              \/
                              ()@phenomnominal 2020
import { promises as fs } from 'fs';
async function readSnowflake () {
  return fs.readFile('./snowflake.txt', 'utf8');
}
async function saveSnowflake (data: string) {
  await fs.mkdir('./saved/snowflakes', { recursive: true });
  await fs.writeFile('./saved/snowflakes/snowflake.txt', data);
}
const snowflake = await readSnowflake();
await saveSnowflake(snowflake);
@phenomnominal 2020
path.resolve
path.parse
@phenomnominal 2020
import * as path from 'path';
const relativeToThisFile = path.resolve(__dirname, './snowflake.txt');
const parsed = path.parse(relativeToThisFile);
// interface ParsedPath {
//   root: string;
//   dir: string;
//   base: string;
//   ext: string;
//   name: string;
// }import { promises as fs } from 'fs';
import * as path from 'path';
export async function readSnowflake () {
  const relativePath = path.resolve(__dirname, './snowflake.txt');
  const relativePath = path.resolve(process.cwd(), './snowflake.txt');
  return fs.readFile(relativePath, 'utf8');
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { promises as fs } from 'fs';
import * as path from 'path';
async function readSnowflakes () {
  const snowflakePath = path.resolve(__dirname, './snowflakes.json');
  const json = await fs.readFile(snowflakePath, 'utf8');
  return JSON.parse(json);
}
console.log(await readSnowflakes());@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
const SNOW_CODE_PATH = path.resolve(
  __dirname,
  './elsa',
  process.env.SECRET_SNOW_FILE
);@phenomnominal 2020
const SNOW_CODE_PATH = path.resolve(
  __dirname,
  './elsa',
  process.env.SECRET_SNOW_FILE
);@phenomnominal 2020
@phenomnominal 2020
import { promises as fs } from 'fs';
export async function readSnowCode () {
  return fs.readFile(SNOW_CODE_PATH, 'utf8');
}
console.log(await readSnowCode());@phenomnominal 2020
Weaseltown:dywbabt queenelsa$ node secret_snow_code_file_dont_touch.js 
import { doPhysics, WaterMolecule } from './physics';
requestAnimationFrame(() => {
  for (let lat = -90; lat < 90; lat += 0.000000001) {
    for (let long = -180; long < 180; long += 0.000000001) {
      for (let alt = 0; alt < 80000; alt += 0.000000001) {
        const updated = update(lat, long, alt);
        render(updated);
      }
    }
  }
});
function update (lat, long, alt) {
  const molecule = global.waterMolecules[lat][long][alt];
  return doPhysics(molecule);
}
@phenomnominal 2020
@phenomnominal 2020
// kristoff.js
import { promises as fs } from 'fs';
import { readSnowCode } from './read-snow-code';
const code = await readSnowCode();
  
code += `; console.log('Kristoff is the best!');`
  
await fs.writeFile('./kristoffs-cool-new-snow-code.js', code);
@phenomnominal 2020
// olaf.js
import { promises as fs } from 'fs';
const code = await fs.readFile('./kristoffs-cool-new-snow-code.js');
code = code.replace(/Kristoff/, 'Olaf');
await fs.writeFile('./kristoffs-cool-new-snow-code.js', code);@phenomnominal 2020
// sven.js
import { promises as fs } from 'fs';
const code = await fs.readFile('./kristoffs-cool-new-snow-code.js');
code = code.replace(/Olaf/, 'Sven');
code = code.replace(/best!/, 'bestest!!!!');
code = code.replace(/console.log\((.*)\)/, 'console.log($1.toUpperCase())');
await fs.writeFile('./kristoffs-cool-new-snow-code.js', code);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import * as path from 'path';
const parsed = path.parse('/some/path/to/some/file.txt');
// interface ParsedPath {
//   root: string;
//   dir: string;
//   base: string;
//   ext: string;
//   name: string;
// }
console.log(parsed.ext);// read-snowflakes.js
import { promises as fs } from 'fs';
import * as path from 'path';
export async function readSnowflakes () {
  const snowflakePath = path.resolve(__dirname, './snowflakes.json');
  const data = await fs.readFile(snowflakePath, 'utf8');
  const snowflakes = JSON.parse(data);
  
  console.log(snowFlakes[0].velocity.x)
}@phenomnominal 2020
import { parseScript } from 'esprima';
import { readSnowCode } from './read-snow-code';
const code = await readSnowCode();
const ast = parseScript(code);
console.log(ast);@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
data structure made up of vertices and edges without any cycles
the way in which linguistic elements are put together
Not associated with any specific instance
@phenomnominal 2020
@phenomnominal 2020
An Abstract Syntax Tree is a data structure that represents the structure of code, but without any actual syntax.
let it = go('let it go');it = go 'let it go'it <= go ['let it go']'let it go' -> go => it@phenomnominal 2020
{
  type: 'Program',
  body: [{
    type: 'VariableDeclaration',
    declarations: [{
      type: 'VariableDeclarator',
      id: {
        type: 'Identifier',
        name: 'it'
      },
      init: {
        type: 'CallExpression',
        callee: {
          type: 'Identifier',
          name: 'go'
        },
        arguments: [{
          type: Literal',
          value: 'let it go'
        }]
      }
    }],
    kind: 'let'
  }]
}@phenomnominal 2020
            'let it go' Literal
Identifier
CallExpression
Identifier
VariableDeclarator
VariableDeclaration
         go         go('let it go')    it    it = go('let it go')let it = go('let it go');@phenomnominal 2020
Identifier
IfStatement
ImportDeclaration
Literal
CallExpression
ClassDeclaration
FunctionDeclaration
VariableDeclaration
ExpressionStatement
AwaitExpression
ForStatement
WhileStatement
DoWhileStatement
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
const code = `let it = go('let it go');`
const ast = parseScript(code);
const arg = ast.body[0].declarations[0].init.arguments[0];
console.log(arg);@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
{
  "kind": "document",
  "children": [{
    "kind": "h2",
    "children": [{
      "kind": "text",
      "text": "Weather result"
    }]
  }, {
    "kind": "h3",
    "children": [{
      "kind": "p",
      "children": [{
        "kind": "text",
        "text": "Arendelle, Norway"
      }]
    }, {
      "kind": "p",
      "children": [{
        "kind": "text",
        "text": "Sunday 19:00"
      }]
    }, {
      "kind": "span",
      "children": [{
        "kind": "text",
        "text": "Sunny"
      }]
    }]
  }, {
    "kind": "img",
    "alt": "Sunny",
    "src": "//arendelle.info/weather/64/sunny.png"
  }]
}@phenomnominal 2020
@phenomnominal 2020
{
  "kind": "document",
  "children": [{
    "kind": "h2",
    "children": [{
      "kind": "text",
      "text": "Weather result"
    }]
  }, {
    "kind": "h3",
    "children": [{
      "kind": "p",
      "children": [{
        "kind": "text",
        "text": "Arendelle, Norway"
      }]
    }, {
      "kind": "p",
      "children": [{
        "kind": "text",
        "text": "Sunday 19:00"
      }]
    }, {
      "kind": "span",
      "children": [{
        "kind": "text",
        "text": "Sunny"
      }]
    }]
  }, {
    "kind": "img",
    "alt": "Sunny",
    "src": "//arendelle.info/weather/64/sunny.png"
  }]
}@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parse } from './parse-html';
const HTML = `
    <h3>...</h3>
    ...
`;
const dom = parse(HTML);
const node = dom.children[1].children[3].children[0];
console.log(node);
@phenomnominal 2020
const dom = parse(HTML);
const node = $(dom, 'body > h3 > span:last-child');
console.log(node);@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
const code = `let it = go('let it go');`;
const ast = parseScript(code);
const query = 'CallExpression:has(Identifier[name="go"]) > Literal';
const nodes = query(ast, query);
console.log(nodes);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
const code = `Object.freeze()`;
const ast = parseScript(code);
const query = 
  'CallExpression:has(MemberExpression[object.name="Object"][property.name="freeze"])';
const nodes = query(ast, query);
if (nodes.length !== 0) {
  throw new Error(`Don't use Object.freeze!`);
}@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { doPhysics } from './physics';
requestAnimationFrame(() => {
  for (let lat = -90; lat < 90; lat += 0.000000001) {
    for (let long = -180; long < 180; long += 0.000000001) {
      for (let alt = 0; alt < 80000; alt += 0.000000001) {
        const updated = update(lat, long, alt);
        render(updated);
      }
    }
  }
});
function update (lat, long, alt) {
  const molecule = global.waterMolecules[lat][long][alt];
  return doPhysics(molecule);
}
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
import { readSnowCode } from './read-snow-code';
const PHYSICS_CALL_QUERY = 'CallExpression:has(Identifier[name="doPhysics"])';
const snowCode = await readSnowCode();
const ast = parseScript(snowCode);
const doPhysicsCalls = query(ast, PHYSICS_CALL_QUERY);
doPhysicsCalls.forEach(doPhysicsCall => {
  doPhysicsCall.expression.name = 'doMagic';
  const doMagicCall = doPhysicsCall;
  doMagicCall.arguments = [{
    type: 'CallExpression',
    callee: {
      type: 'Identifier',
      name: 'doPhysics'
    },
    arguments: [{
      type: 'Identifier',
      name: 'molecule'
    }]
  }];
});@phenomnominal 2020
import { doPhysics, WaterMolecule } from './physics';
requestAnimationFrame(() => {
  for (let lat = -90; lat < 90; lat += 0.000000001) {
    for (let long = -180; long < 180; long += 0.000000001) {
      for (let alt = 0; alt < 80000; alt += 0.000000001) {
        const updated = update(lat, long, alt);
        render(updated);
      }
    }
  }
});
function update (lat, long, alt) {
  const molecule = global.waterMolecules[lat][long][alt];
  return doMagic(doPhysics(molecule));
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
// function doMagic (molecule) {
//   molecule.setTemperature(-10);
//   return molecule;
// }
function createMagicFunction (ast) {
  return {
    type: "FunctionDeclaration",
    id: {
      type: "Identifier",
      name: "doMagic"
    },
    params: [{
      type: "Identifier",
      name: "molecule",
    }],
    body: {
      type: "BlockStatement",
      body: [{
        type: "ExpressionStatement",
        expression: {
          type: "CallExpression",
          callee: {
            type: "MemberExpression",
            object: {
              type: "Identifier",
              name: "molecule"
            },
            property: {
              type: "Identifier",
              name: "setTemperature",
            },
          },
          arguments: [{
            type: "UnaryExpression",
            operator: "-",
            argument: {
              type: "Literal",
              value: 10
            }
          }]
      }
    }, {
    type: "ReturnStatement",
      argument: {
        type: "Identifier",
        name: "molecule"
      }
    }]
  }
}@phenomnominal 2020
@phenomnominal 2020
const h2 = document.createElement('h2');
h2.innerText = 'Weather result';
const h3 = document.createElement('h3');
const p1 = document.createElement('p');
p1.innerText = 'Arendelle, Norway';
const p2 = document.createElement('p');
p2.innerText = 'Sunday 19:00';
const span = document.createElement('span');
span.innerText = 'Sunny';
h3.appendChild(p1);
h3.appendChild(p2);
h3.appendChild(span);
const img = document.createElement('img');
img.setAttribute('alt', 'Sunny');
img.setAttribute('src', '//arendelle.info/weather/64/sunny.png');@phenomnominal 2020
const template = `
  <h2>Weather result</h2>
  <h3>
    <p>{{ location }}</p>
    <p>{{ time }}</p>
  <span>{{ weather }}</span>
  </h3>
  <img
    alt="{{ weather }}"
    src="//arendelle.info/weather/64/{{ weather }}.png">
`;
render(template, {
  location: 'Arendelle, Norway',
  time: 'Sunday 19:00',
  weather: 'Sunny'
});
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { query } from 'esquery';
import { compile } from 'estemplate';
const DO_MAGIC_TEMPLATE = tstemplate.compile(`
  function doMagic (molecule) {
    molecule.setTemperature(-<%= temperature %>);
    return molecule;
  }
`);
function createMagicFunction () {
  const doMagicAst = DO_MAGIC_TEMPLATE({
      temperature: createNumericLiteral('10')
  });
  const [doMagicFunction] = query(doMagicAst, 'FunctionDeclaration');
  return doMagicFunction;
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
import { generate } from 'escodegen';
const code = `let it = go('let it go');`;
const ast = parseScript(code);
const query = 'CallExpression:has(Identifier[name="go"]) > Literal';
const [literal] = query(ast, query);
literal.value = 'LET IT GO!';
const updatedCode = generate(ast);
console.log(updatedCode); // let it = go('LET IT GO!');
@phenomnominal 2020
@phenomnominal 2020
import { readSnowCode } from './read-snow-code';
const snowCode = await readSnowCode();
import { parseScript } from 'esprima';
const ast = parseScript(snowCode);
import { query } from 'esquery';
const doPhysicsCalls = query(ast, 
  'CallExpression:has(Identifier[name="doPhysics"])'
);
import { template } from 'estemplate';
doPhysicsCalls.forEach(oldDoPhysicsCall => {
  oldDoPhysicsCall.expression.name = 'doMagic';
  const doMagicCall = oldDoPhysicsCall;
  const newDoPhysicsAst = template('doPhysics(molecule)');
  const [newDoPhysicsCall] = query(newDoPhysicsAst, 'CallExpression');
  doMagicCall.arguments = [newDoPhysicsCall];
});
  
const doMagicAst = template(`
  function doMagic (molecule) {
    molecule.setTemperature(-<%= temperature %>);
    return molecule;
  }
`, {
    temperature: createNumericLiteral('10')
});
const [doMagicFunction] = query(doMagicAst, 'FunctionDeclaration');
ast.statements.push(doMagicFunction);
import { generate } from 'escodegen';
const updatedSnowCode = generate(ast);
import { writeSnowCode } from './write-snow-code';
await writeSnowCode(updatedSnowCode);@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020