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' }


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!
  • \$\begingroup\$ May we assume the input is a syntactically valid arrow function and nothing else? \$\endgroup\$ Commented Apr 21, 2017 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\$ Commented Apr 21, 2017 at 16:27
  • \$\begingroup\$ @ETHproductions Don't you just love those automagic semicolons! \$\endgroup\$
    – Neil
    Commented Apr 21, 2017 at 16:29
  • \$\begingroup\$ Will we get nested ES6 functions? \$\endgroup\$
    – user41805
    Commented Apr 21, 2017 at 17:00
  • \$\begingroup\$ Can we assume that the input will only contain a single =>? \$\endgroup\$ Commented Apr 21, 2017 at 17:50

3 Answers 3


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.)

  • \$\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
    Commented Apr 21, 2017 at 19:17
  • \$\begingroup\$ I think \(?(.*?)\)?\s*=> might save you 3 bytes. \$\endgroup\$
    – Neil
    Commented Apr 21, 2017 at 20:20

Retina, 86 80 79 bytes


>{return $1}

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!

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

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


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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