Re: Array Dimensionality
I think this proposal goes to far in the dwimmery direction- On Sat, Jun 13, 2009 at 12:58 PM, John M. Dlugosz2nb81l...@sneakemail.com wrote: Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: So, how do I deal with a multidim array? Well, TIMTOWTDI... my @a = 1,[2,[3,4]]; say @a[1][1][1]; say @a[1;1;1]; # I'm not sure this is correct I think that it should be. That is, multi-dim subscript is always the same as chained subscripts, regardless of whether the morphology is an array stored as an element, or a multi-dim container, or any mixture of that as you drill through them. I've not written out a full formalism yet, but I've thought about it. The multi-dim subscript would return a sub-array if there were fewer parameters than dimensions, an element if exact match, and recursively apply the remaining subscripts to the element if too many. Or.. (I'm using the proposed capture sigil here, which has '@%a' as its expanded form) my ¢a = 1,(2,(3,4); say ¢a[1][1][1]; say ¢a[1;1;1]; I think that makes the semantics of the API more clear... daniel The plain Array would work too, in the nested morphology: my @a = 1,[2,[3,4]]; @a has 2 elements, the second of which is type Array. say @a[1][1][1]; naturally. say @a[1;1;1]; means the same thing, intentionally. say @a[1][1;1]; say @a[1;1][1]; ditto. My thought is that captures, multi-D arrays, and arrays of arrays are all different data structures, the programmer will pick them or some mix of them for a reason, and expect consistent access semantics. I agree that the various types should be transparently converted when necessary, but the dwimmery proposed on indexing could make it hard to find bugs in code dealing with complicated data structures. The problem comes with nested structures. Let's talk about a multi-D array, where each element is another multi-D array. This is also an example of my understanding of multi-D list initialization- the specs are silent on that other than initializing elements one at a time eg. @md[1;0] = 4;- apologies for squeezing two topics into one post. # Build it piece by piece, first using explicitly dimensioned sub-arrays # Doesn't matter if the initialization is a list, array, capture of arrays. The RHS is in list context which flattens a capture, and the explicit dimension will pour them all into a 2x2 array. my @sub1[2;2]=(99,\('a',[b BB]; 'c'; CC) ; 88, [1,2,3]); my @sub2[2;2]=77,[d e f], 66,[4,5,6]; my @sub3[2;2]=(55; [g h i], 44, [7,8,9]); # Use slice context to retain the 2x2 shape my @@sub4=([p q r], 33; [10,11,12], 22); # A single column, two high my @sub5[1;2]=([s t u]; [13,14,15]); # 3 ragged rows, 1 long then 2 long then 3 long my @sub6[3;*]=('row1'; row2a row2b; row3a row3b row3c); =begin comment 3 ragged columns, first 3 high, the 2 high, then 3 high c1a c2a c3a c1b c2b c3b c1c c3c =end comment my @sub7[*;3]=(c1a c2a c3a; c1b c2b c3b; 'c3a', Nil, 'c3c'); # Perilous? # Simulate a sparse array, set two elements my @sub8[*;*]; @sub8[(5;6),(8;0)]=elem5_6 elem8_0; # Now build a multi-dimensional array, each element of which is a multi-D array my @a[2;2;2]=\(@@sub1; @@sub2; @@sub3; @@sub4; @@sub5; @@sub6; @@sub7; @@sub8); # This also builds an 8-element 3D cube. Not sure about , vs ; below my @@b=\( \( \(@@sub1; @@sub2); \(@@sub3; @@sub4)); \(\(@@sub5; @@sub6); \(@@sub7; @@sub8))); # Same as above, but no captures, use slices all the way. Valid? my @@c=@@( @@( @@(@@sub1; @@sub2); @@(@@sub3; @@sub4)); @@(@@(@@sub5; @@sub6); @@(@@sub7; @@sub8))); Returning to John's post- In this case all these accessors return different elements- say @a[1][1][1]; BB @a[1] is accessing @a as a flat array, so that returns the 2nd element of @a which is \('a',[b BB]; 'c'; CC), which is then treated as a flat list by the next [1] subscript. The 2nd element of the 2nd element of that is BB. say @a[1;1;1]; @sub8 say @a[1][1;1]; CC @a[1] is \('a',[b BB]; 'c'; CC) which is now treated as a multi-D array. [1;1] asks for the lower-right corner of that 2x2 array, which is CC. say @a[1;1][1]; @sub8 S09 states: You need not specify all the dimensions; if you don't, the unspecified dimensions are wildcarded. So the above becomes @a[1;1;*][1] @a[1;1;*] is \(@@sub7;@@sub8), 2nd element of that is @sub8 S09's Cascaded subscripting of multidimensional arrays says the above will either fail or produce the same results as the equivalent semicolon subscripts. Following that part of the spec, it should convert to @a[1;1;1] and still return @sub8. But what I would really like is a strict array mode that would give me an error when using a subscript dimensioned different from the array's dimensions. I think that if an array has explicit dimensions they need to be obeyed, with 1D access a specific allowed exception. These examples shows a necessity for distinctly different semantics for @a[1][1][1], @a[1][1;1], and @a[1;1;1], which conflicts with S09's Cascaded
Re: Array Dimensionality
Apologies for the long post with mistakes in it. I'm going to try again, biting off less. my @g[2;2]; @g[0;0]='r0c0'; @g[0;1]='r0c1'; @g[1;0]='r1c0'; @g[1;1]='r1c1'; @g[1] is r1c0 r1c1 due to S09: Multi-dimensional arrays, on the other hand, know how to handle a multidimensional slice, with one subslice for each dimension. You need not specify all the dimensions; if you don't, the unspecified dimensions are wildcarded. @g[1] becomes @g[1;*] which is ('r1c0', 'r1c1') (@g[1])[1] is then 'r1c1', which is the same result as @g[1;1] Using that logic, I can't think of a case where @a[1;1;1] means something different from ((@a[1])[1])[1]. @a[1] will become @a[1;*;*] producing a 2d slice of the 2nd row plane, then we get the 2nd to the right column of that from the next slice, and finally the 2nd back element of that. In fact I'd suggest that 'unspecified dimensions are wildcarded' means we don't need the Cascaded subscripting of multidimensional arrays section. I'd still like to have an error or warning on treating a multi-D array as an array of arrays.
Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))
Larry Wall larry-at-wall.org |Perl 6| wrote: Alternately, we leave @@ (or @%) meaning ¢ and instead let some other syntax take over the pay attention to the capture's structure semantics from @@. Maybe it's another use for the zen slice: pay attention to the capture's structure is a can of worms. As things stand now in the Synopses, you get a lot of empty extra wrappers around things. You don't want to keep that exact! When you are not doing full-blown flattening, which levels in the morphology are extra due to passing though functions or grouping parens, and which are intended to be part of the final structure? Since the crazy stuff inside the capture is usually invisible, people will have a hard time using that correctly. (A literal reading of the synopses now gives us the morphology illustrated at http://www.dlugosz.com/Perl6/web/med-loop.html, and I hope to remove _some_ of those extra wrappings through refinement of the rules when I get around to studying that in detail.) My thoughts at this point is that slice context needs to *know* it is being rolled up into a final result that is a 2-dim array. The rules for that will strip out extra wrappers except where it really is significant, designed through use cases of seeing what common constructs actually produce. A shaped array knows what needs to be poured into it, so the RHS can be flattened. The single-dim array is just a special case of that; it generalizes to higher dimensions just fine, as seen in languages like APL. A smart shaped assignment, to handle containers with * in other than the highest position, can be supplied as part of a multi-dim array Module, designed separately along with a coherent set of features such as general vector-driven transposes etc. --John
Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))
Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: So, how do I deal with a multidim array? Well, TIMTOWTDI... my @a = 1,[2,[3,4]]; say @a[1][1][1]; say @a[1;1;1]; # I'm not sure this is correct I think that it should be. That is, multi-dim subscript is always the same as chained subscripts, regardless of whether the morphology is an array stored as an element, or a multi-dim container, or any mixture of that as you drill through them. I've not written out a full formalism yet, but I've thought about it. The multi-dim subscript would return a sub-array if there were fewer parameters than dimensions, an element if exact match, and recursively apply the remaining subscripts to the element if too many. Or.. (I'm using the proposed capture sigil here, which has '@%a' as its expanded form) my ¢a = 1,(2,(3,4); say ¢a[1][1][1]; say ¢a[1;1;1]; I think that makes the semantics of the API more clear... daniel The plain Array would work too, in the nested morphology: my @a = 1,[2,[3,4]]; @a has 2 elements, the second of which is type Array. say @a[1][1][1]; naturally. say @a[1;1;1]; means the same thing, intentionally. say @a[1][1;1]; say @a[1;1][1]; ditto. --John
Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))
On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruosodan...@ruoso.com wrote: Ok, There's one thing that is not clear in the thread, which is when an array is multidimensional or not... For instance: �...@a = (1, 2, 3; 4, 5, 6; 7, 8, 9); Will produce a flatten array, because list assignment causes flattening, so the dimensionality was lost. Right. I should have said: @@a = (1, 2, 3; 4, 5, 6; 7, 8, 9); -- Jonathan Dataweaver Lang
Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))
Em Sex, 2009-06-12 às 11:52 -0700, Jon Lang escreveu: On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruosodan...@ruoso.com wrote: Ok, There's one thing that is not clear in the thread, which is when an array is multidimensional or not... For instance: @a = (1, 2, 3; 4, 5, 6; 7, 8, 9); Will produce a flatten array, because list assignment causes flattening, so the dimensionality was lost. Right. I should have said: @@a = (1, 2, 3; 4, 5, 6; 7, 8, 9); The important point here is that it means we're dealing with a different type, so it can actually behave differently, so @@a.rotate would rotate the first dimension only.. maybe @@a.rotate(1;1) would mean to rotate by 1 in the first dimension and by 1 in the second, producing (5, 6, 4; 8, 9, 7; 2, 3, 1) daniel
Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))
On Fri, Jun 12, 2009 at 04:00:10PM -0300, Daniel Ruoso wrote: : Em Sex, 2009-06-12 às 11:52 -0700, Jon Lang escreveu: : On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruosodan...@ruoso.com wrote: : Ok, There's one thing that is not clear in the thread, which is when an : array is multidimensional or not... : For instance: :@a = (1, 2, 3; 4, 5, 6; 7, 8, 9); : Will produce a flatten array, because list assignment causes flattening, : so the dimensionality was lost. : Right. I should have said: : @@a = (1, 2, 3; 4, 5, 6; 7, 8, 9); : : The important point here is that it means we're dealing with a different : type, so it can actually behave differently, so @@a.rotate would : rotate the first dimension only.. : : maybe @@a.rotate(1;1) would mean to rotate by 1 in the first dimension : and by 1 in the second, producing : : (5, 6, 4; 8, 9, 7; 2, 3, 1) I think captures are a bit of a red herring here. Arrays can be shaped without the @@ sigil, and that is part of its type, so assignment to @a and @.rotate can also do the right thing. The @@ context was originally just a way of declaring a context that turns nested captures into a multidimensional array at binding or coercion time. So @a := @@(1,2,3; 4,5,6; 7,8,9); used to be defined as the same as @a := [[1,2,3], [4,5,6], [7,8,9]]; Treating @@ as a capture sigil would make @@ coercion a no-op. So perhaps @@ isn't the Texas form of a capture sigil after all. Alternately, we leave @@ (or @%) meaning ¢ and instead let some other syntax take over the pay attention to the capture's structure semantics from @@. Maybe it's another use for the zen slice: @a = (1,2,3; 4,5,6; 7,8,9); # 1..9 @a[] = (1,2,3; 4,5,6; 7,8,9); # [1,2,3], [4,5,6], [7,8,9] Interestingly, that would mean that @a = 1,2,3; # 1,2,3 3 elems @a[] = 1,2,3; # [1,2,3] 1 elem! much like subscripts assume .[1,2,3] is a 1-dim slice of three elements, not a 3-dim vector pointing to a single element. There's something slightly pleasing about the equivalence @a = [1,2,3]; @a[] = 1,2,3; Larry