Why isn't grep an l-valued function? 
Author Message
 Why isn't grep an l-valued function?



~>Can't modify grep iterator in scalar assignment ...

Why is this illegal?  I know it's easy to convert that
into a real slice:



I'm just wondering if there is a problem with making grep
work just like substr() does for scalars.

Thanks.
--
Joe Schaefer



Sun, 16 May 2004 21:36:59 GMT  
 Why isn't grep an l-valued function?

Quote:



> ~>Can't modify grep iterator in scalar assignment ...

what do you think grep does?

Quote:
> Why is this illegal?  I know it's easy to convert that
> into a real slice:



over which it iterates is a list of indices.  the replacement
of elements is done by the array slice, not grep.

Quote:

> I'm just wondering if there is a problem with making grep
> work just like substr() does for scalars.

grep isn't like substr.  perhaps you wanted splice().

--

CGI Meta FAQ - http://www.perl.org/CGI_MetaFAQ.html
Troubleshooting CGI scripts - http://www.perl.org/troubleshooting_CGI.html



Sun, 16 May 2004 23:54:06 GMT  
 Why isn't grep an l-valued function?
On 28 Nov 2001 15:36:59 -0500,

Quote:



> ~>Can't modify grep iterator in scalar assignment ...

> Why is this illegal?  I know it's easy to convert that

Because grep operates on a list, not an array. You can't modify a
list. How would


work if grep produced an lvalue array? and where would this array be
stored?

Quote:
>                       I know it's easy to convert that
> into a real slice:




But here the changes are made by the array slice, as you obviously
know. Grep is only used to produce a set of indexes into that array.

Quote:
> I'm just wondering if there is a problem with making grep
> work just like substr() does for scalars.

Mainly because grep needs to work with lists, and lists are not
modifiable. The scalar that goes into substr is a modifiable value, or
if it isn't, you get an error. Functions that can be used as lvalues
need to operate on an lvalue, which should be either a scalar (e.g.
substr) or an array (e.g. splice), or possibly a hash (keys is an
lvalue operating on a hash, but in a different way).

I don't think it would be possible to allow grep to work in the way
you want it to without changing its semantics, and breaking quite a
few things along the way. grep has to be able to operate on lists, I
think.

Martien
--
                                |
Martien Verbruggen              | I'm just very selective about what I
Trading Post Australia Pty Ltd  | accept as reality - Calvin
                                |



Mon, 17 May 2004 01:06:03 GMT  
 Why isn't grep an l-valued function?

Quote:

> Because grep operates on a list, not an array. You can't modify a
> list. How would


> work if grep produced an lvalue array? and where would this array be
> stored?

Thanks for responding- I think you've understood what I'm trying to do.

  ($a,$b)        = "foo";   # OK
  (1, $b)        = "foo";   # can't modify constant item in list assign
  ( (1,$b)[-1] ) = "foo";   # can't modify list slice in list assignment

The errors here are compile-time errors, so I guess perl needs to
know all about the elements in the LHS's *list* at compile time.  I think
I'm starting to see why grep can't work the way I'd like, since a list
slice won't even work this way.

[...]

Quote:
> I don't think it would be possible to allow grep to work in the way
> you want it to without changing its semantics, and breaking quite a
> few things along the way. grep has to be able to operate on lists, I
> think.

  % perl -wle 'print ++$_ for grep $a++, ($a, 2*$a, $a, 0)'
  Use of uninitialized value in multiplication (*) at -e line 1.
  1
  5
  Modification of a read-only value attempted at -e line 1.

I'm very happy with the way grep builds a list of scalars; the
outcome above is ok by me.  I was just wondering why you can't
use the resulting list on the LHS of an assignment.

It looks like the reason is that the list elements need to be known
to perl at compile-time, which isn't really possible with list slices
or grep().

--
Joe Schaefer             "Life is just one damn thing after another."
                                               --Mark Twain



Mon, 17 May 2004 01:54:40 GMT  
 Why isn't grep an l-valued function?

Quote:


>> ~>Can't modify grep iterator in scalar assignment ...

>> Why is this illegal?

>Because grep operates on a list, not an array. You can't modify a
>list. How would


>work if grep produced an lvalue array? and where would this array be
>stored?

That doesn't make sense. The argument between parens for a foreach
command, is a list too, yet you can still modify it.



            $_ = ++$i;
        }

This works: every value, i.e. every array item and every scalar
variable, will be modified.

It works with slices, too.

The reason why it doesn't work with grep, is IMO incidental: grep()
doesn't return a list of Lvalues, *that* is the problem. But so far,
nobody has ever requested that feature, I think, I don't think many
people have even tried to use it. Perhaps there are even speed
considerations against it. Funny, the $_ alias in the grep block *is* an
Lvalue.

--
        Bart.



Mon, 17 May 2004 02:31:47 GMT  
 Why isn't grep an l-valued function?
On Thu, 29 Nov 2001 01:31:47 GMT,

Quote:


>>> ~>Can't modify grep iterator in scalar assignment ...

>>> Why is this illegal?

>>Because grep operates on a list, not an array. You can't modify a
>>list. How would


>>work if grep produced an lvalue array? and where would this array be
>>stored?

> That doesn't make sense. The argument between parens for a foreach
> command, is a list too, yet you can still modify it.



>        $_ = ++$i;
>    }

> This works: every value, i.e. every array item and every scalar
> variable, will be modified.

But you modify the individual elements of the list, not the list
itself. The suggested (grep) approach is an assignment in list
context, which is a different beast, IMO.

Quote:
> It works with slices, too.

> The reason why it doesn't work with grep, is IMO incidental: grep()
> doesn't return a list of Lvalues, *that* is the problem. But so far,
> nobody has ever requested that feature, I think, I don't think many
> people have even tried to use it. Perhaps there are even speed
> considerations against it. Funny, the $_ alias in the grep block *is* an
> Lvalue.

Even if it did, it couldn't do what the original intent was. To be
able to do that, it would need to return a list of _aliases_ to the
original elements of the list. To reiterate that:

It was asked why



Does not behave, or couldn't be made to behave like:


which produces


If grep suddenly started returning aliases, many things could go very
strange.

This would be a consequence of it:

$b[0] = 3;


I suspect that grep could be made to return a list of aliases only if
used as an lvalue function, but that would, IMO only be confusing. And
besides that, what would be the result of:


Martien
--
                                |
Martien Verbruggen              | Hi, Dave here, what's the root
Trading Post Australia Pty Ltd  | password?
                                |



Mon, 17 May 2004 03:07:31 GMT  
 Why isn't grep an l-valued function?

Quote:

>If grep suddenly started returning aliases, many things could go very
>strange.

>This would be a consequence of it:



>$b[0] = 3;



Yup, you're right. I hadn't thought of that. But you are absolutely
right. And we can't have that.

--
        Bart.



Mon, 17 May 2004 03:34:54 GMT  
 Why isn't grep an l-valued function?

Quote:


> >If grep suddenly started returning aliases, many things could go very
> >strange.

> >This would be a consequence of it:



> >$b[0] = 3;


> Yup, you're right. I hadn't thought of that. But you are absolutely
> right. And we can't have that.

OK- now I'm confused again.  Here's what the documentation for grep
says:

       grep BLOCK LIST
       grep EXPR,LIST

       [...]
               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.

So grep *already* returns a list of aliases, right?  Why do

--
Joe Schaefer   "There is nothing so annoying as to have two people talking when
                                  you're busy interrupting."
                                               --Mark Twain



Mon, 17 May 2004 03:48:19 GMT  
 Why isn't grep an l-valued function?
On 28 Nov 2001 21:48:19 -0500,

Quote:


>> >If grep suddenly started returning aliases, many things could go very
>> >strange.

>> >This would be a consequence of it:



>> >$b[0] = 3;


>> Yup, you're right. I hadn't thought of that. But you are absolutely
>> right. And we can't have that.

> OK- now I'm confused again.  Here's what the documentation for grep
> says:

>        grep BLOCK LIST
>        grep EXPR,LIST

>        [...]
>                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.

> So grep *already* returns a list of aliases, right?  Why do


Well, look at that... That is interesting. I never saw that bit, but
it seems to be true:




__END__
10 2 30 4
10 30


copies. However, this is not because grep returns copies, but because
of the assignment operation.

Let me think for a bit about this.

Ok... I think I need to retract everything I said before, both in
response to your post, and Bart Lateur's. Apart from the fact that
grep is not an lvalue function, I don't see any reason why

$b[0] = 12;

shouldn't be able to be made to result in



Martien
--
                                |
Martien Verbruggen              | Unix is the answer, but only if you
Trading Post Australia Pty Ltd  | phrase the question very carefully
                                |



Mon, 17 May 2004 04:09:51 GMT  
 Why isn't grep an l-valued function?
On 28 Nov 2001 21:48:19 -0500,

Quote:


>> >If grep suddenly started returning aliases, many things could go very
>> >strange.

>> >This would be a consequence of it:



>> >$b[0] = 3;


>> Yup, you're right. I hadn't thought of that. But you are absolutely
>> right. And we can't have that.

> OK- now I'm confused again.  Here's what the documentation for grep
> says:

>        grep BLOCK LIST
>        grep EXPR,LIST

>        [...]
>                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.

> So grep *already* returns a list of aliases, right?  Why do


Well, look at that... That is interesting. I never saw that bit, but
it seems to be true:




__END__
10 2 30 4
10 30


copies. However, this is not because grep returns copies, but because
of the assignment operation.

Let me think for a bit about this.

Ok... I think I need to retract everything I said before, both in
response to your post, and Bart Lateur's. Apart from the fact that
grep is not an lvalue function, I don't see any reason why

$b[0] = 12;

_couldn't_ be made to result in



Of course, on the other hand, I don't feel it fits the semantics of
grep very well to have it behave this way. It's almost like grep or
map in a void context, i.e. it isn't what grep is meant to do. I doubt
that anyone will want this changed, even though it may be possible.

Martien
--
                                |
Martien Verbruggen              | Unix is the answer, but only if you
Trading Post Australia Pty Ltd  | phrase the question very carefully
                                |



Mon, 17 May 2004 04:20:15 GMT  
 Why isn't grep an l-valued function?


Quote:
>Even if it did, it couldn't do what the original intent was. To be
>able to do that, it would need to return a list of _aliases_ to the
>original elements of the list.

So are you saying Perl handles things in such a way that it's not
possible to return a list which is itself an lvalue?  A list whose
elements are all lvalues isn't the same idea as a list that itself is
an lvalue.

Anyway, I now present lvgrep():

        #! /packages/perl-5.6.1/bin/perl


        {
            my $code = shift;


            my $index = 0;


            {

                $index++;
            }


        }

        # try it with an array



        # try it with a list
        ($x, $y, $z) = 1 .. 3;
        (lvgrep { $_ % 2 } $x, $y, $z ) = a .. z;
        print "\$x, \$y, and \$z:  $x $y $z\n";

It's not the most beautiful thing imaginable, but it works:

        $ ./lvgrep.pl

        $x, $y, and $z:  a 2 b
        $

Hmm.  Why was it again that anyone would ever actually want to use
this?

  - Logan
--
"In order to be prepared to hope in what does not deceive,
 we must first lose hope in everything that deceives."

                                          Georges Bernanos



Mon, 17 May 2004 04:44:39 GMT  
 Why isn't grep an l-valued function?

Quote:

>Ok... I think I need to retract everything I said before, both in
>response to your post, and Bart Lateur's.

I hate  to admit that I was wrong about being wrong. This is all too
confusing. Now if that's not a good enough reason to stay away from
it... :-)

Anyway, if grep returns a list of lvalues, there's not really a reason
why you shouldn't be able to assign to it. Except for the list I gave
earlier: nobody ever asked for this feature (until now), or it might be
slower when implemented, or... or?

--
        Bart.



Mon, 17 May 2004 04:50:44 GMT  
 Why isn't grep an l-valued function?
On 28 Nov 2001 21:44:39 -0600,

Quote:


>>Even if it did, it couldn't do what the original intent was. To be
>>able to do that, it would need to return a list of _aliases_ to the
>>original elements of the list.

> So are you saying Perl handles things in such a way that it's not
> possible to return a list which is itself an lvalue?  A list whose
> elements are all lvalues isn't the same idea as a list that itself is
> an lvalue.

A list isn't the same as an array or array slice :) But it doesn't
really matter, since all that is really required for this to work is
that a list of lvalues is returned. We're not assigning to the 'list',
but to the individual elements of it. The whole list thing is a red
herring, which is my fault.

If grep was an lvalue function, it could probably arrange for things
to be handled in very much the same way as your subroutine does
(which, BTW, is quite nice).

Quote:
> Anyway, I now present lvgrep():

>   #! /packages/perl-5.6.1/bin/perl


>   {
>       my $code = shift;


>       my $index = 0;


>       {

>           $index++;
>       }


>   }
> It's not the most beautiful thing imaginable, but it works:

And it also neatly returns a list of (expected) values:




And it even returns a list of aliases to the original elements, just
like grep:






2 2 6 4 10 6 14 8 18 10
2 6 10 14 18
2 2 6 4 10 6 14 8 18 10
2 6 10 14 18

Pretty cool.

Quote:
> Hmm.  Why was it again that anyone would ever actually want to use
> this?

Semantics, maybe. Assigning to a grep is just... well.. weird. But
that may be unfamiliarity :)

Does anyone have a real-world use for this?

Martien
--
                                |
Martien Verbruggen              | I took an IQ test and the results
Trading Post Australia Pty Ltd  | were negative.
                                |



Mon, 17 May 2004 06:03:45 GMT  
 Why isn't grep an l-valued function?
On Thu, 29 Nov 2001 03:50:44 GMT,

Quote:

>>Ok... I think I need to retract everything I said before, both in
>>response to your post, and Bart Lateur's.

> I hate  to admit that I was wrong about being wrong. This is all too
> confusing. Now if that's not a good enough reason to stay away from
> it... :-)

> Anyway, if grep returns a list of lvalues, there's not really a reason
> why you shouldn't be able to assign to it. Except for the list I gave
> earlier: nobody ever asked for this feature (until now), or it might be
> slower when implemented, or... or?

The only reference I can find (after an admittedly less than thorough
search) in the p5p archives is a bug report by Tom Phoenix (hi Tom,
where are you?) for 5.002, which is about the return values of grep,
and its peculiarities:

http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/9612/msg01736....

Excerpt from message:

Quote:

> generated with the help of perlbug 1.13 running under perl 5.002.

> The grep function seems to be returning a slice of the original list,
> as modifying the return value modifies the list itself. Note that this
> is not at all the same as the well-known, documented aliasing of $_ to
> each element during the test operation.    


> This is not documented in (my copy of) perlfunc(1) under grep(). At
> least, not the way I read the docs. :-)

> I don't really have a problem with the behavior, although fixing it
> wouldn't be bad, either. Fixing it shouldn't break anybody's code,
> should it? Of course, leaving it in could allow some cool hacks,
> especially if we can make grep an lvalue. Hmmm....

> I can't tell whether this is the same as NETaa15198 in the bug
> database.  It may be that they're tightly related, though. I also
> haven't been able to test this on the latest development release.

Note that there is a mention of grep as a possible lvalue. I don't
know if there have been other discussions of this in other places.

Martien
--
                                |
Martien Verbruggen              | Little girls, like butterflies, need
Trading Post Australia Pty Ltd  | no excuse - Lazarus Long
                                |



Mon, 17 May 2004 06:16:27 GMT  
 Why isn't grep an l-valued function?

Quote:



> ~>Can't modify grep iterator in scalar assignment ...

> Why is this illegal?

Firstly grep is only l-valued in a list context so it should read:


Secondly there are bugs in the Perl compiler that trigger spurious
'cant modify' errors at compile time for many inbuilt l-valued
functions.  The above is one such case.  I can't recall if this bug
already has a perlbug ID.  I definely recall posting here about it
when I discovered it a while back.

Quote:



Here's a generic workround to suppress these errors on list l-valued
inbuilt functions:





Quote:
> I'm just wondering if there is a problem with making grep
> work just like substr() does for scalars.

ISTR if you simply hack the compiler to remove these spurious
compile-time errors the code runs just fine.

--
     \\   ( )
  .  _\\__[oo

 .  l___\\
  # ll  l\\
 ###LL  LL\\



Mon, 17 May 2004 09:42:44 GMT  
 
 [ 20 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Lvalue-ness of 'values' function

2. Perl isn't intended to be what it isn't (Was: read(THIS) || die)

3. Lvalues revisited: what's *not* an lvalue?

4. Why isn't it local?

5. Comma operator: why isn't this working?

6. Why isn't Perl highly orthogonal?

7. Why isn't this a race condition ?

8. Why isn't Perl highly orthogonal?

9. Why isn't this code working?

10. Why isn't this working?

11. Why the Win32::GD isn't Working?

12. Why isn't this a slice?

 

 
Powered by phpBB® Forum Software