atomic extension, each

stevan apter — 2003-05-29 12:50:39

related to my previous post:

k has a combinator 'each' which resembles map. in joyish
terms, it takes a size n list of lists and an n-ary program
p and applies p to corresponding elements of the lists.

[[1 2 3][4 5 6]] [+] each
[5 7 9]

each is tolerant:

[1 [4 5 6]] [+] each
[5 6 7]

this is called "atomic extension". again, if transpose were
tolerant, 'each' could be defined (inefficiently) as

each == [transpose] dip [infra first] cons map

(in my version of joy - 15:46:02 may 13 2003 (NOBDW) - tranpose
doesn't work as i expected - shouldn't [[1 2 3][4 5 6]] tranpose
-> [[1 4][2 5][3 6]] ?)

the atomic primitives of k have a built-in each-to-the-atoms
recursion. e.g. [[1 2 3][4 5 6]] [+] each <-> [1 2 3][4 5 6] +.

phimvt@lurac.latrobe.edu.au — 2003-05-30 06:36:18

On Thu, 29 May 2003, stevan apter wrote:

> related to my previous post:
>
> k has a combinator 'each' which resembles map. in joyish
> terms, it takes a size n list of lists and an n-ary program
> p and applies p to corresponding elements of the lists.
>
> [[1 2 3][4 5 6]] [+] each
> [5 7 9]

I agree that 'each' might indeed be a very useful addition to
Joy, and some definition similar to yours would be right.
It resembles mapr2 (= zipwith) and the (unwritten) map2 for
Joy in the binary case at least. But it uses a single list
for the two list operands, rather than two separate lists.
For the binary case this would do:
each == [uncons uncons pop] dip mapr2 (or map2 in future)
But you are suggesting the most general case, perhaps even
n = 0:
[[1 2 3][4 5 6][7 8 9]] [+ +] each ==> [12 15 18]
[[1 2 3][4 5 6] ] [+ ] each ==> [5 7 9]
[[1 2 3] ] [succ] each ==> [2 3 4]
[ ] [42] each ==> [ ]
Yes, it does look like a sensible sort of combinator to have.

> each is tolerant:
>
> [1 [4 5 6]] [+] each
> [5 6 7]

But, similar to the case at the end of my reply,
what do you do when the binary operator is not + but, say cons:

[[1 2 3] [[4] [5] [6]] [cons] each
==> [[1 4] [2 5] [3 6] ] ? ordinary each
==> [[[1 2 3] 4] [[1 2 3] 5] [[1 2 3] 6] ] ? "tolerance of each"

> this is called "atomic extension". again, if transpose were
> tolerant, 'each' could be defined (inefficiently) as
>
> each == [transpose] dip [infra first] cons map


>
> (in my version of joy - 15:46:02 may 13 2003 (NOBDW) - tranpose
> doesn't work as i expected - shouldn't [[1 2 3][4 5 6]] tranpose
> -> [[1 4][2 5][3 6]] ?)

It works for me.
The 'transpose' operator is in the seqlib.joy "sequence" library,
and there is an identical one 'm-transpose-m' in the mtrlib.joy
"matrix" library.

> the atomic primitives of k have a built-in each-to-the-atoms
> recursion. e.g. [[1 2 3][4 5 6]] [+] each <-> [1 2 3][4 5 6] +.

But I am not so sure about the built-in-each for the atoms,
for two reasons: (1) It will only work for atoms, of course,
and for non-atomic operators to be 'each'ed over a list there
would still have to be a combinator 'each' to handle arbitrary
quotations. (2) There are likely to be some (perhaps not many)
cases of ambiguity arising:
[[1 2] [3]] [[4] [5 6]] concat
=> [[1 2] [3] [4] [5 6]] ? (concat of two lists)
=> [[1 2 4] [3 5 6]] ? (built-in-each for concat)

Thanks for the discussion.

- Manfred

stevan apter — 2003-05-30 12:38:46

----- Original Message -----
From: <phimvt@...>
To: <concatenative@yahoogroups.com>
Sent: Friday, May 30, 2003 2:36 AM
Subject: Re: [stack] atomic extension, each


>
> On Thu, 29 May 2003, stevan apter wrote:
>
> > related to my previous post:
> >
> > k has a combinator 'each' which resembles map. in joyish
> > terms, it takes a size n list of lists and an n-ary program
> > p and applies p to corresponding elements of the lists.
> >
> > [[1 2 3][4 5 6]] [+] each
> > [5 7 9]
>
> I agree that 'each' might indeed be a very useful addition to
> Joy, and some definition similar to yours would be right.
> It resembles mapr2 (= zipwith) and the (unwritten) map2 for
> Joy in the binary case at least. But it uses a single list
> for the two list operands, rather than two separate lists.
> For the binary case this would do:
> each == [uncons uncons pop] dip mapr2 (or map2 in future)
> But you are suggesting the most general case, perhaps even
> n = 0:
> [[1 2 3][4 5 6][7 8 9]] [+ +] each ==> [12 15 18]
> [[1 2 3][4 5 6] ] [+ ] each ==> [5 7 9]
> [[1 2 3] ] [succ] each ==> [2 3 4]
> [ ] [42] each ==> [ ]
> Yes, it does look like a sensible sort of combinator to have.

there are two specialized forms, which are also useful:

[10 20] [1 2 3] [+] right
[[11 21] [12 22] [13 23]]

[1 2 3] [10 20] [+] left
[[11 21] [12 22] [13 23]]

>
> > each is tolerant:
> >
> > [1 [4 5 6]] [+] each
> > [5 6 7]
>
> But, similar to the case at the end of my reply,
> what do you do when the binary operator is not + but, say cons:
>
> [[1 2 3] [[4] [5] [6]] [cons] each
> ==> [[1 4] [2 5] [3 6] ] ? ordinary each
> ==> [[[1 2 3] 4] [[1 2 3] 5] [[1 2 3] 6] ] ? "tolerance of each"

[[1 2 3] [[4] [5] [6]]] [cons] each
[[1 4] [2 5] [3 6]]

i.e.

1 [4] -> [1 4]
2 [5] -> [2 5]
3 [6] -> [3 6]

neither [1 2 3] nor [[4] [5] [6]] is an atom - they're both
lists of size 3.

>
> > this is called "atomic extension". again, if transpose were
> > tolerant, 'each' could be defined (inefficiently) as
> >
> > each == [transpose] dip [infra first] cons map
>
>
> >
> > (in my version of joy - 15:46:02 may 13 2003 (NOBDW) - tranpose
> > doesn't work as i expected - shouldn't [[1 2 3][4 5 6]] tranpose
> > -> [[1 4][2 5][3 6]] ?)
>
> It works for me.
> The 'transpose' operator is in the seqlib.joy "sequence" library,
> and there is an identical one 'm-transpose-m' in the mtrlib.joy
> "matrix" library.

ah - i haven't gotten to the point where i know how to work
with the joy libraries. i need to spend some time on this ...
i thought transpose was a primitive.

>
> > the atomic primitives of k have a built-in each-to-the-atoms
> > recursion. e.g. [[1 2 3][4 5 6]] [+] each <-> [1 2 3][4 5 6] +.
>
> But I am not so sure about the built-in-each for the atoms,
> for two reasons: (1) It will only work for atoms, of course,
> and for non-atomic operators to be 'each'ed over a list there
> would still have to be a combinator 'each' to handle arbitrary
> quotations.

in k (ck) there's a non-atomic operator 'find'

list x ? -> index of first occurrence of x in list
or list size if x not in list.

[[[10 20 30 20][40 50][60 70]] [20 30 60]] [?] each
[1 2 0]

'find' is the inverse of 'at'.

each penetrates just one level - whatever it finds there is
what it finds. but in APL, 'find' is "right-atomic". if x
is an atom, it behaves just like k's 'find'. but if x is a
list, then it penetrates to the atoms in x and does a 'find'
with that. the result has the structure of x. so there is
scope for deciding how primitives like 'find' behave.

(2) There are likely to be some (perhaps not many)
> cases of ambiguity arising:
> [[1 2] [3]] [[4] [5 6]] concat
> => [[1 2] [3] [4] [5 6]] ? (concat of two lists)
> => [[1 2 4] [3 5 6]] ? (built-in-each for concat)

right - concat shouldn't be atomic. i think that most primitives
are either obviously atomic (like +) or obviously not (like concat
and size). there are only a few (at least in my experience) which
aren't obviously one or the other (like 'find'), and in each such
case the standard sorts of deliberation are called for - ease of
use, typical cases, consistency with other cases, &c.

>
> Thanks for the discussion.

thank you!

>
> - Manfred
>
>
>
> To unsubscribe from this group, send an email to:
> concatenative-unsubscribe@egroups.com
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>