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>
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
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
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>
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>
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
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
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
eh, whatever. the point is, this does look like a useful op, whatever its name.
~jerry
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.
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"
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>
... 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
This ticket could be closed, but replying to rt would reopen it - please check
subjects and recipients in this thread.
Thanks,
leo
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>
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