Hmmm... David, you seem to have covered all the issues with that rather lucid screed [attached at bottom]. I have a couple of dragon-nits to pick, one involving infrastructure and one involving syntax.
First: it seems strange to me to add yet another property ("but used_to_be_scalar") to the output of the LoL semicolon, when there's a perfectly good distinction still floating around (the one that is deliberately blurred between [1] and 1). Using the scalarness of a LoL element has the potential to make some really esoteric but useful things very easy to do, since it's a general syntax that could be used for any LoL, not just for slicing. But then, there may be good reasons (not obvious to me) to use a property. Second: Regardless of the LoL infrastructure, we seem to be adopting opposing viewpoints on whether scalar-ish element in the LoL should be a scalar by default, with a syntactic hook to denote it as a list-of-1; or whether it should be a list-of-1 by default, with a syntactic hook to denote it as a scalar. There are good reasons why either case will surprise a nontrivial subset of people. Maybe we can sidestep the issue by making use of list context as you pointed out. Hmmm... What about replacing '*' entirely, with the yadda-yadda-yadda? Certainly '0...' ought to enumerate (lazily) everything from 0 to infinity, so it ought to return everything. But then why not make term-'...' into an abbreviation for '0...'? That sort of keeps the conceptual crud down while letting everything get written straightforwardly: How about this scenario?: Ground rules: list expressions slice; scalar expressions index; Basic cases: [5 ; 0..6] # scalar exps are scalar by default (index) [(5) ; 0..6] # 5 is now in list context (slice) [1..1 ; 0..6] # '..' returns a list of 1 element (slice) [0... ; 0..6] # '0...' is a valid lazy list, if ugly (whole axis) [... ; 0..6] # '...' acts like '0...' (whole axis) [* ; 0..6] # OK, have it your way - '*' is a synonym for '0...'. Cases that return nothing: (either an empty list or undef...) [ ; 0..6] # An empty list yields nothing [undef; 0..6] # undefined value yields nothing [1..0; 0..6] # '..' gives list of no elements; you get nothing Forcing syntax: [+(5) ; 0..6] # unary '+' forces scalar context (index always) [(5) ; 0..6] # List-context parens force list context (slice always) [5* ; 0..6] # postfix-* forces a slice? (no conflicts?) Not accepted syntax: [*5 ; 0..6] # does something strange -- tries to index with a glob. The only reason to gripe about that (for me) is that surrounding parens change sense compared to perl5/PDL slicing -- but that seems trivial compared to hammering out something that's convenient for everyone and still makes some sort of coherent sense. Quoth David Green on Wednesday 12 January 2005 05:40 am, > OK, so at issue is the difference between an element of an array ($p5[1]) > and a slice (that might contain only one element, @p5[1]), only > generalised to n dimensions. (A problem which didn't exist in P5 because > there were no higher dimensions!) > > And we don't want @B[4; 0..6] to reduce to a 1-D 6-array because then > dimensions would just be disappearing into some other...dimension. > (To lose one dimension is a misfortune, to lose two is plane careless....) > On the other hand, nobody wants to have to write @B[gone(4)] every time > you need an array element. > > Given $a=42 and @a=(42), what if @X[$a] returned a scalar and @[EMAIL > PROTECTED] > returned a slice? Similarly, @X[$a; 0..6] would return a 6-array, and > @[EMAIL PROTECTED]; 0..6] a 1x6-array -- scalar subscripts drop a given > dimension and > array subscripts keep it. (I think this is almost what Craig was > suggesting, only without giving up ! for factorial. =)) > > The list-of-lists semicolon can still turn the 42 into [42], so that if > you have a list-of-listy function that doesn't care whether you started > with scalars or not, it doesn't have to know. But really the LoL > semicolon would turn 42 into C<[42] but used_to_be_scalar>, so that > something that *does* care (e.g. subscripting an array) can simply check > for that property. > > Using a scalar to get a scalar feels rather appropriate, and not too > surprising, I think. Most people would probably expect @X[$a] to return > a scalar, and use @[EMAIL PROTECTED] to mean a slice (if @a happened to have > only a > single element, you're still probably using an array subscript to get > possibly many elements -- otherwise why would you be using an array @a > instead of just a plain scalar in the first place?) > > Plus if you do want to force an array subscript instead of a scalar, or > vice versa, you don't need any new keywords to do it: @[EMAIL PROTECTED]; > 0..6] or > @X[[42]; 0..6] (which is the same as @X[list 42; 0..6], right? Which > could also be written @X[*42; 0..6], which is kind of nice, because [*42] > means "give me the 42nd slice" while [*] means "give me an unspecified > slice, a slice of everything".) > > > Anyway, delving right into the can of wyrms, in P5 there were list, > scalar, and void contexts (1-D, 0-D, and... uh... -1-D?), but now that we > have real multidimensional arrays, we could have infinite contexts (ouch). > Well, there must be some nice way to generalise that, but it raises a > bunch of questions. (I can imagine "table context" being reasonably > popular.) > > Various functions in P5 left the dimension of their arg untouched (take a > list, return a list), or dropped it down one (take a list, return a > scalar). (Taking a scalar and returning a list is less common, but I can > imagine a 2-D version of 'split' that turns a string into a table....) > > So in p6, should 'shift'ing an n-D array return a scalar or an array of > n-1 dimensions? It depends on whether you see it as a way to criss-cross > through an array one element at a time, or as a way to take one 'layer' > off something. Both would be useful. > > 'grep' could return a list (1-D) of all matching individual elements, but > perhaps more usefully it could preserve dimensionality: > my @board is shape(8;8); > #match alternating squares: > @checkerboard=grep { ($_.index[0] + $_.index[1])%2 } @board; > > ...to end up with a ragged 2-D array containing only the usable half of > our checkerboard. (I'm assuming we have something like .index to get the > x, y co-ords of an element?) > > 'reverse' would presumably flip around the indices in all dimensions. Ah, > the fun of coming up with new multidimensional variations on all the old > (or new) favourites! > > > - David "a head-scratcher no matter how you slice it" Green