| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | 221005T150944Z | bigyihsu | |
| 039 | Google Sheets | 221005T182616Z | General |
| 045 | PHP7.4 | 220405T103223Z | user1117 |
| 039 | Python 3 | 220405T093404Z | Jitse |
| 096 | Aussie++ | 220406T030713Z | Bbrk24 |
| 134 | Rust | 210908T152933Z | Aiden4 |
| 135 | Nim | 210908T090231Z | xigoi |
| 038 | Math.JS | 170420T014650Z | ATaco |
| 4432 | APL Dyalog Classic | 180525T015740Z | Adalynn |
| 111 | Java 8 | 180525T010553Z | Jakob |
| 083 | C GCC | 180524T195725Z | Jakob |
| 020 | Attache | 180505T185342Z | Conor O& |
| 027 | 8086 machine code | 170421T024717Z | user5434 |
| 006 | BrainFlak | 180415T141517Z | ბიმო |
| 206 | C | 170420T171010Z | Julian W |
| 058 | C# | 170419T203749Z | Eugene D |
| 053 | C# | 170426T014339Z | John Cle |
| 022 | k | 170421T215655Z | skeevey |
| 018 | JavaScript ES6 | 170419T191922Z | Neil |
| 036 | Perl 5 | 170420T210746Z | hobbs |
| 029 | Clojure | 170422T103638Z | NikoNyrh |
| 058 | C | 170419T223356Z | Conor O& |
| 091 | C++ gcc | 170420T075655Z | Neil |
| 072 | C++ | 170419T233733Z | hvd |
| 089 | Lua | 170421T155515Z | Blab |
| 019 | Pyth | 170419T221019Z | Steven H |
| 058 | Scala | 170420T162356Z | corvus_1 |
| 096 | C | 170419T224556Z | betseg |
| 052 | R | 170420T024140Z | BLT |
| 039 | Octave | 170420T135516Z | rahnema1 |
| 069 | Python | 170420T094632Z | Zhengqun |
| 063 | Python 3 | 170420T054503Z | ovs |
| 086 | PowerShell | 170420T114717Z | Andrei O |
| 118 | Haskell GHC | 170420T111746Z | Zgarb |
| 044 | PHP | 170419T214226Z | Jör |
| 040 | R | 170420T104223Z | Konrad R |
| 062 | C# | 170420T093318Z | TheLetha |
| 018 | Julia 0.5 | 170420T001905Z | Dennis |
| 052 | Julia v0.5+ | 170419T211924Z | Julian W |
| 061 | Python | 170419T215153Z | Julian W |
| 034 | Dyvil | 170419T221831Z | Clashsof |
| 025 | Mathematica | 170419T203303Z | Martin E |
| 031 | Perl 6 | 170419T212711Z | Sean |
| 023 | Ruby | 170419T203958Z | daniero |
| 036 | Python 2 | 170419T192305Z | mbomb007 |
Go, 87 82 bytes
func f(x int)func(int)any{return func(y int)any{if y<1{return x+y}
return f(x+y)}}
Stopping value is 0.
This works because the any in Go represents all types, at the expense of every call after the 2nd needing to be cast with .(func(int)any), like f(3)(4).(func(int)any)(0).
- -5 by returning the function directly.
Google Sheets, 39
Based on the explanation here
Named functions:
| name | args | body |
|---|---|---|
| F | a | G(0,a) |
| G | a, b | IF(b>0,LAMBDA(c,G(a+b,c)),a) |
Score: 34 (body text) + 2 (names) + 3 (args) = 39
Example
Termination call arg is any non-positive number:
=F(2)(4)(0)
gives 6.
PHP7.4 (45 chars)
The superglobal function $_ENV will return an adder function continuously.
After the operations, when no argument is provided $_ENV will return the result.
The function $_ENV is not designed to accept a negative value or no input at all.
$_ENV=fn($a)=>fn($b=-1)=>~$b?$_ENV($a+$b):$a;
Usage :
var_dump($_ENV(1)() == 1); // bool(true)
var_dump($_ENV(4)(2)(7)() == 13); // bool(true)
var_dump($_ENV(4)(2)(7)(5)(2)() == 20); // bool(true)
Info: Overriding a superglobal like $_ENV variable isn't recommended.
Python 3, 39 bytes
class f(int):__call__=lambda s,o:f(s+o)
Not the shortest (by 3 bytes), but it's different from all previous Python approaches. It works by making a callable int subclass. Termination call is optional, but requires a 0 argument if used.
Aussie++, 98 96 bytes
-2 because I remembered the angle brackets aren't necessary for a single-statement YA RECKON body.
THE HARD YAKKA FOR f IS(x)<THE HARD YAKKA FOR g IS(y)<YA RECKON y ?BAIL f(x +y);BAIL x;>BAIL g;>
Tested in commit 9522366. For the final call, give it BUGGER ALL or YEAH, NAH! instead of a number.
The general structure is something like
function f(x) {
function g(y) {
if (y) return f(x + y);
return x;
}
return g;
}
Since Aussie++ doesn't have function expressions or anonymous functions yet, it is necessary to put the function declaration and return as separate statements.
Rust, 134 bytes
|x|{fn b(a:i32,n:i32)->Box<dyn std::any::Any>{if n>0{Box::new(Box::new(move|x|b(a+n,x))as Box<dyn Fn(_)->_>)}else{Box::new(a)}}b(0,x)}
In your face, strict type system! Terminates if the input is negative. You do have to downcast the result after every call though (see tio). I took a similar approach to the Math.js solution.
ungolfed:
|x| {
fn b(a: i32, n: i32) -> Box<dyn std::any::Any> {
if n > 0 {
Box::new(Box::new(move |x| b(a + n, x)) as Box<dyn Fn(_) -> _>)
} else {
Box::new(a)
}
}
b(0, x)
}
Rust's strong type system makes this almost impossible. Fortunately, trait objects come to the rescue. Trait objects erase the type and all associated data except for the trait's implementation. In this instance, I use the Any trait, which allows downcasting back into a concrete type. There are some wrinkles because you can't explicitly name the type of closures, so I have to cast the closure into a Fn trait object and then recast it into an an Any before use.
Nim, 135 bytes
import sugar
type X=object
case t:int8
of 0:i:int
else:f:int->X
func s(x:int):int->X=(y:int)=>(if y<0:X(t:0,i:x)else:X(t:1,f:s x+y))
Like the JavaScript answer, but with type safety.
Math.JS, 38 Bytes
f(x)=i(x,0)
i(x,y)=x<0?y:j(z)=i(z,y+x)
Call it with f(number_a)(number_b)(...)(negative_number)
If we're allowed to specify the initial call, 12 bytes (f(x)=i(x,0)\n) can be dropped, and it can be called with i(number_one,0)(number_two)(...)(negative_number)
Explanation
$$ \begin{align} f(x) & = i(x, 0) \\ i(x, y) & = \begin{cases} y, & \text{if } x < 0 \\ j(z) = i(z, y+x), & \text{otherwise} \end{cases} \end{align} $$
As shown above, f(x) simply calls i(x,0), then, i(x,y) returns the value of y if x is less than 0, or the function j(z)=i(z,x+y) otherwise.
APL (Dyalog Classic), 48 47 46 44 32 bytes
∇r←(a f)x
r←⍎'(a+x)f'↓⍨-0=x
∇
0f
Terminates by passing in zero . Call syntax: ((0 f 1) 2) 0
-15 bytes thanks to @ngn
Requires ⎕IO←0
Any golfing tips are welcome!
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;}}
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.
C (GCC), 83 bytes
My first C golf! There are a couple of other C solutions, but this one's a bit different. Preprocessor use is purely cosmetic. This approach was first discussed in Conor O'Brien's answer here.
#define r union r
t=0;r{int v;r(*f)();};r e;r f(a){t+=a;e.v=a?f:t;t*=a>0;return e;}
The terminal value is zero. The return value is a union, so to call the result, use field f, and to access the final value, use field v, e.g.
f(1).f(2).f(3).f(0).v
Limitations
A global variable holds the running total. While this is explicitly disallowed, the submission does support repeated invocations (the total is reset in the terminal call), which seems to be the reason for the ban on global state.
A pointer to f is stored to the returned union through the int member, so this is clearly not portable. I'm not sure if this works on GCC on all platforms or just on Linux or just on x86 or just with ELF or... If anyone knows any details about this, please comment or send a message!
Attache, 20 bytes
{If[_,$&Sum[__],_2]}
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.
8086 machine code, 27 bytes
00000000 bb 00 00 85 c0 74 13 01 d8 be 00 01 89 e7 47 47 |.....t........GG|
00000010 57 b9 1b 00 f3 a4 5b 89 47 01 c3 |W.....[.G..|
0000001b
This machine code must be at address 0x100, and assumes the tiny code model (cs=ds=es=ss). The function location can be changed without costing extra bytes, though. Putting it at offset 0 would save a byte (xor si,si instead of mov si, 0x100)
Required calling convention
This assumes the caller has pre-allocated at least 27 bytes on the stack. It takes a number in ax, and returns a function pointer in bx. Calling this pointer with ax=0 terminates the chain, and returns the sum in bx.
So for the first call:
mov bp, sp
sub sp, 28
mov ax, number_to_add
call function
; new function pointer in bx
Then, for each subsequent call:
sub sp, 28
mov ax, number_to_add
call bx
; new function pointer in bx
To terminate:
mov ax, 0
call bx
; result in bx
mov sp, bp
Ungolfed (commented disassembly of the machine code):
00000000 BB0000 mov bx,0x0 ; 0 is replaced after copying
00000003 85C0 test ax,ax
00000005 7413 jz 0x1a ; if(ax==0) ret (with value in bx)
00000007 01D8 add ax,bx ; arg += total
00000009 BE0001 mov si,0x100 ; address of the original: ds:0x100
0000000C 89E7 mov di,sp
0000000E 47 inc di
0000000F 47 inc di ; dst = sp+2 = above return address
00000010 57 push di
00000011 B91B00 mov cx,0x1b
00000014 F3A4 rep movsb ; copy the function code.
00000016 5B pop bx ; bx = start of copy destination
00000017 894701 mov [bx+0x1],ax ; update total in the copied code
0000001A C3 ret ; with bx = function pointer
After calling this with non-zero AX, bx = sp and the buffer is filled with a modified copy of the machine code from function. The 16-bit immediate in the first instruction holds the total. (It's written by the last instruction before the ret.)
push di / pop bx could be replaced with mov bx, di (before rep movsb), making it simpler but no savings.
Requiring the caller to pass a pointer to the dst buffer in di would save 4 bytes vs. calculating it relative to sp.
Making the function start address the same as the function size would save a byte (mov cx, si).
Brain-Flak, 6 bytes
Actually I just noticed that since the ToS is a valid return format popping the 0 is not really needed which saves 2 bytes:
({{}})
Original submission(s), 8 bytes
Uses 0 as the special value:
({{}}{})
Explanation
Given the arguments a1, a2, … , an, 0 the stack initially looks like this:
an
⋮
a2
a1
0
The code then goes on, pops every ai, accumulates them, pops the 0 adds them and pushes the result:
( ) -- push the following value:
{ } -- while ToS ≠ 0 (sums the runs):
{} -- pop 1 element
{} -- pop the remaining 0 & add it
Alternative solutions, 8 bytes
Instead of popping the 0 and adding it to the sum, we can also swap stacks since the right one is initially empty:
({{}}<>)
Using the -r flag the 0 is on the top of the stack, so we could pop it first:
({}{{}})
{}({{}})
C, 232 206 bytes
#include<string.h>
#include<stdlib.h>
#define f(X)s(""#X)?0:g
#define g(X)u(""#X)?0:h
#define h(X)u(""#X)?0:g
g=0,h=0;s(char*s){g=h=atoi(s);return 0;}u(char*s){char*a=strlen(s)?s:"0";g=h+=atoi(a);return 0;}
This can probably be golfed significantly, but should serve as a proof of concept that C can be used, without any language extensions*, to solve this problem by calling without arguments rather than with a magic value.
* @hvd has noted that, while this works out of the box using gcc, some of the behavior is not defined in the C standard, meaning that this may not be portable. Use at your own risk!
Ungolfed:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define f(X) start("" #X) ? 0 : f0
#define f0(X) update("" #X) ? 0 : f1
#define f1(X) update("" #X) ? 0 : f0
long f0 = 0;
long f1 = 0;
int start(const char *s) {
f0 = f1 = strtol(s, NULL, 10);
return 0;
}
int update(const char *s) {
const char *a = strlen(s) ? s : "0";
f0 = f1 += strtol(a, NULL, 10);
return 0;
}
int main() {
printf("f(1)() -> %ld\n", f(1)());
printf("f(1)(2)(0)(3)() -> %ld\n", f(1)(2)(0)(3)());
printf("f(1)(-2)(3)() -> %ld\n", f(1)(-2)(3)());
printf("f() -> %ld\n", f());
return 0;
}
Compiling and running with gcc arbitrary-length-currying.c -o arbitrary-length-currying && ./arbitrary-length-currying outputs (after some warnings)
f(1)() -> 1
f(1)(2)(3)(0)() -> 6
f(1)(-2)(3)() -> 2
f() -> 0
C#, 91 58 bytes
dynamic f(int x)=>(Func<int, dynamic>)(y=>y<1?x:f(x + y));
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
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
JavaScript (ES6), 18 bytes
f=n=>m=>m?f(m+n):n
Pass a falsy value to retrieve the sum. Zeros could be allowed for a cost of 2 bytes.
Ungolfed:
f = function(n) {
return function(m) {
if (m) {
return f(m+n);
} else {
return n;
}
}
}
Perl 5, 36 bytes
sub f{my$n=pop;sub{@_?f($n+pop):$n}}
say f(1)->(); # 1
say f(1)->(2)->(3)->(); # 6
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)
C, 62 58 bytes, borderline competing
Saved 4 bytes thanks to Kevin! (Still not removing typedef because it's something needed in order to be called.)
typedef(*(*B)(_))(_);q;f(x,o,_){x=x?(q+=x,f):(x=q,q=0,x);}
The function to call is f; you stop calling it and get the result by calling it with a non-positive number like 0. Try a test harness online!
So, as far as I can tell, the only way to "curry" functions that have multiple return types is to do one of the following:
- Cast the result to a function to tell the compiler you wish to call the result again;
- or create a
union/structtype that has anintand function/self-referential subtypes.
I tried doing (2), but it seemed a bit against the spirit of the question and, quite frankly, nigh undoable. Thus, in keeping with the spirit of the challenge, I have opted for option (1). This requires casting each returned function into a function, that it may be used.
This "currying" syntax looks a bit odd, but is quite similar. To emulate f(21)(1), one would have to write ((B)((B)f(21))(1))(0). I defined the B type to be a function that takes an integer and returns a pointer to a function that takes an integer. Expanded, this looks like:
( (B)( (B) f(21) )(1) )(0)
// f(21) - call f with 21
// (B) - cast to B, a function pointer
// ( )(1) - call with 1
// (B) - cast to a function pointer
// ( )(0) - call with 0
C++ (gcc), 95 91 bytes
struct f{int s;f(int t):s(t){}int operator()(){return s;}f operator()(int t){return s+t;}};
C++, 72 bytes
#define O(P)operator()(P){return{P+a};}int
struct F{F O(int(m))O()a;}f;
This defines a type F which acts as the requested function, and a variable f of that type to invoke. It's valid as of C++11 and works with online versions of GCC, clang, icc and VC++.
Usage:
int main() {
return f(1)(2)(3)(); // returns 6
}
Explanation:
After preprocessing and reformatting, it looks like:
struct F {
F operator()(int(m)) { return{int(m)+a}; }
int operator()() { return {+a}; }
int a;
} f;
This would normally be written:
struct F {
F operator()(int m) { return {m+a}; }
int operator()() { return a; }
int a;
} f;
return a; and return {+a}; do the same thing, as unary + doesn't change the value, and redundant braces around the return value are allowed. int m and int(m) do the same thing, as redundant parentheses around a variable name are allowed, including function parameters. return {m+a}; and return {int(m)+a}; do the same thing, as a cast of m from int to int does not change its value. These changes get the two operator() overloads closer in syntax, allowing a single macro definition to be invoked twice. Picking the right order for the three members allows the first word of the next line (int) to be included in the macro definition as well.
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!
Pyth, 19 bytes
DhdDebR?bh+dbdR$end
I'm impressed that Javascript beats Pyth, but then again Pyth is not quite designed to be passing functions.
Scala, 58 chars
case class f(n:Int){def apply(m:Int)=f(n+m)
def apply()=n}
Ungolfed:
case class f(n:Int){
def apply(m:Int)=f(n+m)
def apply()=n
}
Explanation:
This code defines a case class called f with a constructor taking an int. Definind a case class which will generate the equals, hashcode, toString and copy methods, and a companion object with the same name to enable object creation without the new keyword.
This class has an overloaded apply method: One takes another integer to add and creates a new object with the updated sum, and one without arguments to get the sum.
In Scala, any object with an apply method can be called like a method, that is o.apply(x) can be written as o(x). This is used in the standard libary for arrays, lists, maps and the Function1 trait implemented by anonymous functions
C, 104 96 bytes
#define a(i)s(i)|b
#define b(i)u(i)|c
#define c(i)u(i)|b
b,c,d;s(i){b=c=i;i=d;}u(i){c=b+=i;i=d;}
Uses the method from the link that @JulianWolf shared. Last argument must be 0.
R, 54 52 bytes
f=function(x){g=function(y='')'if'(y>'',f(x+y),x);g}
Saved 2 bytes thanks to MickyT!
Similar to one of the python answers. Ungolfed:
f=function(x){
g=function(y=''){
if(y>''){
f(y+x)
}
else{x}
}
g
}
Runs as
> f(1)(2)(4)()
[1] 7
Octave, 39 bytes
function r=f(n)r=@(m)merge(m,f(m+n),n);
*Argument of the termination call is 0.
*endfunction required to add some other codes.
Python, 69 bytes
def f(a=0,s=[]):
if a:
return lambda b=0:f(b,s+[a])
return sum(s)
Python 3, 63 bytes
f=lambda n,l=[]:n and(l.append(n)or f)or sum(l)*(l.clear()or 1)
Terminates with 0
PowerShell, 86 bytes
$f={$n=$args[0];$f=(gv f).value;{if($args){&$f($args[0]+$n)}else{$n}}.getnewclosure()}
Test code:
&(&(&(&(&(&$f 4)2)7)5)2)
Output: 20
Haskell (GHC), 118 bytes
This is 98 bytes for the code and 20 bytes for the GHC compiler flag -XFlexibleInstances, which enables a type system extension.
class F a where f::Int->a
instance F(()->Int)where f n()=n
instance F a=>F(Int->a)where f=(f.).(+)
This defines a "function" f, which can be called with an arbitrary number of integers followed by the unit (), after which it returns an integer.
Type annotations are required.
Try it online!
Explanation
Forcing Haskell's strict type system to allow this requires some magic, namely, enabling the GHC extension for flexible typeclass instances.
How this works is that f is a parametrically polymorphic function restricted by a type class constraint: its type is F a => Int -> a.
This means that f takes an integer and returns a value of type a, for any type a that belongs to the typeclass F.
F is just the name of the typeclass that provides the function f; it's declared on the first line.
The next two lines are two instances of F for different types a.
The second line states that the type of functions from () to integers belongs to F (where () is the unit type whose only member is the value ()), and the implementation is f n () = n; the function returns its first argument.
The last line states that if a belongs to F, then so does the type of functions from integers to a: from a function f :: Int -> a we can generate another function f :: Int -> Int -> a.
The implementation is f m n = f (m+n) (the code uses combinators to make it shorter), where the f on the left is the new one, and the f on the right is the old one.
This essentially gives f a new integer argument, which is added to the next one.
Multiple arguments are summed together like this:
f a1 a2 a3 a4 a5 ()
= f (a1 + a2) a3 a4 a5 ()
= f (a1 + a2 + a3) a4 a5 ()
= f (a1 + a2 + a3 + a4) a5 ()
= f (a1 + a2 + a3 + a4 + a5) ()
= a1 + a2 + a3 + a4 + a5
The f on each line has a different type.
Haskell functions are curried automatically, so if you give f only integers, you get a function.
PHP, 44 Bytes
An Idea from @user63956
Termination call 0
function f($i){return[$_GET[0]+=$i][$i]?:f;}
Termination call with NULL need a càst [$i] to [+$i]
PHP, 47 Bytes
function f($i){global$s;return$i?f.!$s+=$i:$s;}
PHP, 52 Bytes
Termination call NULL or any other value that is false in PHP
function f($i){global$s;$i?$s+=$i:print$s;return f;}
if the program must terminate after the Output replace print$s with die("$s") + 2 Bytes
R, 40 bytes
f=function(x)function(y)`if`(y,f(x+y),x)
0 acts as the stop value here. For two more bytes, we can omit it.
The problem is that R lacks a concise built-in lambda. But if we add one, we can get the code to 26 bytes:
f=x->(y->`if`(y,f(x+y),x))
(Yes, that’s valid R. It just needs an import.)
C#, 62 bytes
dynamic f(int n)=>(System.Func<int,dynamic>)(m=>m<0?n:f(n+m));
To end the call pass in a negative number e.g.
f(1)(2)(3)(-1) == 6
Julia v0.5+, 52 bytes
type F n end
F()=0
(f::F)()=f.n
(f::F)(x)=(f.n+=x;f)
Call as F. This could probably be made a lot shorter by adopting a less OO method, but I always like getting the chance to use this idiom.
If it can be assumed that "at least one call will be made before the termination call", the second line can be removed to save 6 bytes.
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)
Dyvil, 34 bytes
infix int apply(i:int,j:int=0)=i+j
Usage:
0() // = 0
0(1)() // = 1
0(1)(2)() // = 3
The trailing () can be omitted.
Explanation:
Defines a juxtaposition operator that takes two ints and adds them. The parameter j has the default value 0 to support the call without arguments. The 0 in the examples above is not the name, but a literal.
Mathematica, 25 bytes
f[x_]@y_=f[x+y]
f[x_][]=x
Try it online! (Using Mathics.)
It's possible to do three bytes less by porting the JavaScript answer, but I wanted to present a more idiomatic Mathematica solution. The @ is just a bit of syntactic sugar, which makes the solution equivalent to:
f[x_][y_]=f[x+y]
f[x_][]=x
So yeah the idea is that in Mathematica you can't just define a function f[x_] but you can directly attach a value to a more complicated expression containing f, e.g. f[x_] being passed another argument. By setting up two definitions for this, we can get the desired behaviour:
- The first definition collapses one
f[x][y]call intof[x+y], thereby consuming one "call" and adding up the arguments inside. This rule applies until we're left withf[sum][]. - The second definition unpacks this final case by defining the entire thing to evaluate to
sum.
Perl 6, 31 bytes
sub f(\n){->$m?{$m??f n+$m!!n}}
Ruby, 23 bytes
f=->n{->m{m ?f[n+m]:n}}
Usage:
f[1][2][3][nil]
=> 6
Python 2, 42 41 36 bytes
This solution will never have an overflow, since Python supports arbitrary-precision integers. Zero is the "special value".
f=lambda n:lambda m:m and f(m+n)or n
Ungolfed:
def f(n):
def g(m=''):
return f(m+n)if m<''else n
return g