Re: Readline using foreach and while
Re: Readline using foreach and while
am 29.03.2008 16:47:34 von szr
Ben Morrow wrote:
> Quoth "szr" :
>> Ben Morrow wrote:
>>> Quoth "szr" :
>>>>
>>>> Actually the behaviors of "for (@ary)" and "for (@ary, ())" do seem
>>>> consistant if you really think about it. The resulting list is what
>>>> it iterates over (from the first element, to what ever *count*
>>>> is... in the former case *count* come fro mthe array, and since the
>>>> condition is checked at the start of each iteration, if the array
>>>> is added to, the count is incremented.
>>>>
>>>> In the latter case, a new list is created from contents of @ary +
>>>> an empty list, which gives you a new list, which contains the
>>>> values of @ary, but is a new seperate list, and thus is not
>>>> effected by changes to @ary because it has it's own copy of @ary's
>>>> values.
>>>
>>> OK, now explain to me why
>>>
>>> my @ary = qw/a b c/;
>>> print map { /c/ and push @ary, 'd'; $_ } @ary;
>>>
>>> *doesn't* work like that :).
>>
>> Actually it does. The difference is, map doesn't recheck the count
>> every time around like for/foreach do. If you print the contents of
>> @ary after the line with the map statement, it does indeed contain
>> 'd' at the end. This behavior seems to correct, as one would likely
>> expect that the list map returns when it is finished to be the same
>> length as the one /passed/ into map at the start. If you pass a 3
>> element list, you should get back a 3 element list, should you not?
>
> Absolutely not. my %h = map { $_ => 1 } qw/a b c/; is quite a common
> idiom.
Well, you're still getting that many *sets* which is probably what I
should of said, or have been clearer. In that example, you get 3 set of
hash pairs resulting from the 3 element list. The point is you get
count_of_passed_list amount of something from the map, in some form or
another. How exactly it's returned is determined by the template inside
the map.
>
>> $_ is aliased to the current array element just like in for. Again,
>> the only difference I see if that map doesn't recheck the count of
>> the passed list for each iteration.
>
> No, you're misunderstanding the difference between a list and an
> array. Evaluating an array in list context returns a list of its
> elements *as they are now*;
I seem to understand it just fine. What we both said above seems to be
true. Maybe we're just misunderstanding what the other is trying to say?
:-)
> under most circumstances, it returns a
> list of aliases to those elements, but any changes to the order of
> the elements in @ary are not propagated into the list. Consider
>
> my @ary = qw/a b c/;
> sub foo {
> my @keep = map "$_", @_; # kill the aliasing
Ok @keep now contains (a, b, c)...
> unshift @ary, 'h';
@ary, which comes from a scope outside this sub, now contains (h, a, b,
c)
> $_[$_] .= $keep[$_] for 0..$#_;
Keep in mind $_[0] *still* points to what used to be the first element
of @ary. Remember, the aliasing isn't to the *array* but to it's
*elements*. This is because when you normally pass args to a sub (e.g.,
do_something($x, $y); ), the aliasing is with $x and $y to $_[0] and
$_[1]. Passing an array just like passing that many scalars as are
elements in the array; each individual one gets aliased to the next
sequential element of @_ in the sub's scope.
> }
> foo @ary;
> print for @ary;
Running this (with the last line as `print "$_\n" for @ary;` for
clarity) prints:
h
aa
bb
cc
Seems the changes propgated just fine to me. You pushed 'h' to the
beginning of @ary, then you effectively iterated from
$ary[1]..$ary[$#ary].
Map is the same way in that regard; $_ is an alias to an *element*
>> To me, this behavior is part of what separates map from for/foreach.
>
> It separates for (LIST) from everything else that accepts a LIST.
> This is why I called it 'weird'.
I still don't see what you consider weird about it. What does it do that
you don't expect it to do?
--
szr
Re: Readline using foreach and while
am 29.03.2008 17:02:37 von Uri Guttman
>>>>> "s" == szr writes:
>> Absolutely not. my %h = map { $_ => 1 } qw/a b c/; is quite a common
>> idiom.
s> Well, you're still getting that many *sets* which is probably what I
s> should of said, or have been clearer. In that example, you get 3 set of
s> hash pairs resulting from the 3 element list. The point is you get
s> count_of_passed_list amount of something from the map, in some form or
s> another. How exactly it's returned is determined by the template inside
s> the map.
you are still missing the picture. map can return ANY number of elements
(not sets). it executes its expression/block once for each input element
but that can generate 0-?? elements which are appended to the return
list. there are no boundaries in those elements so there are no true
sets. if you return a reference which holds stuff you can force your own
boundaries and make sets. that is also a known map idiom. map generates
a new list from input from another list. the transformation can be
anything and isn't tied to how many input elements there are.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
Re: Readline using foreach and while
am 29.03.2008 17:27:57 von szr
Uri Guttman wrote:
>>>>>> "s" == szr writes:
>
> >> Absolutely not. my %h = map { $_ => 1 } qw/a b c/; is quite a
> common >> idiom.
>
> s> Well, you're still getting that many *sets* which is probably
> what I s> should of said, or have been clearer. In that example, you
> get 3 set of s> hash pairs resulting from the 3 element list. The
> point is you get s> count_of_passed_list amount of something from
> the map, in some form or s> another. How exactly it's returned is
> determined by the template inside s> the map.
>
> you are still missing the picture. map can return ANY number of
> elements (not sets). it executes its expression/block once for each
> input element but that can generate 0-?? elements which are appended
> to the return list.
I understand, but still, whatever is being generated to the LHS of map,
it's done that many times are there are elements in the list on the RHS.
Is that fair to say?
> there are no boundaries in those elements so there are no true sets.
I meant "set" in a very generic way. Not in the mathematical sense, but
in the sense that you get back something that can be group of something
on the LHS by the number of elements on the RHS of map. The `map { $_ =>
1 }` example gives you that many pairs, for example.
--
szr
Re: Readline using foreach and while
am 29.03.2008 17:51:36 von Uri Guttman
>>>>> "s" == szr writes:
>> you are still missing the picture. map can return ANY number of
>> elements (not sets). it executes its expression/block once for each
>> input element but that can generate 0-?? elements which are appended
>> to the return list.
s> I understand, but still, whatever is being generated to the LHS of map,
s> it's done that many times are there are elements in the list on the RHS.
s> Is that fair to say?
no, i wouldn't say what is being generated. just what i previously said
happens. the CODE in the expression/block is executed ONCE for each
input element. then the collected list of those is returned. use the
correct terminology and you will get it easier.
>> there are no boundaries in those elements so there are no true sets.
s> I meant "set" in a very generic way. Not in the mathematical sense, but
s> in the sense that you get back something that can be group of something
s> on the LHS by the number of elements on the RHS of map. The `map { $_ =>
s> 1 }` example gives you that many pairs, for example.
but there are no 'pairs' in the list except by the context of assigning
the list to a hash. there is just a list of elements created by the
map. map doesn't know or care what happens to its generated list. so
calling them pairs is out of context. and as such there are no
boundaries (which pairs implies). map can generate ANY sort of list you
want. no sets or pairs or groups need to be created. a single list is
what you get and all you should care about. how you use that list is up
to the next part of the expression.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
Re: Readline using foreach and while
am 29.03.2008 18:06:44 von szr
(Please use proper capitalization and such, it will make your replies
easier to read.)
Uri Guttman wrote:
>>>>>> "s" == szr writes:
>
> >> you are still missing the picture. map can return ANY number of
> >> elements (not sets). it executes its expression/block once for
> each >> input element but that can generate 0-?? elements which are
> appended >> to the return list.
>
> s> I understand, but still, whatever is being generated to the LHS
> of map, s> it's done that many times are there are elements in the
> list on the RHS. s> Is that fair to say?
>
> no, i wouldn't say what is being generated. just what i previously
> said happens. the CODE in the expression/block is executed ONCE for
> each input element. then the collected list of those is returned.
> use the correct terminology and you will get it easier.
Well that's basically how I understand it. In fact it seems you
basically restated the same thing in a different way. 1) the expr/block
is executed once per cycle. Yep. 2) The end result is something that is
a grouping, whether singular (say, a simple list) or more complex (like,
say, a hash key/value pair), of the same amount of elements in the input
list.
I know using proper terminology is important, but I think understand
meaning as someone put it into their own words is also an important
skill. This is something I have to do quite frequently in my line of
work when dealing with many kinds of people regarding projects I work
on. Not all of them are as savvy with programming (or a specific
language like Perl) and often I have to use simpler terms to describe
things.
> >> there are no boundaries in those elements so there are no true
> sets.
>
> s> I meant "set" in a very generic way. Not in the mathematical
> sense, but s> in the sense that you get back something that can be
> group of something s> on the LHS by the number of elements on the
> RHS of map. The `map { $_ => s> 1 }` example gives you that many
> pairs, for example.
>
> but there are no 'pairs' in the list except by the context of
> assigning the list to a hash.
I'm sorry, but I really have to disagree here. A hash is essentially a
list divided into pairs (keys and values, respectively), and `map { $_
=> s> 1 }` is creating such a pair in a statement like that.
--
szr
Re: Readline using foreach and while
am 29.03.2008 18:15:34 von 1usa
"szr" wrote in
news:fslqmd01gvu@news2.newsguy.com:
> Uri Guttman wrote:
>>>>>>> "s" == szr writes:
>>
>> >> Absolutely not. my %h = map { $_ => 1 } qw/a b c/; is quite a
>> common >> idiom.
>>
>> s> Well, you're still getting that many *sets* which is probably
>> what I s> should of said, or have been clearer. In that example,
>> you get 3 set of s> hash pairs resulting from the 3 element
>> list. The point is you get s> count_of_passed_list amount of
>> something from the map, in some form or s> another. How exactly
>> it's returned is determined by the template inside s> the map.
>>
>> you are still missing the picture. map can return ANY number of
>> elements (not sets). it executes its expression/block once for
>> each input element but that can generate 0-?? elements which are
>> appended to the return list.
>
> I understand, but still, whatever is being generated to the LHS of
> map, it's done that many times are there are elements in the list
> on the RHS. Is that fair to say?
If I understand you correctly, yeah, that's fine to say.
On the other hand, you might find the following example instructive:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @result = map { split // } ( '5' x rand(10) ) ;
print Dumper \@result;
__END__
Note that, the RHS is always a single element list. On the other hand,
the number of elements in the result of map is variable. So, yes, the
operation inside the block is only carried out once, what you are
saying is fair in that sense, but the map operation can change the
length of the list in non-simplistic ways:
E:\Home\asu1\Src\Test> t1.pl
$VAR1 = [];
E:\Home\asu1\Src\Test> t1.pl
$VAR1 = [
'5',
'5',
'5',
'5',
'5',
'5',
'5'
];
E:\Home\asu1\Src\Test> t1.pl
$VAR1 = [
'5',
'5',
'5',
'5'
];
Sinan
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)
comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
Re: Readline using foreach and while
am 29.03.2008 18:29:00 von Uri Guttman
>>>>> "s" == szr writes:
s> Well that's basically how I understand it. In fact it seems you
s> basically restated the same thing in a different way. 1) the expr/block
s> is executed once per cycle. Yep. 2) The end result is something that is
s> a grouping, whether singular (say, a simple list) or more complex (like,
s> say, a hash key/value pair), of the same amount of elements in the input
s> list.
you keep saying grouping and that is the wrong way to think about
it. drop that word from this concept. map generates ONE list. how it
gets there is irrelevent so there is no grouping.
>> but there are no 'pairs' in the list except by the context of
>> assigning the list to a hash.
s> I'm sorry, but I really have to disagree here. A hash is essentially a
s> list divided into pairs (keys and values, respectively), and `map { $_
s> => s> 1 }` is creating such a pair in a statement like that.
no. a hash creates the pairs when it is assigned a list. the map just
generates a list with no real 'pairs'. you may think they are there but
they are not pairs yet. you have to separate what the map does from what
the hash expects.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
Re: Readline using foreach and while
am 29.03.2008 21:39:15 von szr
A. Sinan Unur wrote:
> "szr" wrote in
> news:fslqmd01gvu@news2.newsguy.com:
>
>> Uri Guttman wrote:
>>>>>>>> "s" == szr writes:
>>>
>>> >> Absolutely not. my %h = map { $_ => 1 } qw/a b c/; is quite a
>>> common >> idiom.
>>>
>>> s> Well, you're still getting that many *sets* which is probably
>>> what I s> should of said, or have been clearer. In that example,
>>> you get 3 set of s> hash pairs resulting from the 3 element
>>> list. The point is you get s> count_of_passed_list amount of
>>> something from the map, in some form or s> another. How exactly
>>> it's returned is determined by the template inside s> the map.
>>>
>>> you are still missing the picture. map can return ANY number of
>>> elements (not sets). it executes its expression/block once for
>>> each input element but that can generate 0-?? elements which are
>>> appended to the return list.
>>
>> I understand, but still, whatever is being generated to the LHS of
>> map, it's done that many times are there are elements in the list
>> on the RHS. Is that fair to say?
>
> If I understand you correctly, yeah, that's fine to say.
>
> On the other hand, you might find the following example instructive:
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Data::Dumper;
>
> my @result = map { split // } ( '5' x rand(10) ) ;
>
> print Dumper \@result;
>
> __END__
>
> Note that, the RHS is always a single element list. On the other hand,
> the number of elements in the result of map is variable. So, yes, the
> operation inside the block is only carried out once, what you are
> saying is fair in that sense, but the map operation can change the
> length of the list in non-simplistic ways:
Nice example. And yes, this does go with my point. Perhaps I should of
said, the number of elements on the RHS dictates how many passes map
will make. In this case, it's indeed once, where split creates the list
(in fact the map statement is obviously redundant, but I see your
point.)
Thanks.
--
szr