53
\$\begingroup\$

Write a function, f, that takes in a positive integer and returns a function.

The new function returned should be identical to f. However, when the "termination call" happens, f should instead return the sum of all integers passed.

For example, g=f(4) (if f is the first function) should set g to another function. h=g(3) will do the same. However, when you call h with no arguments (see below for details), it should output 7, as that is the sum of the previous function arguments. Put another way, f(3)(4)() == 7.

Do note this is not the same as f(3,4)().

"Termination call" is one of the following options (your choice):

  • call w/o arguments
  • null as argument
  • any non-positive value

Arbitrary amount of function calls should be supported, there is no predefined limit.

It's guaranteed that total sum will not be bigger than 1'000.

We can assume that there is at least one call is made prior to "termination call".

Your code should not use static, per-program variables, so it should be possible to run the experiment multiple times in the same runtime and observe exactly the same behavior.

Examples:

f(1)() == 1
f(4)(2)(7)() == 13
f(4)(2)(7)(5)(2)() == 20
\$\endgroup\$
  • 4
    \$\begingroup\$ @LuisMendo It generally means that f(4) returns a new function. If that new function is called without arguments, it returns 4, but if it's called with another argument then it will again return a new function with the same semantics but with the new argument added to the 4 and so on. \$\endgroup\$ – Martin Ender Apr 19 '17 at 21:42
  • 6
    \$\begingroup\$ @LuisMendo It's indeed up to Eugene, but I think that allowing repeated calls would significantly take away from the challenge, because the interesting part isn't to make a stateful function but to make a higher-order function. \$\endgroup\$ – Martin Ender Apr 19 '17 at 21:49
  • 6
    \$\begingroup\$ @MartinEnder That makes a lot of sense. Eugene, if that's the intent, please change the wording of the challenge. Write a function that can be infinitely called doesn't suggest at all that the function shoud return a function \$\endgroup\$ – Luis Mendo Apr 19 '17 at 21:58
  • 4
    \$\begingroup\$ Can we assume that there will only be one instance of the call chain at a time? E.g. No q = f(2)(3); b = f(1)(2)(3); q(); b()? \$\endgroup\$ – Conor O'Brien Apr 19 '17 at 22:08
  • 3
    \$\begingroup\$ Having just recently picked up Haskell, I'm interested in whether this is possible in Haskell. The strong type system makes me think it might not be. \$\endgroup\$ – CAD97 Apr 20 '17 at 7:06

38 Answers 38

1
\$\begingroup\$

k, 22 bytes

Call with a null value to terminate

{$[^y;+/x;.z.s[y,x]@]}

Example:

k)f:{$[^y;+/x;.z.s[y,x]@]}
k)g:f[3]
k)h:g[4]
k)h[0N] //0N is null integer in k
7
\$\endgroup\$
1
\$\begingroup\$

C#, 91 58 bytes

dynamic f(int x)=>(Func<int, dynamic>)(y=>y<1?x:f(x + y));
\$\endgroup\$
  • 2
    \$\begingroup\$ You can get rid of some spaces and the public . \$\endgroup\$ – Kevin Cruijssen Apr 20 '17 at 8:25
1
\$\begingroup\$

Attache, 20 bytes

{If[_,$&Sum[__],_2]}

Try it online!

Explanation

{If[_,$&Sum[__],_2]}
{                  }    lambda, taking parameters stored in `__`
 If[_,            ]     If the first parameter `_` is truthy (nonzero):
      $                    return this function
       &                   bonded with
        Sum[__]            the current running sum
               ,        otherwise:
                _2         return the sum

Since (f&n)[x] is equivalent to f[x, n], this will continue returning itself with the updated sum until n = 0.

If you want computation to occur after the final 0, then one could do this for 28 bytes:

{If[_,Fold[`&,$'__],Sum!__]}

This is much the same thing, except we use Fold[`&,$'__] to bond $ with each individual argument.

\$\endgroup\$
0
\$\begingroup\$

Python, 61 bytes

f=lambda n="":0if n==""else lambda m="":n if m==""else f(n+m)

Much longer than the other Python version, but uses the no-argument syntax rather than a magic number. Can probably be improved upon.

If it can be assumed that "at least one call will be made before the termination call", this can be reduced to 44 bytes:

f=lambda n:lambda m="":n if m==""else f(n+m)
\$\endgroup\$
  • \$\begingroup\$ You can use 0 as default value and gain a bunch of bytes rearranging things: f=lambda n=0:n and(lambda m=0:m and f(n+m)or n)or n \$\endgroup\$ – PieCot May 6 '18 at 11:17
0
\$\begingroup\$

Lua, 89 bytes

function f(...)n,p=...p=p or 0 return n and loadstring("return f(...,"..n+p..")")or p end

Well it's not exactly the shortest I see (Lua never is), but it was an interesting challenge. Had a lot of attempted arithmetic on a function and attempted to call a number along the way before the aha moment.

As a slight bonus though, it does work with non-positive numbers since nil and false are the only false values in Lua. In many golfing challenges, 0 ~= false is a drawback but not here!

\$\endgroup\$
0
\$\begingroup\$

Clojure, 29 bytes

(defn f[n]#(if %(f(+ n %))n))

Example:

(for [f (->> [3 2 1 4 10] (reductions (fn [f val] (f val)) f) rest)]
  (f nil))
(3 5 6 10 20)
\$\endgroup\$
0
\$\begingroup\$

C#, 53 bytes

Func<int,dynamic>f(int i)=>m=>m<0?(dynamic)i:f(m+i);

Any negative number can act as the stop value

int j = f(5)(3)(4)(-1); // j = 12

int j = f(-1); // Compile Error, must be 2 or more calls
\$\endgroup\$
0
\$\begingroup\$

Java 8, 111 bytes

A lambda from int to a function. Calls are terminated by passing zero.

i->new java.util.function.Function<Long,Object>(){int t=i;public Object apply(Long x){t+=x;return x<1?t:this;}}

Try It Online

Ungolfed

i ->
    new java.util.function.Function<Long, Object>() {
        int t = i;
        public Object apply(Long x) {
            t =+ x;
            return x < 1 ? t : this;
        }
    }

Due to an interesting interplay between byte counts of primitive and object integer types, intermediate functions take a Long as a parameter, but the total is stored in and returned as an int.

Limitations

The returned function is mutated when called, so, for instance, it's not possible to obtain two integer results without two calls of the lambda. However, the functions returned by separate calls to the lambda are fully independent, so it seems the challenge requirements are met.

Liberal casting is required when constructing expressions that use the lambda. See the TIO for a usage example.

\$\endgroup\$
  • \$\begingroup\$ It's actually a lambda from int to an Object. \$\endgroup\$ – Zacharý May 25 '18 at 1:59
  • \$\begingroup\$ Well you can cast it that way, but the actual return type isn't Object. \$\endgroup\$ – Jakob May 25 '18 at 5:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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