--- Michael Lazzaro <[EMAIL PROTECTED]> wrote:
> 
> OK, I think we agree that 'default' refers to what to put in the 
> 'holes' of an array (or hash, but that's a separate discussion.) 
> When 
> you overlay a real hash on top of your default values, the default 
> values "show through the holes".  So now we just have to define what 
> "holes" are.
> 
> An assertion:  The 'is default' property overrides the default
> 'empty' 
> value of the given underlying type.  For a normal array of scalars, 
> that 'empty' value is 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


Reply via email to