Skip to content

Instantly share code, notes, and snippets.

@ndbroadbent
Last active November 10, 2018 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ndbroadbent/708bc33db76dce32f541e7f4abdb43ac to your computer and use it in GitHub Desktop.
Save ndbroadbent/708bc33db76dce32f541e7f4abdb43ac to your computer and use it in GitHub Desktop.
Idea for a Babel/Webpack plugin that makes JavaScript more like Ruby
// Assume const by default, instead of global var
// Source
// ---------------------------------------
varA = 1
const varB = 2
let varC = 2
// Transpiled
// ---------------------------------------
const varA = 1;
const varB = 2;
let varC = 3;
// Same as destructuring in ES7.
// Source
// ---------------------------------------
fnA = (opts) => ({
a: opts.a + 1,
b: opts.b + 2,
c: { d: opts.c + 3 },
})
{ a, b, c: { d } } = fnA a: 1, b: 2, c: 3
// Transpiled
// ---------------------------------------
const fnA = (opts) => ({
a: opts.a + 1,
b: opts.b + 2,
c: { d: opts.c + 3 },
});
const { a, b, c: { d } } = fnA({ a: 1, b: 2, c: 3 });
// * Borrow the "end" keyword from Ruby to replace closing braces, and make opening braces implicit
// * Implicit return in functions (unless you use an explicit "void")
// * At runtime with a typeof check. At compile-time if you use a Flow or TypeScript plugin
// Source
// ---------------------------------------
fnA = function
end
fnB = function
fnA
end
function fnC
void fnB
end
// Transpiled
// ---------------------------------------
const fnA = function() {};
const fnB = function() {
return (typeof fnA === 'function' ? fnA() : fnA);
};
function fnC() {
void (typeof fnB === 'function' ? fnB() : fnB);
};
// * Borrow the "end" keyword from Ruby to replace closing braces, and make opening braces implicit
// * Implicit return in functions (unless you use an explicit "void")
// * At runtime with a typeof check. At compile-time if you use a Flow or TypeScript plugin
// Source
// ---------------------------------------
fnA = (arg) =>
a = arg + 1
console.log a
end
fnB = () =>
foo = 1
fnA foo
end
fnC = () =>
void fnB
end
// Transpiled
// ---------------------------------------
const fnA = (arg) => {
const a = arg + 1;
return console.log(a);
};
const fnB = () => {
const foo = 1;
return fnA(foo);
};
const fnC = () => {
void (typeof fnB === 'function' ? fnB() : fnB);
};
// * Optional parentheses for function calls.
// * But required for any function definitions that have 1 or more arguments.
// * Implicit function calls
// * Unless you are passing it as an argument
// Source
// ---------------------------------------
fnA = () => console.log "Hello World!"
fnA
console.log fnA
console.log(fnA)
console.log fnA()
console.log(fnA())
// Transpiled
// ---------------------------------------
const fnA = () => console.log("Hello World!");
typeof fnA === 'function' ? fnA() : fnA;
console.log(fnA);
console.log(fnA);
console.log(fnA());
console.log(fnA());
// Implicit objects in function args
// Source
// ---------------------------------------
fnA = (a, opts = {}) =>
a + opts.foo + opts.bar
end
result = fnA 1, foo: 2, bar: 3
console.log result
console.log fnA 1, foo: 2, bar: 3
// The whitespace is a little ambiguous, but it works in Ruby:
// def foo(b, c, d); b + c + d[:a]; end; puts foo 1, 2, a: 3
// Transpiled
// ---------------------------------------
const fnA = (a, opts = {}) => {
return a + opts.foo + opts.bar;
}
const result = fnA(1, { foo: 2, bar: 3 });
console.log(result);
console.log(fnA(1, { foo: 2, bar: 3 }));
@ndbroadbent
Copy link
Author

ndbroadbent commented Nov 10, 2018

This would be a superset of JS, and there would be a one-to-one mapping. This means we could have a bi-directional transpiler, so you can edit either the source or the JS, and the other file would be updated whenever you save. It would use an intermediate AST to generate both versions (source + JS). Might even be able to do this with Prettier and write a custom parser/formatter.

@ndbroadbent
Copy link
Author

ndbroadbent commented Nov 10, 2018

No idea how types would work. Would be based on TypeScript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment