* Larry Wall <[EMAIL PROTECTED]> [05/08/2001 09:36]:
>
> Taking history into account is good, though I'd argue that now is the
> proper time to change history, if we're going to change.  Perl would
> never have been accepted in the first place had it been too different
> from what came before, but now that Perl has its own momentum, we can
> now look at how our own history gets in our way, and maybe do something
> about it.

Very true. To this end I just would add that I think many JAPHs are used
to and like <> as readline. I know I do. I'm not going to harp on this
point endlessly, but this is one aspect that I do like about Perl. And
keep in mind that unlike "->" vs "." , *everyone* knows about <FILEHANDLE>.
It is as pervasive as $ and @.

That being said, I'm open to the idea of simply replacing <> with < and
tweaking the semantics a little. For one thing, it's a char shorter. For
another, there's a > equivalent. So:

   $x = <$STDIN;        # "read" from STDIN.more

So < could mean "more" and > could mean "less". Or something like that.
Whether or not > was implemented in 6.0 is unknown, but having that
analogous functionality may be interesting.

   @a = <$STDIN[0..3];  # @a = ($STDIN.more)[0..3]
   @b = >$STDIN[0..3];  # @a = ($STDIN.less)[0..3]

"more" and "less" could be inverses, "more" reading from the current
position forward and "less" from the current position backwards. This 
notion could be generalized to files/networks/stacks/datastructs/etc/etc.

> I think someone mentioned qh() for "hash".  That's a possibility, but I'd
> still love to have enough brackets to give all of these standard shortcuts.

It is worth noting that qr// has no true shortcut. That is these:

   $x = /\w+/;
   $x = "\w+";

Are definitely not the same as this:

   $x = qr/\w+/;

I also think that looking at qr// or qw// as being in the same class as
qq// is not 100% accurate. Really, qw// is a special type of q// that
also splits on whitespace.

> : > We don't actually have a good
> : > notation for forcing a scalar context yet, let alone a scalar context
> : > wanting a certain number of arguments.
> : 
> : Personally, I'd look at it differently. I don't think that getting a number
> : of arguments out of a scalar context makes sense. Rather, I think you need
> : to call a member function or do whatever to get a list, then lazily evaluate
> : that.
> : 
> :    @a = $STDIN;    # @a gets a single element - $STDIN
> :    @b = <$STDIN>;  # @b gets the entire contents of $STDIN
> :                    # iterations via calls to more()
> 
> You don't actually get the entire contents of $STDIN.  You get a value
> of $STDIN marked as a placeholder in the list assigned to @b, and that
> placeholder says the RHS requested expansion of this in a manner
> appropriate to the context supplied by the LHS.
>
> Assuming Perl 5 semantics of = continue, a similar thing will happen
> when you say:
> 
>     @a = @b;
> 
> or
> 
>     push(@c, @b);
> 
> Perl 6 might not put all the elements of @b on the stack as a temporary
> list.  Rather, it might just put \@b marked as expandable.  (It might
> also have to put some kind of copy-on-write lock on @b to keep it from
> changing out from under, depending on how lazy the assignment (or
> subroutine) actually gets about reading out the array.)

Nice.

> In this view, * and < could just be two different kinds of "expandable" flags.
> But I'm uncomfortable with that, because I'd like to be able to say
> 
>     lazy_sub(<$STDIN, <$STDIN, <$STDIN, <$STDIN)
>
> to feed four lines to lazy_sub without defeating the prototype, er,
> signature checking.  Maybe you have to us *<$STDIN to do both.  But that
> would probably say to slurp the whole rest of the file.

That would be my guess. Assuming < instead of <>, how about

   lazy_sub(<$STDIN[0..3]);     # same as ($STDIN.more)[0..3]
   lazy_sub(*<$STDIN);          # same as ($STDIN.more)[0..-1]

I would define * and < as:

   *      -     greedy glob/list flattener
   <      -     more iterator
   >      -     less iterator
 
All of those are unary, of course. 

> : Basically, <> is left as direct access to the iterator, but it's not
> : magically called except where it clearly make sense (and I don't think
> : normal variable manip like passing into subs and hashes should be in this
> : category).
> : 
> : >     $<$STDIN # Return one element regardless of context.
> : >      <$STDIN # Return number of element wanted by context.
> : >     @<$STDIN # Return all element regardless of context.
> : >
> : > or some other casting mechanism yet to be devised.
> : 
> : I'd do a variation on the above. Looking from a functional perspective:
> : 
> :      $STDIN.more          # context-dependent
> :     ($STDIN.more)[0..3]   # just selected elements (lazily)
> :     ($STDIN.more)[0..-1]  # forced all
> : 
> : Then we'd have the following shorcuts as a side-effect:
> : 
> :     <$STDIN>              # context-dependent
> :    (<$STDIN>)[0..3]       # just selected elements (lazily)
> :    (<$STDIN>)[0..-1]      # forced all
> : 
> : Seems to be easy and clean, without lots of new syntax.
> 
> I'd lose the parens, but yes, an official slice is one way to be explicit
> about context.  But in a way that defers the problem to the slice notation.
> What context would the following provide?
> 
>    <$STDIN>[somefunc()]

The same one that this would provide, I'd imagine:

   ($STDIN.more)[somefunc()]

Let's see how Perl 5 does that <code testing> ... ok, so taking a simple
localtime example:

   sub iter {
       return 0..2;
   }

   $full  = join '/', localtime;
   $slice = join '/', (localtime)[iter()];

   print "slice = $slice  (full = $full)\n";

That prints out:

   slice = 17/39/11  (full = 17/39/11/8/4/101/2/127/1)

"slice" is the first three elements of the return from localtime. So I
don't think we'd really have to mess with these semantics too much -
this seems to be what we're after. If we did that lazily, we'd probably
be there.

> : >     for ($iter) { ... }
> : 
> : This is tricky. I see two ways. First, you could expand more()
> : automatically, then go through its arguments. But I don't think that
> : necessarily makes sense. Consider in Perl 5:
> : 
> :    $a = \@b;
> :    for ($a) { ... }
> : 
> : This only gets one thing. And I know we're redoing semantics, but I think
> : this is sensible. I don't want auto-element-grabbing-conversion. If I want
> : to iterate, I think I want to say:
> : 
> :    for (<$iter>) { ... }                # whole thing ($iter.more)
> :    for ( ($iter.more)[0..4] ) { ... }   # lazy evaluation
> :    for my $n (<$iter>[0..4]) { ... }    # same thing
> 
> It's possible we're thinking of iterators wrong here.  Perhaps
> iterators should typically be stored in @iter, not $iter.  Then it's
> pretty obvious that
> 
>     for (@iter) { }
> 
> iterates, because it's in a list context.  I think iterator magic
> always works in list context, and never in scalar.  

Yes, that sounds excellent. And if you have a scalar object with a
more() method attached to it, you have to iterate it with <> (or
possibly < if we went that way).

> What we have to get
> away from is the notion that lists are always flattened immediately.
> They're not, unless you use unary * to force it.  Most lists will be
> passed around notionally in Perl 6, not physically.  That will allow
> 
>     @a || @b
> 
> to work regardless of whether it's in a scalar or list context.

Yes, I like this a lot. Passing $s, @a, and %h around as "special
objects" is the way to go, I think. 

   @c = @a || @b;
   print "The length of \@c is $(@c.length) with elements: '@c'\n";

   $FH = open "</path/to/file" or die "Can't open: $!\n";
   $FD = dup $FH;               # maybe more generic "clone"?
   print while (<$FD);          # iterate $FD.more
   close $_ for ($FH, $FD);     # close them both

Si?

-Nate


Reply via email to