53
3
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
Can we require a specific non-positive value as the terminator? – Tutleman – 2017-04-19T20:55:20.800
@Tutleman, not sure what it would lead to, let's say any non-positive should be OK to terminate the chain if this option is choosen – Eugene D. Gubenkov – 2017-04-19T20:58:52.637
I don't understand what is being asked here. Can you ellaborate or clarify? What does the notation
f(4)(2)(7)()
mean? – Luis Mendo – 2017-04-19T21:40:01.9434@LuisMendo It generally means that
f(4)
returns a new function. If that new function is called without arguments, it returns4
, 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 the4
and so on. – Martin Ender – 2017-04-19T21:42:40.777@LuisMendo, it means 4 function calls, arguments on first 3 should be summed, because the forth call is "terminating" – Eugene D. Gubenkov – 2017-04-19T21:42:49.660
@MartinEnder Thanks. So does the code need to return a function, or is that just one possible approach? Can it be a function with a "persistent" variable, such that the same function is called several times? This question is more for Eugene I guess – Luis Mendo – 2017-04-19T21:47:28.603
6@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. – Martin Ender – 2017-04-19T21:49:04.830
6@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 – Luis Mendo – 2017-04-19T21:58:41.740
4Can 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()
? – Conor O'Brien – 2017-04-19T22:08:22.613Are functors allowed? – Steadybox – 2017-04-19T23:26:11.273
Apologies, I am not sure I understand. I have a 'plus over' function in k
+/
---- so+/[1 2 3]
returns 6, is this incorrect? Do the arguments need to be (1)(2)(3)() - with parentheses AND a null terminator? What is the significance of the null terminator? If it isn't present should the function do nothing?? – Chromozorz – 2017-04-19T23:31:19.970@EugeneD.Gubenkov Let me know when you clarify the above (whether the function should return a function or simply have memory across calls), so that I can remove my downvote – Luis Mendo – 2017-04-19T23:36:27.340
2@Chromozorz the significance is currying and higher-order functions. I think a better title would be "Arbitrary-length Currying". – Brian McCutchon – 2017-04-20T01:55:17.243
@LuisMendo, Please check out the updated description -- should be more precise now. – Eugene D. Gubenkov – 2017-04-20T06:19:24.547
Arbitrary amount of function calls should be supported
I believe some environment won't able to handle more than 1000 recursive call. It will simply throwStackOverflow
error. – Thariq Nugrohotomo – 2017-04-20T06:24:49.4471@ThariqNugrohotomo, let's go with 1000 as maximum sum, it is not critical to the spirit of the challenge – Eugene D. Gubenkov – 2017-04-20T06:37:12.387
3Having 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. – CAD97 – 2017-04-20T07:06:13.887
I have some questions here. We can't use static storage so this function obviously needs some dynamically allocated buffer space. Does
f()
itself need to take care of that? Canf()
take an additional parameter to a pre-allocated buffer? What about stack allocation? That has to be done (and eventually cleaned up) by the caller. – user5434231 – 2017-04-21T02:02:54.617@CAD97 - I believe it is, although I don't have time to work on it right now. The trick is that you can thread the expected output type of each function invocation backwards through in order to selected a typeclass instance at that invocation. So just like
read "123"
can return eitherInt
orFloat
depending on what the code calling it expects,f
can have the type eitherVariadicFunction v => Int -> v
or() -> Int
depending on what's expected of it... It wouldn't be a short solution, but interestingly it may well be the only statically typed one on the list. – Jules – 2017-04-21T09:45:25.897it should be
f(4)(3)()
, or the definitions should be flipped. – Will Ness – 2017-04-21T13:04:23.7071Does "any non-positive value" mean that we can e.g. specify 0 as the termination value and negative values as unsupported, or does it mean that, if we choose that option, the code must treat all non-positive inputs as termination values? – Ilmari Karonen – 2017-04-21T16:09:59.930
@CAD97 I haven't really learned Haskell yet, but I know that functions are curried by default. Does it have any varargs functionality? I found this.
– Brian McCutchon – 2017-04-21T21:13:10.103Tangentially related.
– Neil – 2017-05-06T00:55:02.063