develooper Front page | perl.perl6.language | Postings from May 2005

Re: (1,(2,3),4)[2]

Thread Previous | Thread Next
May 27, 2005 06:44
Re: (1,(2,3),4)[2]
Message ID:
Markus Laire wrote:
>>>> @m[0;1] is a multidim deref, referencing the 4.
>>> Referencing the 2, I hope?
>> Doh!
>> Yes, the 2.
> Really?

I consider this puzzling indicative that the (,) vs. [,] distinction
in Perl6 falls into the same category as e.g. starting the capture
variables at $1.

> @m here has _single_ array-ref so
> @m[0] returns that single array-ref - [[1,2],[3,4]]
> @m[0;1] then returns array-ref [3,4]
> @m[0;0] would return [1,2]
> @m[0;0;1] would return 2

Yea, that's the---in my eyes unfortunate---preservation of
reference level depending on the left side of assignment.
Or stated the other way round, the auto-referencing when
the lhs is a $ variable. BTW, are lvalue subs handled the
same as $ vars here?

Could the ones who know it, enlighten me *why* it has to be so?
What does it buy the newbie, average, expert Perl6 programmer?
The answer "that's how Perl5 did it" is a good default, but
never hindered @Larry to change things.

Here are some speculations from me:

1) On one hand @a shall be a single handle to an array but
    always writing a total slice, or flattener when you want
    to replace the array as a whole is considered cumbersome
    or redundant. Thus @a = 1 is basically a shortcut for
    @a[] = 1 or *@a = 1.  Note that for keeping some of the
    existing values one has to use a non-total index/slice
    like @a[42] = 1.

    Question: With @a = (0,1,2,3,4,5), what does @a[2..4] = 7 mean?
    @a == (0,1,7,5)? @a == (0,1,7,7,7,5)? I think it's the former,
    and the latter actually is written @a[2..4] »=« 7.
    How about: @a[1] = @b? Is that storing a ref to @b in @a at
    position 1? Then @a[1] = 23 puts the 23 into @b at position 0?
    So to get it back one has to use @a[1][0]?

2) Since a distinction between (,) and [,] for arrays and
    ( => , => ) and { => , => } for hashes is /syntactically/ possible
    it is used to separate values from refs. But context spills
    over from the lhs, though. I wouldn't unify these directly but
    through the following typing:

      (,)         --> Eager  (but not flattening nested Lazy stuff)
      ..          --> Lazy
      =>          --> Pair
      ( => , => ) --> Eager of Pair
      []          --> Array  (this actually doesn't need the comma op)
      {}          --> Hash   (actually Code, but evaluated immediately if
                              recognizeable at compile time)

3) The example in 1) might actually be wrong if @a = 1 sets
    the size of the array. I see a tendency in perlkind to
    have special cases like "it's a number assigned to an array,
    so the size changes". The assignment is smutten with these
    special meanings because an imperative language is built
    around it. E.g. ($x,$y) = (1,2) falls in this category as
    well. In a purer setting it could be required to write
    ($x,$y) »=« (1,2) as it is for ($x,$y) »+« (1,2). Hmm,
    then this is ultra-pure: @a[] »=« (1,2,3). Note that when @a
    always denotes a single handle @a »=« (1,2,3) could be expanded
    to (@a = 1, @a = 2, @a = 3) not (@a[0] = 1, @a[1] = 2, @a[2] = 3).

4) I guess not many want @a = \1 to be valid. But why not?
    &prefix:{'\'}:( Any $x : --> Ref of $x.type ) could build
    an anonymous Ref of Int and then that is assigned to the
    array on the left making it "two-dimensional" because of the
    reference. Thus getting back the 1 needs one of the following
    forms: @a[0][0], @a[0][], *@a[0] or $@a[0]. The first three forms
    assume that &postcircumfix:<[ ]> is supported by the Ref type.

I'm still arguing in favor of a---possibly strictly compiler enforced---
least upper bound typing of plain sigil expressions:

   & --> Code
   $ --> Item   (if that is the name now)
   @ --> Array
   % --> Hash

The strict type enforcement would prevent things like

   @foo = sub (Int $x) { return $x * $x }
   say @foo(13);  # prints 169

OTOH without it, going almost sigilless would just be

   my &foo = 3;
   my &bar = "HaloO";

   if foo < 2 { say bar }

   my &array is Array;

   array[12] = 17;

My line of thought might actually be easier to understand if
you treat = as a normally dispatched infix operator without any
special significance. The two operators ::= and := are *not*
dispatched. They are macros or a direct part of the grammar.
::= is mostly syntactic sugar for a BEGIN block and := is basically 
compiled to the engine level destructive assignment operation.
But this view might also be completely wrong.

TSa (Thomas Sandlaß)

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About