Last active
November 10, 2018 15:10
-
-
Save ndbroadbent/708bc33db76dce32f541e7f4abdb43ac to your computer and use it in GitHub Desktop.
Idea for a Babel/Webpack plugin that makes JavaScript more like Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 }); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// * 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); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// * 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); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// * 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()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 })); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.