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

[perl #40178] None Must Die

5 views
Skip to first unread message

Chip Salzenberg

unread,
Aug 17, 2006, 2:24:56 AM8/17/06
to bugs-bi...@rt.perl.org
# New Ticket Created by Chip Salzenberg
# Please include the string: [perl #40178]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=40178 >


The None class serves no useful (portable) purpose and it should be removed,
especially from the public interface of Hash.
--
Chip Salzenberg <ch...@pobox.com>

Chip Salzenberg

unread,
Aug 17, 2006, 2:29:00 AM8/17/06
to bugs-bi...@rt.perl.org
# New Ticket Created by Chip Salzenberg
# Please include the string: [perl #40179]

# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=40179 >

Leopold Toetsch

unread,
Aug 17, 2006, 3:12:07 PM8/17/06
to perl6-i...@perl.org, Chip Salzenberg, bugs-bi...@rt.perl.org
Am Donnerstag, 17. August 2006 08:24 schrieb Chip Salzenberg:
>
> The None class serves no useful (portable) purpose and it should be
> removed, especially from the public interface of Hash.

I've started fixing that. I'll do that in small steps, as there are some build
and test errors. The main problem is related to code like:

$P0 = hsh['no_such_key']
# check type of $P0 against 'None'

or

$P0 = hsh['no_such_key']
if $P0 ...

The current only safe replacement is:

$I0 = exist hsh['no_such_key']
...

This can *later* be optimized to:

$P0 = hsh['no_such_key']
ifnull $P0 / unless $P0 ...

A releated change:

$S0 = hsh['no_such_key']

used to return an empty STRING*, it'll soon return a NULL STRING*.

Folks, please check your usage of testing for existing hash keys.

NB: retrieving native {I,N} of non-existing keys is no problem, it will still
return 0, 0.0.

leo

Patrick R. Michaud

unread,
Aug 17, 2006, 3:30:30 PM8/17/06
to Leopold Toetsch, perl6-i...@perl.org, Chip Salzenberg, bugs-bi...@rt.perl.org
On Thu, Aug 17, 2006 at 09:12:07PM +0200, Leopold Toetsch wrote:
> A releated change:
>
> $S0 = hsh['no_such_key']
>
> used to return an empty STRING*, it'll soon return a NULL STRING*.

Just a note (to copy from irc #parrot) -- this will cause a number
of things in PGE and perl6 to break, as I rely on the "return empty string"
behavior. In particular, changing it to return NULL will mean
in many places that I will have to replace single-line key lookups

$S0 = hsh['key']

with

$S0 = hsh['key']
unless null $S0 goto label
$S0 = ''
label:


I don't mind if

$P0 = hsh['no_such_key'] (get_pmc_keyed)

returns NULL, but it would be nice if

$S0 = hsh['no_such_key'] (get_string_keyed)

could continue to return a string (''), the same way that

$I0 = hsh['no_such_key'] (get_int_keyed)
$N0 = hsh['no_such_key'] (get_number_keyed)

still return ints (0) and nums (0.0).

In the meantime, I'm checking the PGE code to see how many
lookups will actually be affected. If it's a small number,
I'll withdraw my objection.

Pm

Chip Salzenberg

unread,
Aug 17, 2006, 3:50:40 PM8/17/06
to Leopold Toetsch via RT
On Thu, Aug 17, 2006 at 12:13:30PM -0700, Leopold Toetsch via RT wrote:
> Am Donnerstag, 17. August 2006 08:24 schrieb Chip Salzenberg:
> > The None class serves no useful (portable) purpose and it should be
> > removed, especially from the public interface of Hash.
>
> I've started fixing that.

Yay, leo++

> The current only safe replacement is:
>
> $I0 = exist hsh['no_such_key']
> ...
>
> This can *later* be optimized to:
>
> $P0 = hsh['no_such_key']
> ifnull $P0 / unless $P0 ...

So you're planning to (1) change the tests/usercode so they work with both
the old and new Hash interfaces; then (2) change Hash; then (3) re-optimize
the tests and usercode to use the isnull test?

That is the long way around, but it'll keep the users working. Works for
me. :-)

> A releated change:
> $S0 = hsh['no_such_key']
> used to return an empty STRING*, it'll soon return a NULL STRING*.

Good choice.

> Folks, please check your usage of testing for existing hash keys.

Well, we (core hackers) changing the interface out from underneath them, so
if their code breaks, we should fix it up, if we can. Code outside the svn
tree (e.g. pirate) is of course beyond our reach.
--
Chip Salzenberg <ch...@pobox.com>

Chip Salzenberg

unread,
Aug 17, 2006, 3:55:54 PM8/17/06
to Patrick R. Michaud via RT
{DESIGNER ALERT - Allison, what think?}

On Thu, Aug 17, 2006 at 12:31:11PM -0700, Patrick R. Michaud via RT wrote:
> I rely on the "return empty string" behavior. In particular, changing it
> to return NULL will mean in many places that I will have to replace
> single-line key lookups
>
> $S0 = hsh['key']
>
> with
>
> $S0 = hsh['key']
> unless null $S0 goto label
> $S0 = ''
> label:

Indeed. I think we can reduce the pain of dealing with this to the point
where you'll hardly feel it. For example, I really like Python's lookup
semantic where you can provide the default value on the call.

How about a 'default' opcode that provides a value instead of null? It
would work for strings and PMCs. Something like:

$S0 = default hsh['key'], ''

or

$P0 = new .Undef
...

$P1 = default hsh['key1'], $P0
$P1 = default hsh['key2'], $P0
...

It would work without the lookups too:

$S0 = default $S0, '' # if $S0 is null, assign it ''

what say?
--
Chip Salzenberg <ch...@pobox.com>

Jerry Gay

unread,
Aug 17, 2006, 4:11:00 PM8/17/06
to Chip Salzenberg, Patrick R. Michaud via RT
On 8/17/06, Chip Salzenberg <ch...@pobox.com> wrote:
> How about a 'default' opcode that provides a value instead of null? It
> would work for strings and PMCs. Something like:
>
> $S0 = default hsh['key'], ''
>
> or
>
> $P0 = new .Undef
> ...
>
> $P1 = default hsh['key1'], $P0
> $P1 = default hsh['key2'], $P0
> ...
>
> It would work without the lookups too:
>
> $S0 = default $S0, '' # if $S0 is null, assign it ''
>
> what say?
>

default is ugly. err is sexy.

## if $S0 is null, assign it ''
#pasm
err $S0, ''
err $S1, $S2, ''

#pir
$S0 //= ''
$S0 = err ''
$S0 = err $S1, ''

~jerry

Patrick R. Michaud

unread,
Aug 17, 2006, 4:12:55 PM8/17/06
to Chip Salzenberg, Patrick R. Michaud via RT
On Thu, Aug 17, 2006 at 12:55:54PM -0700, Chip Salzenberg wrote:
> {DESIGNER ALERT - Allison, what think?}
>
> On Thu, Aug 17, 2006 at 12:31:11PM -0700, Patrick R. Michaud via RT wrote:
> > I rely on the "return empty string" behavior. In particular, changing it
> > to return NULL will mean in many places that I will have to replace
> > single-line key lookups
> >
> > $S0 = hsh['key']
> >
> > with
> >
> > $S0 = hsh['key']
> > unless null $S0 goto label
> > $S0 = ''
> > label:
>
> Indeed. I think we can reduce the pain of dealing with this to the point
> where you'll hardly feel it. For example, I really like Python's lookup
> semantic where you can provide the default value on the call.

FWIW, I reviewed the PGE code and found only five cases where I think
the code will have to change if hsh['nokey'] returns NULL, so I have to
substantially reduce the weight of my previous objection. (I still
think it's nicer if get_string_keyed always returns a string, the same
as get_int_keyed and get_number_keyed always return an int or num, but
it's not a major pain for me if it doesn't.)

> How about a 'default' opcode that provides a value instead of null? It
> would work for strings and PMCs. Something like:
>
> $S0 = default hsh['key'], ''

I can think of a lot of cases where this would be really useful to me.

Pm

Patrick R. Michaud

unread,
Aug 17, 2006, 4:17:09 PM8/17/06
to jerry gay, Chip Salzenberg, Patrick R. Michaud via RT
On Thu, Aug 17, 2006 at 01:11:00PM -0700, jerry gay wrote:
> On 8/17/06, Chip Salzenberg <ch...@pobox.com> wrote:
> > $S0 = default hsh['key'], ''
> >[...]
> > $P0 = new .Undef

> > $P1 = default hsh['key1'], $P0
> > $P1 = default hsh['key2'], $P0
> > ...
> >
> >It would work without the lookups too:
> >
> > $S0 = default $S0, '' # if $S0 is null, assign it ''
> >
> >what say?
> >
>
> default is ugly. err is sexy.
>
> ## if $S0 is null, assign it ''
> #pasm
> err $S0, ''
> err $S1, $S2, ''
>
> #pir
> $S0 //= ''
> $S0 = err ''
> $S0 = err $S1, ''

There might be a cognitive dissonance here with "err", since
C<err> in pasm/pir is testing for null, while C<err> in
perl6 tests for definedness. While it doesn't much matter
for strings in the examples above, it might make a difference for

$S0 = err hsh['key1'], 'foo'

Pm

Jerry Gay

unread,
Aug 17, 2006, 4:26:31 PM8/17/06
to Patrick R. Michaud, Chip Salzenberg, Patrick R. Michaud via RT
On 8/17/06, Patrick R. Michaud <pmic...@pobox.com> wrote:
> There might be a cognitive dissonance here with "err", since
> C<err> in pasm/pir is testing for null, while C<err> in
> perl6 tests for definedness. While it doesn't much matter
> for strings in the examples above, it might make a difference for
>
> $S0 = err hsh['key1'], 'foo'
>
good point. at first thought, i thought this looked much like nvl()
that i use in sql, so i can set a default (usually '%') to a parameter
if a null is specified. as i was writing it, i s/nvl/err/ and added
the //= magic without thinking it through. in any case, i think
default is ugly. but assign_if_null looks too long.

eh, whatever. the point is, this does look like a useful op, whatever its name.
~jerry

Leopold Toetsch

unread,
Aug 17, 2006, 6:07:34 PM8/17/06
to perl6-i...@perl.org, Chip Salzenberg
Am Donnerstag, 17. August 2006 21:50 schrieb Chip Salzenberg:
> > Folks, please check your usage of testing for existing hash keys.
>
> Well, we (core hackers) changing the interface out from underneath them, so
> if their code breaks, we should fix it up, if we can.  Code outside the svn
> tree (e.g. pirate) is of course beyond our reach.

I've fixed all the core tests which is including libraries, e.g. Test*, but
I'm not going into languages *if* it is not a plain s/a/b/ operation [1].
I've spent already hours of figuring out PGE breakage with the already
mentioned STRING* issue and have failed - sorry.

leo

[1] that's usually generated code and it is really not trivial, to find the
location, where that's generate, at least in some $LANG compilers.

Leopold Toetsch

unread,
Aug 17, 2006, 6:17:58 PM8/17/06
to perl6-i...@perl.org, Chip Salzenberg
Am Donnerstag, 17. August 2006 21:55 schrieb Chip Salzenberg:
> >     $S0 = hsh['key']
> >
> > with
> >
> >     $S0 = hsh['key']
> >     unless null $S0 goto label
> >     $S0 = ''
> >   label:
>
> Indeed.  I think we can reduce the pain of dealing with this to the point
> where you'll hardly feel it.

A lot of src/string string_ operations are capable of dealing with NULL
strings currently [1]. *But* that's AFAIK specificied nowhere, and might just
be an accident, i.e. an extra (unneeded/unwanted) check for A NULL argument.
A consistent behavior would make all these things just errors, the same as we
got with the Null PMC, which has been created for this very reason - the same
as a SEGV in C, when accessing a NULL ptr.

leo

[1]

null S0 # this is not ''
length I0, S0 # 0
concat S1, S0, "foo" # "foo"

Chip Salzenberg

unread,
Aug 17, 2006, 6:59:40 PM8/17/06
to Leopold Toetsch, perl6-i...@perl.org
On Fri, Aug 18, 2006 at 12:17:58AM +0200, Leopold Toetsch wrote:
> A lot of src/string string_ operations are capable of dealing with NULL
> strings currently [1]. *But* that's AFAIK specificied nowhere, and might just
> be an accident, i.e. an extra (unneeded/unwanted) check for A NULL argument.
> A consistent behavior would make all these things just errors, the same as we
> got with the Null PMC, which has been created for this very reason - the same
> as a SEGV in C, when accessing a NULL ptr.

Indeed, these _should_ all be errors. However, there is often no direct way
to indicate an error when the output type has no out-of-band values, like
INTVAL. And exceptions are still too expensive. So at present I'd consider
this a misbug.
--
Chip Salzenberg <ch...@pobox.com>

Leopold Toetsch

unread,
Aug 17, 2006, 7:10:07 PM8/17/06
to perl6-i...@perl.org, Chip Salzenberg, bugs-bi...@rt.perl.org
Am Donnerstag, 17. August 2006 08:24 schrieb Chip Salzenberg:
> The None class serves no useful (portable) purpose and it should be
> removed, especially from the public interface of Hash.

... and the None class is gone.

As mentioned:

$S0 = hsh['no_such_key']

is unchanged and returns ''

and

$P0 = hsh['no_such_key']

returns the NULL PMC which can be tested for with:

PASM # PIR
if_null $P0, ... # if null $P0 goto ...

or

unless_null $P0, ... # unless null $P0 goto ...

leo

Leopold Toetsch

unread,
Aug 17, 2006, 7:15:10 PM8/17/06
to perl6-i...@perl.org
Am Donnerstag, 17. August 2006 08:24 schrieb Chip Salzenberg:
> The None class serves no useful (portable) purpose and it should be
> removed, especially from the public interface of Hash.

This ticket could be closed, but replying to rt would reopen it - please check
subjects and recipients in this thread.

Thanks,
leo

Chip Salzenberg

unread,
Aug 17, 2006, 7:22:29 PM8/17/06
to Leopold Toetsch, perl6-i...@perl.org
{ not replying to the ticket }

On Fri, Aug 18, 2006 at 01:10:07AM +0200, Leopold Toetsch wrote:
> Am Donnerstag, 17. August 2006 08:24 schrieb Chip Salzenberg:
> > The None class serves no useful (portable) purpose and it should be
> > removed, especially from the public interface of Hash.
>
> ... and the None class is gone.
>

> $P0 = hsh['no_such_key']
> returns the NULL PMC

Rockin'. Totally.

> $S0 = hsh['no_such_key']
> is unchanged and returns ''

Good. I don't know whether we'll keep this, but the strategy of how to use
null strings is a bit fuzzy to me, so it's just as well not to cause users
pain until we know we mean it.
--
Chip Salzenberg <ch...@pobox.com>

Allison Randal

unread,
Aug 17, 2006, 10:21:59 PM8/17/06
to Chip Salzenberg, Patrick R. Michaud via RT
Chip Salzenberg wrote:
>
> How about a 'default' opcode that provides a value instead of null? It
> would work for strings and PMCs. Something like:
>
> $S0 = default hsh['key'], ''
>
> or
>
> $P0 = new .Undef
> ...
>
> $P1 = default hsh['key1'], $P0
> $P1 = default hsh['key2'], $P0
> ...
>
> It would work without the lookups too:
>
> $S0 = default $S0, '' # if $S0 is null, assign it ''
>
> what say?

This is a great feature. The name is confusing, it seems more like it
should be setting a default on the object than retrieving a value with a
default. If you follow Python's example, that would be just 'get' (or
'set' in Parrot) with an extra argument, but that's even more confusing
for different reasons. It almost makes the most sense as a variant of a
test for Null:

$S0 = isnull $S1 # returns a true/false value
$S0 = isnull $S1, '' # returns the value of $S1, or '' if $S1 is null

To look at the problem from another angle, how much is the choice of
default likely to vary from one access to another, and how much is it
likely to be something that's consistent for all accesses to a
particular hash? Individual HLLs will certainly have different defaults
for what their data structures return when looking up a key that doesn't
exist.

Out of curiosity, I did a little digging: Python 2.5 has added a
__missing__ hook to set the whole data structure's default for accessing
a key that doesn't exist.

<http://docs.python.org/dev/whatsnew/other-lang.html>

Here's some discussion that surrounded that design decision:

<http://mail.python.org/pipermail/python-dev/2006-February/061261.html>


What about allowing the Hash constructor to optionally set a default
return value for the hash?

Allison

0 new messages