8
\$\begingroup\$

For a challenge, I recently submitted the JavaScript solution

[].push

To be clear, this isn't x=>[].push. The entry itself is a function: it's the function identified by the JavaScript expression [].push.

The critical complication is that it wouldn't work to place this function in a variable. this would not work:

f=[].push;
f(...);

This is because push needs to be accessed as a method (i.e., a property accessed from some parent value) in the lexical invocation expression where it is called in order for it to push into the correct array. A correct invocation must be [].push(...) (or, to separate the answer from the input, ([].push)(...) would be fine, too). The "bare" invocation f(...) does not include property access, so the push function is called but does not work correctly.


If this is allowed, are more complex answers of the same form allowed, e.g.:

{
    x: 5,
    f: function() { return Math.dothing(this.x) }
}.f

where you define an object with properties and then conclude with .f so that the whole expression returns that single function?

\$\endgroup\$
  • 1
    \$\begingroup\$ The fact that f=[].push; f(); doesn't work makes me hesitant, and also makes me wonder what the challenge was. Can you post a link to that challenge/answer? \$\endgroup\$ – Kamil Drakari Apr 10 '18 at 15:32
  • \$\begingroup\$ @KamilDrakari This was for How many arguments were passed? (my answer is here) \$\endgroup\$ – apsillers Apr 10 '18 at 15:38
  • \$\begingroup\$ I don't know Javascript, but based on your explanation I suspect that that type of answer is not reusable. Which is required of function submissions. \$\endgroup\$ – Sriotchilism O'Zaic Apr 10 '18 at 15:53
  • \$\begingroup\$ @user56656 I don't really agree that it's not reusable, based on trying it out. It's possible to call [].push(...) any number of times with correct results, at least to my cursory testing \$\endgroup\$ – Kamil Drakari Apr 10 '18 at 15:57
  • \$\begingroup\$ @user56656 Well, it is reusable, but it's not assignable. For example, immediately sequential calls like ([].push)(1,2,3); ([].push)(4,5,6,7); give correct results for each run. \$\endgroup\$ – apsillers Apr 10 '18 at 15:58
  • \$\begingroup\$ Should I add the javascript tag? In Python function on a object is auto bind to that object. \$\endgroup\$ – user202729 Apr 10 '18 at 16:03
  • \$\begingroup\$ @user202729 Good suggestion -- I just did. This is potentially very specific to JavaScript \$\endgroup\$ – apsillers Apr 10 '18 at 16:05
  • \$\begingroup\$ @KamilDrakari That's not reusing the same function that is using different functions by the same name. The two lists are different references. See also \$\endgroup\$ – Sriotchilism O'Zaic Apr 10 '18 at 16:05
  • 2
    \$\begingroup\$ @user56656 I think this gets right to the heart of the question: is a function submission a sequence of bytes that can run in an environment to produce a result, or is it the function object (and associated data structure) that is produced by the evaluation of this byte sequence? \$\endgroup\$ – apsillers Apr 10 '18 at 16:07
  • \$\begingroup\$ "function" is language-specific, it cannot be measured as a "sequence of bytes" generally. \$\endgroup\$ – user202729 Apr 17 '18 at 11:41
10
\$\begingroup\$

If it quacks like a function, it's a function

For example, if you want to join a list of strings with spaces in Python, the function to use would be ' '.join. I don't see any reason that this function should be invalid in such a challenge, as it can be assigned (as e.g. f = ' '.join; f(list_of_strings)) or even used as is (e.g. ' '.join(list_of_strings)).

The reason why a function like Python's [].append won't work in a challenge that asks you to return a singleton list containing a value passed as input is that the function itself doesn't return the result, but instead it assigns it in place, and that place is the new reference created by mentioning [], and so the function isn't even the same function when used multiple times without assigning it to a variable.

\$\endgroup\$
  • 2
    \$\begingroup\$ This answer doesn't seem to take a stance on the issue presented in the question. It says things that are true but it doesn't make it clear how those are related to the question at hand. \$\endgroup\$ – Sriotchilism O'Zaic Apr 10 '18 at 17:29
  • 3
    \$\begingroup\$ In JavaScript's case, [].push cannot be assigned. Or, rather, it can be assigned, but it stops working when invoked as a bare function f() rather than as a method. You mention "it can be assigned" as a function-y property, but it's unclear to what degree this is a hard requirement of your answer here. \$\endgroup\$ – apsillers Apr 10 '18 at 17:31
  • \$\begingroup\$ @user56656 I don't understand what you mean, the question seems to be about whether non-"lambda"/"=>" functions are allowed without assigning them to a variable. \$\endgroup\$ – Erik the Outgolfer Apr 10 '18 at 17:34
  • \$\begingroup\$ @apsillers I'm referring to Python's case here. I'm not sure what you mean by "what degree this is a hard requirement", however, f = [].append will work just like [].append, except that the "[]" will always point to the same, albeit not very easily discoverable, place. \$\endgroup\$ – Erik the Outgolfer Apr 10 '18 at 17:41
  • \$\begingroup\$ @EriktheOutgolfer To rephrase, I meant: f=[].push; f(...); does not return a correct result (whereas ([].push)(...) does return the correct result). Does that, according to your criteria for function validity, make [].push an invalid submission? I'm not entirely sure from the content of this answer. \$\endgroup\$ – apsillers Apr 10 '18 at 17:45
  • \$\begingroup\$ Also, I appreciate we're talking about different languages. If your answer for my JavaScript case is, "I am not prepared to discuss the nuances of JavaScript as it applies to this question," that's fine. I am asking narrowly about JavaScript. \$\endgroup\$ – apsillers Apr 10 '18 at 17:49
  • \$\begingroup\$ @apsillers Hm, I'll delete this answer if your question is specifically about JavaScript, and clarify the question (creating a javascript tag isn't really clear). \$\endgroup\$ – Erik the Outgolfer Apr 10 '18 at 17:52
  • \$\begingroup\$ @EriktheOutgolfer I have just modified the question title to be more strict: I'm really asking about the case where a function must, structurally, be a method on an object. Python's ability to remember a method's parent object means that that case does not apply to what I am asking about. I don't mean to ask about JavaScript in particular (other languages may exhibit this behavior) but Python seems to expressly not exhibit the problem I'm asking about. \$\endgroup\$ – apsillers Apr 10 '18 at 18:00
  • \$\begingroup\$ @EriktheOutgolfer Hmm, you may want to mention that the only time functions need to be assigned to a variable is if they are recursive \$\endgroup\$ – ASCII-only Apr 21 '18 at 0:24
  • \$\begingroup\$ @ASCII-only If it's the case that the function refers to its own name, then it sure has to be assigned, because otherwise what would it refer to? I don't think it needs to be explicitly specified, it's just like how you can't assume any input is in a variable n for example. However, some languages have a way to recurse without referring to a "lambda"'s name, for example in Dyalog you can use inside a dfn (Dyalog lambda) to refer to itself regardless of if you assign that dfn to a variable or not. \$\endgroup\$ – Erik the Outgolfer Apr 21 '18 at 9:16
6
\$\begingroup\$

That is not a valid function

Although the meta ruling on what qualifies as a function isn't conclusive with two top answers at roughly equal scores, both of those answers indicate that a function only counts if it can be assigned to a variable or given a name. The fact that you need to replicate the entire code of the submission in order to call it each time, rather than being easily able to store it to a chosen name, to me means that it can't qualify as a function. I think it's also obvious that it doesn't qualify as a program either.

Since it is neither a Function nor a Program, based on a much stronger consensus it isn't a valid solution unless the challenge specifically allows it. I would recommend replacing it with a=>[].push(a) or something similar, or asking a followup question about whether a submission can be called a function if it requires some simple and consistent boilerplate in order to name/assign/store it.

\$\endgroup\$
  • \$\begingroup\$ Also, JavaScript has an explicit operatir for making a valid function from that, you do ::[].push \$\endgroup\$ – Downgoat Apr 22 '18 at 20:33
-3
\$\begingroup\$

You're essentially referencing a builtin. While that's very much allowed, the correct code (which can be stored in a variable and called later) would be one of these:

[].push.bind()
a=>[].push(a)

Now, in your example, a better way to write it would be:

f=>Math.dothing(x);x=5

Since you don't need to worry about global variable name collision.

\$\endgroup\$
  • \$\begingroup\$ To be 100% clear, this answer is asserting that the standalone answer [].push is not a valid solution, correct? (I completely agree that your arrow function and bind solutions are inarguably valid.) \$\endgroup\$ – apsillers Apr 10 '18 at 15:44
  • 1
    \$\begingroup\$ This answer doesn't answer the question being asked, or, if it does, it is very unclear about that fact. \$\endgroup\$ – caird coinheringaahing Apr 10 '18 at 16:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .