1

In the Om.next wiki, there is example code like this (code listing at the bottom of the linked page):

(apply dom/ul nil
    (map person list))

Since dom/ul takes a variable number of arguments, what is the benefit of using apply vs this:

(dom/ul nil (map person list))

This second approach seems more analogous to passing an array as children in vanilla React, which is supported.

Actual question (response to comment): Is apply necessary? If so, why doesn't the latter approach work? If not, what benefit is gained from using apply like in the example?

FeifanZ
  • 16,250
  • 7
  • 45
  • 84

2 Answers2

2

The ClojureScript signature of dom/ul is apparently something like (defn ul [attrs & children] ...). Here children is a vararg. The caller can pass in 0 or more children. Therefore, the following invocations are valid:

(dom/ul nil (person jack))
(dom/ul nil (person jack) (person jill))
(dom/ul nil)

Now suppose you have a collection of elements that you'd like to wrap in a ul. The collection maybe comes from (map person list), which returns a sequence of elements. If ul is invoked like (dom/ul nil (map person list)), only a single child argument is passed to ul, and it is of the wrong type. Each child is expected to be an element, but a collection of element is passed in instead.

apply to the rescue. The job of apply is deal with the situation where we have a collection of arguments, which must be passed in individually. So, (dom/ul nil (person jack) (person jill)) is equivalent to (apply dom/ul nil (map person [jack jill])). apply is necessary in this case to make sure the arguments are passed to ul as that function is expecting them. Skipping apply is not an option.

ez121sl
  • 2,371
  • 1
  • 21
  • 28
  • Ok, that makes sense. I was thrown off because in vanilla React, multiple `children` are specified as a single array. Currently appears that, because of that, either approach works in this case – FeifanZ Feb 17 '16 at 00:32
1

In Lisp you can't pass a list or collection in place of individual variadic arguments and expect the same behavior.

If you do so anyway, the collection argument will be interpreted as a first of all variadic arguments. To spread a collection as function arguments, you have to use apply.

Leon Grapenthin
  • 9,246
  • 24
  • 37