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 [EMAIL PROTECTED] = 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][], [EMAIL PROTECTED] or [EMAIL PROTECTED] 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.

Regards,
--
TSa (Thomas Sandlaß)

Reply via email to