[% setvar title Simple assignment lvalue subs should be on by default %]

This file is part of the Perl 6 Archive

Note: these documents may be out of date. Do not use as reference!

To see what is currently happening visit http://www.perl6.org/


Simple assignment lvalue subs should be on by default


  Maintainer: Nathan Wiger <nate@wiger.org>
  Date: 24 Aug 2000
  Last-Modified: 25 Sep 2000
  Mailing List: perl6-language-subs@perl.org
  Number: 154
  Version: 2
  Status: Frozen


Currently, there are several competing RFC's for lvalue subs, all of which do things a little differently to please different groups.

This RFC proposes a means by which they can mostly coexist peacefully, simply by making simple assignment-only lvalue subs the default.


Unfortunately, there was no chance for people to attempt to reach consensus on the complicated subject of lvalue subs. The author feels that this RFC has some nice syntactic advantages. However, implementing it would be "tricky", to say the least, since it essentially requires a specialized fake-rvalue-context-bubble-inside-true-lvalue-context for the sub to be evaluated in. As such, it may not be feasible. However, if it were feasible it would be, in the author's opinion, really cool.


Simple lvalue subs

RFC's 107 proposes a very simplistic lvalue sub mechanism which seeks to make lvalue and rvalue subs more or less directly equivalent. While nice, this is truly only suitable for assignment. Still, this approach provides powerful capabilities:

   $cgi->param($name) = @newval;
   $oldpath = $tree->path('L','R') = 'R';
   @document = ($title, $junk, $r->xml_extract) = <STDIN>;

Here, assignment can be used to dynamically call subs in lvalue and rvalue contexts, allowing powerful syntactic constructs. This presents functionality akin to tie, without all the unnecessary overhead or pain tie involves.

This RFC proposes that this capability be on by default. No :lvalue constraint would be required. Instead, the sub would obey the exact same rules as an rvalue sub, including sub parameters, @_, scoping, and so forth:

   package CGI;
   sub param ($var, @val) {
       # do stuff

   $r = new CGI;
   $r->param($var, @val);      # ok
   $r->param($var) = @val;     # ok too
   $r->param = $var, @val;     # ok, but silly looking

The key to the proposal is this: lvalue and rvalue versions of a sub would work identically, and both would be enabled by default. However, assignment is the only valid operator for these default lvalue subs. Attempts to use other operators, such as ++ or s/// on these subs would yield an error like:

   Attempt to modify simple lvalue sub, only = is allowed

Even with this restriction, lvalue subs in this format give us lots of syntax advantages. As users, not only are we allowed to choose which form suits a given situation:

   $cgi->param($name) = split /\s+/, "Nathan Wiger";
   ($user, $r->uid('anon')) = @data;

But it also allows you to chain subs together, as you can do in Perl 5 with basic data types and even tied variables:

   @htmldoc = ($title, $r->htmlify) = <FILE>;

If overused, this could be gross. However, if used properly this greatly increases the amount of Laziness and Impatience you can have as a Perl programmer. The above example would require at least 2-3 lines with several "in-betweener" variables in Perl 5. [1] As written, it's quite readable and obvious what it does.

Complex lvalue subs

Damian has an upcoming RFC on this topic, and it is being widely discussed. These complex lvalue subs should have several properties differentiating them from the simple lvalue subs described in this RFC:

   1. True lvalue scoping

   2. Ability to accept any operation

   3. Return an lvalue which is then evaluated like any
      other lvalue

These complex subs are outside the scope of this RFC. However, these would be enabled with the :lvalue constraint, indicating that they are fundamentally different from rvalue subs.

By using the :lvalue constraint on these fundamentally different subs, we can allow both the simple and complex lvalue subs to coexist.


Enable lvalue and rvalue versions of subs to be used interchangeably by default. Everything about the two (including scoping) should be identical.


None. This introduces new functionality, and since it does not require the use of an :lvalue constraint requires no code translation.


[1] Or unreadable syntactic sugar. Take your pick. Either way it's nastier than the example of chained lvalue subs presented.


RFC 107: lvalue subs should receive the rvalue as an argument

RFC 57: Subroutine prototypes and parameters