petdance/scratch — Issue #1107: [BUG] hash iterator interface changed, needs errata or deprecation notice
Author: petdance
Created: 2011-11-01 05:39:13+00:00
State: open
Labels: bug, core, Pri-normal, Sev-release

The following code worked in Parrot 1.0.0 (r37535) and Parrot 1.3.0 (r39599):
{{{
$ cat hash-1.pir
.sub 'main'
.local pmc hash, hash_it
hash = new ['Hash']
hash['1'] = 'a'
hash['2'] = 'b'
hash['3'] = 'c'

hash_it = iter hash
loop:
unless hash_it goto done
$P0 = shift hash_it
$P1 = concat $P0, 'x'
say $P1
goto loop
done:
.end

$ 37535/parrot hash-1.pir
1x
2x
3x
$ 39599/parrot hash-1.pir
1x
2x
3x
}}}

The same code fails in 1.4.0 (r40185) and current trunk:

{{{
$ 40185/parrot hash-1.pir
Multiple Dispatch: No suitable candidate found for 'concatenate_str', with signature 'PSP->P'
current instr.: 'main' pc 24 (hash-1.pir:12)
$ trunk/parrot hash-1.pir
Multiple Dispatch: No suitable candidate found for 'concatenate_str', with signature 'PSP->P'
current instr.: 'main' pc 24 (hash-1.pir:13)
$
}}}

The problem is not limited to the concat opcode -- other opcodes cause problems also:

{{{
$ cat hash-2.pir
.sub 'main'
.local pmc hash, hash_it
hash = new ['Hash']
hash['1'] = 'a'
hash['2'] = 'b'
hash['3'] = 'c'

hash_it = iter hash
loop:
unless hash_it goto done
$P0 = shift hash_it
$P1 = add $P0, 100
say $P1
goto loop
done:
.end

$ 37535/parrot hash-2.pir
101
102
103
$ 39599/parrot hash-2.pir
101
102
103
$ 40185/parrot hash-2.pir
Multiple Dispatch: No suitable candidate found for 'add_int', with signature 'PIP->P'
current instr.: 'main' pc 24 (hash-2.pir:12)
$ trunk/parrot hash-2.pir
Multiple Dispatch: No suitable candidate found for 'add_int', with signature 'PIP->P'
current instr.: 'main' pc 24 (hash-2.pir:13)
$
}}}

The underlying problem appears to be that starting with the 1.4.0 release, hash iterators began returning HashIteratorKey PMCs instead of String PMCs:

{{{
$ cat hash-3.pir
.sub 'main'
.local pmc hash, hash_it
hash = new ['Hash']
hash['1'] = 'a'
hash['2'] = 'b'
hash['3'] = 'c'

hash_it = iter hash
loop:
unless hash_it goto done
$P0 = shift hash_it
$P1 = typeof $P0
say $P1
goto loop
done:
.end

$ 37535/parrot hash-3.pir
String
String
String
$ 39599/parrot hash-3.pir
String
String
String
$ 40185/parrot hash-3.pir
HashIteratorKey
HashIteratorKey
HashIteratorKey
$ trunk/parrot hash-3.pir
HashIteratorKey
HashIteratorKey
HashIteratorKey
$
}}}

It seems to me that a change of this sort should have been preceded by a deprecation notice -- as far as I can tell no such notice was given. Regardless, returning a HashIteratorKey PMC would seem to be the least usable or useful of any of the options available.

Pm

Originally http://trac.parrot.org/parrot/ticket/1253