Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

More Array Behaviors

20 views
Skip to first unread message

Michael Lazzaro

unread,
Jan 27, 2003, 2:00:17 PM1/27/03
to perl6-l...@perl.org
Some requests for verification, plus additional questions. If anyone
has any arguments/clarifications/questions on these, please discuss so
I can document.


1) Edge cases in array indexing:

my int @a = (1,2,3);

@a[0] # 1
@a[1] # 2
@a[2] # 3
@a[3] # undef
@a[2**128] # undef (but not exception???)
@a[Inf] # undef (but not exception)
@a[ undef ] # undef, or 1?
@a['foo'] # undef, or 1?

@a[-1] # 3
@a[-2] # 2
@a[-3] # 1
@a[-4] # undef
@a[-Inf] # undef (but not exception)

Is [undef] the same as [0] in Perl6? Is there any index value you can
give that will cause an exception?


2) As hinted above, is there a (platform-dependent) maximum addressable
array index, or do we promise to correctly handle all integers, even if
BigInt? (This might come into play for lazy/sparse arrays. Maybe.)


3) Array default values. It has been mentioned repeatedly that it
would be nice to be able to specify what the value an array cell will
contain, if it has not been previously stored to. What's the preferred
syntax? One example:

my @a is Array( default => 'foo' ); # (a) by value?

my @a is Array( default => { $_ ** 2 } ); # (b) via closure???

Note that if (b) is possible, I don't know how you'd _store_ a closure
as the default value of an array, if you're into that sort of thing.


4) Optional array behavior. In addition to default values, it may be
possible to expose other details of array behavior, such that the user
has some flexibility in the implementation of a given array. Examples:

my @a is Array(
min_size => 50, # minimum reported size of this array
max_size => 100, # maximum reported size of this array

resize => (1024), # internal blocksize (in indexes)
# by which array expands?
resize => { $_ * 2 }, # or via closure, based on current size?

exception => 1, # whether out-of-bounds addressing
# causes an exception to be thrown
exception_neg => 1, # (for negative indexes only?)
exception_pos => 1, # (for positive indexes only?)

locked => 1, # read-only, can't store new values

start_index => 0, # starting index, if not zero
);

... if such capabilities exist, what are their real names? Can
anyone think of any that are absolute must-haves? Are any of the above
must-haves?

(Note that the obvious added complexity caused by so many options can
probably be optimized away for the default array implementation.)

MikeL

Nicholas Clark

unread,
Jan 27, 2003, 3:32:42 PM1/27/03
to Michael Lazzaro, perl6-l...@perl.org
On Mon, Jan 27, 2003 at 11:00:17AM -0800, Michael Lazzaro wrote:

> resize => (1024), # internal blocksize (in indexes)
> # by which array expands?
> resize => { $_ * 2 }, # or via closure, based on current size?

I think you're making too many assumptions about the internal implementations
of arrays here.
At least, I'm hoping that the innards will be flexible enough to let me
do different things, such as request sparse arrays by default

> locked => 1, # read-only, can't store new values

There was a discussion on p5p about "restricted hashes", and what one might
want. Even for arrays I can think of at least 2 levels.

1: everything locked - no new elements, existing elements treated as read only
2: size locked - you can't extend (or shrink) the array, but you can
add/remove elements

If array indexes have a concept of exists distinct from defined, then several
more graduations appear.

Nicholas Clark

Leopold Toetsch

unread,
Jan 27, 2003, 3:44:07 PM1/27/03
to Michael Lazzaro, perl6-l...@perl.org
Michael Lazzaro wrote:

I have some answers from current low level implementation.

> 2) As hinted above, is there a (platform-dependent) maximum addressable
> array index, or do we promise to correctly handle all integers, even if
> BigInt? (This might come into play for lazy/sparse arrays. Maybe.)


new P0, .PerlArray
set I0, 1
shl I0, I0, 31
dec I0
dec I0
set P0[I0], I0
set I1, P0[I0]
print I1
print "\n"
end

Current max index is 2^31-2 (for 32bitters). SIZE/RSS of above running
is 1152 (list.c can do sparse arrays). IMHO for bigger arrays use a 64
bit processor, and you can't fill them anyway ;-)


> 4) Optional array behavior. In addition to default values, it may be
> possible to expose other details of array behavior, such that the user
> has some flexibility in the implementation of a given array. Examples:
>
> my @a is Array(
> min_size => 50, # minimum reported size of this array


Just set @a[49]


> resize => (1024), # internal blocksize (in indexes)


items per chunk, yes.


> # by which array expands?
> resize => { $_ * 2 }, # or via closure, based on current size?


Small arrays start extending by doubling chunk sizes, big arrays start
with maximum chunk sizes and don't grow chunks anymore. Closures or such
are for sure overkill and will slow it down.


> exception => 1, # whether out-of-bounds addressing


This is default for Array.pm (PerlArray does auto resize).


> MikeL


leo

Austin Hastings

unread,
Jan 27, 2003, 4:02:28 PM1/27/03
to Nicholas Clark, Michael Lazzaro, perl6-l...@perl.org

--- Nicholas Clark <ni...@unfortu.net> wrote:
> On Mon, Jan 27, 2003 at 11:00:17AM -0800, Michael Lazzaro wrote:
>
> > resize => (1024), # internal blocksize (in indexes)
> > # by which array expands?
> > resize => { $_ * 2 }, # or via closure, based on current
> size?
>
> I think you're making too many assumptions about the internal
> implementations
> of arrays here.
> At least, I'm hoping that the innards will be flexible enough to let
> me
> do different things, such as request sparse arrays by default
>
> > locked => 1, # read-only, can't store new values
>
> There was a discussion on p5p about "restricted hashes", and what one
> might
> want. Even for arrays I can think of at least 2 levels.
>
> 1: everything locked - no new elements, existing elements treated as
> read only
> 2: size locked - you can't extend (or shrink) the array, but you can
> add/remove elements
>

How bizarre. When you said you could think of two levels, I immediately
thought of two levels, but mine and yours aren't the same. I thought of
"totally read-only" and "content-locked" -- expanding/contracting is
okay, but no updates. (Think of implementing a stack, say.)

Maybe this is my C background coming out. The difference between

const int * ptr; /* Variable pointer to unchanging elements. */

and

const int const * ptr; /* Unchanging pointer to unchanging elements */

versus

int const * ptr; /* Unchanging pointer to variable elements */

Anyway, I guess "locked" means different things to different folks.
Probably this shouldn't be core -- it should be easy enough to code up
a standard set of permutations.

(OTOH, it's not unreasonable to talk about a standard set of methods
for this stuff, so that all those post-facto implementations speak the
same language.

Far better to have

LockedArray, LockedString, LockedNumeric, LockedBarnDoor, LockedMouth

than to have

FrozenArray, StaticString, ConstNumeric, LockedBarnDoor, SealedLips

(Unless this is one of those gobhoblins... ?)

=Austin

Dave Whipp

unread,
Jan 27, 2003, 4:15:22 PM1/27/03
to perl6-l...@perl.org
"Michael Lazzaro" <mlaz...@cognitivity.com> wrote in message
news:935680D1-3229-11D7...@cognitivity.com...

> ... if such capabilities exist, what are their real names? Can
> anyone think of any that are absolute must-haves? Are any of the above
> must-haves?

I think that the only must-have is the ability to add these things later.
The size constraints are probably C<but> properties, as is C<locked>. The
exception behavior probably deserves to remain an C<is> property. There are
so many possibilities that we can't expect to have them as built-ins. And I
don't really see any compelling reason for any of the suggestions as a
builtin. Examples of other properties include:

but sparse # sparse arrays
but lower_bound=>N # orthogonal to base_index
is interpolated(algorithm=>Linear) # permit fractional indexes on this
variable.

> (Note that the obvious added complexity caused by so many options can
> probably be optimized away for the default array implementation.)

Any that are defined as C<is> properties are trivially optimized, because
they don't affect the stored value.


Damian Conway

unread,
Jan 27, 2003, 4:24:23 PM1/27/03
to perl6-l...@perl.org
Dave Whipp suggested:

> The size constraints are probably C<but> properties, as is C<locked>. The
> exception behavior probably deserves to remain an C<is> property.

Nope. They're all C<is> properties. C<but> properties only apply to *values*.
Variable such as Arrays always take C<is> properties.

Damian

Dave Whipp

unread,
Jan 27, 2003, 4:45:16 PM1/27/03
to perl6-l...@perl.org

"Damian Conway" <dam...@conway.org> wrote in message
news:3E35A387...@conway.org...

This confuses me: I thought an array *is* a value. Sure, its a value that
holds other values: but an array is a run-time construct, which is not
(necessarily) lexically scoped, and which changes over time. Am I missing
something? Are you distinguishing between value-semantics and
reference-semantics? Are you saying that only scalars have C<but> properties
(i.e. an ArrayRef can, but an array can't)? My mental image is of variables
that provide access to values: variables are compile-time, and lexically
scoped: values are run-time, and (can be) dynamically scoped.

Dave.
--
mailto:da...@whipp.name; http://dave.whipp.name


Damian Conway

unread,
Jan 27, 2003, 5:06:01 PM1/27/03
to perl6-l...@perl.org
> This confuses me: I thought an array *is* a value.

Nope. Arrays are variables.


> Sure, its a value that holds other values:

Anything that "holds" anything is a variable, not a value.


> Are you saying that only scalars have C<but> properties
> (i.e. an ArrayRef can, but an array can't)?

I'm saying that only scalar *values* can have C<but> properties.
And yes, that includes Array references, but not arrays.


> My mental image is of variables
> that provide access to values: variables are compile-time, and lexically
> scoped: values are run-time, and (can be) dynamically scoped.

Not quite. Variables are containers, values are the data they contain.
Compile-time/run-time and scoping are orthogonal to that.

Damian

Michael Lazzaro

unread,
Jan 27, 2003, 5:34:05 PM1/27/03
to perl6-l...@perl.org
On Monday, January 27, 2003, at 11:46 AM, John Williams wrote:

> On Mon, 27 Jan 2003, Michael Lazzaro wrote:
>> 1) Edge cases in array indexing:
>>
>> @a[ undef ] # undef, or 1?
>> @a['foo'] # undef, or 1?
>
> These should generate warnings, at least.
> I don't know whether undef or 1 is more correct.

It's certainly a legitimate question. (I'm not sure that @a[undef] ==
@a[0] is the correct behavior, going forward. It certainly can be
error-prone.)

We need an expert decision here, please.

> Perl5 chooses 1, but it's smart enough to distiguish between $a["1e0"]
> (returns 2) and $a["1e"] (returns 1 and a non-numeric warning), so it's
> definitely choosing to return $a[0] for non-numeric indexes.
> (0+"1e" is 1, not 0)

> What about @a[NaN]? Just another warning probably.

Probably. After all, 'foo' in a numeric context should probably be...
um... NaN. Or did we ever decide on that one, after discussing it into
the ground?

MikeL

Michael Lazzaro

unread,
Jan 27, 2003, 5:40:47 PM1/27/03
to perl6-l...@perl.org

On Monday, January 27, 2003, at 01:15 PM, Dave Whipp wrote:
> "Michael Lazzaro" <mlaz...@cognitivity.com> wrote in message
>> ... if such capabilities exist, what are their real names? Can
>> anyone think of any that are absolute must-haves? Are any of the
>> above
>> must-haves?
>
> I think that the only must-have is the ability to add these things
> later.
> The size constraints are probably C<but> properties, as is C<locked>.
> The
> exception behavior probably deserves to remain an C<is> property.
> There are
> so many possibilities that we can't expect to have them as built-ins.
> And I
> don't really see any compelling reason for any of the suggestions as a
> builtin. Examples of other properties include:

(modulo Damian's correction that it's C<is>, not C<but>, in this case.)

Um, as an aside, I think perhaps I need a(nother, (better))
clarification on which things properties are to be used for, and what
class inheritance is to be used for. What's the underlying philosophy
here? When should something be a property, vs. a normal behavior of a
class?

I would think that 'properties' should be reserved for things that can
be applied to all variables, regardless of type, but some of these
example 'behaviors' are very specific to Array -- to a particular
assumed implementation of an Array, in fact. I would figure those
would more likely be attributes of the implementing class.

What's the (stylistic) rules?

MikeL

John Williams

unread,
Jan 27, 2003, 2:46:33 PM1/27/03
to Michael Lazzaro, perl6-l...@perl.org
On Mon, 27 Jan 2003, Michael Lazzaro wrote:

> Some requests for verification, plus additional questions. If anyone
> has any arguments/clarifications/questions on these, please discuss so
> I can document.
>
> 1) Edge cases in array indexing:
>

> @a[ undef ] # undef, or 1?
> @a['foo'] # undef, or 1?

These should generate warnings, at least.

I don't know whether undef or 1 is more correct.

Perl5 chooses 1, but it's smart enough to distiguish between $a["1e0"]


(returns 2) and $a["1e"] (returns 1 and a non-numeric warning), so it's
definitely choosing to return $a[0] for non-numeric indexes.
(0+"1e" is 1, not 0)

> Is [undef] the same as [0] in Perl6? Is there any index value you can


> give that will cause an exception?

What about @a[NaN]? Just another warning probably.

~ John Williams


Damian Conway

unread,
Jan 27, 2003, 5:50:19 PM1/27/03
to perl6-l...@perl.org
Michael Lazzaro wrote:

>>> 1) Edge cases in array indexing:
>>>
>>> @a[ undef ] # undef, or 1?
>>> @a['foo'] # undef, or 1?
>>
>> These should generate warnings, at least.
>> I don't know whether undef or 1 is more correct.
>
> It's certainly a legitimate question. (I'm not sure that @a[undef] ==
> @a[0] is the correct behavior, going forward. It certainly can be
> error-prone.)
>
> We need an expert decision here, please.

I'd expect that C<undef> converts to zero (with an evitable warning).

I would expect that non-numeric strings like 'foo' convert to C<undef>
and thence on to zero (again with an evitable warning).

Unless C<use strict 'conversions'> is in effect, of course.

Note that converting to and from C<undef> in numeric contexts is much
less troublesome in Perl 6, because the C<//> operator makes it trivial to
catch bad cases and handle them appropriately:

@a[$str//0] // silently convert to zero
@a[$str//die] // silently convert to exception

>> What about @a[NaN]? Just another warning probably.

Actually, I would expect it to throw an exception. Using something that is
explicitly and deliberately *not* a number [*], in a context that expects a
number, almost certainly points to a serious problem in the code.

Damian


[*] ...as opposed to 'foo', which is merely implicitly and accidentally not a
number ;-)

Dave Whipp

unread,
Jan 27, 2003, 6:00:39 PM1/27/03
to perl6-l...@perl.org
"Damian Conway" <dam...@conway.org> wrote in message
news:3E35AD49...@conway.org...

>Anything that "holds" anything is a variable, not a value.
> [...]

> I'm saying that only scalar *values* can have C<but> properties.
> And yes, that includes Array references, but not arrays.
>
> > My mental image is of variables
> > that provide access to values: variables are compile-time, and lexically
> > scoped: values are run-time, and (can be) dynamically scoped.
>
> Not quite. Variables are containers, values are the data they contain.
> Compile-time/run-time and scoping are orthogonal to that.

OK, I've assimilated all that (though it still feels wrong). I think you are
saying that of the following, the 4th is an error.

my @a is Foo = @x;
my $b = [@x] but Foo;
my $c = @x but Foo; # ArrayRef automagically created
my @d = @x but Foo; # error: no values involved in this assignment
my @e is Foo := @x;

I think that the thing that confused is that C<is> Vs C<but> distinction was
introduced as compile-time vs run-time. It seems that this distinction is
not relevant.

Lets see if I apply this to objects. Objects are variables (they contain
attributes). All access to objects is via (scalar) references: these
references, being values, can have C<but> properties. When a method is
invoked on an object, that method has an invocant, which enables the method
to see the C<but> properties on that reference. If an object wants to have
properties that apply to all references (to a given instance), then that
property must be defined as an attribute of the object. An instance, itself,
doesn't have postIt style properties.

Dave.


Austin Hastings

unread,
Jan 27, 2003, 6:18:36 PM1/27/03
to Damian Conway, perl6-l...@perl.org

--- Damian Conway <dam...@conway.org> wrote:
> Note that converting to and from C<undef> in numeric contexts is much
> less troublesome in Perl 6, because the C<//> operator makes it
> trivial to
> catch bad cases and handle them appropriately:
>
> @a[$str//0] // silently convert to zero
> @a[$str//die] // silently convert to exception

Good point. When it's this simple to avoid the warning, the warning
should stay on by default.

>
> >> What about @a[NaN]? Just another warning probably.
>
> Actually, I would expect it to throw an exception. Using something
> that is
> explicitly and deliberately *not* a number [*], in a context that
> expects a
> number, almost certainly points to a serious problem in the code.

It's a sink. A data sink if we allow it, and a time sink if we discuss
it.

Given that NaN is, in fact, a "numerish" value (IOW: The context in
which NaN is meaningful is a numeric one) you could argue for allowing
storing into @a[NaN]. But you can't make a meaningful argument about
fetching from it.

Since NaN == NaN is false, how could you possibly retrieve any value
you earlier stored?

So it's either illegal, or legal but write-only.

=Austin

Austin Hastings

unread,
Jan 27, 2003, 6:27:24 PM1/27/03
to Dave Whipp, perl6-l...@perl.org

I'll ask, since I don't know: What's the access syntax for these
things?

my $i is wooly;

How do I test for wooliness? if ($i.wooly) { print "Booly!"; }

my $i = 6 but wooly;

How do I test for wooliness? if ($i.wooly) { print "Booly!"; }

class Mammoth {
member Boolean wooly;
};

my Mammoth $i;

if ($i.wooly) { print "Booly!!"; }

Is this right?


I ask this because I can easily see wanting a class behavior that
attaches value properties, such as "but true". This might almost become
a standard idiom, as:

my HideousDatabaseConnection $hdc = new HideousDatabaseConnection(...);

die "Hideous Death"
unless $hdc;


Where the ctor would ensure that but true/but false was set.

(Welcome to 1977. K&R, anyone?)

=Austin

=Austin

Damian Conway

unread,
Jan 27, 2003, 6:35:52 PM1/27/03
to perl6-l...@perl.org
Dave Whipp wrote:

> OK, I've assimilated all that (though it still feels wrong). I think you are
> saying that of the following, the 4th is an error.
>

> my @d = @x but Foo; # error: no values involved in this assignment

Correct. Although presumably this:

my @d = @x »but« Foo;

is okay.


> I think that the thing that confused is that C<is> Vs C<but> distinction was
> introduced as compile-time vs run-time. It seems that this distinction is
> not relevant.

Let's say it's an approximation to the true.


> Lets see if I apply this to objects. Objects are variables

Yes.


> (they contain attributes).

Yes.


> All access to objects is via (scalar) references:

Yes.


> these references, being values, can have C<but> properties.

Yes.


> When a method is invoked on an object, that method has an invocant, which
> enables the method to see the C<but> properties on that reference.

Yes.


> If an object wants to have properties that apply to all references
> (to a given instance), then that property must be defined as an attribute
> of the object.

Yes. At least, for the new "opaque" objects. Because there's no way to ascribe
the necessary C<is> property to them.

Of course, old-style blessed objects *can* have C<is> properties, if they're
created with them:

method new ($class: $name, $rank, $snum) {
my %self is Proper('teed') =
( name=> $name, rank=>$rank, snum=>$snum );
return $class.bless(%self);
}


> An instance, itself, doesn't have postIt style properties.

Not sure what you mean by "postIt style". In my view, *all* properties are
"PostIt style"...to the extent that they are stuck loosely on the variable or
value to which they're ascribed.

Damian

Thomas A. Boyer

unread,
Jan 27, 2003, 7:23:40 PM1/27/03
to Damian Conway, perl6-l...@perl.org
> And, please, let's spawn no threads talking about how parentheses in font Foo
> on platform Bar look like they point outwards. Ulk.

Er... I meant to say "inwards". Else that sentence makes NO sense.

Double Ulk.

=thom
"You live and learn. Or you don't live long." --Lazarus Long

Damian Conway

unread,
Jan 27, 2003, 7:34:47 PM1/27/03
to perl6-l...@perl.org
Thomas A. Boyer wrote:

> Damian, somewhere in the conversation on hyper-ops you switched over from this syntax:
> my @sum = @a «+» @b;
> to this syntax:
> my @sum = @a »+« @b;
>
> Would you care to share your thoughts on why you've gone with
inward-pointing guillemets?

Because that's what Larry decided last time this thread arose.
Convex guillemets will be used for word lists:

use strict «vars subs conversions»;

for «Doh Ray Me Far So La Tee» -> $word {
print "$word, %desc{$word}\n";
}

This is a far more naturally parenthetical usage of guillemets than vector ops
would be.

And I strongly prefer the concave guillemets for vectorizing, because they
highlight the operation, pointing it out in a distinctly "lookie-here" manner.


Damian

Thomas A. Boyer

unread,
Jan 27, 2003, 7:11:52 PM1/27/03
to Damian Conway, perl6-l...@perl.org

Damian Conway wrote:
> Correct. Although presumably this:
>
> my @d = @x »but« Foo;

Damian, somewhere in the conversation on hyper-ops you switched over from this syntax:


my @sum = @a «+» @b;
to this syntax:
my @sum = @a »+« @b;

(Since those two statements use non-ASCII characters, let's just say that on my screen those two statements look a lot like:


my @sum = @a <<+>> @b;

and


my @sum = @a >>+<< @b;

respectively, but the doubled angle brackets are single characters [guillemets].)

I saw one post from someone who said that the French use the outward-pointing convention for quoting, and the Germans use the inward-pointing convention. I never saw anything else along these lines, but you've used the outward-pointing convention since then.

I like the outward-pointing convention better (why *else* would I be whinging? :-) because parentheses and brackets are both used with the outward-pointing convention. Would you care to share your thoughts on why you've gone with inward-pointing guillemets?

And, please, let's spawn no threads talking about how parentheses in font Foo on platform Bar look like they point outwards. Ulk.

=thom

Piers Cawley

unread,
Jan 28, 2003, 3:46:26 AM1/28/03
to Damian Conway, perl6-l...@perl.org
Damian Conway <dam...@conway.org> writes:

Bugger. I was hoping that Perl 6 was going to make a Pixie like Object
database easier to write; looks like I'm wrong. One of the things
Pixie does is to attach its control data by magic to the object itself
(rather than any particular variable pointing to it). This lets us do
all sorts of useful stuff without invading the object since we know
that it will carry our metadata around it. Please, consider making
<but> properties attach to the target of a pointer rather than to the
pointer itself. And if you don't want to do that, I'd say that there
is a need to be able to specify some new kind of property that does
attach to the target.

--
Piers

Damian Conway

unread,
Jan 28, 2003, 12:17:36 PM1/28/03
to perl6-l...@perl.org
Piers Cawley wrote:

> Bugger. I was hoping that Perl 6 was going to make a Pixie like Object
> database easier to write; looks like I'm wrong. One of the things
> Pixie does is to attach its control data by magic to the object itself
> (rather than any particular variable pointing to it). This lets us do
> all sorts of useful stuff without invading the object since we know
> that it will carry our metadata around it. Please, consider making
> <but> properties attach to the target of a pointer rather than to the
> pointer itself.

Err....no. That's rather the whole point of C<but> properties [*].

However, if your class returns a reference to an object and that reference
has the appropriate value properties ascribed to it (i.e. stuck on the
*reference*), then any access through that reference (or through any
subsequent copy of it) will see those properties.

So your magic Pixie would look something like"

class Pixie {

method new($class: %args) {
return $class.SUPER::new(%args)
but Magic('whatever');
}

# etc.
}

Damian


[*] People, we just *have* to find better names for these things!
I'd suggest we henceforth call them "value" properties (for C<but>)
and "referent" properties (for C<is>).

Dan Sugalski

unread,
Jan 28, 2003, 11:48:31 AM1/28/03
to Piers Cawley, Damian Conway, perl6-l...@perl.org
At 8:46 AM +0000 1/28/03, Piers Cawley wrote:
>Bugger. I was hoping that Perl 6 was going to make a Pixie like Object
>database easier to write; looks like I'm wrong. One of the things
>Pixie does is to attach its control data by magic to the object itself
>(rather than any particular variable pointing to it). This lets us do
>all sorts of useful stuff without invading the object since we know
>that it will carry our metadata around it. Please, consider making
><but> properties attach to the target of a pointer rather than to the
>pointer itself. And if you don't want to do that, I'd say that there
>is a need to be able to specify some new kind of property that does
>attach to the target.

Given the current implementation (And I hear rumors that you lurk on
the internals list, Piers... :) I think we can manage something like
this. Might require a drop to assembly somewhere, perhaps hidden
behind a function rather than with syntax, but it should be doable...
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Piers Cawley

unread,
Jan 28, 2003, 12:25:16 PM1/28/03
to Dan Sugalski, Damian Conway, perl6-l...@perl.org
Dan Sugalski <d...@sidhe.org> writes:

> At 8:46 AM +0000 1/28/03, Piers Cawley wrote:
>>Bugger. I was hoping that Perl 6 was going to make a Pixie like Object
>>database easier to write; looks like I'm wrong. One of the things
>>Pixie does is to attach its control data by magic to the object itself
>>(rather than any particular variable pointing to it). This lets us do
>>all sorts of useful stuff without invading the object since we know
>>that it will carry our metadata around it. Please, consider making
>><but> properties attach to the target of a pointer rather than to the
>>pointer itself. And if you don't want to do that, I'd say that there
>>is a need to be able to specify some new kind of property that does
>>attach to the target.
>
> Given the current implementation (And I hear rumors that you lurk on
> the internals list, Piers... :)

Nah, that's someone else with the same name and writing style.

> I think we can manage something like this. Might require a drop to
> assembly somewhere, perhaps hidden behind a function rather than
> with syntax, but it should be doable...

<Breaths sigh of relief>

--
Piers

Piers Cawley

unread,
Jan 28, 2003, 1:10:02 PM1/28/03
to Damian Conway, perl6-l...@perl.org
Damian Conway <dam...@conway.org> writes:

> Piers Cawley wrote:
>
>> Bugger. I was hoping that Perl 6 was going to make a Pixie like Object
>> database easier to write; looks like I'm wrong. One of the things
>> Pixie does is to attach its control data by magic to the object itself
>> (rather than any particular variable pointing to it). This lets us do
>> all sorts of useful stuff without invading the object since we know
>> that it will carry our metadata around it. Please, consider making
>> <but> properties attach to the target of a pointer rather than to the
>> pointer itself.
>
> Err....no. That's rather the whole point of C<but> properties [*].
>
> However, if your class returns a reference to an object and that reference
> has the appropriate value properties ascribed to it (i.e. stuck on the
> *reference*), then any access through that reference (or through any
> subsequent copy of it) will see those properties.
>
> So your magic Pixie would look something like"
>
> class Pixie {
>
> method new($class: %args) {
> return $class.SUPER::new(%args)
> but Magic('whatever');
> }
>
> # etc.
> }
>

> [*] People, we just *have* to find better names for these things!
> I'd suggest we henceforth call them "value" properties (for C<but>)
> and "referent" properties (for C<is>).

Hmm... Here's Pixie's interface:

my $pixie = Pixie.new.connect('dbi:foo:bar', $user, $pass);

...

my $cookie = $pixie.insert($some_arbitrary_object);

# Time passes, we forget everything but the value of $cookie

my $pixie = Pixie.new.connect('dbi:foo:bar', $user, $pass);
my $locked_object =
$pixie.get_with_locking_strategy( $cookie,
Strategy::ExclusiveLock.new );

When $locked_object is collected, Pixie unlocks it in the
database. If, while $locked_object is in scope something else tries to
fetch an object with the same cookie (from within the same thread)
then Pixie hands 'em a reference to the same object. Right now Pixie
keeps a handle on everything by attaching 'ObjectInfo' objects to
every object that comes under its control so it can keep track of
what's going on (it's a two way link, the object has a normal ref
(via magic) to the objectinfo, which has a weakref back to the object
itself, so when the object goes out of scope, the objectinfo goes out
of scope too, triggering unlocking and other such stuff).

So, if Pixie::get_with_locking_strategy looks something like:

method get_with_locking_strategy( $self: $oid,
Strategy $lock_strategy ) {
return $self.cache_get($oid);

CATCH Exception::NotInCache {
my $flattened_object =
$self.store.get_with_locking_strategy($oid, $lock_strategy);
my $obj_info = ObjectInfo.new.set_pixie($self)
.set_oid($oid)
.set_lock_strategy($lock_strategy);
my $real_obj =
Storable::retrieve($flattened_object) but PixieInfo($obj_info);
$obj_info.set_real_object($real_obj);
$self.cache_insert($obj_info);
return $real_obj;
}
}

method cache_get( $oid ) {
my $info = %.cache{$oid} // die Exception::NotInCache.new;
return $info.real_object;
}

Will every copy of the value of $real_obj have the PixieInfo property?
Am I going mad, or is order really that important? My initial idea was
to do the C<set_real_object> and C<cache_insert> and then just do
C<return $real_obj but PixieInfo($obj_info)>, but then, if I
understand you correctly, the Info object's back reference to the real
object wouldn't have a PixieInfo property, which would in turn mean
that cache_get's return value wouldn't have the property and Bad
Things would happen. It seems counterintuitive that the order of
operations in this case should be so important.

Or am I missing something?

--
Piers

Michael Lazzaro

unread,
Jan 28, 2003, 1:13:34 PM1/28/03
to perl6-l...@perl.org
OK, here are the answers so far -- or more accurately, strawman
interpretations of those answers that should be objected to if they're
wrong.

1) Edge cases in array indexing:

my int @a = (1,2,3);

@a[0] # 1
@a[1] # 2
@a[2] # 3

@a[3] # undef (warning: index out-of-bounds)
@a[2**128] # EXCEPTION: index is above max allowed index
@a[ Inf ] # undef (warning: can't use Inf as array index)
@a[ undef ] # 1 (warning: undefined index)
@a['foo'] # 1 (warning: non-numeric index)
@a[ NaN ] # EXCEPTION: can't use NaN as array index

@a[-1] # 3
@a[-2] # 2
@a[-3] # 1

@a[-4] # undef (warning: index out-of-bounds)
@a[-Inf] # undef (warning: can't use Inf as array index)


2) There is a platform-dependent maximum array size, ((2**32)-1 for
32-bit platforms.) Attempting to access an index outside that range
throws an exception. Note that this applies to both 'real' and
'sparse' arrays.

If these are incorrect statements, please correct me.

---

The other two questions are less definitively answered, so far. I
shall attempt to disambiguate them...

MikeL

Dan Sugalski

unread,
Jan 28, 2003, 1:20:22 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org
At 10:13 AM -0800 1/28/03, Michael Lazzaro wrote:
>OK, here are the answers so far -- or more accurately, strawman
>interpretations of those answers that should be objected to if
>they're wrong.

I think some of this is incorrect which, because Damian thinks
otherwise, will need some hashing out from Larry on how he wants perl
arrays to behave. Because...

>1) Edge cases in array indexing:
>
> my int @a = (1,2,3);
>

> @a[3] # undef (warning: index out-of-bounds)

Or a real 0, since you said @a can only return integers.

> @a[2**128] # EXCEPTION: index is above max allowed index

Except we can manage this internally, so I don't know that it's a problem

> @a[ Inf ] # undef (warning: can't use Inf as array index)

I'd throw an exception here.

> @a[-4] # undef (warning: index out-of-bounds)
> @a[-Inf] # undef (warning: can't use Inf as array index)

Or zero, since it's an int array.

>2) There is a platform-dependent maximum array size, ((2**32)-1 for
>32-bit platforms.) Attempting to access an index outside that range
>throws an exception. Note that this applies to both 'real' and
>'sparse' arrays.

But since we've got big(int|float|rat)s there's no real reason for
that to be a problem. If you want to use 10**100**100 as an array
index, you could just throw an awful lot of memory at us...

Michael Lazzaro

unread,
Jan 28, 2003, 1:44:22 PM1/28/03
to Dan Sugalski, perl6-l...@perl.org

On Tuesday, January 28, 2003, at 10:20 AM, Dan Sugalski wrote:
> At 10:13 AM -0800 1/28/03, Michael Lazzaro wrote:
>> 1) Edge cases in array indexing:
>>
>> my int @a = (1,2,3);
>>
>> @a[3] # undef (warning: index out-of-bounds)
>
> Or a real 0, since you said @a can only return integers.

Thanks -- I stand corrected, you're almost certainly right. Arrays
defined with a cell type that can't be undefined should never return
undef, regardless of index. They should instead return the "default"
for that type... int(0), num(0.0), str(''), whatever...

I also agree @a[Inf] is worthy of an exception. Without objection, so
documented.

MikeL

John Williams

unread,
Jan 28, 2003, 1:35:19 PM1/28/03
to perl6-l...@perl.org
On Tue, 28 Jan 2003, Dan Sugalski wrote:
> At 10:13 AM -0800 1/28/03, Michael Lazzaro wrote:
>
> > @a[ Inf ] # undef (warning: can't use Inf as array index)
>
> I'd throw an exception here.
>
> > @a[-4] # undef (warning: index out-of-bounds)
> > @a[-Inf] # undef (warning: can't use Inf as array index)
>
> Or zero, since it's an int array.

If you throw an exception for +Inf, you should throw it for -Inf too.

~ John Williams

Michael Lazzaro

unread,
Jan 28, 2003, 2:15:26 PM1/28/03
to perl6-l...@perl.org

There has been discussion of allowing a "default" value for array cells
-- that is, one aside from C<undef> 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

Jonathan Scott Duff

unread,
Jan 28, 2003, 2:30:54 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org
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
du...@cbi.tamucc.edu

Austin Hastings

unread,
Jan 28, 2003, 2:33:49 PM1/28/03
to Damian Conway, perl6-l...@perl.org

--- Damian Conway <dam...@conway.org> wrote:
>
> [*] People, we just *have* to find better names for these things!
> I'd suggest we henceforth call them "value" properties (for
> C<but>) and "referent" properties (for C<is>).

Hmm. According to this, C<return 0 is true;> would therefore be a
malvalapropism, no?

=Austin

Jonathan Scott Duff

unread,
Jan 28, 2003, 2:35:25 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org
On Tue, Jan 28, 2003 at 01:30:54PM -0600, Jonathan Scott Duff wrote:
> 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?

Ah, nevermind ... I just realized that you were counting backward from
the end of the array. Such behavior would be surprising at best.
Perhaps the indexing-from-the-end magic and the auto-defaulting magic
need to be mutually exclusive.

Paul Johnson

unread,
Jan 28, 2003, 2:47:08 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org

Michael Lazzaro said:

>
> There has been discussion of allowing a "default" value for array cells
> -- that is, one aside from C<undef> 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 - pa...@pjcj.net
http://www.pjcj.net

Austin Hastings

unread,
Jan 28, 2003, 3:30:41 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org

--- Michael Lazzaro <mlaz...@cognitivity.com> 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 C<is 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

Damian Conway

unread,
Jan 28, 2003, 3:46:46 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org
Michael Lazzaro wrote:
> OK, here are the answers so far -- or more accurately, strawman
> interpretations of those answers that should be objected to if they're
> wrong.
>
> 1) Edge cases in array indexing:
>
> my int @a = (1,2,3);
>
> @a[0] # 1
> @a[1] # 2
> @a[2] # 3
> @a[3] # undef (warning: index out-of-bounds)
> @a[2**128] # EXCEPTION: index is above max allowed index

I would have thought that for SparseArrays (which require index remapping
anyway), BigInt indices should be allowed.


> @a[ Inf ] # undef (warning: can't use Inf as array index)

I would have though the behaviour of out-of-range indices like @a[2**128] and
@a[Inf] ought to be consistent. Hence I'd have expected an exception here.


> @a[ undef ] # 1 (warning: undefined index)
> @a['foo'] # 1 (warning: non-numeric index)
> @a[ NaN ] # EXCEPTION: can't use NaN as array index
>
> @a[-1] # 3
> @a[-2] # 2
> @a[-3] # 1
> @a[-4] # undef (warning: index out-of-bounds)
> @a[-Inf] # undef (warning: can't use Inf as array index)

Another exception, I'd have thought.


> 2) There is a platform-dependent maximum array size, ((2**32)-1 for
> 32-bit platforms.) Attempting to access an index outside that range
> throws an exception.

Which is why I'd expect that C<Inf> as an index should be fatal.


> Note that this applies to both 'real' and 'sparse' arrays.

Given the implicit promotion of ints to BigInts everywhere else, this
seems inconsistent. At least for SparseArrays, where indices are remapped
anyway.

Damian


Austin Hastings

unread,
Jan 28, 2003, 3:50:52 PM1/28/03
to Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org

--- Austin Hastings <austin_...@yahoo.com> 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

Aaron Sherman

unread,
Jan 28, 2003, 4:07:17 PM1/28/03
to Paul Johnson, Perl6 Language List
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 C<ifexists=>, not
C<//=>

--
Aaron Sherman <a...@ajs.com>
This message (c) 2003 by Aaron Sherman,
and granted to the Public Domain in 2023.
Fight the DMCA and copyright extension!


Damian Conway

unread,
Jan 28, 2003, 4:14:09 PM1/28/03
to Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org

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 C<is default> as specifying a mapping from an implicit or explicit
C<undef> to something else.

I'm not compelled by the counter-argument that this makes it impossible to
store an C<undef> in an array with a default. Because the whole point of an
array having a default is to prevent those nasty out-of-range C<undef>s 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 C<is 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

Nicholas Clark

unread,
Jan 28, 2003, 3:49:04 PM1/28/03
to Damian Conway, perl6-l...@perl.org
On Tue, Jan 28, 2003 at 09:17:36AM -0800, Damian Conway wrote:
> Err....no. That's rather the whole point of C<but> properties [*].

> [*] People, we just *have* to find better names for these things!


> I'd suggest we henceforth call them "value" properties (for C<but>)
> and "referent" properties (for C<is>).

Over on perl6-i...@perl.org there seemed to be confusion about attributes
and properties, given that some languages use one where we use the other.
I had a dig in a thesaurus, I suggested that "chattels" and "virtues"
were interesting words that unambiguously describe respectively extra data
you've attached to a thing, and an extra qualities you've given it.
But that's still only one (controversial) word for properties, and we need two.
And I don't really like "chattels", whereas"virtues" sits nicely with "bless".

I got one private reply, and summarised. But nothing further. Warnock's
Dilemma?

(Message ID 2003011520...@Bagpuss.unfortu.net if that helps - I don't
have an archive link).

Nicholas Clark

Nicholas Clark

unread,
Jan 28, 2003, 4:07:12 PM1/28/03
to Austin Hastings, Michael Lazzaro, perl6-l...@perl.org
On Mon, Jan 27, 2003 at 01:02:28PM -0800, Austin Hastings wrote:
>
> --- Nicholas Clark <ni...@unfortu.net> wrote:
> > On Mon, Jan 27, 2003 at 11:00:17AM -0800, Michael Lazzaro wrote:

> > > locked => 1, # read-only, can't store new values
> >
> > There was a discussion on p5p about "restricted hashes", and what one
> > might
> > want. Even for arrays I can think of at least 2 levels.

Er, I think I meant "I can think of 2 levels, and there may be more"

> > 1: everything locked - no new elements, existing elements treated as
> > read only
> > 2: size locked - you can't extend (or shrink) the array, but you can
> > add/remove elements
> >
>
> How bizarre. When you said you could think of two levels, I immediately
> thought of two levels, but mine and yours aren't the same. I thought of
> "totally read-only" and "content-locked" -- expanding/contracting is
> okay, but no updates. (Think of implementing a stack, say.)
>
> Maybe this is my C background coming out. The difference between

Hmm. I have a C background too.

> Anyway, I guess "locked" means different things to different folks.
> Probably this shouldn't be core -- it should be easy enough to code up
> a standard set of permutations.

Yes, although it may be useful to have the functionality in core.
Then again, perl5 has to do restricted hashes in core to have any hope of
doing it with usable speed, whereas parrot is designed to allow perl5
slow perl5 goodies such as tieing and overloading to have no additional
calling overhead.

> (OTOH, it's not unreasonable to talk about a standard set of methods
> for this stuff, so that all those post-facto implementations speak the
> same language.

Yes, although I suspect that the details of the concepts, let alone the
names, can be deferred until later on. Having subroutines and objects
would be nicer.

Nicholas Clark

Nicholas Clark

unread,
Jan 28, 2003, 4:01:06 PM1/28/03
to Austin Hastings, Michael Lazzaro, perl6-l...@perl.org
On Tue, Jan 28, 2003 at 12:30:41PM -0800, Austin Hastings wrote:
>
> --- Michael Lazzaro <mlaz...@cognitivity.com> 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

Leopold Toetsch

unread,
Jan 28, 2003, 4:23:50 PM1/28/03
to Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org
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

Aaron Sherman

unread,
Jan 28, 2003, 4:32:26 PM1/28/03
to Leopold Toetsch, Perl6 Language List
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?

Michael Lazzaro

unread,
Jan 28, 2003, 4:42:24 PM1/28/03
to Damian Conway, Austin_...@yahoo.com, perl6-l...@perl.org

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 C<undef> in an array with a default. Because
> the whole point of an array having a default is to prevent those nasty
> out-of-range C<undef>s 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 C<is computed>), so as to
> distinguish:

The next (oft-asked) question is whether or not C<is computed> denotes
read-only, or if you can store to an C<is 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

Michael Lazzaro

unread,
Jan 28, 2003, 5:13:22 PM1/28/03
to perl6-l...@perl.org

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 <mlaz...@cognitivity.com> 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 C<my int @a>):

@a[ undef ]

C<undef> should be autoconverted to 0 with warning, but in:

@a[0] = undef;

C<undef> should _not_ be autoconverted to 0, but instead trigger an
exception.

They're both in C<int> context, unless we want to make a special "int
being used as an array index" context that's different from normal
C<int> context. Seems like C<undef> should be treated like 0 (plus
warning) in numeric context either everywhere, or nowhere. (?)

MikeL

Smylers

unread,
Jan 28, 2003, 5:24:01 PM1/28/03
to perl6-l...@perl.org
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

Austin Hastings

unread,
Jan 28, 2003, 5:26:39 PM1/28/03
to Damian Conway, Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org

--- Damian Conway <dam...@conway.org> wrote:
> Austin Hastings wrote:
> > --- Austin Hastings <austin_...@yahoo.com> 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 C<is default> as specifying a mapping from an implicit or
> explicit
> C<undef> 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 C<undef> in an array with a default.
> Because the whole point of an array having a default is to
> prevent those nasty out-of-range C<undef>s 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 C<is computed>), so as to distinguish:

[[ code elided ]]

Yeah, that too. I like "is computed".

=Austin

Smylers

unread,
Jan 28, 2003, 5:28:42 PM1/28/03
to perl6-l...@perl.org
Austin Hastings wrote:

What's wrong with C<delete> 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 C<delete> and C<undef> rather than
C<undef @a[1]> and C<@a[1] = undef>.

Smylers

Austin Hastings

unread,
Jan 28, 2003, 5:30:33 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org

I agree. "Warning: Using undef as array index" would be a nice message
- probably save a bunch of debugging.

=Austin


Nicholas Clark

unread,
Jan 28, 2003, 5:37:52 PM1/28/03
to Michael Lazzaro, perl6-l...@perl.org
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 C<my int @a>):
>
> @a[ undef ]
>
> C<undef> should be autoconverted to 0 with warning, but in:
>
> @a[0] = undef;
>
> C<undef> should _not_ be autoconverted to 0, but instead trigger an
> exception.
>
> They're both in C<int> context, unless we want to make a special "int
> being used as an array index" context that's different from normal
> C<int> context. Seems like C<undef> 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

Damian Conway

unread,
Jan 28, 2003, 6:06:19 PM1/28/03
to perl6-l...@perl.org
Austin Hastings wrote:

> --- Damian Conway <dam...@conway.org> 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 C<undef>), 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 C<undef> is how we signify
the absence of a value.

Damian

Paul Johnson

unread,
Jan 28, 2003, 7:24:45 PM1/28/03
to Aaron Sherman, Perl6 Language List
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

unread,
Jan 28, 2003, 7:49:43 PM1/28/03
to Damian Conway, perl6-l...@perl.org
On Tue, Jan 28, 2003 at 03:06:19PM -0800, Damian Conway wrote:
> Austin Hastings wrote:
>
> >--- Damian Conway <dam...@conway.org> 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 C<undef>), 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.

Damian Conway

unread,
Jan 28, 2003, 7:51:29 PM1/28/03
to perl6-l...@perl.org
Michael Lazzaro wrote:

> The next (oft-asked) question is whether or not C<is computed> denotes
> read-only, or if you can store to an C<is computed> array.
>
> my @a is computed { $^index**2 };
>
> @a[4] = 'something completely different';

I'd expect that C<is computed> and C<is 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 C<pop> is always -1.

;-)

Damian


Dave Whipp

unread,
Jan 28, 2003, 10:58:23 PM1/28/03
to perl6-l...@perl.org, Michael Lazzaro, perl6-l...@perl.org
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 C<undef> is a valid value for a cell, then I should be able to store
it. I think that C<delete> 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 C<default> 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

Dave Whipp

unread,
Jan 28, 2003, 11:13:58 PM1/28/03
to perl6-l...@perl.org
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

Attriel

unread,
Jan 28, 2003, 11:42:50 PM1/28/03
to perl6-l...@perl.org
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 ... )


Joseph F. Ryan

unread,
Jan 29, 2003, 2:03:14 AM1/29/03
to att...@d20boards.net, perl6-l...@perl.org
attriel wrote:

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
ryan...@osu.edu

Aaron Sherman

unread,
Jan 29, 2003, 9:44:27 AM1/29/03
to Paul Johnson, Perl6 Language List
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.

Mark J. Reed

unread,
Jan 29, 2003, 10:32:58 AM1/29/03
to Aaron Sherman, Paul Johnson, Perl6 Language List
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 | mark...@cnn.com
Atlanta, GA 30348 USA | +1 404 827 4754

Mark J. Reed

unread,
Jan 29, 2003, 10:34:43 AM1/29/03
to Aaron Sherman, Paul Johnson, Perl6 Language List
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.

Austin Hastings

unread,
Jan 29, 2003, 10:42:58 AM1/29/03
to du...@pobox.com, perl6-l...@perl.org

--- Jonathan Scott Duff <du...@cbi.tamucc.edu> 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

Austin Hastings

unread,
Jan 29, 2003, 10:46:43 AM1/29/03
to Nicholas Clark, Damian Conway, perl6-l...@perl.org

--- Nicholas Clark <ni...@unfortu.net> wrote:
> On Tue, Jan 28, 2003 at 09:17:36AM -0800, Damian Conway wrote:
> > Err....no. That's rather the whole point of C<but> properties [*].
>
> > [*] People, we just *have* to find better names for these things!
> > I'd suggest we henceforth call them "value" properties (for
> C<but>)
> > and "referent" properties (for C<is>).
>
> Over on perl6-i...@perl.org there seemed to be confusion about
> attributes
> and properties, given that some languages use one where we use the
> other.
> I had a dig in a thesaurus, I suggested that "chattels" and "virtues"
> were interesting words that unambiguously describe respectively extra
> data
> you've attached to a thing, and an extra qualities you've given it.
> But that's still only one (controversial) word for properties, and we
> need two.
> And I don't really like "chattels", whereas"virtues" sits nicely with
> "bless".
>

Obviously, values are pure and therefrom spring "virtues," while
objects are but vile clay -- fallible constructs of a sinful man,
pathetically trying to recreate an envisioned ideal. Ergo, they have
naught but "vices."

Can I get an "Amen," brothers and sisters?

=Austin


Nicholas Clark

unread,
Jan 29, 2003, 10:52:22 AM1/29/03
to Austin Hastings, Nicholas Clark, Damian Conway, perl6-l...@perl.org
On Wed, Jan 29, 2003 at 07:46:43AM -0800, Austin Hastings wrote:
> Obviously, values are pure and therefrom spring "virtues," while
> objects are but vile clay -- fallible constructs of a sinful man,
> pathetically trying to recreate an envisioned ideal. Ergo, they have
> naught but "vices."
>
> Can I get an "Amen," brothers and sisters?

I'm not sure. I thought about vices, but I can remember that Larry doesn't
like the idea of a "curse" function to un-bless things, so I suspect
that "vices" aren't going to see much favour. "flaws", maybe. There's
always scope for redeeming your flaws. :-)

Nicholas Clark

Austin Hastings

unread,
Jan 29, 2003, 12:15:04 PM1/29/03
to Nicholas Clark, Nicholas Clark, Damian Conway, perl6-l...@perl.org

Of course not. The opposite of bless in this case would be
"excommunicate."

Can we replace croak and carp with "damn" and "darn"?

Can I say:

CATCH {
when mortal { ... }
when venal { ... }
}

I think that having "begone" and "exorcise" as keywords would probably
rock. Plus, we could write "Perl Catechism"(*). How cool would that be?

(I'm going to "heck" for this, I'm sure. :-) :-) :-)

=Austin


(*) That title is MINE.

Aaron Sherman

unread,
Jan 29, 2003, 12:40:21 PM1/29/03
to Mark J. Reed, Perl6 Language List
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 would expect that:

(@a=%b)[0].key eq (shift %b).key

wouldn't you? That is assuming that C<@a=%b> assigns into C<@a> a list
of pairs, not the expanded form that Perl5 assigns, but my point holds
either way, just not the example.

> 3. shift. ditto.

No problem here. In fact, it's almost always a cheap operation too.
Sometimes (e.g. for some types of external data) it will be expensive,
but see above.

> 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.

Only if you want them to be.

Andrew Wilson

unread,
Jan 29, 2003, 12:40:47 PM1/29/03
to perl6-l...@perl.org

What about appendage or adjunct then:

Appendage \Ap*pend"age\, n.
1. Something appended to, or accompanying, a principal or
greater thing, though not necessary to it, as a portico to
a house.
[1913 Webster]

Adjunct \Ad"junct`\, n.
1. Something joined or added to another thing, but not
essentially a part of it.
[1913 Webster]


andrew
--
Aries: (March 21 - April 19)
You will come very close to acting heroically when you push an old lady
out of the way of a hurtling bus and underneath a cement truck.

Michael Lazzaro

unread,
Jan 29, 2003, 1:23:26 PM1/29/03
to perl6-l...@perl.org

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 C<undef>. 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 C<is 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

Attriel

unread,
Jan 29, 2003, 1:38:54 PM1/29/03
to perl6-l...@perl.org
> 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


Austin Hastings

unread,
Jan 29, 2003, 1:59:46 PM1/29/03
to Michael Lazzaro, perl6-l...@perl.org

--- Michael Lazzaro <mlaz...@cognitivity.com> 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 C<undef>. 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 C<is 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 be valid to want to just
store 0's in the uninit sections until they get accessed, so the p6int
guys MAY want to do fake/real undef. But that's not the charter of
this list.

=Austin


Jonathan Scott Duff

unread,
Jan 29, 2003, 2:02:21 PM1/29/03
to Michael Lazzaro, perl6-l...@perl.org
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 C<undef>. 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 C<is 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
du...@cbi.tamucc.edu

Michael Lazzaro

unread,
Jan 29, 2003, 2:32:53 PM1/29/03
to du...@pobox.com, perl6-l...@perl.org

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 C<int> 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 C<is 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

Aaron Sherman

unread,
Jan 29, 2003, 2:29:52 PM1/29/03
to Michael Lazzaro, Perl6 Language List
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....

Juergen Boemmels

unread,
Jan 29, 2003, 2:49:42 PM1/29/03
to perl6-l...@perl.org
Michael Lazzaro <mlaz...@cognitivity.com> 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 boem...@physik.uni-kl.de
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

Austin Hastings

unread,
Jan 29, 2003, 2:53:48 PM1/29/03
to Michael Lazzaro, du...@pobox.com, perl6-l...@perl.org

--- Michael Lazzaro <mlaz...@cognitivity.com> 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 C<int> 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 C<is 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

Jonathan Scott Duff

unread,
Jan 29, 2003, 2:54:51 PM1/29/03
to Juergen Boemmels, perl6-l...@perl.org
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?

Jonathan Scott Duff

unread,
Jan 29, 2003, 2:59:37 PM1/29/03
to Michael Lazzaro, du...@pobox.com, perl6-l...@perl.org
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 C<int> 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 C<is 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 :)

Juergen Boemmels

unread,
Jan 29, 2003, 3:07:37 PM1/29/03
to du...@pobox.com, perl6-l...@perl.org

Ok, here is one

my float @weight_factor is default (1.0);

$weighted_sum = sum (@weight_factor »*« @a);

$weight_factor[4711] = 0.0;

Mark Biggar

unread,
Jan 29, 2003, 3:00:33 PM1/29/03
to perl6-l...@perl.org
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
mark.a...@attbi.com

Jonathan Scott Duff

unread,
Jan 29, 2003, 3:13:34 PM1/29/03
to Mark Biggar, perl6-l...@perl.org
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

Jonathan Scott Duff

unread,
Jan 29, 2003, 3:12:41 PM1/29/03
to Juergen Boemmels, du...@pobox.com, perl6-l...@perl.org
On Wed, Jan 29, 2003 at 09:07:37PM +0100, Juergen Boemmels wrote:
> Jonathan Scott Duff <du...@cbi.tamucc.edu> 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.

Austin Hastings

unread,
Jan 29, 2003, 3:20:00 PM1/29/03
to du...@pobox.com, Juergen Boemmels, perl6-l...@perl.org

--- Jonathan Scott Duff <du...@cbi.tamucc.edu> wrote:

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

Aaron Sherman

unread,
Jan 29, 2003, 3:29:57 PM1/29/03
to du...@pobox.com, Perl6 Language List
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.

Jonathan Scott Duff

unread,
Jan 29, 2003, 3:37:04 PM1/29/03
to Aaron Sherman, du...@pobox.com, Perl6 Language List
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?

Smylers

unread,
Jan 29, 2003, 3:38:22 PM1/29/03
to perl6-l...@perl.org
> Agreed, it's not pretty. The fundamental problem is that a primitive
> like an C<int> simply cannot be undefined... there's no flag for that
> (which is they're primitive.)

Certainly there's no way of _storing_ C<undef>.

> 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 C<undef> that a _valid_ default is required.

> A simple solution is perhaps to say that C<is 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 C<undef> can't be stored in an int, why does it mean
that _trying_ to store an C<undef> 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
C<undef> 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 C<undef>, 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
C<undef> should put the default value there.

That would make the rule very simple indeed:

Assigning C<undef> 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 C<undef> will, by default,
actually store C<undef>. If the array has a different default
defined then that will be stored instead.

* In an array of int, attempting to store C<undef> will, by default,
store zero. If the array has a different default defined then that
will be stored instead.

Smylers

Aaron Sherman

unread,
Jan 29, 2003, 3:44:24 PM1/29/03
to Austin Hastings, Perl6 Language List
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.

Dan Sugalski

unread,
Jan 29, 2003, 3:48:18 PM1/29/03
to Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org
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
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Jonathan Scott Duff

unread,
Jan 29, 2003, 3:55:05 PM1/29/03
to Dan Sugalski, Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org
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 :-)

Nicholas Clark

unread,
Jan 29, 2003, 4:41:03 PM1/29/03
to Aaron Sherman, Mark J. Reed, Perl6 Language List
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

Michael Lazzaro

unread,
Jan 29, 2003, 4:54:10 PM1/29/03
to Smylers, perl6-l...@perl.org

On Wednesday, January 29, 2003, at 12:38 PM, Smylers wrote:
> That would make the rule very simple indeed:
>
> Assigning C<undef> 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 C<undef> will, by default,
> actually store C<undef>. If the array has a different default
> defined then that will be stored instead.
>
> * In an array of int, attempting to store C<undef> 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 C<undef> 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

Dan Sugalski

unread,
Jan 29, 2003, 5:12:11 PM1/29/03
to Aaron Sherman, Mark J. Reed, Perl6 Language List
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.

Austin Hastings

unread,
Jan 29, 2003, 5:18:09 PM1/29/03
to Dan Sugalski, Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org

--- Dan Sugalski <d...@sidhe.org> 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 M&M, and whatever
miniscule guilt I feel goes away... :-) :-) :-)

But yeah, "spec" != "code".

=Austin

Paul Johnson

unread,
Jan 29, 2003, 5:34:39 PM1/29/03
to Mark Biggar, perl6-l...@perl.org
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 C<undef @a[2]>. This
is undesirable, but could be solved by using C<delete @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 C<exists> and they may be
deleted with C<delete>. 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 - pa...@pjcj.net
http://www.pjcj.net

Stéphane Payrard

unread,
Jan 29, 2003, 7:06:27 PM1/29/03
to Perl6 Language List
On Wed, Jan 29, 2003 at 09:44:27AM -0500, 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. 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.

I think that arrays and associative tables are very different entities
for two reasons:
-type of keys. array keys are integers
-cost of insertion and deletion operations: O(n) and
lower for associative table ( O(1) if you don't care for key ordering,
O(log(n)) if you care for ordering).

This is enough to warrant different syntaxes for arrays and hash.
This is one of the main things that attracted me to Perl, variable names ($a,
@a, %a) were a clear indication of behavior.

Perl6 should also support associative tables with ordered keys.
The default type of associative tables should be hashes.

# hash based associative table metonymically called hash
my %assoctbl1;

# tree based associative tables.
properties should specify the tree algo used and possibly the ordering function.

my %assoctbl2 is redblack;
my %assoctbl3 is ordered( &sortfun);

>
> 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.
>

--
stef

Joseph F. Ryan

unread,
Jan 29, 2003, 7:17:43 PM1/29/03
to st...@payrard.net, Perl6 Language List
Stéphane Payrard wrote:

>On Wed, Jan 29, 2003 at 09:44:27AM -0500, 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. 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.
>>
>>
>
>I think that arrays and associative tables are very different entities
>for two reasons:
> -type of keys. array keys are integers
> -cost of insertion and deletion operations: O(n) and
> lower for associative table ( O(1) if you don't care for key ordering,
> O(log(n)) if you care for ordering).
>
>This is enough to warrant different syntaxes for arrays and hash.
>

I'm sure I'll get shot for saying this, but no it doesn't. PHP arrays
are simply associative arrays with a integer as the key value.

Of course, this doesn't mean I like the idea, but I just wanted to
point out that there are some languages that do it this way. However,
I hope that we are not going to be one of those.


Joseph F. Ryan
ryan...@osu.edu

Dan Sugalski

unread,
Jan 29, 2003, 8:01:12 PM1/29/03
to Austin_...@yahoo.com, Michael Lazzaro, perl6-l...@perl.org
At 2:18 PM -0800 1/29/03, Austin Hastings wrote:
>--- Dan Sugalski <d...@sidhe.org> 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. :)

Luke Palmer

unread,
Jan 29, 2003, 8:43:31 PM1/29/03
to dam...@conway.org, perl6-l...@perl.org
> Date: Mon, 27 Jan 2003 13:24:23 -0800
> From: Damian Conway <dam...@conway.org>
>
> Dave Whipp suggested:
>
> > The size constraints are probably C<but> properties, as is C<locked>. The
> > exception behavior probably deserves to remain an C<is> property.
>
> Nope. They're all C<is> properties. C<but> properties only apply to *values*.
> Variable such as Arrays always take C<is> properties.

I'm getting flashbacks of the whole ser/estar discrepancy from my
spanish years.

So, as a clarification, can (almost) any property act as both a
referent and a value property? That is, in:

my @foo is bar;
my $baz = [] but bar;

@foo and @$foo are equivalent in all but a few cases? So that C<but>
is just a designator of where to put the property, not where the
property is seen.

Um, I think I could have been clearer in that question, but people get
my gist, I hope.

Luke

Rick Delaney

unread,
Jan 29, 2003, 9:16:46 PM1/29/03
to Aaron Sherman, du...@pobox.com, Perl6 Language List

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
rick.d...@rogers.com

Rick Delaney

unread,
Jan 29, 2003, 9:52:07 PM1/29/03
to Michael Lazzaro, Smylers, perl6-l...@perl.org
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 C<undef> 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 C<undef> will, by default,
> > actually store C<undef>. 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 C<undef> 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 C<undef> 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
rick.d...@rogers.com

Dave Whipp

unread,
Jan 29, 2003, 10:26:29 PM1/29/03
to perl6-l...@perl.org
"Jonathan Scott Duff" <du...@cbi.tamucc.edu> wrote in message
news:2003012913...@cbi.tamucc.edu...

> 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 C<int> 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 C<is 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


It is loading more messages.
0 new messages