I've had an idea rattling around in my head for awhile now,
and thought I'd run it up the flag pole to see who salutes.
The gist of it is this, in the spirit of anything the core
can do the user can to, syntax for many functions should be
tweaked. Instead of
push @foo, 'bar'
the syntax would be
push \@foo, 'bar';
Afterall, this is what user defined code must do.
One could go the other way and allow user-defined
code to act as push etc. do now. However,
I suggest that where an array or hash is to be
modified a reference should be passed. In this manner,
any unescaped hash or array in code could be
read as an in place expansion of that variable;
removing ambiguity and making the code easier to
understand for beginners. This also has the advantage
of rendering syntax such as
push @{ $arrayref }, 'scalar';
unnecessary. This is purely hypothetical as I realize
this is a rather major change and unlikely to happen.
What do you think?
PS> On a seperate but related note, things like
keys might then be reasonably expected to except
a hash or hash reference; which IMHO would be most useful.
--
perl -wpe "s/\b;([mnst])/'$1/g"
Re: Consistency, syntax, and little minds
by Felonious (Chaplain) on Oct 02, 2002 at 19:06 UTC
|
One could go the other way and allow user-defined code to act as push etc. do now.
Prototypes can do exactly that.
From perlsub:
sub mypush (\@@)
[TINPC@perlcabal.com shh]$ su real | [reply] [d/l] |
|
| [reply] |
Re: Consistency, syntax, and little minds
by chromatic (Archbishop) on Oct 02, 2002 at 20:34 UTC
|
I suggest that where an array or hash is to be modified a reference should be passed.
my @foo = (1, 2, 3);
\@foo = (1, 2, 3); # ?
\@foo = [ 1, 2, 3 ]; # ??
Too much "consistency", I fear.
| [reply] [d/l] |
|
| [reply] |
|
Ahh, I see. You and I mean different things by the word defining. I use it as a synonym for "declaring", while you are using it as a synonym for "assigning to".
I also disagree that there's no modification of an array happening. @foo is indeed a name, and the data structure to which it refers is indeed being modified.
Regardless, you're still trying to solve the problem for which prototypes already exist. If you don't like them, that's fine, but you might as well argue that all instances of push can be replaced by:
@foo = (@foo, 'extra element');
Proposing a backwards-incompatible modification to the core of Perl to remove a parser exception intended to make everyone's life a little easier for the sake of more explicit knowing what-goes-on-under-the-covers-consistency is, in my opinion, a mistake. Doubly so since you have access to a mechanism which gives you nearly the same power.
Update: It also occurs to me that it's inconsistent to say that in-place use of an aggregate automatically expands. How would one explain that "This single name refers to a bunch of things, but it's always a bunch of things in an uncollected sense when it's referred to with the name, but when it's referred to with the name and another token, it's the collected bunch of things."
| [reply] [d/l] [select] |
Re: Consistency, syntax, and little minds
by jepri (Parson) on Oct 02, 2002 at 22:29 UTC
|
IIRC Perl6 does this. Or maybe that was some other language I was looking at recently. Certainly it's a good idea - what else could a programmer have meant if he passes a reference to an array?
It's just one of those things in Perl5 that could and should be tweaked, like the 'No comma after filehandle in print statement' error. If perl can detect the problem, why can't it do what I want? (The answer, of course, is that I haven't gotten off my arse and patched perl). ____________________
Jeremy
I didn't believe in evil until I dated it. | [reply] |
|
Well I guess I didn't want to bring it up but the lines between parentheses and square brackets are being seriously blurred in perl6. Read this longish thread for the full scoop. It's still waiting for a ruling from Larry but in general lists treated as scalars return array references and array references treated as lists dereference themselves.
http://www.perl.com/pub/a/2002/09/p6pdigest/20020929.html?page=2
__SIG__ printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B::svref_2object(sub{})->OUTSIDE
| [reply] [d/l] |
Re: Consistency, syntax, and runtime optree mangling
by diotalevi (Canon) on Oct 03, 2002 at 12:59 UTC
|
This is my first crack at hacking the opcode tree at compile time but the general idea is to dereference any array references given to push() as the first argument. This doesn't address forms like push(.., ..), push(\@a, ..) or really anything beyond retrieving the array reference from a global or lexical value. I was following the lead from the perl.com article http://www.perl.com/pub/a/2002/05/07/optree.html. Right now the code just exits and I'm sure that I'm doing things incorrectly (I just picked '0' as an arbitrary value for the new rv2av opcode) but don't have the expertise to get further. I'm sharing the code so you can at least see that in perl 5.8 you can have whatever you want as long as you're willing to get your hands dirty.
#!/usr/local/bin/perl
CHECK
{
require B::Generate;
use B::Utils qw(opgrep walkallops_filtered);
walkallops_filtered
(
sub { opgrep( { name => 'push',
first => { sibling => { name => [ 'padsv', 'g
+vsv' ] } } }, $_[0] ) },
sub { my $kid0 = $_[0]->first;
my $ref = $kid0->sibling;
my $val = $ref->sibling;
my $rv2av = B::UNOP->new( 'rv2av', 0, $ref );
$kid0->sibling( $rv2av );
$rv2av->sibling( $val );
$ref->sibling( undef );
$rv2av->first( $ref );
$kid0->next( $ref );
$ref->next( $rv2av );
$rv2av->next( $val );
}
);
}
my @a = 1;
my $a = \@a;
push @{$a}, 2;
push $a, 4; # alter this to do @$a
print join(', ',@a) . "\n";
No modifications: This is the original opcode tree that is generated with no modifications
$ /usr/local/bin/perl -MO=Concise over.pl
Type of arg 1 to push must be array (not private variable) at over.pl line 31, near "4;"
over.pl had compilation errors.
1aq <@> leave@a:128,131 KP/REFC ->(end)
19s <0> enter ->19t
19t <;> nextstate(main 128 over.pl:28) ->19u
19y <2> aassignt2 KS ->19z
- <1> ex-list lK ->19w
19u <0> pushmark s ->19v
19v <$> const(IV 1)t10 s ->19w
- <1> ex-list lK ->19y
19w <0> pushmark s ->19x
19x <0> padav@a:128,131 lRM*/LVINTRO ->19y
19z <;> nextstate(main 129 over.pl:29) ->1a0
1a4 <2> sassign sKS/2 ->1a5
1a2 <1> refgen sK/1 ->1a3
- <1> ex-list lKRM ->1a2
1a0 <0> pushmark sRM ->1a1
1a1 <0> padav@a:128,131 lRM ->1a2
1a3 <0> padsv$a:129,131 sRM*/LVINTRO ->1a4
1a5 <;> nextstate(main 131 over.pl:30) ->1a6
----> this is the push @$a, 2 line
1aa <@> pusht5 sK/2 ->1ab
1a6 <0> pushmark s ->1a7
1a8 <1> rv2avt4 lKRM/1 ->1a9
- <@> scope sK ->1a8
- <0> ex-nextstate v ->1a7
1a7 <0> padsv$a:129,131 sM/32 ->1a8
1a9 <$> const(IV 2)t11 s ->1aa
1ab <;> nextstate(main 131 over.pl:31) ->1ac
----> this is the push $a, 2 line. Here you see
the raw lexical being passed to push().
1af <@> pusht6 K/2 ->1ag
1ac <0> pushmark s ->1ad
1ad <0> padsv$a:129,131 ->1ae
1ae <$> const(IV 4)t12 s ->1af
1ag <;> nextstate(main 131 over.pl:32) ->1ah
1ap <@> print K ->1aq
1ah <0> pushmark ->1ai
1ao <2> concatt9 K/2 ->1ap
1al <@> joint7 K/2 ->1am
1ai <0> pushmark ->1aj
1aj <$> const(PV ", ")t13 ->1ak
1ak <0> padav@a:128,131 ->1al
1an <@> stringifyt8 K/1 ->1ao
- <0> ex-pushmark ->1am
1am <$> const(PV "\n")t14 ->1an
Modified opcode tree: Here I've attempted to instert a rv2av and thread execution through it. I'm not sure why that rv2av is now the end point but that's my own ignorance peeking.
$ /usr/local/bin/perl -MO=Concise over.pl
Type of arg 1 to push must be array (not private variable) at over.pl line 30, near "4;"
over.pl had compilation errors.
1an <@> leave@a:128,131 KP/REFC ->(end)
19p <0> enter ->19q
19q <;> nextstate(main 128 over.pl:27) ->19r
19v <2> aassignt2 KS ->19w
- <1> ex-list lK ->19t
19r <0> pushmark s ->19s
19s <$> const(IV 1)t10 s ->19t
- <1> ex-list lK ->19v
19t <0> pushmark s ->19u
19u <0> padav@a:128,131 lRM*/LVINTRO ->19v
19w <;> nextstate(main 129 over.pl:28) ->19x
1a1 <2> sassign sKS/2 ->1a2
19z <1> refgen sK/1 ->1a0
- <1> ex-list lKRM ->19z
19x <0> pushmark sRM ->19y
19y <0> padav@a:128,131 lRM ->19z
1a0 <0> padsv$a:129,131 sRM*/LVINTRO ->1a1
1a2 <;> nextstate(main 131 over.pl:29) ->1a3
----> Again, this is the push @$a, 2 line.
1a7 <@> pusht5 sK/2 ->1a8
1a3 <0> pushmark s ->1a4
1a5 <1> rv2avt4 lKRM/1 ->1a6
- <@> scope sK ->1a5
- <0> ex-nextstate v ->1a4
1a4 <0> padsv$a:129,131 sM/32 ->1a5
1a6 <$> const(IV 2)t11 s ->1a7
1a8 <;> nextstate(main 131 over.pl:30) ->1a9
-----> and this is what that CHECK{} block was tying up in knots.
1ac <@> pusht6 K/2 ->1ad
1a9 <0> pushmark s ->1aa
- <1> rv2avt15 K/1 ->1ab
1aa <0> padsv$a:129,131 ->-
1ab <$> const(IV 4)t12 s ->1ac
1ad <;> nextstate(main 131 over.pl:31) ->1ae
1am <@> print K ->1an
1ae <0> pushmark ->1af
1al <2> concatt9 K/2 ->1am
1ai <@> joint7 K/2 ->1aj
1af <0> pushmark ->1ag
1ag <$> const(PV ", ")t13 ->1ah
1ah <0> padav@a:128,131 ->1ai
1ak <@> stringifyt8 K/1 ->1al
- <0> ex-pushmark ->1aj
1aj <$> const(PV "\n")t14 ->1ak
$
__SIG__ printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B::svref_2object(sub{})->OUTSIDE | [reply] [d/l] [select] |
Re: Consistency, syntax, and little minds
by japhy (Canon) on Oct 03, 2002 at 00:23 UTC
|
Well, that's why we should have methods of data types, not functions. (See Ruby.)
_____________________________________________________
Jeff[japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??; | [reply] |
Re: Consistency, syntax, and little minds
by shotgunefx (Parson) on Oct 03, 2002 at 01:41 UTC
|
Just FYI, in 5.8 a new prototype is available.
sub pushit(\[$@%&]) { # All args are passed as refs.
}
-Lee
"To be civilized is to deny one's nature." | [reply] [d/l] |
Re: Consistency, syntax, and little minds
by BUU (Prior) on Oct 02, 2002 at 23:57 UTC
|
I see a problem here, namely that it could lead into a situation where i do my $foo=\@_; print $foo; and it prints @_. I would consider that a Bad Thing, as it blurs the line between references and actual data structures even more so then it already is. If i do "print $foo", i expect to see "ARRAY(0x97ca44)", thus telling me its an array ref. (Ok, i could use ref to do the same thing.. but this is perl. Must be more then one way. If i want to expand the ref, i'll bloody well dereference it. | [reply] [d/l] |
|
| [reply] |
Re: Consistency, syntax, and little minds
by Abigail-II (Bishop) on Oct 04, 2002 at 14:34 UTC
|
However, I suggest that where an array or hash is to be modified a reference should be passed. In
this manner, any unescaped hash or array in code could be read as an in place expansion of that variable; removing
ambiguity and making the code easier to understand for beginners.
There is already a language addressing the sentiments expressed
above. It's called Python.
Abigail
| [reply] |
|
| [reply] |
|
I wasn't side stepping any issue. I was just pointing to a
language that was created not to have "problem"s as the one
you described regarding push. Python has a much
more regular syntax than Perl - and that's what you like
push to have.
I don't think the syntax of push is a problem,
not at all. By being non-regular, it's easier to program,
and to learn. One doesn't have to know references to be able
to use push.
Abigail
| [reply] [d/l] [select] |
Re: Consistency, syntax, and little minds
by Hercynium (Hermit) on Jan 30, 2013 at 16:39 UTC
|
Wow, talk about a time warp! (it's just a jump to the left)
I ran across this thread looking for examples of the use of B::Generate (see diotalevi's post, below), for some enlightenment of my own.
When I read through the rest of the thread, I had a little chuckle realizing that few of the other commenters seem to have understood what you were asking for all those years ago - and it seems that none really saw the utility and advantage of it! Well, fast forward 9+ years but your idea is now in core, (more or less, unless I failed to understand it as well :), as of perl 5.14!
Recently I have been able to code on perl 5.14 and I find myself using this feature more and more often. I like that it adds a carefully-considered bit of DWIM in a places where I once added a lot of syntax that always felt tedious and distracting. I myself have wished explicit deref for push/keys/shift/etc. was unnecessary - and now it is! In the code where I am using this feature, other people working on or reviewing that code have expressed that they like the feature quite a bit.
More info here: http://perldoc.perl.org/perl5140delta.html#Syntactical-Enhancements
Original Patch and rationale from David Golden (xdg++) here: http://code.activestate.com/lists/perl5-porters/157092/
| [reply] |
|
I was looking forward to this feature too, but when 5.14 was released the docs had this to say e.g. from push:
Starting with Perl 5.14, push can take a scalar EXPR, which must hold a reference to an unblessed array. The argument will be dereferenced automatically. This aspect of push is considered highly experimental. The exact behaviour may change in a future version of Perl.
... which has discouraged me from using it :(
| [reply] |
|
|