114

Looking at this CoffeeScript tutorial : http://jashkenas.github.com/coffee-script/

I don't quite see what the Splats is for. What is this construction? Where does it come from (historically)

interstar
  • 26,048
  • 36
  • 112
  • 180
  • And as usual, you should also know how it can be implemented in vanilla Js: `arguments` + `call`: http://stackoverflow.com/questions/17380315/splat-operators-in-javascript-equivalent-to-args-and-kwargs-in-python – Ciro Santilli OurBigBook.com Oct 22 '14 at 07:22
  • 1
    I like to think of it as a parameter that gets "splatted" (like paint) into an indefinite continuum – arviman Nov 14 '14 at 11:48
  • 3
    For anyone Python-inclined: this is your `*args` in `def foo(*args):`. – maligree Mar 29 '15 at 09:10
  • 1
    Terminology note: ES6 adopted similar but prefix syntax. In ES6 receiving `, ...args` is named [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) and expanding `...args` into a function call / array / object literal is named [spread](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Spread_syntax) – Beni Cherniavsky-Paskin Aug 08 '18 at 14:10

4 Answers4

199

The term "splat operator" comes from Ruby, where the * character (sometimes called the "splat"—see the Jargon File entry) is used to indicate that an entry in an argument list should "soak up" a list of arguments.

CoffeeScript adopted Ruby-style splats very early on (see issue 16), but at Douglas Crockford's suggestion, the syntax was changed from *x to x... a couple of weeks later (see issue 45). Nevertheless, CoffeeScripters still refer to the syntax as the "splat" or "splat operator."

As to what they actually do, splats slice the arguments object in such a way that the splatted argument becomes an array of all "extra" arguments. The most trivial example is

(args...) ->

In this case, args will simply be an array copy of arguments. Splatted arguments can come either before, after, or between standard arguments:

(first, rest...) ->
(rest..., last) ->
(first, rest..., last) ->

In the first two cases, if the function receives 0-1 arguments, rest will be an empty array. In the last case, the function needs to receive more than 2 arguments for rest to be non-empty.

Since JavaScript doesn't allow multiple signatures for functions with the same name (the way C and Java do), splats are a huge time-saver for dealing with varying numbers of arguments.

Trevor Burnham
  • 76,828
  • 33
  • 160
  • 196
  • 2
    Similar to the C# [`params`](http://msdn.microsoft.com/en-us/library/w5zay9db.aspx) keyword. – ThatMatthew Sep 27 '12 at 19:17
  • When would I ever need to use this? – Jeff Scott Ward Nov 22 '13 at 17:21
  • 1
    when you are unsure of the number of params that you want to accept . – gprasant Dec 31 '13 at 07:58
  • 1
    Technically known as a [variadic function] (http://en.wikipedia.org/wiki/Variadic_function), or a function of indefinite "arity". Most languages use an ellipses form of some sort to indicate variable arguments. – Lawrence Dol Mar 26 '15 at 17:47
  • 1
    @JeffScottWard a perfect example is console.log, it accepts any number of arguments. `console.log('this:',variable,'should be replaced with', another_variable);` – Rob Aug 25 '15 at 16:31
13

if you know python, args... roughly similar to *args, as it allows you to treat function parameters as list

for example:

concat = (args...) -> args.join(', ')
concat('hello', 'world') == 'hello, world'
concat('ready', 'set', 'go!') == 'ready, set, go!'

it works in assginments, too:

[first, rest...] = [1, 2, 3, 4]
first == 1
rest == [2, 3, 4]
keppla
  • 1,753
  • 2
  • 15
  • 29
6

Splats is the term for the use of the ... operator for var-args (functions that take a variable number of arguments).

Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
3

I think it is a syntactic sugar for javascript's arguments object.

The idea may come form ruby's splat operator *.

Zifei Tong
  • 1,697
  • 1
  • 19
  • 32
  • technically, it's a little bit more, as it can used left-hand-sided in assignments, and can be combined with named arguments: in `(x, rest...) ->`, `rest` wont contain `x`, `arguments` does. – keppla Jan 11 '14 at 19:52