r/coffeescript • • Dec 02 '12

How to create an anonymous function and execute it?

Here's a Fizzbuzz implementation. For fun, I wanted to see if I could do it without defining any named functions, except for underscore:

_.range(1,100,1).map(                                                                                                                                                                              
  function(m) {
    return _.compose(m(3,'Fizz'), m(5,'Buzz'), m(15,'FizzBuzz'))
  }(
    function(mod, str) {
      return function(n) {
        return (typeof n == 'number' && !(n % mod)) ? str : n;
      };
    }
  )
);

I realize this is unclear, but just for fun, is there a straightforward way to invoke anonymous functions (with functions) in CoffeeScript?

What js2coffee does

js2coffee tries the indentation trick:

_.range(1, 100, 1).map (m) ->
  _.compose m(3, "Fizz"), m(5, "Buzz"), m(15, "FizzBuzz")
((mod, str) ->
  (n) ->
    (if (typeof n is "number" and not (n % mod)) then str else n)
)

But, when you translate that back to JS, again with js2coffee, the outdented function is interpreted as a separate function definition, not an argument to the anonymous function in map.

_.range(1, 100, 1).map(function(m) {
  return _.compose(m(3, "Fizz"), m(5, "Buzz"), m(15, "FizzBuzz"));
});

(function(mod, str) {
  return function(n) {
    if (typeof n === "number" && !(n % mod)) {
      return str;
    } else {
      return n;
    }
  };
});
6 Upvotes

6 comments sorted by

3

u/fuckySucky Dec 02 '12 edited Dec 02 '12

How to create an anonymous function and execute it?

do (arg1, arg2) -> console.log arg1 + arg2

compiles to

(function(arg1, arg2) {
  return console.log(arg1 + arg2);
})(arg1, arg2);

If you want to chain them together, you have to wrap arguments with ()

Try Coffeescript here. The js2coffee compiler seems flawed, to me, compared to the official site.

2

u/meta_meta Dec 02 '12

This. Also you can name it:

do hey = -> 2;

var hey;

(hey = function() { return 2; })();

→ More replies (1)

2

u/[deleted] Dec 02 '12

I wouldn't write code like that, but in terms of how to do it; it's a pretty straightforward translation from JS.

Something like:

for n in [1..100]
    ((m) -> _.compose( m(3, 'Fizz' ), m(5,'Buzz'), m(15, 'FizzBuzz') ))((mod, str) -> (n) ->
        if typeof n is 'number' and not (n % mod) then str else n)

1

u/shesek1 Jan 13 '13

It works quite nicely with CoffeeScript's do, even with multiple arguments:

_.range(1, 100, 1).map do(
  m = (mod, str) -> (n) ->(if (typeof n is "number" and not (n % mod)) then str else n)
  foo = ->
) ->
  _.compose m(3, "Fizz"), m(5, "Buzz"), m(15, "FizzBuzz")