print array with separator?

J

Jochen Lehmeier

$_ 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

C.DeRykus

  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 :).
 
J

Jürgen Exner

C.DeRykus said:
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
 
D

Dr.Ruud

Jochen said:
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.
 
J

Jochen Lehmeier

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.
 
C

C.DeRykus

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.

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)
 
C

C.DeRykus

Jochen said:

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.
 
U

Uri Guttman

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.

uri
 
C

C.DeRykus

  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]}"
 
C

C.DeRykus

There are no changed semantics, just an optimisation.

Agreed, "bridge the optimization" would have been the correct
wording.
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.
 
C

C.DeRykus


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

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.
 
D

Dr.Ruud

C.DeRykus said:
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)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,295
Latest member
EmilG1510

Latest Threads

Top