Roger Hui-2 wrote: > >> Since I'm so stuck on monoids, why not look how this is done in >> Haskell. After all, if anybody knows anything about them,... >> >> Prelude> foldr1 (*) [] >> *** Exception: Prelude.foldr1: empty list >> Prelude> foldr1 (+) [] >> *** Exception: Prelude.foldr1: empty list >> >> Aha! Haskell doesn't know how to sum up elements of >> an empty list! >> >> "Why, of course", says Haskeller, "it just does not make sense." > > K.E. Iverson, Notation as a Tool of Thought, 1980. > http://www.jsoftware.com/papers/tot.htm > > 4.2 Partitioning Identities > > Partitioning of an array leads to a number of obvious and useful > identities. For example: > > ×/3 1 4 2 6 ←→ (×/3 1) × (×/4 2 6) > > More generally, for any associative function f : > > f/v ←→ (f/k↑v) f (f/k↓v) > f/v,w ←→ (f/v) f (f/w) > > If f is commutative as well as associative, the partitioning need not > be limited to prefixes and suffixes, and the partitioning can be made > by compression by a boolean vector u : > > f/v ←→ (f/u/v) f (f/(~u)/v) > > If e is an empty vector (0=⍴e), the reduction f/e yields the identity > element of the function f , and the identities therefore hold in the > limiting cases 0=k and 0=∨/u . >
Operation of partitioning depends on what's being partitioned. So, in the first round of reasoning, Haskell's behavior can be interpreted as: List can contain anything, so I don't know if [] refers to a partition of a list of numbers or something else, like a list of strings. In the second round, we look at the whole expression, and do type inference: * multiplies numbers, Haskell knows that, so why not infer that [] refers to a partition of a list of numbers? This is why: The types of foldr1, * and [] are: foldr1 :: (a -> a -> a) -> [a] -> a (*) :: (Num a) => a -> a -> a [] :: [a] The type of * requires that type of its arguments follows from the class of types called Num, while [] does not require this. So when foldr1 has (*) and [] for its arguments, it cannot be inferred whether it was meant, for instance: (Int -> Int -> Int) -> [Int] -> Int or (Int -> Int -> Int) -> [b] -> ? for some b other than a member of Num, so the last type, the type of the result, cannot be inferred. This is just a fancy way of saying that empty list could come from a partition of list containing any type whatsoever *regardless* of the type of the folding operation. In turn, to achieve its default identity functions work, J cheats a bit when dealing with empty arrays: '' -: 0$0 1 (0 5 5 $ 'abc') -: 0 5 5 $ 123 1 +/0 5 5 $ 'abc' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */0 5 5 $ 'abc' 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "Aha! by definition, empty arrays in J are in the Num class of types", Haskeller would say. In J we do compute a lot with number arrays, while lists in Haskell and LISP are more similar to boxes in J, and yet, the type foo of Haskell still let us catch some tacit assumptions taken in the generalizations that APL and J do with arrays. Why does then the LISP example work at all? Well, because The Common LISP standard invokes a concept of "programmer's intent" when trying to resolve implicit types of things, thus it's clearly programmers intention that the empty list in (reduce'*()) comes from a list of numbers. Better be it so, or else it may be a bug. > A few examples from J: > > +/ i.0 > 0 > */ i.0 > 1 > > You've identified these. How about: > > +&.^./ i. 0 > 1 > *&.^/ i. 0 > 0 > > +/ .* / i.0 4 4 > 1 0 0 0 > 0 1 0 0 > 0 0 1 0 > 0 0 0 1 > Yes, all great examples, and I am aware at least to some extent aware of the sophistication of J's mechanism with (deriving of) identity functions and liking it. On Fri, Oct 21, 2011 at 8:12 AM, Viktor Cerovski <[email protected]> wrote: > > > Raul Miller-4 wrote: >> >> On Fri, Oct 21, 2011 at 9:08 AM, Viktor Cerovski >> [...] >>> and that is the monoidal zero wrt list appending. >>> There is, however, no an "empty number", neither in J nor >>> mathematically. >> >> That depends, of course -- 0 could be thought of as an empty number. >> >> The issue, of course, is that you are not using "empty" to refer to a >> quality of a number -- you are using it to refer to a quality of an >> array. >> > I never used terms like "quality of something". I merely talk about > monoids > etc, and so did you without knowing it when you defined the number of > elements of an array, as well as when you define > > A number is an array >> which has a shape whose product is 1 and a value whose fill element is 0. >> > (notice that I strictly distinguish between 1 1 1 $ 123 and 123, > the former for me is an array, and only the latter a number, > and do not ever associate fill element with an array). > > Let's see the hidden monoid in your definitions: > > nelem =: */@$ NB. No of elem of an array > nelem 123 > 1 > > How does this work? Like this: > */0$0 > 1 > > What is that? Product of elements of an array of zero > elements is, um, 1!? > > An explanation is simple: 1 is the right monoidal zero (ok, in > this case we call it monoidal one, or just right neutral) of > numerical arrays wrt multiplication, that is: > > (a*b*...*d*1) === (a*b*...*d) > +/a,b,...,1 === +/a,b,...,d > > then we extend the same logic to the following: > > +/(0$0),1 === +/(0$0) > > since the lhs is one, so is the rhs. > > This monoidal knowledge is built-in in J though identity > functions. Exactly the same way works + > > +/0$0 > 0 > > Here the right neutral is 0. So it is not the same number, > but it is the same monoidal structure. > > Let's hypothetically say that you object to this on the ground of some > quality of arrays that this monoidal business distorts or looses. > > I would try to trick you first by saying: Look, it's the same in LISP: > > [1]> (reduce '* ()) > 1 > [2]> (reduce '+ ()) > 0 > > But of course, LISP modeled reduce after APL, so, well, > nice try of me. > > Since I'm so stuck on monoids, why not look how this is done in > Haskell. After all, if anybody knows anything about them,... > > Prelude> foldr1 (*) [] > *** Exception: Prelude.foldr1: empty list > Prelude> foldr1 (+) [] > *** Exception: Prelude.foldr1: empty list > > Aha! Haskell doesn't know how to sum up elements of > an empty list! > > "Why, of course", says Haskeller, "it just does not make sense." > >> So it's not about some deficiency of J per se. It is perhaps more >> related to a so-to-say natural property that appending two numbers >> gives a list, not a number, while appending lists still gives a list; >> appending two chars gives a string, while appending strings gives >> string, etc. > > Here is how I would map those concepts from english into J and then > back to english: > > A number is an array which has a shape whose product is 1 and a value > whose fill element is 0. > > A character is an array which has a shape whose product is 1 and a > value whose fill element is space. > > A string is an array which has a rank of 1 and a value whose fill > element is space. > >> What I find problematic in J regarding arrays, appending and >> similar operations is the fill. In some circumstances is useful, >> for instance for shift, but I mostly see it as a difficult problem >> that needs a better solution rather than a language feature. > > I am having trouble parsing this sentence. > >> I mostly agree, and I like the same things about J. I just can't see >> number as a special kind of matrix, and, that said, I never once felt >> that this clashes with programming in J, so to me numbers and >> matrices are two different things that work together just fine in J. > > Following the above convention, for me a matrix is an array whose rank > is 2 and whose fill element is 0. > > So some numbers are matrices, and some matrices are numbers, but > neither can be said to always be an instance of the other. This, > superficially at least, seems to agree with how you have phrased your > point here. ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm -- View this message in context: http://old.nabble.com/%7B.-y-produces-an-array.-tp32687373s24193p32702563.html Sent from the J Programming mailing list archive at Nabble.com. ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
