8
\$\begingroup\$

The ECMAScript 6 standard added many new features to the JavaScript language, including a new arrow function notation.

Your task is to write a basic ES6-to-ES5 transpiler. Given only an ES6 arrow function as input, output its ES5-compatible counterpart.

It's ! May the shortest program in bytes win!


The Basics

An arrow function looks like this:

(a, b, c) => { return a + b - c }

And its equivalent ES5 function expression looks like this:

function(a, b, c) { return a + b - c }

In general, you can copy the body of the function (everything between the curly braces) verbatim.


Implicit Return Statement

Instead of a body with curly braces, a single expression can be used; the result of this expression is then returned.

(a, b, c) => a + b - c

function(a, b, c) { return a + b - c }

Another example:

(a, b, c) => (a + 1, b - 2 * c / 3)

function(a, b, c) { return (a + 1, b - 2 * c / 3) }

Again, you may simply copy the expression verbatim - BUT take care that you do not output a line break between it and the return keyword to avoid automatic semicolon insertion!


One Argument

Parentheses are optional if one argument is provided.

foo => { return foo + 'bar' }

function(foo) { return foo + 'bar' }

Whitespace

Finally, you must be able to account for any number of whitespace characters (space, tab, newline) before or after parentheses, variables, commas, curly braces, and the arrow*.

 ( o   ,  O
     , _    )=>{

    return                                     "Please don't write code like this."
}

Whether or not you choose to preserve whitespace in the output is up to you. Keep 'em, remove 'em, or add your own - just make sure it's valid code!

*It's technically illegal for an arrow to come immediately after a line break, but I doubt this fact would help you. :)


A quick way to validate your output:

Enter var foo = <your output>; foo() into your browser console. If it doesn't complain, you're probably on the right track.


More rules for the wizards:

  • Input is a syntactically valid ES6 arrow function.
  • Assume the body of the function is ES5-compatible (and doesn't reference this, super, arguments, etc). This also means that the function will never contain another arrow function (but you may not assume that "=>" will never occur within the body).
  • Variable names will only consist of basic Latin letters, $ and _.
  • You need not transpile ES6 features that aren't listed above (default parameters, rest operator, destructuring, etc).
  • The space after a return statement is optional if followed by (, [, or {.
  • It isn't strictly necessary to match my test cases exactly - you can modify the code as much as you need if it'll help lower your byte count. Really, as long as you produce a syntactically valid, functionally equivalent ES5 function expression, you're golden!
\$\endgroup\$
  • \$\begingroup\$ May we assume the input is a syntactically valid arrow function and nothing else? \$\endgroup\$ – ETHproductions Apr 21 '17 at 16:18
  • \$\begingroup\$ An edge case would be a =>\na, where function(a){ return\na } would actually return undefined no matter what the value of a is. Do we need to handle this? \$\endgroup\$ – ETHproductions Apr 21 '17 at 16:27
  • \$\begingroup\$ @ETHproductions Don't you just love those automagic semicolons! \$\endgroup\$ – Neil Apr 21 '17 at 16:29
  • \$\begingroup\$ Will we get nested ES6 functions? \$\endgroup\$ – Cows quack Apr 21 '17 at 17:00
  • \$\begingroup\$ Can we assume that the input will only contain a single =>? \$\endgroup\$ – math junkie Apr 21 '17 at 17:50
5
\$\begingroup\$

JavaScript (ES6), 123 110 100 97 bytes

Saved 3 bytes thanks to @Neil

s=>s.replace(/\(?(.*?)\)?\s*=>\s*([^]*)/,(_,a,b)=>`function(${a})${b[0]=='{'?b:`{return ${b}}`}`)

Assumes the input is a syntactically valid arrow function and nothing else. Correctly handles the case a =>\na, though not handling is not any shorter as far as I can tell.

Output when the code is run through itself:

function(s){return s.replace(/\(?(.*?)\)?\s*=>\s*([^]*)/,(_,a,b)=>`function(${a})${b[0]=='{'?b:`{return ${b}}`}`)}

I can save 9 bytes with a possibly invalid format:

s=>s.replace(/\(?(.*?)\)?\s*=>\s*({?)([^]*?)}?$/,(_,a,z,b)=>Function(a,z?b:'return '+b))

Output for itself:

function anonymous(s) {
return s.replace(/\(?([^=)]*)\)?\s*=>\s*({?)([^]*?)}?$/,(_,a,z,b)=>Function(a,z?b:'return '+b))
}

(Specifically, the function anonymous is what I'm worried about.)

\$\endgroup\$
  • \$\begingroup\$ Shame that your function itself contains a further arrow function so that when run through itself it's not actually fully transpiled. \$\endgroup\$ – Neil Apr 21 '17 at 19:17
  • \$\begingroup\$ I think \(?(.*?)\)?\s*=> might save you 3 bytes. \$\endgroup\$ – Neil Apr 21 '17 at 20:20
2
\$\begingroup\$

Retina, 86 80 79 bytes

^([^(]*?)=
($1)=
s(`\s*$

>\s*(.*[^}])$
>{return $1}
)`(.*?)=>(.*)
function$1$2

Try it Online!

Saved a byte thanks to Neil

Saved 6 bytes with help from ETHproductions

Edit: Fixed for possibility of newlines in function body.

75 byte solution assuming the input won't contain §: Try it Online!

\$\endgroup\$
  • 1
    \$\begingroup\$ You can use a pilcrow instead of \n to save a byte. \$\endgroup\$ – Neil Apr 21 '17 at 19:00
  • 1
    \$\begingroup\$ This seems to remove line breaks within the function body, which may alter the functionality. \$\endgroup\$ – darrylyeo Apr 21 '17 at 20:19
  • \$\begingroup\$ I think \s includes , so line three can be \s*$ to save 4 bytes. \$\endgroup\$ – ETHproductions Apr 23 '17 at 13:58
  • \$\begingroup\$ @ETHproductions It seems \s only matches when the s configuration option is added. Nevertheless, it saved me some bytes \$\endgroup\$ – math junkie Apr 23 '17 at 14:32
0
\$\begingroup\$

PHP, 112 bytes

preg_match("#\(??(.*)\)?=>(\{?)(.*$)#U",$argn,$m);echo"function($m[1])",trim($b=$m[3])[0]=="{"?$b:"{return $b}";

takes input from STDIN; run with -R

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.