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

print array with separator?

1 view
Skip to first unread message

Peng Yu

unread,
Jan 25, 2010, 5:25:32 PM1/25/10
to
@array=("a", "b", "c");
print "@array\n";

The above code will not print a separator (say a newline) between the
elements. I could use a foreach loop to do so. But I feel that there
might be a more convenient way. Could somebody let me know if there is
one?

foreach (@array) {
print;
print "\n";
}

sreservoir

unread,
Jan 25, 2010, 5:33:04 PM1/25/10
to

perldoc -fjoin

--

"Six by nine. Forty two."
"That's it. That's all there is."
"I always thought something was fundamentally wrong with the universe"

John Bokma

unread,
Jan 25, 2010, 6:03:17 PM1/25/10
to
Peng Yu <peng...@gmail.com> writes:

> @array=("a", "b", "c");
> print "@array\n";

@array = qw( a b c );
$" = "\n";
print "@arr";

$" is the list separator, if you do:

use English;

you can use
$LIST_SEPARATOR = "\n";

which is default a space. (Note that modifying $" or the English variant
stays in effect which might be what you want, or not).

Other options:

print map { "$_\n" } @array;

> foreach (@array) {
> print;
> print "\n";
> }

shorter:

for ( @array) {
print "$_\n";
}

or:

print "$_\n" for @array;

or:

print join( "\n", @array ), "\n";

and one I which I don't like much:

map { print "$_\n" } @array;

--
John Bokma j3b

Hacking & Hiking in Mexico - http://johnbokma.com/
http://castleamber.com/ - Perl & Python Development

John W. Krahn

unread,
Jan 25, 2010, 6:08:46 PM1/25/10
to
John Bokma wrote:
>
> and one I which I don't like much:
>
> map { print "$_\n" } @array;

Because it *should* be:

print map "$_\n", @array;

John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway

Tad McClellan

unread,
Jan 25, 2010, 6:10:24 PM1/25/10
to
Peng Yu <peng...@gmail.com> wrote:

> @array=("a", "b", "c");


You should always enable strictures in your Perl programs:

use strict;

then make that

my @array=("a", "b", "c");


> print "@array\n";
>
> The above code will not print a separator (say a newline) between the
> elements.


print join("\n", @array), "\n";


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"

Ben Morrow

unread,
Jan 25, 2010, 6:11:53 PM1/25/10
to

Quoth Peng Yu <peng...@gmail.com>:

> @array=("a", "b", "c");
> print "@array\n";
>
> The above code will not print a separator (say a newline) between the
> elements. I could use a foreach loop to do so. But I feel that there
> might be a more convenient way. Could somebody let me know if there is
> one?

See $" in perlvar, and remember to restrict the scope of any changes
with local.

Ben

Brad Baxter

unread,
Jan 25, 2010, 8:36:22 PM1/25/10
to
On 1/25/2010 5:25 PM, Peng Yu wrote:

The above code positively does printer a separator (a space)
between the elements. Change $" to the separator you want.

use warnings;
use strict;

my @array=("a", "b", "c");
print "@array\n";

$" = "\n";

print "@array\n";

--
Brad

John Bokma

unread,
Jan 25, 2010, 9:37:55 PM1/25/10
to
"John W. Krahn" <som...@example.com> writes:

> John Bokma wrote:
>>
>> and one I which I don't like much:
>>
>> map { print "$_\n" } @array;
>
> Because it *should* be:
>
> print map "$_\n", @array;

Duh, that one is nearly the same as the first one I listed under "other
options" ;-)

As for *should*, I don't like map in void context but that's nowadays
more a matter of taste than anything else as far as I know.

I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
no reason to have a problem with map in void context because we use
other functions in void context without problems (like print).

Uri Guttman

unread,
Jan 25, 2010, 11:23:44 PM1/25/10
to
>>>>> "JB" == John Bokma <jo...@castleamber.com> writes:

JB> I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
JB> no reason to have a problem with map in void context because we use
JB> other functions in void context without problems (like print).

the point with map in void context is not efficiency but in conveying
meaning to the reader. map is intended to generate a list, not execute
side effects. for modifier does the same thing and is meant for side
effects as it doesn't generate a list. perl has many related things like
this and you should choose the one with better semantics for your
intentions. map generates lists so use it that way. for modifier doesn't
generate lists so use it for side effects.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

Dr.Ruud

unread,
Jan 26, 2010, 4:38:16 AM1/26/10
to
Peng Yu wrote:

> @array=("a", "b", "c");

1. "array" is the stupidest name for an array.
2. whitespace is cheap
0. use strict; use warnings;

my @word = qw/ a b c /;

my @word = "a" .. "c";

--
Ruud

Peter J. Holzer

unread,
Jan 26, 2010, 5:44:54 AM1/26/10
to
On 2010-01-26 09:38, Dr.Ruud <rvtol+...@xs4all.nl> wrote:
> Peng Yu wrote:
>> @array=("a", "b", "c");
>
> 1. "array" is the stupidest name for an array.
[...]

> my @word = qw/ a b c /;

The name of a variable should tell the reader something about its
content and/or purpose. So I would agree that @array is in almost all
cases a very stupid name, as it doesn't tell you anything except that
it's an array, and it does so redundantly ("@" and "array").

However, in this example, the only thing important is that is an array.
It isn't important what kind of data is in the array (except that the
elements are strings or can be stringified) or what the data is used
for. So @array is ok, because it tells you that this is "just an array".

@word, however, is a bad name. It conveys that the array contains
"words". This then causes the reader to wonder what a "word" is (an
English word? No, "b" and "c" are not English words. Some other natural
language? Maybe. Strings matching /^\w+$/? Maybe.) and whether the
example is still valid if an element contains data which is not a
"word".

So @stringifiable_data might be ideal but it's a bit long. @strings is
already a bit too narrow (is 1 a string? Is an object with an
overloaded "" operator a string?), in about the same sense that @array
is too wide. So I don't really see that one of @stringifiable_data,
@strings or @array is clearly better than the others.

hp

J�rgen Exner

unread,
Jan 26, 2010, 11:39:43 AM1/26/10
to
"Peter J. Holzer" <hjp-u...@hjp.at> wrote:
>On 2010-01-26 09:38, Dr.Ruud <rvtol+...@xs4all.nl> wrote:
>> Peng Yu wrote:
>>> @array=("a", "b", "c");
>>
>> 1. "array" is the stupidest name for an array.
>[...]
>> my @word = qw/ a b c /;
>
>The name of a variable should tell the reader something about its
>content and/or purpose. So I would agree that @array is in almost all
>cases a very stupid name, as it doesn't tell you anything except that
>it's an array, and it does so redundantly ("@" and "array").
>
>However, in this example, the only thing important is that is an array.
>It isn't important what kind of data is in the array (except that the
>elements are strings or can be stringified) or what the data is used
>for. So @array is ok, because it tells you that this is "just an array".

Ack

>@word, however, is a bad name. It conveys that the array contains
>"words".

Actually it conveys that @word contains exactly one word, maybe split
into individual letters.

>This then causes the reader to wonder what a "word" is (an
>English word? No, "b" and "c" are not English words. Some other natural
>language? Maybe. Strings matching /^\w+$/? Maybe.) and whether the
>example is still valid if an element contains data which is not a
>"word".

If that would have been the intented meaning then @words would have been
preferable to @word.

jue

Peter J. Holzer

unread,
Jan 26, 2010, 12:11:20 PM1/26/10
to
On 2010-01-26 16:39, J�rgen Exner <jurg...@hotmail.com> wrote:
> "Peter J. Holzer" <hjp-u...@hjp.at> wrote:
>>On 2010-01-26 09:38, Dr.Ruud <rvtol+...@xs4all.nl> wrote:
>>> Peng Yu wrote:
>>>> @array=("a", "b", "c");
>>>
>>> 1. "array" is the stupidest name for an array.
>>[...]
>>> my @word = qw/ a b c /;
>>
>>The name of a variable should tell the reader something about its
>>content and/or purpose. So I would agree that @array is in almost all
>>cases a very stupid name, as it doesn't tell you anything except that
>>it's an array, and it does so redundantly ("@" and "array").
>>
>>However, in this example, the only thing important is that is an array.
>>It isn't important what kind of data is in the array (except that the
>>elements are strings or can be stringified) or what the data is used
>>for. So @array is ok, because it tells you that this is "just an array".
>
> Ack
>
>>@word, however, is a bad name. It conveys that the array contains
>>"words".
>
> Actually it conveys that @word contains exactly one word, maybe split
> into individual letters.
[...]

> If that would have been the intented meaning then @words would have been
> preferable to @word.

I, too, prefer using the plural for array names.

But there are valid arguments for using the singular:

* $word[5] reads more naturally as "word (number) 5" than $words[5].

* In Perl, singular/plural is expressed by the sigil, so
@word is already "several word(s)" and the English plural-s is
at best redundant and at worst harmful, because Perl doesn't
understand it (@words is *not* the array containing $word[0],
$word[1], ...).

So I consider that a matter of personal style and decided not to
complicate this discussion by bringing up the singular/plural debate.
I should have known that somebody else would ...

hp

Dr.Ruud

unread,
Jan 26, 2010, 1:21:01 PM1/26/10
to

When calling it @word, I hoped for these comments.
:)

--
Ruud

John Bokma

unread,
Jan 26, 2010, 1:29:19 PM1/26/10
to
"Uri Guttman" <u...@StemSystems.com> writes:

>>>>>> "JB" == John Bokma <jo...@castleamber.com> writes:
>
> JB> I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
> JB> no reason to have a problem with map in void context because we use
> JB> other functions in void context without problems (like print).
>
> the point with map in void context is not efficiency

It used to be, and back then, IMO there was a much stronger argument to
not use map in void context.

> but in conveying
> meaning to the reader. map is intended to generate a list, not execute
> side effects.

But who decides that map is not intended for its side effects? In Perl
there are IMO quite some constructs that are used in somewhat unexpected
ways, especially to people new to the language.

> for modifier does the same thing and is meant for side
> effects as it doesn't generate a list. perl has many related things like
> this and you should choose the one with better semantics for your
> intentions. map generates lists so use it that way. for modifier doesn't
> generate lists so use it for side effects.

Like I wrote, I don't like it, and won't use it. But the arguments
against using map in void context are more a matter of taste IMO. The
"its not intended for that" is weak at best, in my (current) opinion.

Dr.Ruud

unread,
Jan 26, 2010, 2:28:28 PM1/26/10
to
John Bokma wrote:

> the arguments
> against using map in void context are more a matter of taste IMO. The
> "its not intended for that" is weak at best, in my (current) opinion.

Recent perls do pretty well with map in a void context.

Unrecent perls have real issues with a map inside a map:
memory allocated by the inner map gets released too late.
Nothing to much worry about, unless the inner map is big.

--
Ruud

John Bokma

unread,
Jan 26, 2010, 3:13:33 PM1/26/10
to
"Dr.Ruud" <rvtol+...@xs4all.nl> writes:

> John Bokma wrote:
>
>> the arguments
>> against using map in void context are more a matter of taste IMO. The
>> "its not intended for that" is weak at best, in my (current) opinion.
>
> Recent perls do pretty well with map in a void context.

which gives me the impression that it's more a matter of taste/style
than using map "wrong" of for something it is not intented for.

But before the flame war really starts, let me repeat that I don't like
it, and it will be unlikely to show up in my code in the near future.

I've done TE for a book in which the author used a lot map in void
context, and each time I remarked "Don't use void in a map
context". While I don't think it's wrong, I wouldn't recommend it to
use it that often in a book. I haven't seen the final version of the
book yet, so no idea what happened with my advice. But it also made me
think: what's really wrong with it. And I couldn't think of a strong
argument other than that it looks odd (to me). And some of the code
looked better (IMO, again style) with for.

J�rgen Exner

unread,
Jan 26, 2010, 3:39:33 PM1/26/10
to
John Bokma <jo...@castleamber.com> wrote:

>"Uri Guttman" <u...@StemSystems.com> writes:
>> but in conveying
>> meaning to the reader. map is intended to generate a list, not execute
>> side effects.
>
>But who decides that map is not intended for its side effects? In Perl
>there are IMO quite some constructs that are used in somewhat unexpected
>ways, especially to people new to the language.

The root cause of this confusion is probably that for most people with a
formal background in computer science 'map()' is the first operation
that comes to mind when you want to apply an operation to a list of
values. After all it is one of the three canonical higher-order list
functions map, reduce, and filter.

And because Perl happens to have a function map() that happens to work
the same way in a functional as well as in an imperative programming
style it is only natural that people are using it for both purposes.
And I don't see anything wrong with that.

jue

Tad McClellan

unread,
Jan 26, 2010, 5:29:12 PM1/26/10
to
John Bokma <jo...@castleamber.com> wrote:
> "Uri Guttman" <u...@StemSystems.com> writes:
>
>>>>>>> "JB" == John Bokma <jo...@castleamber.com> writes:
>>
>> JB> I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
>> JB> no reason to have a problem with map in void context because we use
>> JB> other functions in void context without problems (like print).
>>
>> the point with map in void context is not efficiency
>
> It used to be, and back then, IMO there was a much stronger argument to
> not use map in void context.
>
>> but in conveying
^^^^^^^^^

>> meaning to the reader. map is intended to generate a list, not execute
^^^^^^^^^^^^^^^^^^^^^

>> side effects.
>
> But who decides that map is not intended for its side effects?


That is a red herring.

What is intended by map does not matter, what map conveys to the reader
is what matters.

map conveys "I am building a list" (because it returns a list).


>> for modifier does the same thing and is meant for side
>> effects as it doesn't generate a list. perl has many related things like
>> this and you should choose the one with better semantics for your
>> intentions. map generates lists so use it that way. for modifier doesn't
>> generate lists so use it for side effects.
>
> Like I wrote, I don't like it, and won't use it. But the arguments
> against using map in void context are more a matter of taste IMO.


Using map in a void context is an obfuscation.

Arguments against obfuscation are NOT a matter of taste, they are
a matter of Good Programming Practice.


> The
> "its not intended for that" is weak at best, in my (current) opinion.


That was not Uri's argument.

Uri's argument was that map in void context conveys the wrong meaning.

Ben Morrow

unread,
Jan 26, 2010, 5:54:32 PM1/26/10
to

Quoth Tad McClellan <ta...@seesig.invalid>:

> John Bokma <jo...@castleamber.com> wrote:
> > "Uri Guttman" <u...@StemSystems.com> writes:
> >
> >>>>>>> "JB" == John Bokma <jo...@castleamber.com> writes:
> >>
> >> JB> I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
> >> JB> no reason to have a problem with map in void context because we use
> >> JB> other functions in void context without problems (like print).
> >>
> >> the point with map in void context is not efficiency
> >
> > It used to be, and back then, IMO there was a much stronger argument to
> > not use map in void context.
> >
> >> but in conveying
> ^^^^^^^^^
> >> meaning to the reader. map is intended to generate a list, not execute
> ^^^^^^^^^^^^^^^^^^^^^
> >> side effects.
> >
> > But who decides that map is not intended for its side effects?
>
>
> That is a red herring.
>
> What is intended by map does not matter, what map conveys to the reader
> is what matters.
>
> map conveys "I am building a list" (because it returns a list).

So does delete. Would you object to delete in void context?

Ben

John Bokma

unread,
Jan 26, 2010, 6:08:44 PM1/26/10
to
Tad McClellan <ta...@seesig.invalid> writes:

> Arguments against obfuscation are NOT a matter of taste, they are
> a matter of Good Programming Practice.

Like I already wrote several times: I wouldn't use map in void context
at this stage. But I don't think one /must/ (or /should/) not use it in
void context.

> Uri's argument was that map in void context conveys the wrong meaning.

One could - to some extent - argue the same for using a 'for' for its
aliasing effect in my opinion, e.g.

my $string = 'hello, world';
for ( $string ) {
s/e/a/;
s/l/1/;
}

I consider the above a Perl idiom; one that I have no problem using.
Yet I am sure it would confuse quite some beginning Perl programmers. To
them it might convey a wrong meaning.

But I don't like to dumb down my Perl code to a beginner's level. YMMV,
in my opinion, it's opinion.

And to avoid of being accused of "promoting map in void context", let me
repeat again: I don't use map in void context, and when TEing a
technical book I recommended the author not to use map in void
context. But it's (no longer) a religious issue to me.

Uri Guttman

unread,
Jan 26, 2010, 6:11:29 PM1/26/10
to
>>>>> "BM" == Ben Morrow <b...@morrow.me.uk> writes:

>> map conveys "I am building a list" (because it returns a list).

BM> So does delete. Would you object to delete in void context?

but delete conveys the message of doing a side effect. its return value
is nice sugar but isn't needed (amazing how often i show use of delete's
return value and how few know it). map's history (yes, history isn't
taught much) is from building a list from a list. its primary purpose is
building that list and that is what is says to the reader. i always
teach code is for people, not computers. we all can use things in ways
that were unintended but we try to stay away from them for fear of
confusing readers. given that map has the for modifier for use when
doing side effects, that is a better semantic match for that case. note
that for modifier was added after perl5 was first out. map could have
been used for that but given the inefficiency then of throwing out the
list (not true anymore but still) and wrong semantics, it was a good
addition to the language. so why not use it for its purpose? for means
you are doing some side effects in the expression. map means you are
building a list and supposedly not doing side effects.

this is similar to using ?: with side effects. it is a bad idea even if
you get the syntax right (using parens with assignments). ?: is meant to
return a value and not for side effects. perl allows any legit
expression including side effect ones anywhere. that doesn't mean it is
a good idea to do that.

code is for people, not computers.

code is for OTHER people, not yourself.

code is the record of the logical decisions you made when creating this
program.

code is where you can let your ego shine in the reflection of those who
read your code.

Dr.Ruud

unread,
Jan 26, 2010, 6:41:26 PM1/26/10
to
Tad McClellan wrote:

> map conveys "I am building a list" (because it returns a list).

IIRC: unless in void context.
(as one of the recent optimizations)

Not that I like to see map used in void context,
I rather see a for loop.


Just joking:

perl -wle '
my @x = -3 .. 3;
grep { ++$_; 0 } @x;
print for @x;
'
-2
-1
0
1
2
3
4


(huh? C<grep ++$_, -3..3> doesn't complain about readonly-ness)

--
Ruud

sreservoir

unread,
Jan 26, 2010, 7:07:34 PM1/26/10
to
On 1/26/2010 6:41 PM, Dr.Ruud wrote:
> Tad McClellan wrote:
>
>> map conveys "I am building a list" (because it returns a list).
>
> IIRC: unless in void context.
> (as one of the recent optimizations)

not that that really matters.

> Not that I like to see map used in void context,
> I rather see a for loop.
>
>
> Just joking:
>
> perl -wle '
> my @x = -3 .. 3;
> grep { ++$_; 0 } @x;
> print for @x;
> '
> -2
> -1
> 0
> 1
> 2
> 3
> 4
>

perl -wle 'my @a = -3 .. 3; map { --$_; () } @a; print for @a'

not much worse, but still hell for readability.

> (huh? C<grep ++$_, -3..3> doesn't complain about readonly-ness)

(huh? it's rw pass-by-ref)

Ben Morrow

unread,
Jan 26, 2010, 8:42:47 PM1/26/10
to

Quoth sreservoir <srese...@gmail.com>:

> On 1/26/2010 6:41 PM, Dr.Ruud wrote:
>
> > (huh? C<grep ++$_, -3..3> doesn't complain about readonly-ness)
>
> (huh? it's rw pass-by-ref)

$_ ought to be an alias to a constant.

~% perl -e'map $_++, -3..3'
~% perl -e'map $_++, -3, -2, -1, 0, 1, 2, 3'
Modification of a read-only value attempted at -e line 1.
~%

In fact, it seems perl precomputes the range at compile-time, puts the
results in a constant array, but forgets to make the elements constant:

~% perl -e'map $_++, -3..3'
a <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
7 <|> mapwhile(other->8)[t5] vK ->a
6 <@> mapstart K ->7
3 <0> pushmark s ->4
- <1> null lK/1 ->4
9 <1> postinc[t1] sK/1 ->7
- <1> ex-rv2sv sKRM/1 ->9
8 <$> gvsv(*_) s ->9
5 <1> rv2av lKPM/1 ->6
4 <$> const(AV ) s ->5

which has some side-effects which make this definitely a bug:

~% perl -E'for (1..2) { map {say ++$_} -2..2 }'


-1
0
1
2
3
0
1
2
3
4

~%

Ben

Jochen Lehmeier

unread,
Jan 27, 2010, 3:40:46 AM1/27/10
to
On Wed, 27 Jan 2010 02:42:47 +0100, Ben Morrow <b...@morrow.me.uk> wrote:

> $_ ought to be an alias to a constant.

From "perldoc map":

"Note that $_ is an alias to the list value, so it can be used to modify
the elements of the LIST. While this is useful and supported, it can cause
bizarre results if the elements of LIST are not variables. Using a regular
foreach loop for this purpose would be clearer in most cases."

From "perldoc grep":

"Note that $_ is an alias to the list value, so it can be used to modify
the elements of the LIST. While this is useful and supported, it can cause
bizarre results if the elements of LIST are not variables. Similarly, grep
returns aliases into the original list, much as a for loop's index
variable aliases the list elements. That is, modifying an element of a
list returned by grep (for example, in a foreach , map or another grep)
actually modifies the element in the original list. This is usually
something to be avoided when writing clear code."

C.DeRykus

unread,
Jan 27, 2010, 2:39:38 PM1/27/10
to
On Jan 25, 8:23 pm, "Uri Guttman" <u...@StemSystems.com> wrote:

> >>>>> "JB" == John Bokma <j...@castleamber.com> writes:
>
>   JB> I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
>   JB> no reason to have a problem with map in void context because we use
>   JB> other functions in void context without problems (like print).
>
> the point with map in void context is not efficiency but in conveying
> meaning to the reader. map is intended to generate a list, not execute
> side effects. for modifier does the same thing and is meant for side
> effects as it doesn't generate a list. perl has many related things like
> this and you should choose the one with better semantics for your
> intentions. map generates lists so use it that way. for modifier doesn't
> generate lists so use it for side effects.
>

However 'perldoc -q void' has an addendum about map being context
aware since 5.8.1. And there's no "ahem, but map is intended to
generate a list" to disparage its use in void content.

I prefer the for modifier but wish 'void' was a keyword for side-
effects only map use. Then I suppose there'd be crazies who'd use
void with print or delete too :).


--
Charles DeRykus

J�rgen Exner

unread,
Jan 27, 2010, 2:50:40 PM1/27/10
to
"C.DeRykus" <der...@gmail.com> wrote:
>I prefer the for modifier but wish 'void' was a keyword for side-
>effects only map use.

Doesn't
undef = map .....
work (I didn't try it)?

jue

Dr.Ruud

unread,
Jan 27, 2010, 2:51:07 PM1/27/10
to
Jochen Lehmeier wrote:

> From "perldoc grep":
>
> "Note that $_ is an alias to the list value, so it can be used to modify
> the elements of the LIST. While this is useful and supported, it can
> cause bizarre results if the elements of LIST are not variables.
> Similarly, grep returns aliases into the original list, much as a for
> loop's index variable aliases the list elements. That is, modifying an
> element of a list returned by grep (for example, in a foreach , map or
> another grep) actually modifies the element in the original list. This
> is usually something to be avoided when writing clear code."

Yeah, though I'd rather see an error if an immutable is violated.


But wait, it does:

perl -e'grep ++$_, -2..2'

perl -e'grep ++$_, -2,-1,0,1,2'


Modification of a read-only value attempted at -e line 1.

perl -e'grep ++$_, @{[ -2,-1,0,1,2 ]}'

So -2..2 just iterates mutables.

--
Ruud

Jochen Lehmeier

unread,
Jan 27, 2010, 3:03:10 PM1/27/10
to
On Wed, 27 Jan 2010 20:51:07 +0100, Dr.Ruud <rvtol+...@xs4all.nl> wrote:

> perl -e'grep ++$_, -2..2'
>
> perl -e'grep ++$_, -2,-1,0,1,2'
> Modification of a read-only value attempted at -e line 1.
>
> perl -e'grep ++$_, @{[ -2,-1,0,1,2 ]}'
>
> So -2..2 just iterates mutables.

Aye.

perl -e 'for (0,0) { print ++$_ for (1..2) }'
2323

So, the expression "1..2" is evaluated to an array at runtime, not compile
time (if it were evaluated at compile time, the result would be "2334"
instead of "2323"). No read-only values involved. Same goes for @{[...]}.
I guess perl could optimize both constructs at compile time, but obviously
doesn't, so it does not need to throw an error about read-only values.

Ben Morrow

unread,
Jan 27, 2010, 4:43:06 PM1/27/10
to

Quoth J�rgen Exner <jurg...@hotmail.com>:

> "C.DeRykus" <der...@gmail.com> wrote:
> >I prefer the for modifier but wish 'void' was a keyword for side-
> >effects only map use.

Dear Lord no. That's as bad as the people who insist on casting
everything to (void) in C. Evaluating a function in void context is a
perfectly ordinary thing to do, so why does it need a redundant keyword?

> Doesn't
> undef = map .....
> work (I didn't try it)?

No, that's scalar assignment, which gives scalar context to the RHS. At
runtime you get 'Modification of a read-only value attempted', of
course.

Ben

C.DeRykus

unread,
Jan 27, 2010, 7:10:08 PM1/27/10
to
On Jan 27, 1:43 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth Jürgen Exner <jurge...@hotmail.com>:

>
> > "C.DeRykus" <dery...@gmail.com> wrote:
> > >I prefer the for modifier but wish 'void' was a keyword for side-
> > >effects only map use.
>
> Dear Lord no. That's as bad as the people who insist on casting
> everything to (void) in C. Evaluating a function in void context is a
> perfectly ordinary thing to do, so why does it need a redundant keyword?

I mentioned "crazies" but you're probably right. Rather than
judicious use in cases like map to bridge changed semantics,
it'd turn viral.


>
> > Doesn't
> >    undef = map .....
> > work (I didn't try it)?
>
> No, that's scalar assignment, which gives scalar context to the RHS. At
> runtime you get 'Modification of a read-only value attempted', of
> course.
>

Ah. I suppose you could still signal map's only purpose were the
side-effects with '() = map ...' (added keystrokes+slower though)

--
Charles DeRykus

C.DeRykus

unread,
Jan 27, 2010, 7:41:29 PM1/27/10
to
On Jan 27, 11:51 am, "Dr.Ruud" <rvtol+use...@xs4all.nl> wrote:
> Jochen Lehmeier wrote:
>> ...

>
> Yeah, though I'd rather see an error if an immutable is violated.
>
> But wait, it does:
>
> perl -e'grep ++$_, -2..2'
>
> perl -e'grep ++$_, -2,-1,0,1,2'
> Modification of a read-only value attempted at -e line 1.
>
> perl -e'grep ++$_, @{[ -2,-1,0,1,2 ]}'
>
> So -2..2 just iterates mutables.
>

That seems wrong (or at least surprising) because the range op
should just generate a list - in this case a list of literals -
not an array of mutables. That is, these two appear to be
equivalently processed by grep:

perl -e 'grep ++$_, -2..2'

perl -e 'grep ++$_, [-2..2]'

grep appears to be creating a temp array in the former case instead
of a list.

--
Charles DeRykus

Uri Guttman

unread,
Jan 27, 2010, 7:54:28 PM1/27/10
to
>>>>> "CD" == C DeRykus <der...@gmail.com> writes:

CD> perl -e 'grep ++$_, -2..2'
CD> perl -e 'grep ++$_, [-2..2]'

CD> grep appears to be creating a temp array in the former case instead
CD> of a list.

the second line makes no sense as it is passing an array ref to grep.

perl -le 'print grep ++$_, [-2..2]'
162189897

the ref address get numified and then gets bumped.

as for the other issues about modifying the ranges vs a list, possible
this is from the optimization that perl does with large ranges. it used
to generate them as a list and now it creates an iterator. another
thought is that to make a range list it needs to create real sv's so it
can bump them. but a list of ints is passed as constants and so they
can't be modified. this harkens back to a bug i found when 5.6 changed
qw() from a runtime split (which made sv's) to a compile time list of
constant strings. some code i was analyzing for porting to 5.6 was
crashing due to modification of constants in the qw. this feels like a
similar thing. a generated list has to be sv's which can be modified. a
passed list of constants are still constants and can't be modified.

Ben Morrow

unread,
Jan 27, 2010, 8:18:00 PM1/27/10
to

Quoth "C.DeRykus" <der...@gmail.com>:

> On Jan 27, 1:43�pm, Ben Morrow <b...@morrow.me.uk> wrote:
> > Quoth J�rgen Exner <jurge...@hotmail.com>:

> >
> > > "C.DeRykus" <dery...@gmail.com> wrote:
> > > >I prefer the for modifier but wish 'void' was a keyword for side-
> > > >effects only map use.
> >
> > Dear Lord no. That's as bad as the people who insist on casting
> > everything to (void) in C. Evaluating a function in void context is a
> > perfectly ordinary thing to do, so why does it need a redundant keyword?
>
> I mentioned "crazies" but you're probably right. Rather than
> judicious use in cases like map to bridge changed semantics,
> it'd turn viral.

There are no changed semantics, just an optimisation.

> > > Doesn't
> > > � �undef = map .....
> > > work (I didn't try it)?
> >
> > No, that's scalar assignment, which gives scalar context to the RHS. At
> > runtime you get 'Modification of a read-only value attempted', of
> > course.
> >
>
> Ah. I suppose you could still signal map's only purpose were the
> side-effects with '() = map ...' (added keystrokes+slower though)

That's a list assignment, so the RHS is in list context (it *is*
possible to try these things before posting, you know).

Ben

C.DeRykus

unread,
Jan 27, 2010, 9:41:38 PM1/27/10
to
On Jan 27, 4:54 pm, "Uri Guttman" <u...@StemSystems.com> wrote:

> >>>>> "CD" == C DeRykus <dery...@gmail.com> writes:
>
>   CD>    perl -e 'grep ++$_, -2..2'
>   CD>    perl -e 'grep ++$_, [-2..2]'
>
>   CD> grep appears to be creating a temp array in the former case instead
>   CD> of a list.
>
> the second line makes no sense as it is passing an array ref to grep.

Oops, right, I meant: perl -we "print grep ++$_, @{[0..1]}"

> ...

--
Charles DeRykus

C.DeRykus

unread,
Jan 27, 2010, 10:07:51 PM1/27/10
to
On Jan 27, 5:18 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth "C.DeRykus" <dery...@gmail.com>:

>
> > On Jan 27, 1:43 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> > > Quoth Jürgen Exner <jurge...@hotmail.com>:

>
> > > > "C.DeRykus" <dery...@gmail.com> wrote:
> > > > >I prefer the for modifier but wish 'void' was a keyword for side-
> > > > >effects only map use.
>
> > > Dear Lord no. That's as bad as the people who insist on casting
> > > everything to (void) in C. Evaluating a function in void context is a
> > > perfectly ordinary thing to do, so why does it need a redundant keyword?
>
> > I mentioned "crazies" but you're probably right. Rather than
> > judicious use in cases like map to bridge changed semantics,
> > it'd turn viral.
>
> There are no changed semantics, just an optimisation.

Agreed, "bridge the optimization" would have been the correct
wording.

>
> > > > Doesn't
> > > >    undef = map .....
> > > > work (I didn't try it)?
>
> > > No, that's scalar assignment, which gives scalar context to the RHS. At
> > > runtime you get 'Modification of a read-only value attempted', of
> > > course.
>
> > Ah. I suppose you could still signal map's only purpose were the
> > side-effects with  '() = map ...' (added keystrokes+slower though)
>
> That's a list assignment, so the RHS is in list context (it *is*
> possible to try these things before posting, you know).
>

Um, I was addressing the broader issue of using map in scalar
context without generating a LHS list. I *wanted* to suggest
map could be put in list context and resultant list tossed to
clarify that only the side-effects were of interest.

--
Charles DeRykus

C.DeRykus

unread,
Jan 27, 2010, 10:15:11 PM1/27/10
to
On Jan 27, 7:07 pm, "C.DeRykus" <dery...@gmail.com> wrote:
> On Jan 27, 5:18 pm, Ben Morrow <b...@morrow.me.uk> wrote:
>
> ...

>
>
> > > > > Doesn't
> > > > >    undef = map .....
> > > > > work (I didn't try it)?

Ah, I think the above is attributed to me but I didn't say it.

>
> > > > No, that's scalar assignment, which gives scalar context to the RHS. At
> > > > runtime you get 'Modification of a read-only value attempted', of
> > > > course.
>
> > > Ah. I suppose you could still signal map's only purpose were the
> > > side-effects with  '() = map ...' (added keystrokes+slower though)
>
> > That's a list assignment, so the RHS is in list context (it *is*
> > possible to try these things before posting, you know).

I see how the mis-attribution created more confusion now.


>
> Um, I was addressing the broader issue of using map in scalar
> context without generating a LHS list.  I *wanted* to suggest
> map could be put in list context and resultant list tossed to
> clarify that only the side-effects were of interest.

And that's why I responded here in this vein.

--
Charles DeRykus

Dr.Ruud

unread,
Jan 28, 2010, 7:17:41 AM1/28/10
to
C.DeRykus wrote:

> Ah. I suppose you could still signal map's only purpose were the
> side-effects with '() = map ...' (added keystrokes+slower though)

That would signal that you don't want map to optimize for void context.
(map knows when it is in void context)

--
Ruud

0 new messages