5 ms·
In case this was a serious entry... which I honestly can't tell. The problem with array_sum is not that it's too long but instead that it's combined two rather
by tel 13y ago
In case this was a serious entry... which I honestly can't tell.
The problem with array_sum is not that it's too long but instead that it's combined two rather specific bits of functionality into a fixed (if common) form, while the Ruby code separates the ideas of "folding" and "addition" allowing for many orthogonal creations.
To pick another favorite, in Haskell you could write
Foldable.foldl1 (+)
which sums any foldable thing—anything which has elements which can be combined together one-by-one. So it'll apply to Trees or Sets or Dictionaries (well, Maps) just as easily while also allowing things like (+) to be replaced by other binary operators.
- Scriptor 13y agoPHP does have array_reduce, however operators like '+' can't be used as callables so you'd have to make your own wrapper functions. Edit: Screw it, haven't self promoted on a while. In Pharen (https://github.com/scriptor/pharen https://github.com/scriptor/pharen), which compiles to PHP, you could do: (reduce (+) 0 [1 2 3 4 5])
- tel 13y agoThat's really cool, but the syntax is strange to me. How do you distinguish between operator sectioning (+) and a side-effecting function call (f)?
- Scriptor 13y agoIt works (superficially) similarly to how Haskell does things and treats (+) as a partial function call by recognizing that + isn't getting at least 2 arguments. You could also do stuff like: ((+ 1) 2) ; => 3 (map (* 2) [1 2 3]) ; => [2 4 6] If a function f takes any arguments and Pharen knows this, it'll convert (f) into a partial function call as well. Unfortunately I haven't figured out a way to check if a function has any side effects. Otherwise in this case at least operators are treated like functions.
- tel 13y agoSo it's tracking the arity of functions and turning anything which has been applied to fewer than ARITY arguments to a partial application? I suppose that comes at the cost of (+ 1 2 3 4)?
- aaronem 13y agoWhy would it?
- tel 13y agoMy hypothesis was that the compiler was tracking the arities of each function in order to open up opportunities for partial application. That means there's some ambiguity when you write something like (+ 1) which, in Scheme is a complete application equal to 1 but may also be interpreted as a partial application equal to (lambda (x) (+ 1 x)). There are many ways to mitigate that ambiguity statically and dynamically, but I feel there's always going to be a tradeoff between favoring partial application, favoring variadic functions, and the complexity/sophistication of your static checking or runtime environment. I just made a stab at where the solution might lie in that design space. Turns out I was wrong.
- knome 13y agoSurprisingly, not really. {-# OPTIONS -fglasgow-exts #-} class BuildList a r | r-> a where build' :: [a] -> a -> r instance BuildList a [a] where build' l x = reverse$ x:l instance BuildList a r => BuildList a (a->r) where build' l x y = build'(x:l) y varargs x = build' [] x main = print $ ( sum $ varargs 1 2 3 4 5 6 100) $ ./Test 121 http://okmij.org/ftp/Haskell/vararg-fn.lhs http://okmij.org/ftp/Haskell/vararg-fn.lhs
- tel 13y agoI love that example, but it does depend upon some pretty arcane features in Haskell's type inference engine.
- 13y ago
- afrdofdwnvtes 13y agoWell how about this then. foreach(array(1,2,3,4,5) as $x) $i=$i+$x; echo $i;
- 7Figures2Commas 13y ago1. Separate folding and addition. 2. ? 3. Profit.
- tel 13y agoOrthogonality and composability dramatically increase abstraction, code reuse, testability, and likelihood of writing correct code, both for library maintainers and library users. Step 2 is actually extremely well known.