Re: Dimension of slices; scalars versus 1-element arrays?
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
Re: Dimension of slices; scalars versus 1-element arrays?
On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote: @a[4; 0..5]; a 1x6 array (probably correct)? Or a 6 array (probably not correct)? For the ignorant among us (such as myself), what is a 6 array? Google and pdl.perl.org did not yield any immediate answers. --Dks -- [EMAIL PROTECTED]
Re: Dimension of slices; scalars versus 1-element arrays?
6 elements..? On Mon, 10 Jan 2005 07:33:11 -0800, David Storrs [EMAIL PROTECTED] wrote: On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote: @a[4; 0..5]; a 1x6 array (probably correct)? Or a 6 array (probably not correct)? For the ignorant among us (such as myself), what is a 6 array? Google and pdl.perl.org did not yield any immediate answers. --Dks -- [EMAIL PROTECTED]
Re: Dimension of slices; scalars versus 1-element arrays?
On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote: : I just re-read Synopsis 9, which covers PDL-related actions and array slicing, : and came to the conclusion that either (A) there's a hole in the syntax as it : is lain out, (B) I lack sufficient understanding of what has been thought : out so far, or (C) that part of the language definition isn't finished yet. I expect C is closest to the mark. :-) : Is the perl6 expression : @a[4; 0..5]; : a 1x6 array (probably correct)? Or a 6 array (probably not correct)? Certainly the former. I don't think dimensions should ever disappear accidentally. : If the former, how do you specify that you want the latter? I don't know offhand. I see both the lure and the danger of the extra parens, so we'll probably not go that route. We could find some keyword that destroys the current dimension while supplying a scalar argument: @a[gone(4); 0..5]; Or maybe we want some notation that is explicitly a null slice with a scalar value, maybe something like: @a[() but 4; 0..5]; or @a[():pick(4); 0..5]; or @a[4 but dim(); 0..5]; or maybe even something strange like: @a[()=4; 0..5]; But I'm certainly open to other suggestions. Larry
Re: Dimension of slices; scalars versus 1-element arrays?
Sorry, too terse :-) I meant ...a two dimensional array with 1x6 elements (probably correct)? Or a one dimensional array with 6 elements (probably not correct)? Cheers, Craig Quoth David Storrs on Monday 10 January 2005 08:33 am, On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote: @a[4; 0..5]; a 1x6 array (probably correct)? Or a 6 array (probably not correct)? For the ignorant among us (such as myself), what is a 6 array? Google and pdl.perl.org did not yield any immediate answers. --Dks
Re: Dimension of slices; scalars versus 1-element arrays?
H... It would be easy to distinguish the slicing cases if it were easier to distinguish between a number and a list containing just [In fact, that is more or less how perl5/PDL's arg-list-based slicer ('mslice') does things.] At the top of Synopsis 9, there's a discussion about exactly that: @array[0..10; 42; @x] is really short for @array.postcircumfix:[ ]( == [0..10], [42], [EMAIL PROTECTED] ); though in the list of lists form, a bare number is interpreted as if it were a list of one element, so you can also say: @array.postcircumfix:[ ]( == [0..10], 42, [EMAIL PROTECTED] ); I believe that this is Wrong, because the distinction that is being blurred turns out to be important. Ideally, those two postcircumfix cases should do different things (slice versus index). But you can have your cake and eat it too. If those postcircumfix cases were really different, one could take advantage of the still-unused postfix unary '!' (for example) to distinguish: @array[0..10; 42!; @x] [[ maps to ]] (== [0..10], 42 , [EMAIL PROTECTED] ); @array[0..10; 42; @x] [[ maps to ]] (== [0..10], [42], [EMAIL PROTECTED] ); Then the default behavior is consistent (semicolons denote lists of lists) but there is an escape hatch that lets you make a list of scalars-and-lists. Quoth Larry Wall on Monday 10 January 2005 11:04 am, On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote: : I just re-read Synopsis 9, which covers PDL-related actions and array : slicing, and came to the conclusion that either (A) there's a hole in the : syntax as it is lain out, (B) I lack sufficient understanding of what : has been thought out so far, or (C) that part of the language definition : isn't finished yet. I expect C is closest to the mark. :-) : Is the perl6 expression : @a[4; 0..5]; : a 1x6 array (probably correct)? Or a 6 array (probably not correct)? Certainly the former. I don't think dimensions should ever disappear accidentally. : If the former, how do you specify that you want the latter? I don't know offhand. I see both the lure and the danger of the extra parens, so we'll probably not go that route. We could find some keyword that destroys the current dimension while supplying a scalar argument: @a[gone(4); 0..5]; Or maybe we want some notation that is explicitly a null slice with a scalar value, maybe something like: @a[() but 4; 0..5]; or @a[():pick(4); 0..5]; or @a[4 but dim(); 0..5]; or maybe even something strange like: @a[()=4; 0..5]; But I'm certainly open to other suggestions. Larry
Re: Dimension of slices; scalars versus 1-element arrays?
Double hmmm That would also supplant the lone '*' wart in indexing syntax: instead of saying @array[0..10;*;@x] you could say @array[0..10; !; @x] Presumably, the '!;' would expand to the scalar undef value, which could be interpreted as do nothing on this axis, while in the related construct @a=(); @array[0..10; @a; @x] the '@a;' would instead expand to a list ref pointing to the empty list, which could be interpreted instead as return the null set -- minimizing surprise if @a is only occasionally empty. (Of course, substitute your favorite postfix unary character instead of '!'; '*' would work just as well...) Quoth Craig DeForest on Monday 10 January 2005 03:56 pm, H... It would be easy to distinguish the slicing cases if it were easier to distinguish between a number and a list containing just [In fact, that is more or less how perl5/PDL's arg-list-based slicer ('mslice') does things.] At the top of Synopsis 9, there's a discussion about exactly that: @array[0..10; 42; @x] is really short for @array.postcircumfix:[ ]( == [0..10], [42], [EMAIL PROTECTED] ); though in the list of lists form, a bare number is interpreted as if it were a list of one element, so you can also say: @array.postcircumfix:[ ]( == [0..10], 42, [EMAIL PROTECTED] ); I believe that this is Wrong, because the distinction that is being blurred turns out to be important. Ideally, those two postcircumfix cases should do different things (slice versus index). But you can have your cake and eat it too. If those postcircumfix cases were really different, one could take advantage of the still-unused postfix unary '!' (for example) to distinguish: @array[0..10; 42!; @x] [[ maps to ]] (== [0..10], 42 , [EMAIL PROTECTED] ); @array[0..10; 42; @x] [[ maps to ]] (== [0..10], [42], [EMAIL PROTECTED] ); Then the default behavior is consistent (semicolons denote lists of lists) but there is an escape hatch that lets you make a list of scalars-and-lists. Quoth Larry Wall on Monday 10 January 2005 11:04 am, On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote: : I just re-read Synopsis 9, which covers PDL-related actions and array : slicing, and came to the conclusion that either (A) there's a hole in : the syntax as it is lain out, (B) I lack sufficient understanding of : what has been thought out so far, or (C) that part of the language : definition isn't finished yet. I expect C is closest to the mark. :-) : Is the perl6 expression : @a[4; 0..5]; : a 1x6 array (probably correct)? Or a 6 array (probably not correct)? Certainly the former. I don't think dimensions should ever disappear accidentally. : If the former, how do you specify that you want the latter? I don't know offhand. I see both the lure and the danger of the extra parens, so we'll probably not go that route. We could find some keyword that destroys the current dimension while supplying a scalar argument: @a[gone(4); 0..5]; Or maybe we want some notation that is explicitly a null slice with a scalar value, maybe something like: @a[() but 4; 0..5]; or @a[():pick(4); 0..5]; or @a[4 but dim(); 0..5]; or maybe even something strange like: @a[()=4; 0..5]; But I'm certainly open to other suggestions. Larry
Dimension of slices; scalars versus 1-element arrays?
I just re-read Synopsis 9, which covers PDL-related actions and array slicing, and came to the conclusion that either (A) there's a hole in the syntax as it is lain out, (B) I lack sufficient understanding of what has been thought out so far, or (C) that part of the language definition isn't finished yet. Is the perl6 expression @a[4; 0..5]; a 1x6 array (probably correct)? Or a 6 array (probably not correct)? If the former, how do you specify that you want the latter? There's a significant difference between the two -- for example, if '4' is some list expression that happens to have just one element, you don't want the whole shape of the output array to change. The problem is the near-universal wart that scalars are not merely lists with but a single element, so you need to be able to tell the difference between a dimension that exists but has size 1, and a dimension that doesn't exist. (In perl5, all arrays are one-dimensional, so the issue is sidestepped by the presence of scalar/list context.) Perl5/PDL solves the problem with 'extra-parenthesis' syntax in slicing, and with zero-size dimensions in operators like range() [no relation to perl6 range operators] that take a dimension size list. Examples: $a( 4, 0:5 ); # This perl5/PDL slice is a 1x6-array $a( (4), 0:5 ); # This perl5/PDL slice is a 6-array $a-range($xy,[1,3]);# This perl5/PDL range is a 1x3-array $a-range($xy,[0,3]);# This perl5/PDL range is a 3-array The extra parens only remove the dimension if they would otherwise be no-ops. It is not (yet) clear to me whether the extra parens syntax is a good solution for perl 6 slices.