Re: Arrays: Default Values
Rick Delaney [EMAIL PROTECTED] writes: I'd also like to point out that ruby has defaults for hashes but assigning nil (the equivalent of undef) does not set the default; delete does. Yeah, but Hashes aren't Arrays. And vice versa. -- Piers
Re: Arrays: Default Values
Aaron Sherman [EMAIL PROTECTED] writes: On Wed, 2003-01-29 at 14:54, Jonathan Scott Duff wrote: Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? my @send_partner_email is default(1); while $websignups.getline { ($id) = /UserID: (\d+)/; if /Source: External DB With No Privacy Policy/ { @send_partner_email[$id] = undef; # No answer given } elsif /Spam Me: Yes/ { @send_partner_email[$id] = 1; } else { @send_partner_email[$id] = 0; } } # If you were not in the websignups list, you signed up before privacy # policy, so we spam you (default=1) In this case, there's a true shrug answer, which is hard to deal with. We need to do something later on with the undefined case (no answer was given, and no spam warning issued). This sort of logic deferral is common to many uses of undefined values (or NULL) in databases, even when columns have defaults that are non-null. In this case surely you're better off doing this with a state object. class UnspecifiedState { method maybe_send_mail($user) { go_get_more_info } } class SendMailState { method maybe_send_mail($user) { generate_and_send_mail_to($user) } } class NoSendMailState { method maybe_send_mail($user) { } } my @send_partner_email is default(SendMailState.new); while $websignups.getline { ($id) = /UserId: (\d+)/; when /Source: External DB With No Privacy Policy/ { @send_partner_email[$id] = UnspecifiedState.new; } when /Spam Me: Yes/ { @send_partner_email[$id] = SendMailState.new; } otherwise { @send_partner_email[$id] = NoSendMailState.new; } } in other words, when you have to deal with tristate logic, make it explicit tri state logic. -- Piers
Re: Arrays: Default Values
Aaron Sherman wrote: On Tue, 2003-01-28 at 16:23, Leopold Toetsch wrote: Arrays (or hashes) don't grow on reading - never. But for less pure forms of reading: foo(@a[0]); auto-vivification will have to happen in some cases. e.g. if foo requires a lvalue parameter. A lvalue param is not strictly reading, but here has to happen something differently - yes: IMHO some sort of proxy could be passed here, saying: if you write to me, this will be at @a[0]. Or auto-vivify the entry. leo
Re: Arrays: Default Values
On Fri, Jan 31, 2003 at 05:59:46PM +0100, Leopold Toetsch wrote: A lvalue param is not strictly reading, but here has to happen something differently - yes: IMHO some sort of proxy could be passed here, saying: if you write to me, this will be at @a[0]. Or auto-vivify the entry. This is what Perl 5 does at the moment: $ perl5.8.0 -MDevel::Peek -e 'sub f{Dump($_[0])}; f($a[9])' SV = PVLV(0x8177118) at 0x8166a74 REFCNT = 1 FLAGS = (GMG,SMG) IV = 0 NV = 0 PV = 0 MAGIC = 0x816e7e0 MG_VIRTUAL = PL_vtbl_defelem MG_TYPE = PERL_MAGIC_defelem(y) TYPE = y TARGOFF = 9 TARGLEN = 1 TARG = 0x817ad88 SV = PVAV(0x8183bd4) at 0x817ad88 REFCNT = 2 FLAGS = () IV = 0 NV = 0 ARRAY = 0x0 FILL = -1 MAX = -1 ARYLEN = 0x0 FLAGS = (REAL) However, I think this is clumsy and overly complex; since Perl6 allows us to declare parameters rw or whatever, I think it should always autovivify unless we know the param is read-only (or in-only, or whatever the correct terminology is). -- There's something wrong with our bloody ships today, Chatfield. Admiral Beatty at the Battle of Jutland, 31st May 1916.
Re: Arrays: Default Values
Dave Mitchell wrote: On Fri, Jan 31, 2003 at 05:59:46PM +0100, Leopold Toetsch wrote: IMHO some sort of proxy could be passed here, saying: if you write to me, this will be at @a[0]. Or auto-vivify the entry. This is what Perl 5 does at the moment: $ perl5.8.0 -MDevel::Peek -e 'sub f{Dump($_[0])}; f($a[9])' Ah, same idea ;-) However, I think this is clumsy and overly complex; since Perl6 allows us to declare parameters rw or whatever, I think it should always autovivify unless we know the param is read-only (or in-only, or whatever the correct terminology is). It's probably not too complex, it's IMHO the same, what we would need to implement the multi_keyed opcodes like: @a[$x] = @b{$y} - @c[2;$i] We can't implement all the opcodes per se, this would need ~64K ops, so one of my proposals (some time ago) was, to split this operation in 3 keyed fetch ops and one plain subtraction. The LHS whould need - as I can set it now - a very similar treatment like above's example. To come back to the array example: - when the sub param is ro, you said it, no autovifiy should happen - for rw (the default?) there is always a chance, that no write will occur, and for the case nothing gets written, we have a volatile PMC (the proxy) collected with the next DOD run. With autovivification we create an anchored value, that is more expensive. A (of course) constructed example could check in a subroutine, if one/some/all elements exist sub e() {return exists shift;} for ([EMAIL PROTECTED]) - $i { do_some($i) if e($a[$i]); } # modulo syntax, operator and other errs :) And, from DWIM POV, autovivification was not the clearest things in the docs, when it could happen or not. I would just expect: when I don't set this very elememt in this array, why is something there. leo
Re: Arrays: Default Values
Jonathan Scott Duff wrote: The solution I advocate is to allow even primitive types to hold undef. Why do you then use a primitive type in the first place? IMHO: 1) primitive types are what they are - no undef, no attributes, just e.g. plain integers (or shorts or bits ...) 2) if you want to store additional information use a normal perl variable i.e. a parrot PMC. Why on earth would we want to take advantage of primitive types - when then people additionally want to tuck their birthdate on it? The array of 1e6 ints takes 1e6 words, the same array of PerlInts allocates ~10 times the memory and causes additional a lot of GC overhead. And finally, if you a need a few more bits of information for your IntArray[1e6], then wrap it into your own array class - we are speaking of perl here - or do we? -Scott leo
Re: Arrays: Default Values
On 29 Jan 2003 14:29:52 -0500, Aaron Sherman wrote (in part): ajs As for the argument that testing for true non-existentness is a ajs burden, check out the way Perl5 does this. Hint: there's a central ajs sv_undef, and that's not what array buckets are initialized to Either you're dead wrong, or you typo'd there. After my @a; $a[4] = 1; The array buckets @a[0..3] most certainly ARE initialized to PL_sv_undef in p5. That's how Cexists $a[2] knows to return false (PL_sv_no) instead of true (PL_sv_yes). And, yes, Cdelete $a[4] re-sets that slot to point to the one true central undef again. This is different from what happens on Cundef $a[1]; -- that actually makes a new SV which is a *copy* of the central undef and makes that the new value in that slot. Thus, even with just the above sequence, Cexists $a[1] would now be true in p5. Please, folks, this discussion's getting complicated enough without making mistaken claims about what p5 currently does, even when that's by accident. -- Spider Boardman (at home) [EMAIL PROTECTED] The management (my cats) made me say this.http://users.rcn.com/spiderb/ PGP public key fingerprint: 96 72 D2 C6 E0 92 32 89 F6 B2 C2 A0 1C AB 1F DC
Re: Arrays: Default Values
On Wed, 2003-01-29 at 16:41, Nicholas Clark wrote: And the demonstration was as expected? Yes, of course. If you modify a hash, or look at another hash, you should not expect the same results. Why would you? More importantly, why would the conversation threat up until now lead to such an example? -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
On Wed, 2003-01-29 at 17:12, Dan Sugalski wrote: At 12:40 PM -0500 1/29/03, Aaron Sherman wrote: Elements of a has ARE ordered, just not the way you may expect. Just to nip this one in the bud... The bud was back that-a-way about 3 days If people start assuming that there's *any* ordering to hashes, I promise I *will* make sure that parrot's external hash class starts returning keys and values in random order. Hashes have no guarantee of ordering, and perl 5 (as Nick demonstrated) delivers on that lack of guarantee. They guarantee (as stated in the docs for keys, in the perlfunc manpage, go check it out) that keys, each and values will return the elements of the hash in the same order as each other as long as you don't modify the hash between calls. If Parrot calls rand on the sequencing of returned hash data, that's fine as long as it saves that seed until the hash is later updated No one has suggested, as far as I can tell, that hashes should order their values internally in any particular way. What I have suggested (and I think culture shock is a bad, but sufficient reason to say that Perl isn't going this way) is that arrays and hashes and trees and funny macaroni pictures don't need separate funky tokens to identify their naming and indexing. Indexing is easy, as far as I can tell. C%a[fire] is totally non-ambiguous. C$a[fire] depends on the type of reference in C$a. If C$a is undefined, then you need a default, but defaulting auto-vivification based on the type of the index seems pretty intuitive to me. PHP does something like this, though I don't think that it implements actual arrays at the lowest level, it just fakes them with hashes. Perl is ok with context, so there's less concern about having arrays and hashes behave differently. No biggie. On the naming side, I like the idea of tossing C%, but I'm not sure you can. C% and C@ have a unique and interesting behavior that is hard to manage otherwise. That is, they determine how assignments between containers behave. The idea that C@a=%b and C%a=%b are non-ambiguous is actually rather clever, and I'm not sure how to get that cleanly without ending up in a bit of a pickle over C@a=(@b=(%c=@d)) But, I've long since decided that we're not going to re-think those symbols because they're part of the root language, not the dialect. It would be like suggesting that regular expressions should be delimited by a function-call interface instead of matched tokens. Perl programmers just don't think that way. No matter the merits of the suggestion, it's not a debate over how it *should* be done, but rather over how it *is* done. I know I sound a little shouty, here. Sorry, it's my style. I respect you all a great deal, and that's why I think this debate was worth spending a couple of days on. Thanks all. -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
On Wed, 2003-01-29 at 17:50, Spider Boardman wrote: On 29 Jan 2003 14:29:52 -0500, Aaron Sherman wrote (in part): ajs As for the argument that testing for true non-existentness is a ajs burden, check out the way Perl5 does this. Hint: there's a central ajs sv_undef, and that's not what array buckets are initialized to Either you're dead wrong, or you typo'd there. After my @a; $a[4] = 1; The array buckets @a[0..3] most certainly ARE initialized to PL_sv_undef This has changed since I last (long ago) looked at the source for av.c. It once was the case that av_fetch could return NULL for uninitialized cells, which is why it returns an CSV** instead of an CSV*. It now looks like you're right and newly allocated cells are given a default undeffing. None the less, the point is valid. We do not HAVE to fill newly allocated arrays with undef. That yeilds a perfectly respectable non-existent case. The question is, do we *want* to do that and is it suitable to the current Parrot implementation? -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
On Thursday, January 30, 2003, at 12:03 AM, Leopold Toetsch wrote: Why do you then use a primitive type in the first place? IMHO: 1) primitive types are what they are - no undef, no attributes, just e.g. plain integers (or shorts or bits ...) 2) if you want to store additional information use a normal perl variable i.e. a parrot PMC. Why on earth would we want to take advantage of primitive types - when then people additionally want to tuck their birthdate on it? The array of 1e6 ints takes 1e6 words, the same array of PerlInts allocates ~10 times the memory and causes additional a lot of GC overhead. And finally, if you a need a few more bits of information for your IntArray[1e6], then wrap it into your own array class - we are speaking of perl here - or do we? I think this is a tremendously valuable point. The idea behind primitive types is that they are small and fast compared to full types. If you ask for them, you are explicitly saying you're willing to give up a lot of functionality in order to gain maximum efficiency. It's not that we want to avoid making Perl6 too slow. It's that we want to actively try and make it *fast*. When dealing with primitive types -- for large image manipulation, for example -- every spent clock cycle matters. We MUST allow some mechanism in Perl6 -- short of escaping to C -- by which algorithms can be tweaked to have some degree of efficiency. This is leading me to the conclusion that primitive-typed arrays should not be allowed to have defaults, period, and that attempting to place one should be a compile-time error. If you want a default, use CInt instead of an Cint, and it will work fine. MikeL
Re: Arrays: Default Values
At 9:53 AM -0800 1/30/03, Michael Lazzaro wrote: This is leading me to the conclusion that primitive-typed arrays should not be allowed to have defaults, period, and that attempting to place one should be a compile-time error. If you want a default, use CInt instead of an Cint, and it will work fine. This isn't necessarily an issue for low-level arrays/hashes. We've got to fill the new elements with something when we extend internal structures, so there's no reason not to set the default. Doesn't mean the default should be a value that can fall outside the range that's OK for the low-level type, but... -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Arrays: Default Values
On Thursday, January 30, 2003, at 09:55 AM, Dan Sugalski wrote: At 9:53 AM -0800 1/30/03, Michael Lazzaro wrote: This is leading me to the conclusion that primitive-typed arrays should not be allowed to have defaults, period, and that attempting to place one should be a compile-time error. If you want a default, use CInt instead of an Cint, and it will work fine. This isn't necessarily an issue for low-level arrays/hashes. We've got to fill the new elements with something when we extend internal structures, so there's no reason not to set the default. Doesn't mean the default should be a value that can fall outside the range that's OK for the low-level type, but... Right, we just can't do the 'undef' thing. OK, so let me see if this is right yet: my Int @a is default(2); @a[5] = 5; @a[4]; # 2 (autofilled) @a[5]; # 5 @a[6]; # 2 (out-of-bounds) undef @a[5]; # undefining the element sets it to the default @a[5]; # 2 @a[5] = undef; # same as above @a[5]; # 2 my int @a is default(2); @a[4]; # 2 (autofilled) @a[5]; # 5 @a[6]; # 2 (out-of-bounds) undef @a[5]; # 0 (Warning: using undef in int context, autoconv to 0) @a[5] = undef; # 0 (Warning: using undef in int context, autoconv to 0) @a[5]; # 0 @a[5] = 0; # nothing special about this @a[5]; # 0 Can everyone buy that? MikeL
Re: Arrays: Default Values
--- Michael Lazzaro [EMAIL PROTECTED] wrote: On Thursday, January 30, 2003, at 12:03 AM, Leopold Toetsch wrote: Why do you then use a primitive type in the first place? IMHO: 1) primitive types are what they are - no undef, no attributes, just e.g. plain integers (or shorts or bits ...) 2) if you want to store additional information use a normal perl variable i.e. a parrot PMC. Why on earth would we want to take advantage of primitive types - when then people additionally want to tuck their birthdate on it? The array of 1e6 ints takes 1e6 words, the same array of PerlInts allocates ~10 times the memory and causes additional a lot of GC overhead. And finally, if you a need a few more bits of information for your IntArray[1e6], then wrap it into your own array class - we are speaking of perl here - or do we? I think this is a tremendously valuable point. The idea behind primitive types is that they are small and fast compared to full types. If you ask for them, you are explicitly saying you're willing to give up a lot of functionality in order to gain maximum efficiency. It's not that we want to avoid making Perl6 too slow. It's that we want to actively try and make it *fast*. When dealing with primitive types -- for large image manipulation, for example -- every spent clock cycle matters. We MUST allow some mechanism in Perl6 -- short of escaping to C -- by which algorithms can be tweaked to have some degree of efficiency. This is leading me to the conclusion that primitive-typed arrays should not be allowed to have defaults, period, and that attempting to place one should be a compile-time error. If you want a default, use CInt instead of an Cint, and it will work fine. There is no reason why primitive-typed arrays can't have a default. It is the confusion of default with undef that is causing this problem. If I have: my int @a; print @a[4]; What comes out? Notice, there's no is default(woo-woo) in there. Just a plain old primitive array. =Austin
Re: Arrays: Default Values
Austin Hastings wrote: There is no reason why primitive-typed arrays can't have a default. It is the confusion of default with undef that is causing this problem. If I have: my int @a; print @a[4]; What comes out? Notice, there's no is default(woo-woo) in there. Just a plain old primitive array. I imagine that each primative type will have a default default :-) int0 str'' num0.0 etc. and if we define a prop is no_default then you get what ever junk happens to be in memory. (this for even more speed) -- Mark Biggar [EMAIL PROTECTED]
Re: Arrays: Default Values
At 10:54 AM -0800 1/30/03, Mark Biggar wrote: and if we define a prop is no_default then you get what ever junk happens to be in memory. (this for even more speed) That's not going to happen. It's too unsafe, and too open to corruption attacks. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Arrays: Default Values
--- Michael Lazzaro [EMAIL PROTECTED] wrote: Right, we just can't do the 'undef' thing. OK, so let me see if this is right yet: my Int @a is default(2); @a[5] = 5; @a[4]; # 2 (autofilled) @a[5]; # 5 @a[6]; # 2 (out-of-bounds) undef @a[5]; # undefining the element sets it to the default @a[5]; # 2 @a[5] = undef; # same as above @a[5]; # 2 undef. I feel like the duck in those AFLAC commercials. undef! undef!! @a is an array of Int (not int) and can store undef, so no error occurs when you make the assignment. But now I, the programmer, am saying that of my own volition I want an undef in there, not a 2. If I wanted @a[5] to take on the default value, I'd say so: C@a[5] = @a.default; my int @a is default(2); @a[4]; # 2 (autofilled) @a[5]; # 5 @a[6]; # 2 (out-of-bounds) undef @a[5]; # 0 (Warning: using undef in int context, autoconv to 0) Like delete @a[5]. Sets value to @a.default; @a[5] = undef; # 0 (Warning: using undef in int context, autoconv to 0) Frankly, I think that this should be a compile time error, while $b = undef; @a[5] = $b; should be a runtime warning. @a[5]; # 0 @a[5] = 0; # nothing special about this @a[5]; # 0 Can everyone buy that? Sure. =Austin
Re: Arrays: Default Values
On Thursday, January 30, 2003, at 12:49 PM, Austin Hastings wrote: undef @a[5]; # undefining the element sets it to the default @a[5]; # 2 @a[5] = undef; # same as above @a[5]; # 2 undef!! @a is an array of Int (not int) and can store undef, so no error occurs when you make the assignment. But now I, the programmer, am saying that of my own volition I want an undef in there, not a 2. If I wanted @a[5] to take on the default value, I'd say so: C@a[5] = @a.default; This is operating on Damian's premise that the presence of an undefined value is what causes the default value to be raised. So we don't have two types of undef (undef but undef, etc.)... a cell is either defined, or it's not. The presence of Cundef is what triggers the default value, regardless of how the undef got there. Thus, as Damian said, there is no way to place an undefined value in an array with a default: I'm not compelled by the counter-argument that this makes it impossible to store an Cundef in an array with a default. Because the whole point of an array having a default is to prevent those nasty out-of-range Cundefs from popping up in the first place. I'll document the behavior as Damian has specified it, since he's the ranking design team member here. If a design team member overrules, we'll change it to match. MikeL
Re: Arrays: Default Values
On Wednesday 29 January 2003 09:52 pm, Rick Delaney wrote: On Wed, Jan 29, 2003 at 01:54:10PM -0800, Michael Lazzaro wrote: On Wednesday, January 29, 2003, at 12:38 PM, Smylers wrote: That would make the rule very simple indeed: Assigning Cundef to an array element causes that element to take the array's default value. The effects of this are: * Assigning a particular integer to an array of int or Int always does what it looks like it's doing, irrespective of whether or not that integer is zero or whether the array happens to have a default. * In an array of Int, attempting to store Cundef will, by default, actually store Cundef. If the array has a different default defined then that will be stored instead. I'd also like to point out that ruby has defaults for hashes but assigning nil (the equivalent of undef) does not set the default; delete does. This makes more sense to me. Say an array has a default. If we use an uninitialized slot in the array, we should get the default. Fine -- we have to initialize the thing anyway. But I think it's much saner to have this: * Have an 'undef' or 'unset' unary operator that sets the slot to the array's default (if there is one), and if there isn't then do whatever (either set to the 'default default' or undef, or actually delete the item if it's practical -- it's a minor detail, and not really my point.) * If we try to assign undef, or 0, or whatever, to a slot, then we put the closest thing to undef or 0 that we can, and not the default. Yes, there's some merit on checking whether we're actually assigning real undef, and not just whatever undef converts into, but that also causes some problems with copying arrays and reading data in and out. Basically, I think it amounts to handling defaults on the setting end, rather than the getting end, which seems a lot more practical to me. I think that having @a[1]=0; print @a[1]; not print '0' is scary voodoo no matter what the reason, and I like having to undefine things with something other than assignment. Possible caveat(s): * Copying arrays. If we handle the set to default case sloppily, and then try to copy into an array which has a different default, then some items that were supposed to be 'undefined' are now defined and have the default from the source array. Not good. * Might be inconvenient if we want to dump out to some plain-text format and read back in, as we would have to write code that's explicitly aware of the existence of a default. I'm getting long-winded here, but what it seems like is: what some people seem to be thinking has a lot of potential for hidden action and foot-shooting. What I'm saying seems to me to be 'safer' but maybe less convenient in some situations. Hrm... I think both behaviors could be done without too much pain from user code wrapping an array (even an array of primitive types), so maybe it's a moot point anyway -- just give the user the choice whether they want to risk cutting off limbs with the swiss army chainsaw. Anyway, cheers and good discussion --Andrew hobbs Rodland arodland at noln.com
Re: Arrays: Default Values
On Thursday 30 January 2003 06:49 pm, Andrew Rodland wrote: On Wednesday 29 January 2003 09:52 pm, Rick Delaney wrote: On Wed, Jan 29, 2003 at 01:54:10PM -0800, Michael Lazzaro wrote: On Wednesday, January 29, 2003, at 12:38 PM, Smylers wrote: I'd also like to point out that ruby has defaults for hashes but assigning nil (the equivalent of undef) does not set the default; delete does. This makes more sense to me. [yadda yadda] Just to tone it down a bit: * Yes, that is all my humble opinion. * Whether or not you liked my proposal, I think there's definitely a communication breakdown between people who are thinking more or less the way I am, and people who are thinking the other. And probably we could figure more things out if we quit talking past each other, as I thinl some people definitely are. :) * Yes, Perl tends to be about letting the user decide whether they want to shoot themselves in the foot -- but it's also about letting them decide when they want to be 'safe' from their own potential stupidity, right? Cheers --hobbs
Re: Arrays: Default Values
On Tue, 2003-01-28 at 19:24, Paul Johnson wrote: If that's not the case, I need to get my head around why, since Perl *does* distinguish between defined and exists. But I wish it wouldn't for arrays. That only came about to support pseudo-hashes which are going / have gone away. Are you suggesting that hashes should also have a default? That would seem consistent and at least as useful as arrays having a default. Yes, I would expect that. In my opinion there is no difference between an array and a hash other than the underlying storage and the type-management of the key. I'm increasingly of the opinion that a) there should be no @ vs %, there should be no {} vs [], there should be a keys, values, defined, delete, exists, push, pop, shift, unshift for every container and foreach shouldn't give a damn. But, that would be a different language, and Perl has hashes and arrays. So, the most we can do is make them not work too differently. -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
On 2003-01-29 at 09:44:27, Aaron Sherman wrote: Yes, I would expect that. In my opinion there is no difference between an array and a hash other than the underlying storage and the type-management of the key. Perhaps it is your opinion that those should be the only differences, but the actual differences, at least in existing languages, are a matter of fact. :) Every language I know of which supports both types distinguishes between them - even those which use the same subscripting syntax for both. So the distinctions must be important. 1. Ordering. The elements of an array have a defined order. The elements of a hash do not. 2. Contents. Arrays are a collection of values. Hashes are a collection of key/value associations. The indices in an array are just a by-product of the above fact that the values are ordered; there is no intrinsic association between, say, the number 1 and the second element. A consequence is that, even when the underlying implementation allows them to be sparse, arrays conceptually do not have any missing elements. If you create a brand new array by giving it a 5,000th item, then the first 4,999 items are logically there even if they're not taking up any memory. (What their value should be is the subject of the parallel thread on array defaults). For example: People keep bringing up JavaScript, so let's look at that language. It is true that JavaScript arrays are implemented on top of hashes. Every object in JavaScript, including an array, is an associative array/hash. But Arrays are a special class because they have the concept of a length. You can give any object properties associated with numeric keys, but only Arrays have their length field automatically updated; furthermore, this is magic that cannot be duplicated by user code: a = new Array a[2] = 'baz' a.length= 3 o = new Object o[2] = 'baz' o.length= undefined I'm increasingly of the opinion that a) there should be no @ vs %, there should be no {} vs [], there should be a keys, values, defined, delete, exists, push, pop, shift, unshift for every container and foreach shouldn't give a damn. Okay, let's look at adding hash operators to arrays first. 1. keys. Easy enough - return 0..a.length 2. values. Easy, if redundant. a.values is identical to a itself. 3. defined. Sure. Any value in Perl may be defined or not, no matter what sort of container it's in. 4. delete. No reason you can't remove an element from an array, but it's effectively a splice - the later elements move down. 5. exists. exists(a[i]) ::== 0 = i a.length Now let's look at array operators on hashes. 1. push.As long as the argument is a Pair, I guess this makes sense. h.push( k = v ) ::= h{k} = v 2. pop. Problem: no ordering. There is no last value. which one should this remove? 3. shift. ditto. 4. unshift. identical to push. My point boils down to this: the semantics are fundamentally different no matter how similar or different the syntax is. -- Mark REED| CNN Internet Technology 1 CNN Center Rm SW0831G | [EMAIL PROTECTED] Atlanta, GA 30348 USA | +1 404 827 4754
Re: Arrays: Default Values
On 2003-01-29 at 10:32:58, Mark J. Reed wrote: (What their value should be is the subject of the parallel thread on array defaults). Whups, that would be THIS thread, actually. The sidebar on removing the syntactic distinction between arrays and hashes made me think I was over in the Spare brackets thread. Sorry. -- Mark REED| CNN Internet Technology 1 CNN Center Rm SW0831G | [EMAIL PROTECTED] Atlanta, GA 30348 USA | +1 404 827 4754
Re: Arrays: Default Values
--- Jonathan Scott Duff [EMAIL PROTECTED] wrote: Can I flame you for being too preemptive? :-) In all honesty, I just wanted to be able to use absquatulate in a real post. ;-) =Austin
Re: Arrays: Default Values
Ok, I'll respond to a couple of points, below, but I think a lot of folks are confusing some operational concepts here, and it's getting hard to un-peel them. A container has many attributes, even if Perl won't let us control them. Those include: 1. Storage 2. Conversion of the whole container to another type 3. Type assigned to keys (array: int, hash: scalar) 3.5 Type used to compare/order keys (array: int, hash: string) 4. Type assigned to values 5. Value which keys default to 6. Value which values default to 7. Behavior on normal instantiation (@a=(1,2,3)) 8. Behavior on sparse instantiation (@a[2]=3) 9. Behavior on lazy instantiation (@a=(1..Inf)) 10. How other types are converted on input 11. Syntax for indexing 12. Syntax for listifying 13. Syntax for holistic container access 14. Methods available 3 and 4 vs 5 and 6 are an interesting thing to get your brain around. When you talk about an array having a default value, I don't think of that as controlling 1..5, 7 or 10..14. I do see it having an effect on 6 and possibly an effect on 8 and 9 depending on implementation. That is to say that C@a[10] = $mumble shouldn't care about the default value for that array. I'm not defaulting it. If the default TYPE for that array doesn't handle the value that I'm trying to store, then type conversion comes into play, and as someone pointed out and undef might become 0 for arrays of ints. But if the default value for my array of ints is 100, then why on earth would assigning it undef result in 100 and not 0?! I could see defining an atomic type which has an alternate conversion for an undefined value. So, for example, you might have an alternate type of int that converts undef to 100. Then, of course, assigning undef to an element of an array of such values should give you 100, AND assigning undef to an element of an array of such values that defaults to 200 should still yield 100! Now again, we have to ask how much of this Perl is going to let us do. I have no idea, and don't want to suggest one way or the other. But, to mash them together into one operation restricts future expansion far too much. On Wed, 2003-01-29 at 10:32, Mark J. Reed wrote: 1. Ordering. The elements of an array have a defined order. The elements of a hash do not. I mentioned storage. Unless your container semantics demand a sort before searching or listing, the underlying storage impacts ordering. Elements of a has ARE ordered, just not the way you may expect. 2. Contents. Arrays are a collection of values. Hashes are a collection of key/value associations. The indices in an array are just a by-product of the above fact that the values are ordered; there is no intrinsic association between, say, the number 1 and the second element. Arrays are a collection of key/value pairs, where the key is stored by virtue of positioning in order to save space and increase access time. Don't start thinking that that information is lost! Of course there's an association between 1 and the second element. What you meant to say is that there's no storage allocated to the number 1, because we can infer the key's value based on position. 4. delete. No reason you can't remove an element from an array, but it's effectively a splice - the later elements move down. I disagree. This would un-exists an item, and leave it in a state that would require auto-vivification if it were accessed in future. 5. exists. exists(a[i]) ::== 0 = i a.length This is a mistake, since you're going to end up claiming that something exists when it literally does not. Now let's look at array operators on hashes. 1. push.As long as the argument is a Pair, I guess this makes sense. h.push( k = v ) ::= h{k} = v Well, the argument would be a list of Pairs, actually. 2. pop. Problem: no ordering. There is no last value. which one should this remove? There is no problem. It will pop the Pair that would be last if you converted to a list. That might be massively expensive to determine, but as long as the documentation warns the same way it does for converting to a list, then you're not causing any new problems. You keep asserting that there's no ordering to Hashes, but that's not true. I don't blame you, even the Perl docs get it wrong sometimes. From the P5 docs: perldata: Hashes are unordered collections of scalar values indexed by their associated string key. perlfunc/keys: order is subject to change in future versions of perl, but it is guaranteed to be the same order as either the values or each function produces So, they're not unordered. They just have an ordering that you can't rely on if you change their contents. So, I
Re: Arrays: Default Values
OK, I think we agree that 'default' refers to what to put in the 'holes' of an array (or hash, but that's a separate discussion.) When you overlay a real hash on top of your default values, the default values show through the holes. So now we just have to define what holes are. An assertion: The 'is default' property overrides the default 'empty' value of the given underlying type. For a normal array of scalars, that 'empty' value is Cundef. But some scalar types can be set to undef, and some can't: my @a; # 'empty' value of a scalar is undef my int @a_int; # 'empty' value of an 'int' is 0 my str @a_str; # 'empty' value of a 'str' is '' my Int @a_Int; # 'empty' value of an 'Int' is undef (right?) my Str @a_Str; # 'empty' value of a 'Str' is undef (right?) So Cis default def is defining the value to use as the 'empty value' of the _underlying cell type_. There are two credible choices, AFAICT: Solution 1: If you attempt to SET a cell to it's 'empty value', it will be set to it's default: my int @a is default(5); # @a[5] = 0;# actually sets it to it's 'empty value', 5 @a[5] = undef;# autocnv to 0, + warning, still sets to 5 my Int @a is default(5); # NOTE difference in type! @a[5] = 0;# THIS really does set it to 0 @a[5] = undef;# and this sets it to 5 So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. Solution 2: _ANY_ other solution would require the introduction of 'fake empty' and 'really empty', and require arrays to keep track of the difference. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset to undef, so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # well, it's still undef, but now mark it # as a 'real' undef, so don't return 5. This is essentially adding another layer of defined-ness on each cell, and therefore requires an additional flag be kept checked for each array element. While this is certainly a possibility, I worry about the complexity it introduces. - In spite of the perhaps surprising nature of solution 1, I think it is probably the more correct solution, if you really insist on putting a default value on a primitive-typed array. As it points out, you can still get both behaviors, simply by choosing int vs. Int, str vs. Str, etc. If you want behavior more complicated than that, I think you probably should be creating a custom Array subclass. Comments? MikeL
Re: Arrays: Default Values
Solution 1: If you attempt to SET a cell to it's 'empty value', it will be set to it's default: my int @a is default(5); # @a[5] = 0;# actually sets it to it's 'empty value', 5 @a[5] = undef;# autocnv to 0, + warning, still sets to 5 my Int @a is default(5); # NOTE difference in type! @a[5] = 0;# THIS really does set it to 0 @a[5] = undef;# and this sets it to 5 So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. - In spite of the perhaps surprising nature of solution 1, I think it is probably the more correct solution, if you really insist on putting a default value on a primitive-typed array. As it points out, you can still get both behaviors, simply by choosing int vs. Int, str vs. Str, etc. OK, it sounds reasonable to me, for those cases where the 'empty value' is undef ... but if I have an array of #s ... I have the list of people I invited to my wedding. I default the # of people attending to 2 (inviting couples or Friend) ... Joe responds, he's coming alone (ok, so i set him to a 1) Karen is bringing her kids (so 4) Fred can't come. That's a 0. Which is a 2. But he's not coming, so the 2 is really a 0, but I can't say 0, b/c 0 is empty and becomes default 2 ... Likewise for strings. I default it to explicitly say UNKNOWN so I know what's not known, but now when I find out it doesn't exist (What's John Doe's middle name?) I can't say that. The answer then is UNKNOWN so John Doe became John UNKNOWN Doe due to a flawed (IMO) functional limitation ... This is also why i (somewhat facetiously) suggested undef but really, although it doesn't help in this case b/c I'm wanting to set it to 0, and saying attendees[23] = 0 but really looks wrong ... so maybe the but really would be for setting to default ('empty value') if you had need and used it in assignment (but undef @attendees[23] would, i think, still make it 'empty val' b/c i'm not assigning a value to it, i'm unassigning the value I've given it, which is a distinction that I think may be relevant ...) --attriel
Re: Arrays: Default Values
--- Michael Lazzaro [EMAIL PROTECTED] wrote: OK, I think we agree that 'default' refers to what to put in the 'holes' of an array (or hash, but that's a separate discussion.) When you overlay a real hash on top of your default values, the default values show through the holes. So now we just have to define what holes are. An assertion: The 'is default' property overrides the default 'empty' value of the given underlying type. For a normal array of scalars, that 'empty' value is Cundef. But some scalar types can be set to undef, and some can't: my @a; # 'empty' value of a scalar is undef my int @a_int; # 'empty' value of an 'int' is 0 my str @a_str; # 'empty' value of a 'str' is '' I understand these, and they seem to make sense. my Int @a_Int; # 'empty' value of an 'Int' is undef (right?) my Str @a_Str; # 'empty' value of a 'Str' is undef (right?) It's going to be undef but 0 or undef but '', but since type promotion will handle that automatically, yes. So Cis default def is defining the value to use as the 'empty value' of the _underlying cell type_. And therefore, if you try to specify an invalid dev for the _underlying cell type_, you should get an error, either compile time or run-time, as soon as it gets noticed. my int @a is default foo; # Compile time error. my int @a is default $param1; # Run time error if $param1 is bogus. There are two credible choices, AFAICT: Solution 1: If you attempt to SET a cell to it's 'empty value', it will be set to it's default: my int @a is default(5); @a[5] = 0;# actually sets it to it's 'empty value', 5 @a[5] = undef;# autocnv to 0, + warning, still sets to 5 my Int @a is default(5); # NOTE difference in type! @a[5] = 0;# THIS really does set it to 0 @a[5] = undef;# and this sets it to 5 So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. I believe that I completely understand what you are saying. I am sure that I absolutely disagree with what I believe I understand you to be saying. my $answer is (;-) but true); [[ This is quoted out of order, but addresses 1, above. --agh ]] In spite of the perhaps surprising nature of solution 1, I think it is probably the more correct solution, if you really insist on putting a default value on a primitive-typed array. As it points out, you can still get both behaviors, simply by choosing int vs. Int, str vs. Str, etc. Solution 2: _ANY_ other solution would require the introduction of 'fake empty' and 'really empty', and require arrays to keep track of the difference. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset to undef, so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # well, it's still undef, but now mark it # as a 'real' undef, so don't return 5. This is essentially adding another layer of defined-ness on each cell, and therefore requires an additional flag be kept checked for each array element. While this is certainly a possibility, I worry about the complexity it introduces. You're confusing specification with implementation, again. I don't propose to require really empty and fake empty. What I propose is that: 1- If a range of values gets strongly implied, like @a[2] in your example, then they should be populated with the default value. After all, it's the default. 2- If a range of values are waekly implied, as in the examples provided by Leopold Tesch: @a[12345678] = 1; @a[12000]; The interior values haven't actually been created because the array is in sparse mode. Any read from them will return @a.default, in your example 5. 3- Any action which serves to destroy, delete, defenestrate, or absquatulate (I love that word!) the value will cause the value to return the default value once again, whether it's allocated-but-destroyed (@a[2]) or unallocated (@a[12000]). 4- Any explicit action by the programmer is taken as gospel, or as close to it as possible via promotion: my int @a is default(5); @a[2] = undef; # Warning: 'undef' used where primitive 'int' expected. @a[2]; # 0, because int(undef) is 0. delete @a[2]; @a[2]; # 5, because deleting restores the default. my Int @a is default(5); # NOTE: type change. @a[2] = undef; # undef, because according to you this is okay. # (I'm not being sarcastic -- you're the # edge cases guy.) @a[2]; # undef, because that's what the programmer told me. delete @a[2]; @a[2]; # 5, because it's the default, as above. Now: Does this require a fake undef and a real undef? WHO CARES? That's p6-internals. I think that it could be coded either way. I also think that as a performance boost, it may
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 10:23:26AM -0800, Michael Lazzaro wrote: OK, I think we agree that 'default' refers to what to put in the 'holes' of an array (or hash, but that's a separate discussion.) When you overlay a real hash on top of your default values, the default values show through the holes. So now we just have to define what holes are. Holes are undefined things. An assertion: The 'is default' property overrides the default 'empty' value of the given underlying type. For a normal array of scalars, that 'empty' value is Cundef. But some scalar types can be set to undef, and some can't: my @a; # 'empty' value of a scalar is undef my int @a_int; # 'empty' value of an 'int' is 0 my str @a_str; # 'empty' value of a 'str' is '' my Int @a_Int; # 'empty' value of an 'Int' is undef (right?) my Str @a_Str; # 'empty' value of a 'Str' is undef (right?) So Cis default def is defining the value to use as the 'empty value' of the _underlying cell type_. I'd say that undef is the universal out-of-bounds value that can be applied to any type or aggregate to show the absense of value (empty). It's just that undef autovivifies to different things depending on how the thing was declared. There are two credible choices, AFAICT: Solution 1: If you attempt to SET a cell to it's 'empty value', it will be set to it's default: my int @a is default(5); # @a[5] = 0;# actually sets it to it's 'empty value', 5 @a[5] = undef;# autocnv to 0, + warning, still sets to 5 my Int @a is default(5); # NOTE difference in type! @a[5] = 0;# THIS really does set it to 0 @a[5] = undef;# and this sets it to 5 So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. Looks like a maintenance nightmare to me. If you always think of undef as the empty value, then @a[5] = 0 gives the sixth element in the array the value of 0 and @a[5] = undef gives the sixth element the undefined value (or the default value if defaulting applies). Solution 2: _ANY_ other solution would require the introduction of 'fake empty' and 'really empty', and require arrays to keep track of the difference. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset to undef, so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # well, it's still undef, but now mark it # as a 'real' undef, so don't return 5. Strange. I was thinking of the default value as what you get when you don't know what goes there (how do you know when you don't know? Easy: if it's undef, you don't know) my int @a is default(5);# int could be *any* type @a[3] = 3; print @a[2];# prints 5, exists but undefined @a[3] = undef; print @a[3];# again, prints 5 Why would you want to put a real undef in your array of default values? The whole point of defaulting is to change what undef means for the array/hash/whatever. MHO, -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
On Wednesday, January 29, 2003, at 11:02 AM, Jonathan Scott Duff wrote: So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. Looks like a maintenance nightmare to me. Agreed, it's not pretty. The fundamental problem is that a primitive like an Cint simply cannot be undefined... there's no flag for that (which is they're primitive.)So it having a 'default value' at all is perhaps a bit of a misnomer. A simple solution is perhaps to say that Cis default can only be applied to types that can be undef (scalar,ref,Int,Str...) and can't be used on things that have no undefined state (bit,int,str...). That would neatly sidestep the problem, and would _force_ you to use Int instead of int when you wanted a default-instead-of-undefined case. MikeL
Re: Arrays: Default Values
Ok, stepping back... there are three questions: * Can a type be undefined * What does an array say when asked for an element that doesn't exist * What happens when you try to undefine something I really think you need an attribute to clarify these. For example, you would not say: my int @a but, rather my @a is of(int) or some such (of is a place-holder here that I don't much like because it looks like if). In other words, the array itself is not an int. It just contains them. You could have said: my FunkyArray is of(int) no? Now, when you ask for an int that doesn't exist what do you get? By default, I would suppose 0, but couldn't I want an integer-only data type that *can* be undef? If so, isn't that: my @a is of(int but undefinable) Ok, now we get to the meat of the matter: my @a is of(int but undefinable), default(100) here we have a perfectly valid thing to want. A list whose elements can be undef or an integer, and which default to 100 when read uninitialized. As for the argument that testing for true non-existentness is a burden, check out the way Perl5 does this. Hint: there's a central sv_undef, and that's not what array buckets are initialized to -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
Michael Lazzaro [EMAIL PROTECTED] writes: Solution 1: If you attempt to SET a cell to it's 'empty value', it will be set to it's default: my int @a is default(5); # @a[5] = 0;# actually sets it to it's 'empty value', 5 @a[5] = undef;# autocnv to 0, + warning, still sets to 5 my Int @a is default(5); # NOTE difference in type! @a[5] = 0;# THIS really does set it to 0 @a[5] = undef;# and this sets it to 5 So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. AAARGH, *runs for shelter* Setting an element to a leagal value, results in a different value to be stored, making it impossible to store this value. And this is even the most prominent value of the underlying type. Solution 2: _ANY_ other solution would require the introduction of 'fake empty' and 'really empty', and require arrays to keep track of the difference. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset to undef, so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # well, it's still undef, but now mark it # as a 'real' undef, so don't return 5. This is essentially adding another layer of defined-ness on each cell, and therefore requires an additional flag be kept checked for each array element. While this is certainly a possibility, I worry about the complexity it introduces. Solution 3: The autoset sets the value to the default value. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset 5 so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # set to undef, so returns undef @a[5] = @a.default # if you really want to reset something to # default. BTW there are now 6 items in # the array. returns 5 @a[4]; # is now autoset to 5 so it remains 5 The default default value is the empty value of the base type. my Int @a; is the same as my Int @a is default(undef); bye b. -- Juergen Boemmels[EMAIL PROTECTED] Fachbereich Physik Tel: ++49-(0)631-205-2817 Universitaet Kaiserslautern Fax: ++49-(0)631-205-3906 PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F 23 F6 C7 2F 85 93 DD 47
Re: Arrays: Default Values
--- Michael Lazzaro [EMAIL PROTECTED] wrote: On Wednesday, January 29, 2003, at 11:02 AM, Jonathan Scott Duff wrote: So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. Looks like a maintenance nightmare to me. Agreed, it's not pretty. The fundamental problem is that a primitive like an Cint simply cannot be undefined... there's no flag for that (which is they're primitive.)So it having a 'default value' at all is perhaps a bit of a misnomer. A simple solution is perhaps to say that Cis default can only be applied to types that can be undef (scalar,ref,Int,Str...) and can't be used on things that have no undefined state (bit,int,str...). Wait a minute. Leaving out the whole is default() bit, what happens when I: my int @a; @a[4] = 100; @a[2]; What does @a[2] return? It must return something, and that something can't be undef, because ... above So, what is it? Whatever it is, that's the default. =Austin
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 08:49:42PM +0100, Juergen Boemmels wrote: Solution 3: The autoset sets the value to the default value. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset 5 so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # set to undef, so returns undef Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 11:32:53AM -0800, Michael Lazzaro wrote: On Wednesday, January 29, 2003, at 11:02 AM, Jonathan Scott Duff wrote: So you can't set something to its type's own empty value, because it will, by definition, thereafter return it's overloaded empty value, def. Looks like a maintenance nightmare to me. Agreed, it's not pretty. The fundamental problem is that a primitive like an Cint simply cannot be undefined... there's no flag for that (which is they're primitive.) The solution I advocate is to allow even primitive types to hold undef. I don't have an implementation, but that's just a detail I'll leave to those actually doing the implementation :-) A simple solution is perhaps to say that Cis default can only be applied to types that can be undef (scalar,ref,Int,Str...) and can't be used on things that have no undefined state (bit,int,str...). That works too (probably better depending on who you ask :) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
Jonathan Scott Duff [EMAIL PROTECTED] writes: On Wed, Jan 29, 2003 at 08:49:42PM +0100, Juergen Boemmels wrote: Solution 3: The autoset sets the value to the default value. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset 5 so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # set to undef, so returns undef Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? Ok, here is one my float @weight_factor is default (1.0); $weighted_sum = sum (@weight_factor »*« @a); $weight_factor[4711] = 0.0; bye b. -- Juergen Boemmels[EMAIL PROTECTED] Fachbereich Physik Tel: ++49-(0)631-205-2817 Universitaet Kaiserslautern Fax: ++49-(0)631-205-3906 PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F 23 F6 C7 2F 85 93 DD 47
Re: Arrays: Default Values
In my opinion, default values for arrays should only come into play for array elements that have NEVER been assigned to or that have been explicity undef'ed. If an assigment is made to an array element then the array element should end up the assigned value (modulo necessary type conversions) and the array's default value should not play any part in the assignment. After an explisit assignment of an array element the only way that the array's default value should magically reappear is if an undef of the element is done. Any other way to handle things, like some of the other ways proposed will only lead to mysterious bugs and programmer missunderstandings. -- Mark Biggar [EMAIL PROTECTED]
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 12:00:33PM -0800, Mark Biggar wrote: In my opinion, default values for arrays should only come into play for array elements that have NEVER been assigned to or that have been explicity undef'ed. If an assigment is made to an array element then the array element should end up the assigned value (modulo necessary type conversions) and the array's default value should not play any part in the assignment. After an explisit assignment of an array element the only way that the array's default value should magically reappear is if an undef of the element is done. Exactly! Any other way to handle things, like some of the other ways proposed will only lead to mysterious bugs and programmer missunderstandings. Exactly! * 2 -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 09:07:37PM +0100, Juergen Boemmels wrote: Jonathan Scott Duff [EMAIL PROTECTED] writes: Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? Ok, here is one my float @weight_factor is default (1.0); $weighted_sum = sum (@weight_factor »*« @a); $weight_factor[4711] = 0.0; I see no undefined things there. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
--- Jonathan Scott Duff [EMAIL PROTECTED] wrote: On Wed, Jan 29, 2003 at 08:49:42PM +0100, Juergen Boemmels wrote: Solution 3: The autoset sets the value to the default value. my Int @a is default(5); @a[3] = 3; # there are now 4 items in the array @a[2]; # was autoset 5 so returns 5 @a[4]; # doesn't exist, so returns 5 @a[2] = undef; # set to undef, so returns undef Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? Sure. Implement an array that is computed such that it automatically invokes a function to interpolate values that haven't been explicitly stored. (Possibly using keys @arry, but that's a different thread.) Use that to hold values of an arbitrary function. When the function divides by zero, or does certain types of unnatural math with Inf, the value is undefined. Likewise, when the interpolator doesn't have enough data, or the points are too far apart for confidence, the value may be undefined. =Austin
Re: Arrays: Default Values
On Wed, 2003-01-29 at 14:54, Jonathan Scott Duff wrote: Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? my @send_partner_email is default(1); while $websignups.getline { ($id) = /UserID: (\d+)/; if /Source: External DB With No Privacy Policy/ { @send_partner_email[$id] = undef; # No answer given } elsif /Spam Me: Yes/ { @send_partner_email[$id] = 1; } else { @send_partner_email[$id] = 0; } } # If you were not in the websignups list, you signed up before privacy # policy, so we spam you (default=1) In this case, there's a true shrug answer, which is hard to deal with. We need to do something later on with the undefined case (no answer was given, and no spam warning issued). This sort of logic deferral is common to many uses of undefined values (or NULL) in databases, even when columns have defaults that are non-null. -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 03:29:57PM -0500, Aaron Sherman wrote: On Wed, 2003-01-29 at 14:54, Jonathan Scott Duff wrote: Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? my @send_partner_email is default(1); while $websignups.getline { ($id) = /UserID: (\d+)/; if /Source: External DB With No Privacy Policy/ { @send_partner_email[$id] = undef; # No answer given } elsif /Spam Me: Yes/ { @send_partner_email[$id] = 1; } else { @send_partner_email[$id] = 0; } } # If you were not in the websignups list, you signed up before privacy # policy, so we spam you (default=1) But aren't those values arbitrary? Couldn't you just have easily used -1 instead of undef? Why would undef be necessary or preferred? -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
Agreed, it's not pretty. The fundamental problem is that a primitive like an Cint simply cannot be undefined... there's no flag for that (which is they're primitive.) Certainly there's no way of _storing_ Cundef. So it having a 'default value' at all is perhaps a bit of a misnomer. Why does that follow? I'd say the opposite is true: it's because the type _can't_ store Cundef that a _valid_ default is required. A simple solution is perhaps to say that Cis default can only be applied to types that can be undef (scalar,ref,Int,Str...) and can't be used on things that have no undefined state (bit,int,str...). But what's the disadvantage of permitting things of int to have non-zero default values? And, just because Cundef can't be stored in an int, why does it mean that _trying_ to store an Cundef can't be the action that triggers the default being stored there? For an int variable with a default of 5, you seem to have gone from the suggestion that attempting to store either zero or undef would result in 5 being stored, to the suggestion that either would result in zero being stored. Why can't zero and undef do different things? People obviously want to be able to store zeros in integer variables and having code that looks like it stores zero -- a valid integer -- actually store some other integer is ridiculous. So have zero store zero always. But storing Cundef denotes clearing the element out of a particular value, which seems like a good time to use the default. Damian yesterday argued in favour of Cundef, the value which is used when no other value is known, not being permitted in Int arrays which have a specific (integer) default, and hence that marking an element as Cundef should put the default value there. That would make the rule very simple indeed: Assigning Cundef to an array element causes that element to take the array's default value. That's it. It's what I assumed Damian meant yesterday, but I could be mistaken. The effects of this are: * Assigning a particular integer to an array of int or Int always does what it looks like it's doing, irrespective of whether or not that integer is zero or whether the array happens to have a default. * In an array of Int, attempting to store Cundef will, by default, actually store Cundef. If the array has a different default defined then that will be stored instead. * In an array of int, attempting to store Cundef will, by default, store zero. If the array has a different default defined then that will be stored instead. Smylers
Re: Arrays: Default Values
On Wed, 2003-01-29 at 14:53, Austin Hastings wrote: Leaving out the whole is default() bit, what happens when I: my int @a; @a[4] = 100; @a[2]; What does @a[2] return? It must return something, and that something can't be undef, because ... above So, what is it? Whatever it is, that's the default. That's an interesting question. At first, I was ready to say zero, of course, but the more I thought about it, the more I realized that an array whose storage is not ultimately a collection of scalars can do one of three things: * Initialize new array sections to default * Only default such arrays when elements are off-the-end * Not allow default on such arrays the second one seems to be a cruel joke to play on a programmer. The first is only slightly better. I'm beginning to go with the third... However, there is always the idea of using the SQL-like null/not null concept to allow simple types to be undefined. It makes sense to me the programmer to constrain data to be integer type, but allow undefined values. Even if there's no savings in terms of storage, I think it should be allowed. Perhaps I'm overreacting to the first option. It's not so bad. undef should still probably keep its old semantics when being converted to an integer and go to zero, though. -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
At 10:59 AM -0800 1/29/03, Austin Hastings wrote: Now: Does this require a fake undef and a real undef? WHO CARES? Very good answer. Leave the details to me and the p6i folks. (Though do please, everyone, pay attention when we tell you that what you want is slow or awkward) -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 03:48:18PM -0500, Dan Sugalski wrote: (Though do please, everyone, pay attention when we tell you that what you want is slow or awkward) Just be sure to reiterate in case we miss it the first time :-) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 12:40:21PM -0500, Aaron Sherman wrote: Elements of a has ARE ordered, just not the way you may expect. Quite: $ perl5.8.0 -le '%a = (small = 1, large =2); %b = %a; print foreach keys %a; print --; print foreach keys %b' large small -- small large $ perl5.8.0 -le '%a = (small = 1, large =2); print foreach keys %a; print --; @a = (0..1e3); $a{$_}=1 foreach @a; delete $a{$_} foreach @a; print foreach keys %a' large small -- small large There is no problem. It will pop the Pair that would be last if you converted to a list. That might be massively expensive to determine, but as long as the documentation warns the same way it does for converting to a list, then you're not causing any new problems. You keep asserting that there's no ordering to Hashes, but that's not true. I don't blame you, even the Perl docs get it wrong sometimes. And the demonstration was as expected? (I don't know two strings that clash for the hash algorithms used in 5.6 and in 5.005 and earlier, hence why I'm specifying 5.8.0 pie = 1 , good = 1 works for the first example in 5.8.0 and 5.6.1, perl = 1, rules = 1 for the second in both) Nicholas Clark
Re: Arrays: Default Values
On Wednesday, January 29, 2003, at 12:38 PM, Smylers wrote: That would make the rule very simple indeed: Assigning Cundef to an array element causes that element to take the array's default value. The effects of this are: * Assigning a particular integer to an array of int or Int always does what it looks like it's doing, irrespective of whether or not that integer is zero or whether the array happens to have a default. * In an array of Int, attempting to store Cundef will, by default, actually store Cundef. If the array has a different default defined then that will be stored instead. * In an array of int, attempting to store Cundef will, by default, store zero. If the array has a different default defined then that will be stored instead. That has merit. One question -- with this approach, attempting to store an Cundef in an array of int therefore silently succeeds (there's no longer any converting undef to 0 warning, right, since it would be triggered constantly by this mechanism?) MikeL
Re: Arrays: Default Values
At 12:40 PM -0500 1/29/03, Aaron Sherman wrote: Elements of a has ARE ordered, just not the way you may expect. Just to nip this one in the bud... If people start assuming that there's *any* ordering to hashes, I promise I *will* make sure that parrot's external hash class starts returning keys and values in random order. Hashes have no guarantee of ordering, and perl 5 (as Nick demonstrated) delivers on that lack of guarantee. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Arrays: Default Values
--- Dan Sugalski [EMAIL PROTECTED] wrote: At 10:59 AM -0800 1/29/03, Austin Hastings wrote: Now: Does this require a fake undef and a real undef? WHO CARES? Very good answer. Leave the details to me and the p6i folks. (Though do please, everyone, pay attention when we tell you that what you want is slow or awkward) Usually, I'm assuming that anything we ask for, you'll be unable, due to geek pride, to stand up and say I can't implement that. I feel slightly guilty about that, but then I eat an MM, and whatever miniscule guilt I feel goes away... :-) :-) :-) But yeah, spec != code. =Austin
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 02:13:34PM -0600, Jonathan Scott Duff wrote: On Wed, Jan 29, 2003 at 12:00:33PM -0800, Mark Biggar wrote: In my opinion, default values for arrays should only come into play for array elements that have NEVER been assigned to or that have been explicity undef'ed. If an assigment is made to an array element then the array element should end up the assigned value (modulo necessary type conversions) and the array's default value should not play any part in the assignment. After an explisit assignment of an array element the only way that the array's default value should magically reappear is if an undef of the element is done. Exactly! This means that C@a[2] = undef is different to Cundef @a[2]. This is undesirable, but could be solved by using Cdelete @a[2]. So, there appear to be two internally consistent ways of doing this: 1. There is a difference between an undefined element and a non existent element. Elements are autovivified to the default value, their existence may be tested for with Cexists and they may be deleted with Cdelete. Undefined values may be read and written. 2. Attempting to read or write undef will substitute the default value. Both approaches seem valid. Choose one. Or two. No, one. Note that both approaches are consistent with the way things are in Perl 5 now if you consider the default value always to be undef. Both approaches can also be extended to hashes. I think the question of what to do with int arrays is somewhat separate. Might I suggest that storing undef in an int array is not appropriate, and thus having a (user defined) default value in an int array is also not appropriate. If you want power, you have to pay for it. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net
Re: Arrays: Default Values
At 2:18 PM -0800 1/29/03, Austin Hastings wrote: --- Dan Sugalski [EMAIL PROTECTED] wrote: At 10:59 AM -0800 1/29/03, Austin Hastings wrote: Now: Does this require a fake undef and a real undef? WHO CARES? Very good answer. Leave the details to me and the p6i folks. (Though do please, everyone, pay attention when we tell you that what you want is slow or awkward) Usually, I'm assuming that anything we ask for, you'll be unable, due to geek pride, to stand up and say I can't implement that. Oh, I can implement almost anything, and the quantum ninja take care of anyone who suggests things I can't implement. That's not the issue--it's efficiency, that's the issue. :) -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 02:37:04PM -0600, Jonathan Scott Duff wrote: On Wed, Jan 29, 2003 at 03:29:57PM -0500, Aaron Sherman wrote: On Wed, 2003-01-29 at 14:54, Jonathan Scott Duff wrote: Can someone give me a realish world example of when you would want an array that can store both undefined values and default values and those values are different? my @send_partner_email is default(1); while $websignups.getline { ($id) = /UserID: (\d+)/; if /Source: External DB With No Privacy Policy/ { @send_partner_email[$id] = undef; # No answer given } elsif /Spam Me: Yes/ { @send_partner_email[$id] = 1; } else { @send_partner_email[$id] = 0; } } # If you were not in the websignups list, you signed up before privacy # policy, so we spam you (default=1) But aren't those values arbitrary? Couldn't you just have easily used -1 instead of undef? Why would undef be necessary or preferred? Sure, they're arbitrary but undef is is preferred because it indicates the decision is undefined. You seem to have snipped this: In this case, there's a true shrug answer, which is hard to deal with. We need to do something later on with the undefined case (no answer was given, and no spam warning issued). This sort of logic deferral is common to many uses of undefined values (or NULL) in databases, even when columns have defaults that are non-null. The reference to databases is salient. There are surely many examples to be found in SQL books. -- Rick Delaney [EMAIL PROTECTED]
Re: Arrays: Default Values
On Wed, Jan 29, 2003 at 01:54:10PM -0800, Michael Lazzaro wrote: On Wednesday, January 29, 2003, at 12:38 PM, Smylers wrote: That would make the rule very simple indeed: Assigning Cundef to an array element causes that element to take the array's default value. The effects of this are: * Assigning a particular integer to an array of int or Int always does what it looks like it's doing, irrespective of whether or not that integer is zero or whether the array happens to have a default. * In an array of Int, attempting to store Cundef will, by default, actually store Cundef. If the array has a different default defined then that will be stored instead. Wouldn't that mean that this would loop forever? my @a is default(foo); #... # please excuse my garbled perl5/6 syntax print @a while $a[0] = FILE; I'd also like to point out that ruby has defaults for hashes but assigning nil (the equivalent of undef) does not set the default; delete does. * In an array of int, attempting to store Cundef will, by default, store zero. If the array has a different default defined then that will be stored instead. That has merit. One question -- with this approach, attempting to store an Cundef in an array of int therefore silently succeeds (there's no longer any converting undef to 0 warning, right, since it would be triggered constantly by this mechanism?) It seems to me that the conversion of undef is separate from the notion of a default. my int @a; is like my int @a is undef_to(0). There is no default here, only a rule saying what assignment of undef stores. Accessing an uninitialized element should raise an exception, not give zero. In the case where people want assigning undef to set the default (i.e. treat undef the same as uninitialized) then they would set both properties to the same value. my int @a is default(1) is undef_to(1); -- Rick Delaney [EMAIL PROTECTED]
Re: Arrays: Default Values
Jonathan Scott Duff [EMAIL PROTECTED] wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... On Wed, Jan 29, 2003 at 11:32:53AM -0800, Michael Lazzaro wrote: Agreed, it's not pretty. The fundamental problem is that a primitive like an Cint simply cannot be undefined... there's no flag for that (which is they're primitive.) The solution I advocate is to allow even primitive types to hold undef. I don't have an implementation, but that's just a detail I'll leave to those actually doing the implementation :-) A simple solution is perhaps to say that Cis default can only be applied to types that can be undef (scalar,ref,Int,Str...) and can't be used on things that have no undefined state (bit,int,str...). C++ had a design principle: you only pay for what you ask for. From a different perspective: if you ask for it, then you're willing to pay. So if you ask for a default on an array of primitive types, then the implementation assumes that you're willing to pay for it: but only for those arrays that have defaults. The fact of the default is a property of the array, not of the elements it stores. There's no need to add undef values to primitive types. The most obvious solution (obvious =/= best) is a boolean (bit) array whose elements are associated with elements in the data array. Yes, there's a cost, but if the programmer asks for something, then they pay for it. But the implementation guys aren't allowed to play bait-and-switch! Dave. -- http://dave.whipp.name
Arrays: Default Values
There has been discussion of allowing a default value for array cells -- that is, one aside from Cundef or whatever the type-specific default is. Questions, in order of increased evilness: 1) What's the final decided syntax? Two possibilities: my @a is Array( default = 'foo' ); # attrib? my @a is default('foo');# property? 2) Assume the default value is a simple value, e.g. 'foo'. my @a is Array( default = 'foo' ); @a[5] = 'bar'; @a[4]; # 'foo' @a[5]; # 'bar' @a[6]; # 'foo' @a[-1];# 'bar' *NOTE!* @a[-3];# 'foo' @a[-10]; # 'foo' Correct? 2a) When a cell is explicitly re-undefined, does the default value take effect? my @a is Array( default = 'foo' ) = (1,2,3); @a[1] = undef; @a[1]; # undef, or 'foo'? STRAWMAN ANSWER: 'foo'. 2b) Primitive-typed arrays: Given the behavior of (2a), and the fact that primitive-typed arrays can't store undef, what happens here? my int @a is Array( default = 5 ); @a[0] = 0; @a[0]; # 0, or 5? @a[0] = undef; @a[0]; # 0, or 5? STRAWMAN ANSWER: 5, in both cases. So don't do that unless you mean it. 3) Can the default value be a closure, based on index location? my @a is Array( default = { $_ ** 2 }); STRAWMAN ANSWER: Yes, because it's cool. 3a) NOTE that closure-based defaults effectively render the array infinite. Therefore -- If the requested index is negative, what happens? @a[-5]; STRAWMAN ANSWER: The closure just gets a negative number as the requested index. It's up to you to make it work, if you want it to. 3b) Does an infinite array still get an exception thrown when trying to access an infinite [Inf] or [-Inf] index? STRAWMAN ANSWER: Yes, it does. MikeL
Re: Arrays: Default Values
On Tue, Jan 28, 2003 at 11:15:26AM -0800, Michael Lazzaro wrote: 2) Assume the default value is a simple value, e.g. 'foo'. my @a is Array( default = 'foo' ); @a[5] = 'bar'; @a[4]; # 'foo' @a[5]; # 'bar' @a[6]; # 'foo' @a[-1];# 'bar' *NOTE!* Um ... why? 2a) When a cell is explicitly re-undefined, does the default value take effect? my @a is Array( default = 'foo' ) = (1,2,3); @a[1] = undef; @a[1]; # undef, or 'foo'? STRAWMAN ANSWER: 'foo'. This makes sense to me. 2b) Primitive-typed arrays: Given the behavior of (2a), and the fact that primitive-typed arrays can't store undef, what happens here? my int @a is Array( default = 5 ); @a[0] = 0; @a[0]; # 0, or 5? 0, definitely. @a[0] was defined so the default doesn't come into play. @a[0] = undef; @a[0]; # 0, or 5? 5, because undefined things get the default value. 3) Can the default value be a closure, based on index location? my @a is Array( default = { $_ ** 2 }); STRAWMAN ANSWER: Yes, because it's cool. Heh. I'd want different syntax for default values vs. default generators though. 3a) NOTE that closure-based defaults effectively render the array infinite. Therefore -- If the requested index is negative, what happens? @a[-5]; STRAWMAN ANSWER: The closure just gets a negative number as the requested index. It's up to you to make it work, if you want it to. Sounds good to me. 3b) Does an infinite array still get an exception thrown when trying to access an infinite [Inf] or [-Inf] index? STRAWMAN ANSWER: Yes, it does. Based on 3a, I'd say that the closure should get Inf (or -Inf) and do the appropriate thing. In your example above, Inf**2 would be Inf, so the closure would return Inf (assuming I've got the Inf math right and it's not really NaN) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Arrays: Default Values
Michael Lazzaro said: There has been discussion of allowing a default value for array cells -- that is, one aside from Cundef or whatever the type-specific default is. Questions, in order of increased evilness: 1 and 2 seem fine to me. 2a) When a cell is explicitly re-undefined, does the default value take effect? my @a is Array( default = 'foo' ) = (1,2,3); @a[1] = undef; @a[1]; # undef, or 'foo'? STRAWMAN ANSWER: 'foo'. Seems right to me. Anything else would be very confusing, I think. 2b) Primitive-typed arrays: Given the behavior of (2a), and the fact that primitive-typed arrays can't store undef, what happens here? my int @a is Array( default = 5 ); @a[0] = 0; @a[0]; # 0, or 5? 0. Being unable to store 0 would seem to be a major limitation. @a[0] = undef; @a[0]; # 0, or 5? An exception or 5. Maybe undefining an element could always set it to the default value. 3) Can the default value be a closure, based on index location? my @a is Array( default = { $_ ** 2 }); STRAWMAN ANSWER: Yes, because it's cool. No, because it's unnecessary. You can always do my $value = @a[$x] //= $x ** 2; or skip the = depending on how you are trading memory / speed. Yes, I know that just about everything is unnecessary to someone. To me, default values as a whole seem a little unnecessary, in fact. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net
Re: Arrays: Default Values
--- Michael Lazzaro [EMAIL PROTECTED] wrote: 1) What's the final decided syntax? Two possibilities: my @a is Array( default = 'foo' ); # attrib? my @a is default('foo');# property? Since we want arrays (lowercase) to support them, too, it should be a property. my @a is default('foo'); 2) Assume the default value is a simple value, e.g. 'foo'. my @a is Array( default = 'foo' ); @a[5] = 'bar'; @a[4]; # 'foo' @a[5]; # 'bar' @a[6]; # 'foo' @a[-1];# 'bar' *NOTE!* @a[-3];# 'foo' @a[-10]; # 'foo' 1) What if I *WANT* an array with negative indices? Case in point, the compare interface returns negative/zero/positive results, so I may want to use those. (Granted, using the -1 as from-end is cool. But writing a hand-optimized table of index values for use in a Shell/Metzner sort is also cool, and depends on quickly getting the results of the carry bit.) 2a) When a cell is explicitly re-undefined, does the default value take effect? No. If I wanted that, I'd say my @a[5] = @a.default; my @a is Array( default = 'foo' ) = (1,2,3); @a[1] = undef; @a[1]; # undef, or 'foo'? STRAWMAN ANSWER: 'foo'. No, undef. OTOH, deleting @a[1] would reset it to default. 2b) Primitive-typed arrays: Given the behavior of (2a), and the fact that primitive-typed arrays can't store undef, what happens here? my int @a is Array( default = 5 ); @a[0] = 0; @a[0]; # 0, or 5? @a[0] = undef; This should cause a blip of some kind. If storing an explicit undef (as opposed to undef but 0 or C$v = undef; @a[0] = $v; there should be an exception. If storing an implicit undef: convert to int (IOW: 0) and emit a warning. @a[0]; # 0, or 5? STRAWMAN ANSWER: 5, in both cases. So don't do that unless you mean it. Again, this is wrong. Storing undef is storing undef. If it's an error, treat it as such. If it's not an error, then let me store it. If I want to store the default value, I have access to the default value and can store it. 3) Can the default value be a closure, based on index location? my @a is Array( default = { $_ ** 2 }); STRAWMAN ANSWER: Yes, because it's cool. No, because defaulting method may be independent of default value. It should be called default_method instead: my @a is default_method( {$_ ** 2} ); 3a) NOTE that closure-based defaults effectively render the array infinite. Therefore -- If the requested index is negative, what happens? @a[-5]; STRAWMAN ANSWER: The closure just gets a negative number as the requested index. It's up to you to make it work, if you want it to. Another question: If you ask for a value and get it, does the array grow? Or does that happen only on assignment? (I favor assignment, but if the closure isn't a pure function, what happens? Can we support differentiating between Cis cached subs (meaning: don't allocate storage for this array element) and not (meaning: you'll want to allocate storage, because this value isn't reproducible)? 3b) Does an infinite array still get an exception thrown when trying to access an infinite [Inf] or [-Inf] index? STRAWMAN ANSWER: Yes, it does. No, it doesn't. Like negative numbers in 3a, Inf gets passed to the default_method, which may itself throw the exception. But since Inf and NaN are floating-point things, they should be easy to recognize. (In fact, I'd say just provide a default sub and show people what it looks like.) ::Array.default_method := ::array.default_method := sub - ($this: $index) { die(Invalid array index) unless $index.isa('int'); # Not setting the array[index] here, since this is cached. return defined($this.default) ? $this.default : undef; } is cached; PS: If the .default changes, the cached values are wrong. How to I tell Perl to clear a function's return cache? Or do we just not cache the function and allocate memory on an index-by-index basis? =Austin
Re: Arrays: Default Values
--- Austin Hastings [EMAIL PROTECTED] wrote: No, undef. OTOH, deleting @a[1] would reset it to default. Ere someone flames my for using a hash keyword in an array context: s/deleting/absquatulating (e.g., via pop, shift, or splice)/ =Austin
Re: Arrays: Default Values
I think this debate is easier if you think of defaults as overriding and auto-vivification method on a container. On Tue, 2003-01-28 at 14:47, Paul Johnson wrote: Michael Lazzaro said: 2a) When a cell is explicitly re-undefined, does the default value take effect? my @a is Array( default = 'foo' ) = (1,2,3); @a[1] = undef; @a[1]; # undef, or 'foo'? STRAWMAN ANSWER: 'foo'. Seems right to me. Anything else would be very confusing, I think. This would be very confusing to me. In fact, it seems WRONG to me unless we're saying that such arrays can simply never hold an undefined value... which again seems wrong. my @a is Array ( default = 'foo' ); @a[1] = undef; Should yield the following, I would think: ('foo', undef, 'foo' x Inf) Though, obviously there's no such thing as @a[2], but if you reference it, that's how it would auto-vivify. If that's not the case, I need to get my head around why, since Perl *does* distinguish between defined and exists. 2b) Primitive-typed arrays: Given the behavior of (2a), and the fact that primitive-typed arrays can't store undef, what happens here? my int @a is Array( default = 5 ); @a[0] = 0; @a[0]; # 0, or 5? 0. Being unable to store 0 would seem to be a major limitation. But of course. @a[0] = undef; @a[0]; # 0, or 5? An exception or 5. The first assignment would attempt to convert undef to type int. That's either an exception or zero, no? The is Array is a constraint on the container, and should not be entering into the conversion at hand until you try to STORE the result. Maybe undefining an element could always set it to the default value. 3) Can the default value be a closure, based on index location? my @a is Array( default = { $_ ** 2 }); STRAWMAN ANSWER: Yes, because it's cool. No, because it's unnecessary. You can always do my $value = @a[$x] //= $x ** 2; Again, different. You're looking for something like Cifexists=, not C//= -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
Austin Hastings wrote: --- Austin Hastings [EMAIL PROTECTED] wrote: No, undef. OTOH, deleting @a[1] would reset it to default. Ere someone flames my for using a hash keyword in an array context: s/deleting/absquatulating (e.g., via pop, shift, or splice)/ Unfortunately, I don't think we can base defaultitude on the (non)existence of an array element. You end up with some rather nasty action-at-a-distance. Consider: my @a is default(666); print @a[2]; # prints 666 @[4] = 1; print @a[2]; # now prints undef :-( I think of Cis default as specifying a mapping from an implicit or explicit Cundef to something else. I'm not compelled by the counter-argument that this makes it impossible to store an Cundef in an array with a default. Because the whole point of an array having a default is to prevent those nasty out-of-range Cundefs from popping up in the first place. And thinking of defaults as mappings leads me to conclude that it's entirely reasonable to allow sub refs as default specifiers, as a means of creating computed arrays. But I'd expect that the property name is different in that case (probably Cis computed), so as to distinguish: # array of subroutine refs # (default value returned is reference to identity function) my @funcs is default { return $^arg } = ( { return 1 }, { return $^arg ** 2 }, { return $^arg ** 3 }, # etc. ); from: # array of data values # (default value returned is square of requested index minus 1) my @vals is computed { return $^index**2-1 } = ( 2, 3, 7, # etc. ); Damian
Re: Arrays: Default Values
On Tue, Jan 28, 2003 at 12:30:41PM -0800, Austin Hastings wrote: --- Michael Lazzaro [EMAIL PROTECTED] wrote: my int @a is Array( default = 5 ); @a[0] = undef; This should cause a blip of some kind. If storing an explicit undef (as opposed to undef but 0 or C$v = undef; @a[0] = $v; there should be an exception. If storing an implicit undef: convert to int (IOW: 0) and emit a warning. @a[0]; # 0, or 5? I'm not sure. I think I like the idea of @a[0] = undef; being a blip, but undef @a[0]; resetting the value to the default. Conceptually perl5 already has a distinction between assigning undef to an aggregate, and passing an aggregate to the undef operator: $ perl -le '@a = %ENV; print scalar @a; undef @a; print scalar @a' 42 0 $ perl -le '@a = %ENV; print scalar @a; @a = undef; print scalar @a' 42 1 so it's not a great leap to extend this difference to scalar values. Although it may be one leap too far. Nicholas Clark
Re: Arrays: Default Values
Austin Hastings wrote: Another question: If you ask for a value and get it, does the array grow? Or does that happen only on assignment? ( Arrays (or hashes) don't grow on reading - never. And another anser from current low level (list.c classes/Array.pmc) *Return value * * *List get functions return a (void*) pointer to the location of the *stored data. The caller has to extract the value from this *pointer. * *For non existent data beyond the dimensions of the *array a NULL pointer is returned. * *For non existing data inside sparse holes, a pointer (void*)-1 *is returned. *The caller can decide to assume these data as undef or 0 or *whatever is appropriate. As the returned ptr is a PMC ** you/the class interface can do what is appropriate: if (ret == 0) internal_exception(OUT_OF_BOUNDS, Array index out of bounds!\n); /* XXX getting non existant value, exception or undef? * current is for perlarray */ if (ret == (void*) -1) value = undef(interp); else { value = *(PMC**) ret; if (value == NULL) /* XXX same here */ value = undef(interp); } leo
Re: Arrays: Default Values
On Tue, 2003-01-28 at 16:23, Leopold Toetsch wrote: Austin Hastings wrote: Another question: If you ask for a value and get it, does the array grow? Or does that happen only on assignment? ( Arrays (or hashes) don't grow on reading - never. Never say never. You're correct for pure reading like so: $x = @a[0]; But for less pure forms of reading: foo(@a[0]); auto-vivification will have to happen in some cases. e.g. if foo requires a lvalue parameter. You can't know if an actual write will happen, so you have to auto-vivify in order to pass a reference. Or did I miss something there? -- Aaron Sherman [EMAIL PROTECTED] This message (c) 2003 by Aaron Sherman, and granted to the Public Domain in 2023. Fight the DMCA and copyright extension!
Re: Arrays: Default Values
On Tuesday, January 28, 2003, at 01:14 PM, Damian Conway wrote: I'm not compelled by the counter-argument that this makes it impossible to store an Cundef in an array with a default. Because the whole point of an array having a default is to prevent those nasty out-of-range Cundefs from popping up in the first place. And thinking of defaults as mappings leads me to conclude that it's entirely reasonable to allow sub refs as default specifiers, as a means of creating computed arrays. But I'd expect that the property name is different in that case (probably Cis computed), so as to distinguish: The next (oft-asked) question is whether or not Cis computed denotes read-only, or if you can store to an Cis computed array. my @a is computed { $^index**2 }; @a[4] = 'something completely different'; And things like this would be downright hysterical: my @a is computed { $^index**2 }; pop @a; :-) MikeL
Re: Arrays: Default Values
On Tuesday, January 28, 2003, at 01:01 PM, Nicholas Clark wrote: On Tue, Jan 28, 2003 at 12:30:41PM -0800, Austin Hastings wrote: --- Michael Lazzaro [EMAIL PROTECTED] wrote: my int @a is Array( default = 5 ); @a[0] = undef; This should cause a blip of some kind. If storing an explicit undef (as opposed to undef but 0 or C$v = undef; @a[0] = $v; there should be an exception. If storing an implicit undef: convert to int (IOW: 0) and emit a warning. Hmm. I don't have a strong preference either way, but I'm not sure why (given Cmy int @a): @a[ undef ] Cundef should be autoconverted to 0 with warning, but in: @a[0] = undef; Cundef should _not_ be autoconverted to 0, but instead trigger an exception. They're both in Cint context, unless we want to make a special int being used as an array index context that's different from normal Cint context. Seems like Cundef should be treated like 0 (plus warning) in numeric context either everywhere, or nowhere. (?) MikeL
Re: Arrays: Default Values
--- Damian Conway [EMAIL PROTECTED] wrote: Austin Hastings wrote: --- Austin Hastings [EMAIL PROTECTED] wrote: No, undef. OTOH, deleting @a[1] would reset it to default. Ere someone flames my for using a hash keyword in an array context: s/deleting/absquatulating (e.g., via pop, shift, or splice)/ Unfortunately, I don't think we can base defaultitude on the (non)existence of an array element. You end up with some rather nasty action-at-a-distance. Consider: my @a is default(666); print @a[2];# prints 666 @[4] = 1; print @a[2];# now prints undef :-( I think of Cis default as specifying a mapping from an implicit or explicit Cundef to something else. I don't understand your example. Can you explain it again, using words of less than one syllable? What's @[4]? Why does it (even if it's a typo from @a[4]) cause @a[2] to become defined? (Small != dense) If it does become defined, why doesn't it get the default value -- no-one explicitly told it to be undef? I'm not compelled by the counter-argument that this makes it impossible to store an Cundef in an array with a default. Because the whole point of an array having a default is to prevent those nasty out-of-range Cundefs from popping up in the first place. The point of having a default is to replace those undefs with something else. To prevent them from appearing would require rewriting ones code in such a way that extraordinary arrefs didn't happen. But given that I can replace undef with 'fednu' in these cases, I'd now like to reduce/reuse/recycle my undefs back as meaningful values -- they're not reserved for the special case of LOCALE=noaquistan any more. And thinking of defaults as mappings leads me to conclude that it's entirely reasonable to allow sub refs as default specifiers, as a means of creating computed arrays. But I'd expect that the property name is different in that case (probably Cis computed), so as to distinguish: [[ code elided ]] Yeah, that too. I like is computed. =Austin
Re: Arrays: Default Values
Austin Hastings wrote: --- Austin Hastings [EMAIL PROTECTED] wrote: No, undef. OTOH, deleting @a[1] would reset it to default. Ere someone flames my for using a hash keyword in an array context: s/deleting/absquatulating (e.g., via pop, shift, or splice)/ What's wrong with Cdelete in an array context? If there's to be a distinction between storing an undef value and resetting to the default value -- and, having read Damian's thoughts on the matter, I'm almost convinced that there shouldn't be -- then I think it's much more obvious to distinguish Cdelete and Cundef rather than Cundef @a[1] and C@a[1] = undef. Smylers
Re: Arrays: Default Values
--- Michael Lazzaro [EMAIL PROTECTED] wrote: On Tuesday, January 28, 2003, at 01:01 PM, Nicholas Clark wrote: On Tue, Jan 28, 2003 at 12:30:41PM -0800, Austin Hastings wrote: --- Michael Lazzaro [EMAIL PROTECTED] wrote: my int @a is Array( default = 5 ); @a[0] = undef; This should cause a blip of some kind. If storing an explicit undef (as opposed to undef but 0 or C$v = undef; @a[0] = $v; there should be an exception. If storing an implicit undef: convert to int (IOW: 0) and emit a warning. Hmm. I don't have a strong preference either way, but I'm not sure why (given Cmy int @a): @a[ undef ] Cundef should be autoconverted to 0 with warning, but in: @a[0] = undef; Cundef should _not_ be autoconverted to 0, but instead trigger an exception. They're both in Cint context, unless we want to make a special int being used as an array index context that's different from normal Cint context. Seems like Cundef should be treated like 0 (plus warning) in numeric context either everywhere, or nowhere. (?) I agree. Warning: Using undef as array index would be a nice message - probably save a bunch of debugging. =Austin
Re: Arrays: Default Values
On Tue, Jan 28, 2003 at 02:13:22PM -0800, Michael Lazzaro wrote: Hmm. I don't have a strong preference either way, but I'm not sure why (given Cmy int @a): @a[ undef ] Cundef should be autoconverted to 0 with warning, but in: @a[0] = undef; Cundef should _not_ be autoconverted to 0, but instead trigger an exception. They're both in Cint context, unless we want to make a special int being used as an array index context that's different from normal Cint context. Seems like Cundef should be treated like 0 (plus warning) in numeric context either everywhere, or nowhere. (?) Hmm. You've got me there. I don't have an answer that's consistent. Unless the context is allowed to govern whether undef conversion is allowable, or an exception. But that feels complex. I think the answer is it depends, and some of the time I'd like each different permutation of behaviour. Nicholas Clark
Re: Arrays: Default Values
Austin Hastings wrote: --- Damian Conway [EMAIL PROTECTED] wrote: my @a is default(666); print @a[2]; # prints 666 @a[4] = 1; print @a[2]; # now prints undef :-( [typo in third line corrected] I don't understand your example. Can you explain it again, using words of less than one syllable? If the scheme is (as someone was advocating) that the default is used only in place of elements that don't exist (as opposed to elements that are allocated but contain Cundef), then allocating a previously unallocated element has the potential to change the value it returns, even if that previously unallocated element is not initialized when allocated. So, assigning to @a[4], causes @a[0..3] to be created as well. Which, under a default-for-non-existent-elements-only policy causes @a[2] to stop returning the default. What's @[4]? Why does it (even if it's a typo from @a[4]) cause @a[2] to become defined? It doesn't. It causes it to exist. I understood that it was being advocating that only non-existent elements returned the default. This is why that's a bad idea. If it does become defined, why doesn't it get the default value -- no-one explicitly told it to be undef? Because the whole idea of a default value is that you *don't* put it in every element. The lack of a value in an element is what triggers the default value to be returned. And in Perl Cundef is how we signify the absence of a value. Damian
Re: Arrays: Default Values
Nicholas Clark wrote: I'm not sure. I think I like the idea of @a[0] = undef; being a blip, but undef @a[0]; resetting the value to the default. That thought crossed my mind as well before I got to your message ... Conceptually perl5 already has a distinction between assigning undef to an aggregate, and passing an aggregate to the undef operator: ... however I'm unconvinced that that's the sort of distinction that should be encouraged. Smylers
Re: Arrays: Default Values
On Tue, Jan 28, 2003 at 04:07:17PM -0500, Aaron Sherman wrote: I think this debate is easier if you think of defaults as overriding and auto-vivification method on a container. Hmm. I don't :-) I think it is easier if you think of defaults as overriding undef. On Tue, 2003-01-28 at 14:47, Paul Johnson wrote: Michael Lazzaro said: 2a) When a cell is explicitly re-undefined, does the default value take effect? my @a is Array( default = 'foo' ) = (1,2,3); @a[1] = undef; @a[1]; # undef, or 'foo'? STRAWMAN ANSWER: 'foo'. Seems right to me. Anything else would be very confusing, I think. This would be very confusing to me. In fact, it seems WRONG to me unless we're saying that such arrays can simply never hold an undefined value... which again seems wrong. I think that seems right. my @a is Array ( default = 'foo' ); @a[1] = undef; Should yield the following, I would think: ('foo', undef, 'foo' x Inf) Though, obviously there's no such thing as @a[2], but if you reference it, that's how it would auto-vivify. If that's not the case, I need to get my head around why, since Perl *does* distinguish between defined and exists. But I wish it wouldn't for arrays. That only came about to support pseudo-hashes which are going / have gone away. Are you suggesting that hashes should also have a default? That would seem consistent and at least as useful as arrays having a default. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net
Re: Arrays: Default Values
On Tue, Jan 28, 2003 at 03:06:19PM -0800, Damian Conway wrote: Austin Hastings wrote: --- Damian Conway [EMAIL PROTECTED] wrote: my @a is default(666); print @a[2];# prints 666 @a[4] = 1; print @a[2];# now prints undef :-( [typo in third line corrected] I don't understand your example. Can you explain it again, using words of less than one syllable? If the scheme is (as someone was advocating) that the default is used only in place of elements that don't exist (as opposed to elements that are allocated but contain Cundef), then allocating a previously unallocated element has the potential to change the value it returns, even if that previously unallocated element is not initialized when allocated. So, assigning to @a[4], causes @a[0..3] to be created as well. Which, under a default-for-non-existent-elements-only policy causes @a[2] to stop returning the default. It doesn't have to be that way: $ perl -le 'sub e { print exists $a[shift] ? 1 : 0 } e 2; $a[4]++; e 2; e 4; delete $a[4]; e 2; e 4' 0 0 1 0 0 No, I don't know which side I'm arguing anymore :-) Actually, I do. I don't like exists on arrays. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net
Re: Arrays: Default Values
Michael Lazzaro wrote: The next (oft-asked) question is whether or not Cis computed denotes read-only, or if you can store to an Cis computed array. my @a is computed { $^index**2 }; @a[4] = 'something completely different'; I'd expect that Cis computed and Cis constant would be orthogonal. And things like this would be downright hysterical: my @a is computed { $^index**2 }; pop @a; Returns 1, of course. Since the $^index for a Cpop is always -1. ;-) Damian
Re: Arrays: Default Values
Michael Lazzaro wrote: 2a) When a cell is explicitly re-undefined, does the default value take effect? my @a is Array( default = 'foo' ) = (1,2,3); @a[1] = undef; @a[1]; # undef, or 'foo'? STRAWMAN ANSWER: 'foo'. If Cundef is a valid value for a cell, then I should be able to store it. I think that Cdelete would better convey the intent -- it would also help with the behavior of negative indexes. 2b) Primitive-typed arrays: Given the behavior of (2a), and the fact that primitive-typed arrays can't store undef, what happens here? my int @a is Array( default = 5 ); @a[0] = 0; @a[0]; # 0, or 5? Definitely 0. Definitely 0. DEFINITELY ZERO. @a[0] = undef; @a[0]; # 0, or 5? STRAWMAN ANSWER: 5, in both cases. So don't do that unless you mean it. 0: see (2a) 3) Can the default value be a closure, based on index location? my @a is Array( default = { $_ ** 2 }); STRAWMAN ANSWER: Yes, because it's cool. sounds good. But we wqant to ensure that the default value can actually be a closure -- i.e. its not a Cdefault if we execute it. 3a) NOTE that closure-based defaults effectively render the array infinite. Therefore -- If the requested index is negative, what happens? @a[-5]; STRAWMAN ANSWER: The closure just gets a negative number as the requested index. It's up to you to make it work, if you want it to. Yes 3b) Does an infinite array still get an exception thrown when trying to access an infinite [Inf] or [-Inf] index? STRAWMAN ANSWER: Yes, it does. Should follow (3a): the generator can through the exception if desired. Now, what about @a[2.5]: can my generator do interpolation? Dave. -- http://dave.whipp.name
Re: Arrays: Default Values
Aaron Sherman wrote: auto-vivification will have to happen in some cases. e.g. if foo requires a lvalue parameter. You can't know if an actual write will happen, so you have to auto-vivify in order to pass a reference. Or did I miss something there? I think the idea is to use a special object which, if assigned to, will create the required element. Dave. -- http://dave.whipp.name
Re: Arrays: Default Values
So ... with the discussion of what if i really wanted to put an undef in there b/c it's not just that i haven't defined it but rather that it really isn't defined. I KNOW it's not defined, and i'm now explicitly saying it's undefined as opposed to before when i was implicitly suggesting that i didn't know what it was and used a default 'unknown' discussion ... What we really need is: @a[2] = undef but undef; or, possibly (more tongue-in-cheek-y) @a[2] = undef but seriously; so the ... property? would say you have a default, maybe, but i don't care. this is REALLY undef is that possible? aside from it being disturbing to write undef but undef :o --attriel (the first suggestion is serious, but the syntax is flawed; the second suggestion has better syntax but is tongue-in-cheek suggested ... )
Re: Arrays: Default Values
attriel wrote: So ... with the discussion of what if i really wanted to put an undef in there b/c it's not just that i haven't defined it but rather that it really isn't defined. I KNOW it's not defined, and i'm now explicitly saying it's undefined as opposed to before when i was implicitly suggesting that i didn't know what it was and used a default 'unknown' discussion ... What we really need is: @a[2] = undef but undef; or, possibly (more tongue-in-cheek-y) @a[2] = undef but seriously; so the ... property? would say you have a default, maybe, but i don't care. this is REALLY undef is that possible? aside from it being disturbing to write undef but undef :o --attriel (the first suggestion is serious, but the syntax is flawed; the second suggestion has better syntax but is tongue-in-cheek suggested ... ) What about: undef @a[2]; or possibly even (although I would argue that undef should remain a unary operator only): @a[2].undef(); Joseph F. Ryan [EMAIL PROTECTED]