5 ms·
The history here is that Common Lisp gets reduce from APL (https://aplwiki.com/wiki/Reduce https://aplwiki.com/wiki/Reduce). It's not an attempt an ML-style fol
by ruricolist 3y ago
The history here is that Common Lisp gets reduce from APL (https://aplwiki.com/wiki/Reduce https://aplwiki.com/wiki/Reduce). It's not an attempt an ML-style fold, but a different formalism from a different lineage.
- moonchild 3y agoI never heard of apl's allowing for an explicit choice of initial value, nor direction control ('from-end'), which mls typically also provide (foldl vs foldr). On the other hand, the ad-hoc choice of result for an empty input is a flaw common to cl and apl.
- myco_logic 3y agoWhile reading this, I was immediately reminded of the reduce operator, glad to see my intuition wasn't far off. The nifty thing about this operator in the array-langs compared to the usual fold function is that they usually define identity elements for all primitive functions, which means that no initial value has to be provided: https://aplwiki.com/wiki/Identity_element https://aplwiki.com/wiki/Identity_element The downside of this approach though, is that using reduce with non-primitive functions can result in domain errors (at least in APL). I think BQN's version of the operator is a bit nicer, in that it allows you to specify an initial value in this situation: https://mlochbaum.github.io/BQN/doc/fold.html https://mlochbaum.github.io/BQN/doc/fold.html
- moonchild 3y ago> downside of this approach though, is that using reduce with non-primitive functions can result in domain errors Yes, that's another problem. There is precedent for associating metadata with user-defined functions (eg inverses); identities seem to have fallen by the wayside, but I am planning to fix that for j.
- pfdietz 3y agoDefining a number of related functions seems to be a pattern that comes up elsewhere. For example, consider functions that compute a hash value, canonicalize, and compute some notion of equality. It would be useful to associate all of these.
- moonchild 3y agoHaskell calls these 'typeclasses'; cl calls them 'protocols'. Apl style is not to expose sophisticated user-level abstractions, so I think that there it is not inappropriate that the scope of associable objects (say, a monad, a dyad, an inverse, and an identity; perhaps a few others) be fixed by the language.
- 0x69420 3y ago> they usually define identity elements for all primitive functions > using reduce with non-primitive functions can result in domain errors ml-style folds in the presence of ad-hoc polymorphism solve this rather handily -- in haskell for instance monoid is the typeclass that only requires an associative operation and an identity element typeclasses have some clunkiness in this regard; you have to wrap numeric types as "sum" or "product" etc to go "ah yes today i want to say numbers are a monoid under this operation" but at the very least it does enable formal, user-defined associations between identity elements and functions luckily most things programmers deal with are plausibly just one kind of monoid. for instance the eleventy billion different string types haskell programmers love to use all tend to satisfy monoid under concatenation without any wrappers
- 082349872349872 3y agoI had thought APL style was to specify initial values simply by pre-catenating the desired initial value onto the argument?
- moonchild 3y agothat doesn't work when the desired initial value is not the same shape as the major cells of the argument array
- mlochbaum 3y agoNo, as you can check with some of the weirder arithmetic functions: </ ⍬ ⍝ Empty list 0 </ ,5 5 </ 0 5 1 </ 5 0 0 It would be more consistent in some ways though (for example forcing </ to always have a boolean result). APL designer Bob Smith's advocated for it, particularly for ,/ to make it behave better as a joining function: http://www.sudleyplace.com/APL/Reduction%20Of%20Singletons.pdf http://www.sudleyplace.com/APL/Reduction%20Of%20Singletons.p...