Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Wiger

Nathan Torkington wrote:
 
 Not every subroutine corresponds to a method call exposing
 object-internal data.  Most of my subroutines *do* something and make
 no sense to be called lvaluably.  Explicit marking the compiler pick
 up assignments to non-lvaluable subroutines.  It makes sense to
 explicitly mark the rare cases (:lvalue), rather than the common
 (:no_assignment).

Well, this argument makes more sense. However, I still have to disagree.
In fact, I think the opposite: ALL subs *should* be lvaluable by
default. Here's why.

One word: CPAN (ok, an acronym :). Let's take CGI.pm as an example.
Currently, you can do this:

   $val = $cgi-param($name);# get the param 
   $cgi-param($name, $val); # assign a val

So, it seems the next logical extension would be this:

   $cgi-param($name) = $val;# assign a val

No problem. In fact, this fits under your rules. HOWEVER, it also
assumes that Lincoln thought that param() was :lvalue-worthy. What if he
forgot? Or didn't think of this case?

Worse, what if a somewhat novice writes a module and doesn't know about
:lvalue, or at least not how to use it. But an experienced user picks up
their module DoCoolStuff.pm on CPAN and tries it:

   use DoCoolStuff;
   $dcs = new DoCoolStuff;
   $dcs-main_matrix_name = "Bob";

Ooops! The author didn't use :lvalue. So even though this makes perfect
sense to be able to do, since the author forgot to use :lvalue, you lose
a really cool syntactic tool. This seems backwards. I, the user, want to
make this decision. There's no way a module author can possibly forsee
all the uses of a function, and they shouldn't have to.

Having lvalue subs that work just like rvalue ones is an invaluable
tool. This RFC is right on. The only way, though, that it's going to be
useful is if it works just like other assignment: automatically and
pervasively. For one thing, you can do this:

   @array = $r-func((split /:/, PASSWD));

Why not this?

   @array = ($r-func) = split /:/, PASSWD;

Might look weird at first, but it's not. It's just like any other
assignment. This surely doesn't look weird:

   @array = ($r-{func}) = split /:/, PASSWD;

And it works just fine in default Perl 5 with no special keywords. No
reason that dropping two {}'s should change this. If it does, then we're
losing valuable OO encapsulation and abstraction. In fact, a lot is
gained in making lvalue subs the default, because it makes things more
reliable and consistent.

lvalue subs are worth a lot more than just simple data accessor
functions. I don't see why we should force-relegate them to a background
role by requiring an :lvalue constraint that most people won't
understand how to use correctly. This is a perfect opportunity to make
an easy thing even easier.

-Nate



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Piers Cawley

Nathan Wiger [EMAIL PROTECTED] writes:
 Nathan Torkington wrote:
  Not every subroutine corresponds to a method call exposing
  object-internal data.  Most of my subroutines *do* something and make
  no sense to be called lvaluably.  Explicit marking the compiler pick
  up assignments to non-lvaluable subroutines.  It makes sense to
  explicitly mark the rare cases (:lvalue), rather than the common
  (:no_assignment).
 
 Well, this argument makes more sense. However, I still have to disagree.
 In fact, I think the opposite: ALL subs *should* be lvaluable by
 default. Here's why.
 
 One word: CPAN (ok, an acronym :). Let's take CGI.pm as an example.
 Currently, you can do this:
 
$val = $cgi-param($name);# get the param 
$cgi-param($name, $val); # assign a val
 
 So, it seems the next logical extension would be this:
 
$cgi-param($name) = $val;# assign a val
 
 No problem. In fact, this fits under your rules. HOWEVER, it also
 assumes that Lincoln thought that param() was :lvalue-worthy. What if he
 forgot? Or didn't think of this case?

Hmm... on a cursory glance at CGI.pm it would appear that just doing 

sub param : lvalue {

At the beginning of the param definition will make it Just Work(tm).
And if lvalue access were made the only way of doing assignment of
params in this context then a whole bunch of the code in param could
be removed.

-- 
Piers





Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Jonathan Scott Duff

On Wed, Aug 16, 2000 at 12:14:09AM -0700, Nathan Wiger wrote:
 No problem. In fact, this fits under your rules. HOWEVER, it also
 assumes that Lincoln thought that param() was :lvalue-worthy. What if he
 forgot? Or didn't think of this case?

Then you email him with a patch, and your reasons why your lvalue
patch should be applied.  If he likes it, it's included otherwise it's
not.  Don't second-guess the design decisions of module authors who
may have perfectly good reasons for doing things the way they do.

 Worse, what if a somewhat novice writes a module and doesn't know about
 :lvalue, or at least not how to use it. But an experienced user picks up
 their module DoCoolStuff.pm on CPAN and tries it:

Then that experienced user can patch the code and send email to the
novice explaining lvalue subs and why he should use them.

 Ooops! The author didn't use :lvalue. So even though this makes perfect
 sense to be able to do, since the author forgot to use :lvalue, you lose
 a really cool syntactic tool. This seems backwards. 

Seems right to me.  I'd rather assignment to a function work on
purpose rather than on accident.  If lvalue subs are the default, then
they "accidently" work where maybe they shouldn't.   Whether a sub
should be lvaluable should be a conscious decision made by the
subroutine author.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Wiger

 And if lvalue access were made the only way of doing assignment of
 params in this context then a whole bunch of the code in param could
 be removed.

Maybe this is the confusion. I'm not saying subs should ONLY be lvalue.
I think they should be both rvalue and lvalue at the same time.
Automatically. 

Did anybody look at this example?

@array = $r-func((split /:/, PASSWD));   # ok
@array = ($r-func) = split /:/, PASSWD;  # same thing

-Nate



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Andy Wardley

On Aug 16,  8:32am, Nathan Wiger wrote:
 Maybe this is the confusion. I'm not saying subs should ONLY be lvalue.
 I think they should be both rvalue and lvalue at the same time.

Point noted and understood, but I'm with the general consensus here.
Lvalue subs should have to be explicitly marked as such.  This could,
of course, be done automatically for you by a Cuse lvalue pragma, or
something similar, but it shouldn't be the default case.


A




-- 
Andy Wardley [EMAIL PROTECTED]   Signature regenerating.  Please remain seated.
 [EMAIL PROTECTED]   For a good time: http://www.kfs.org/~abw/



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Wiger

  Ooops! The author didn't use :lvalue. So even though this makes perfect
  sense to be able to do, since the author forgot to use :lvalue, you lose
  a really cool syntactic tool. This seems backwards.
 
 Seems right to me.  I'd rather assignment to a function work on
 purpose rather than on accident.  If lvalue subs are the default, then
 they "accidently" work where maybe they shouldn't.   Whether a sub
 should be lvaluable should be a conscious decision made by the
 subroutine author.

See, I don't see it as that big a deal, especially not if lvalue and
rvalue subs work identically. 

For example, here's code that works identically in Perl:

   @array = @array, func;   # ok
   push @array, func;   # same thing

Now, maybe someone would argue one is "more correct" or "better style"
than the other. However, TMTOWTDI.

That's all lvalue subs are. Remember, just because something's an lvalue
DOESN'T mean 2 key things:

   1. It's working like a variable
   2. It's all the way to the left

Please look at this example again:

@array = $r-func((split /:/, PASSWD));   # ok
@array = ($r-func) = split /:/, PASSWD;  # same thing

All that is to me is TMTOWTDI.

Now, we can argue forever that the second one is a bad STYLE. I would
probably agree. HOWEVER, we shouldn't be dictating style to the user,
which is all :lvalue does if lvalue and rvalue subs work identically.

I'm actually quite surprised that people are disagreeing with me on this
one. There's a lot of times when you could use cascading lvalue subs to
make things easier:

@result = ($first, $second, $r-fix_the_rest) = split /:/, PASSWD;

This would be at least 2 lines without a cascading lvalue sub, and less
clear:

($first, $second, @rest) = split /:/, PASSWD;
@result = ($first, $second, $r-fix_the_rest(@rest));

As an advanced Perl user, I want to be able to exploit such constructs
at will. I don't want others deciding programming style for me.

-Nate



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Jonathan Scott Duff

On Wed, Aug 16, 2000 at 08:40:18AM -0700, Nathan Wiger wrote:
 See, I don't see it as that big a deal, especially not if lvalue and
 rvalue subs work identically. 

Hrm.  Perhaps you aren't explaining yourself clearly.  Let's pretend
that there is a magical value called $LVALUE that contains the thing
being assigned.  Are you saying that in

somesub = $value;

the subroutine Csomesub, being lvaluable by default is free to use
or ignore $LVALUE?  If so, how does one detect errors?  When
Csomesub is ignoring $LVALUE the above would silently fail, yes?

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Torkington

Nathan Wiger writes:
 Well, this argument makes more sense. However, I still have to disagree.
 In fact, I think the opposite: ALL subs *should* be lvaluable by
 default. Here's why.

I think I failed to explain Damian's use of the word 'dangerous'.

  my $var;
  sub routine {
 $var;
  }

This, by virtue of rvalue subs being default, keeps the lexical $var
private.  Damian's big on privacy.

Your change would make privacy violation *automatic*.

That's dangerous.

 Might look weird at first, but it's not. It's just like any other
 assignment. This surely doesn't look weird:
 
@array = ($r-{func}) = split /:/, PASSWD;
 
 And it works just fine in default Perl 5 with no special keywords.

No it doesn't.  $r-{func} holds a scalar.  split will return the
number of fields, not the data.  This is irrelevant to your thesis,
though.

 lvalue subs are worth a lot more than just simple data accessor
 functions. I don't see why we should force-relegate them to a background
 role by requiring an :lvalue constraint that most people won't
 understand how to use correctly.

Now you're into rhetoric.

(1) It's not a background role.

(2) Changing variables in the subroutine's scope is a BIG THING, and
ought to be explicitly enabled, rather than explicitly disabled.

(3) :lvalue is hardly rocket science.  You drastically overstate its
complexity.

Nat



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Wiger

Nathan Torkington wrote:

  Then I think both of these should act exactly the same:
 
  somesub(@values);
  somesub = @values;
 
 EUGH.  No way!
 
 Assignment should be used to reflect (get this) assignment.  Using
 it as argument passing is disgusting.  I'm assuming you're not
 *advocating* this, merely pointing out that it's a side-effect of
 the RFC's suggested implementation.

Not in this ridiculously trite example, no. It's silly and stupid. And
misleading.

However, chaining together lvalue subs is a very useful shortcut:

   @output = ($title, $x, $f-xml_extract) = FILE;

Agreeably, this is not a 1:1 on the assignment front. But I'd like to be
able to do this. "Disgusting" is a matter of taste. :-)

As for the other arguments about "magical $LVALUE" stuff, I'm firmly
against those. I am 100% behind the RFC - everything should go into @_.
I just think the above is a useful extension that shouldn't be
overlooked. It's really powerful.

-Nate



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Torkington

Nathan Wiger writes:
 Nonetheless, I think a better thing would be to figure out if it's
 possible to "fix" this issue. I would *really* like lvalue subs ==
 rvalue subs.

I think conflating:
   foo(@vals)
and
   foo() = @vals

is misleading and going to cause more confusion that it solves.

 I strongly disagree with this. You know how many people have problems
 with my? Lots.

What kinds of problems can you possibly have with my()?

 The concept isn't that hard ":lvalue makes it so you can assign to
 subs". But the hard part is deciding *where* it should be used. I think
 it puts an unfair burden on a CPAN author to try and forsee all the
 possible uses of a sub.

My turn to strongly disagree.  Module programmers must decide on an
interface to that module.  Programmers wanting to use the module must
read its documentation to see what that interface is.  There might be
thousands of possible interfaces, and module authors are *NOT* under
any obligation to implement them all.  Lvalue subs do not change this.

 If the author doesn't forsee this, then I have to ask them to patch it.

No, you work with what you have.  Modules, like Perl, don't have to
be all things to all people.  This idea that it "ought to work" is
what's broken.

Here's what I want:

 * Andy's RFC on lvalue subs getting the rvalue as arguments reworked
   to account for the possibility of multiple rvalues.

 * A separate RFC saying what I want.

I'll write the separate RFC now.  Then we can shut up and let Larry
sort it out.

Nat



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Wiger

 I think conflating:
foo(@vals)
 and
foo() = @vals
 
 is misleading and going to cause more confusion that it solves.

In simple cases, yes. The above looks misleading. Advanced stuff like
chaining though would be really cool. I could come up with oodles of
examples. :-)

 What kinds of problems can you possibly have with my()?

You'd think that, eh? Not understanding what lexical scope means, where
the nearest block is, thinking that my() is per-package, etc, etc,
etc...

 No, you work with what you have.  Modules, like Perl, don't have to
 be all things to all people.  This idea that it "ought to work" is
 what's broken.

Sorry, I've done *way* too much work with user-interface research and
design to agree to an RTFM argument. This doesn't work for me. Not for
something as "simple" as assignment. Function names, DB interfaces, yes.
"=" (which is all people will see), no.
 
  * Andy's RFC on lvalue subs getting the rvalue as arguments reworked
to account for the possibility of multiple rvalues.

This sounds great to me.
 
I'm not trying to create a commotion. I'm just trying to contribute some
different (what I feel to be useful) angles to this discussion. Most
everyone on this list is an expert. Most Perl users aren't. Something
like this should "just work", consistently. Just like all other forms of
assignment.

-Nate



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Graham Barr

On Wed, Aug 16, 2000 at 01:51:09PM -0600, Nathan Torkington wrote:
 Nathan Wiger writes:
  Nonetheless, I think a better thing would be to figure out if it's
  possible to "fix" this issue. I would *really* like lvalue subs ==
  rvalue subs.
 
 I think conflating:
foo(@vals)
 and
foo() = @vals
 
 is misleading and going to cause more confusion that it solves.

Yes, how will the sub be able to tell between

  foo(1) = 2;

and

  foo(1,2);

ie how does it know where its arguments stop and it's assignments start ?

Graham.



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread James Mastros

- Original Message -
From: "Jonathan Scott Duff" [EMAIL PROTECTED]
Sent: Wednesday, August 16, 2000 10:00 AM
Subject: Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs
should receive the rvalue as an argument)


 On Wed, Aug 16, 2000 at 12:14:09AM -0700, Nathan Wiger wrote:
  No problem. In fact, this fits under your rules. HOWEVER, it also
  assumes that Lincoln thought that param() was :lvalue-worthy. What if he
  forgot? Or didn't think of this case?

 Then you email him with a patch, and your reasons why your lvalue
 patch should be applied.
Or, if you prefer, patch your local copy without emailing Lincon.  Or do an
attributes(CGI::param) |= :lvalue; (assuming synthax that hasn't been
RFCed, but...)

However, I think that this can all be solved fairly simply, by intergrating
it with the other problem: that functions wouldn't be able to tell the
diference between their lvalue and rvalue values.

Now, I rather like Buddha Buck's solution, of making the lvalue attribute
take the variable name the rvalue should be passed in.  However, for those
still of the mind that all subs should be lvalueable, might I propose that a
sub foo, called as foo(@a) = @b gets its @_ as @a,@b, as proposed in the
RFC, with the twist that the elements of @b are passed with a :rvalue
attribute, so that foo can care if it wants to, but if it doesn't, the
lvalue call will "simply work" without any further ado.  Note also that this
means that :no_lvalue can be written in pure perl.

-=- James Mastros




Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Chaim Frenkel

 "NW" == Nathan Wiger [EMAIL PROTECTED] writes:

NW The concept isn't that hard ":lvalue makes it so you can assign to
NW subs". But the hard part is deciding *where* it should be used. I think
NW it puts an unfair burden on a CPAN author to try and forsee all the
NW possible uses of a sub.

I'm sorry but this doesn't make sense?

$foo-twiddle = 42;

What if twiddle is my scramble eggs routine? Why are you assigning a value.

The author decides how his routines are to be used. You the client likes
it great. You think there is a better _approach_ then tell the author.

You are limited by what the author wrote.

chaim
-- 
Chaim FrenkelNonlinear Knowledge, Inc.
[EMAIL PROTECTED]   +1-718-236-0183



Re: Make lvalue subs the default (was Re: RFC 107 (v1) lvalue subs should receive the rvalue as an argument)

2000-08-16 Thread Nathan Wiger

Jonathan Scott Duff wrote:

 Hrm.  Perhaps you aren't explaining yourself clearly.  Let's pretend
 that there is a magical value called $LVALUE that contains the thing
 being assigned.  Are you saying that in
 
 somesub = $value;
 
 the subroutine Csomesub, being lvaluable by default is free to use
 or ignore $LVALUE?  If so, how does one detect errors?  When
 Csomesub is ignoring $LVALUE the above would silently fail, yes?

That's similar to what I'm saying. If you had the sub:

sub somesub {
my(@stuff) = @_;
# do nothing
}

Then I think both of these should act exactly the same:

somesub(@values);
somesub = @values;

According to the RFC, the lvalue sub gets @values in @_ like an rvalue
sub. The two should walk and talk identically. (Scoping aside, see my
email to Nat). In this case, there's nothing special about lvalue subs,
so we should drop :lvalue.

I know that's not how 5.6 works, but it's what the RFC says. See what
I'm saying?

-Nate