Re: Do slurpy parameters auto-flatten arrays?

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

Luke Palmer wrote:

On 8/3/05, Aankhen [EMAIL PROTECTED] wrote:


On 8/3/05, Piers Cawley [EMAIL PROTECTED] wrote:


So how *do* I pass an unflattened array to a function with a slurpy parameter?


Good question.  I would have thought that one of the major gains from
turning arrays and hashes into references in scalar context is the
ability to specify an unflattened array or a hash in a sub call
without any special syntax...


I thought that the obsoletion of special syntax stems from the
type system. Piers seems to have the same view. See his example
of map in his parallel reply.



Well, you can, usually.  This is particularly in the flattening
context.  In most cases, for instance:

sub foo ($a, $b) { say $a }
my @a = (1,2,3);
foo(@a, 3);

Passes the array into $a.  If nothing flattened by default, then you'd
have to say, for example:

map {...} [EMAIL PROTECTED];

And even:

for [EMAIL PROTECTED] - $x {...}

Which I'm not sure people want.  


Ups, I thought the for special form would work as follows.

0. the syntax: for expression block
1. determine (return) type of expression
2. create an iterator for that type
3. Use the iterator until it runs out (is that when it returns undef?)
4. bind the block owner to successive return values of the iterator
   and call the block; if the block is pointy bind its environment as
   well.

With the above

  for @a - $x {...}  # use Iterator of Array

and

  for [EMAIL PROTECTED] - $x {...}  # use Iterator of List

produc the same sequence of values in $x but through different
paths in type space. As long as no user defined types are involved,
I dought they are distinguishable at all.

Here's an idea how a sub becomes its own iterator:

   sub foo() does Iterator[foo]
   {
   random;
   }

   for foo() - $x { say }   # endless loop of random output

How are roles/types composed into Code subtypes?



And the way you pass an array in slurpy context as a single reference
is to backwhack it.  What it comes down to is that either you're
backwhacking things a lot or you're flattening things a lot.  Perl
currently solves it by making the common case the default in each
zone of parameters.


I would be interested to hear arguments to the contrary, however. 


OK, I gave my 0.02.
--
$TSa.greeting := HaloO; # mind the echo!


Re: If topicalization

2005-08-04 Thread Stuart Cook
On 8/4/05, Luke Palmer [EMAIL PROTECTED] wrote:
 How can that possibly work?  If a bare closure { } is equivalent to -
 ?$_ is rw { }, then the normal:
 
 if foo() {...}
 
 Turns into:
 
 if foo() - ?$_ is rw { }
 
 And every if topicalizes! I'm sure we don't want that.
 
 Luke


Here's one solution:

1) Bare blocks don't topicalise if you call them without an argument.

2) 'if' doesn't pass the value of the condition to its body, _UNLESS_
the body is incapable of accepting 0 arguments.


This means:

* The most common case, if foo() { ... }, won't topicalise.

* If you /really/ want to access the value of the conditional, you can
say one of:
if foo() - $_ { ... }# topicalise
if foo() - $cond { ... } # don't topicalise
and 'if' will give it to you.

* The bare-block-to-pointy-sub rewrite rule is preserved, because a
bare block's parameter is optional.

Is there anything I've failed to take into account?


Stuart


Re: zip with ()

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

Luke Palmer wrote:

On 8/1/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:


In general, (@foo, @bar) returns a new list with the element joined,
i.e. @foo.concat(@bar). If you want to create a list with two sublists,
you've to use ([EMAIL PROTECTED], [EMAIL PROTECTED]) or ([EMAIL PROTECTED], 
[EMAIL PROTECTED]). But of course, I could
be totally wrong. :)



I think that's right.  However, it might be a good idea not to
auto-enreference such bare lists:


I don't like this notion of auto enreference/dereference at all.
Either the type system manages to dispatch things correctly or
you get an error. For the List versus Array problem this dispatch
is IMHO decideable at compile time by strictly typing @ vars as
Array and subtypes thereof. The List type to me is a Code subtype
and as such travels in  vars. I'm only unsure how easily such
variables should enter name space, that is how they behave without
sigil.


sub foo ($x) {...}
foo (1,2,3,4,5);   # foo gets called with [1,2,3,4,5]


Yes, the $x makes foo an Item or even Value taker of arity 1.
The call foo (1,2,3,4,5) OTOH calls it with a List. This should
result in a type error. But sub foo (x) might then work for a List
but not for an Item|Value call foo(1).

Since I think that * in a signature is for extending the arity of
the sub to infinity I wonder if it is possible to capture the caller's
list into a single *$arg?

   sub foo (*$x) {...}
   foo (1,2,3,4,5); # type of $x is now Ref of List of Int?

But with an additional array the slurpy item gets at most one value.

   sub foo (*$x, [EMAIL PROTECTED]) {...}
   foo (1,2,3,4,5); # $x == 1; [EMAIL PROTECTED] == 4
   foo @array; # type of $x is now Ref of Array; @a is undef



When you could just as easily have said:

foo [1,2,3,4,5];

And we'll probably catch a lot of Perl 5 switchers that way.  That
actually makes a lot of sense to me.  The statement:

my $x = (1,2,3,4,5);

Looks like an error more than anything else.


Yep. I opt for type error Can't assign List to Item.
By the same token I would disallow

  my @a = 3; # type error Can't assign Item to Array.

It should be

  my @a = *3;

or

  my @a = (3,);

Hmm, wasn't there a nullary *?

  my @a = *;
  say [EMAIL PROTECTED];  # prints 0



 That's the scalar
comma, which has been specified to return a list.  But maybe it
should be an error.


Sorry, I don't understand this.  I thought comma just is *the*
List constructor per se. Parens required to lift precedence :)
Same applies to semi-colon. (1,2,3;4,5,6) is a List of List of Int.



 The main reason that we've kept a scalar comma is
for:

loop (my $x = 0, my $y = 0; $x*$y = 16; $x++, $y++)
{...}

However, I think we can afford to hack around that.  Make the first
and last arguments to loop take lists and just throw them away.


My interpretation of the loop block controler special form is that
it gets a 4-tupel (Block,Block,Block,Block). The last one is of course
the loop's body. The first is the initializer that is executed in a
scope outside the body. The second and third are the condition and
the stepper and also scoped outside the body.

Now to the comma. It should be parsed as List of Block. In your example
the argument type of loop is (List of Block,Block,List of Block,Block).
The loop instanciates an Iterator[List of Block] and uses it to
execute the Blocks one at a time. The only special case is in the
condition which evaluates only the last Block from the List of Block
for truth and the others in Void context.

Is loop supposed to be a topicalizer? Does it bind the block owner?
Does a pointy body block make sense?

   loop (my $x = 0; $x  10; $x++) - {...}  # current count in $_?
   loop (my $x = 0; $x  10; $x++){...}  # $_ unchanged from outside?

   loop (my $x = 0; $x  10; $x++)
   {
   .blubber   # what is the invocant?
   }

Can the last Block also be separated with semi-colon? I guess not.
How about a Code var?

  loop my $x = 0; $x  10; $x++; say $x;  # works?

  loop my $x = 0; $x  10; $x++; foo; # works?

  loop( my $x = 0; $x  10; $x++; foo ) # perhaps as function call?

  loop
 my $x = 0;
 $x  10;
 $x++;

  say $x; # still the loop body? Or does it need { say $x }?

  loop foo; bar; blubb -
  {
  say  # prints return value of blubb while bar returns true
   # first iteration prints return value of foo
  }


 Can
anyone think of any other common uses of the scalar comma?


Not me. It's a C relict.
--
$TSa.greeting := HaloO; # mind the echo!


Re: Do slurpy parameters auto-flatten arrays?

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

Piers Cawley wrote:

By the way, if flattening that way, what's the prototype for zip? We can after
all do:

   zip @ary1, @ary2, @ary3, ... @aryn


How about

   sub zip( List [EMAIL PROTECTED] ) {...}

a slurpy List of Array of List. The return value is a
not yet iterated Code object that knows how to produce
tuples from the outer lists. This implies that zip(@array)
basically returns an unstarted iterator on @array.
--
$TSa.greeting := HaloO; # mind the echo!


TSa's Perl 6 type lattice version 1.0

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

in case someone might be interested, here is my more or less complete
idea of the Perl 6 type lattice as ASCII art.

Enjoy. Comments welcome.


::Any
...| ...
   ___:___/|\:_:
  |   :| :  |  |   static type :
   Package:| : Void  ?Bool   = context :
  |   :| :__|__|   :
Module:|/:.:
   ___|___:|
  |   |   :|
Class Grammar :|
  |___|   :|
  |   :|
 Role : Object Record =::= Frame =::= Dictionary
  :|
  : __/ \_
  with:|  || ||   |
  invocant(s) :  Code  $Item%Hash Frame@Array Tuple
  :|  ||_||___|
  block owner : topic  |  |   |
   $/ : $_ |  |   |
  :___/ \_ ___|   |
 |:  |\   |   ||  | |  |  |
  .Method : Sub\  -Block   \Ref Value  Undef  Inf  Junction  |
/|:  |\ \ ||  |
   / |:  | \ \  __||_ |
Rule |:  | Macro  \/  ||   |   | ||
 |:_/|Ref[Code]   |  :Pair  /Match/  ~Str  +Num   |
 |:  |||   | ||
   Multi  :  |||   |Int   |
..:  |||   |   / ||
 ||___  ___|   Enum  ||
 ||   \/ |   ||
 ||  Entry[::T.does(Hash)]  Bit  ||
_|__  |___  _||
   || |   \/  |
   =Iterator  *List   |  Pos[::T.does(Str|Array)] |
| |   |
|_   _|___|
   |  | ||\ / |
..Range  Pipe  Lazy  **Eager  Ref[Array|Hash] |
   |__|_||   _|
  \ /
   (to | all leafes)
  \|/
::All
--
$TSa.greeting := HaloO; # mind the echo!


Re: zip with ()

2005-08-04 Thread Larry Wall
On Mon, Aug 01, 2005 at 01:13:52PM +0200, TSa (Thomas Sandlaß) wrote:
: BTW, you didn't mean originally:
: 
:   say zip (@odd), (@even); # prints 13572468 or 12345678?

That doesn't work, since () in list context does not enforce scalar context.
It's exactly equivalent to

say zip @odd, @even;

which is also wrong, because zip is requires multidimentional slice
syntax.  Ordinary commas will be taken to separate items of the first
slice.  To separate slices requires semicolon or pipes.

: Does zip now interleave two array refs instead
: of flattened arrays?

No, but separating the arrays with comma doesn't work either, so Pugs
currently has it wrong.  The correct syntax will eventually be:

zip(@odd; @even)
zip @odd == @even

The parens are required only at the top statement level.  Inside other
bracketing structures you can omit the parens:

(zip @odd; @even)

just as in subscripts the semicolon separates multiple dimensions:

@[EMAIL PROTECTED]; @b]

Larry


$pair[0]?

2005-08-04 Thread Ingo Blechschmidt
Hi,

my $pair = (a = 1);
say $pair[0];  # a?
say $pair[1];  # 1?

I've found this in the Pugs testsuite -- is it legal?


--Ingo

-- 
Linux, the choice of a GNU | Black holes result when God divides the
generation on a dual AMD   | universe by zero.  
Athlon!| 



Re: undef.chars?

2005-08-04 Thread Luke Palmer
On 8/4/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
 Hi,
 
 (found in the Pugs testsuite.)
 
 my $undef = undef;
 say $undef.chars?   # 0? undef? die?
 say chars $undef;   # 0? undef? die?
 
 I'd opt for undef.chars to be an error (no such method) and chars
 undef to return 0 (with a warning printed to STDERR^W$*ERR).

Well, I think that chars $undef should be exactly equivalent to
$undef.chars.  In fact, I think it is: chars $undef is just the
indirect object form.

So perhaps method not found errors fail instead of die.

Luke


Re: $pair[0]?

2005-08-04 Thread Ingo Blechschmidt
Hi,

Luke Palmer wrote:
 On 8/4/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
 my $pair = (a = 1);
 say $pair[0];  # a?
 say $pair[1];  # 1?
 
 I've found this in the Pugs testsuite -- is it legal?
 
 Nope.  That's:
 
 say $pair.key;
 say $pair.value;
 
 Also:
 
 say $paira;  # 1
 say $pair{anything else};   # undef
 
 But we don't implicitly cast references like that.

thanks for clarification, that's what I've thought, too :)


--Ingo

-- 
Linux, the choice of a GNU | The next statement is not true.
generation on a dual AMD   | The previous statement is true.
Athlon!|



Data constructors / Unidirectional unification

2005-08-04 Thread Luke Palmer
I'm writing a new module that optimizes sets of conditions into
decision trees.  Initially I allowed the user to specify conditions as
strings, and if that condition began with a !, it would be the
inverse of the condition without the !.

But then I thought, the user will more than likely have condition
*objects* if the conditions are anything but trivial.  Then you can't
just put a ! on the front.  The way Haskell and ML do this is by
allowing data constructors: symbols that can take arguments and be
pattern matched against.  I thought that this was a particularly
elegant way to solve the problem, so I implemented it in the
Symbol::Opaque module.  Now I want it for Perl 6.

Here's my proposal.  Let's generalize the backtick from unit support
into data constructor support.  The following are equivalent:

4`meters
`meters(4)

The postfix form is only available for single-argument constructors,
but the prefix form can be used with more than one argument:

`foo(4, 5)

These things don't need to be declared, but you can use a data
declaration to give them a type (which does Symbol, the type of all
such constructors):

data Quux (`foo, `bar, `baz);

Now whenever you create a `foo, it is a Quux.  These can overlap:

data Foo (`baz);
data Bar (`baz);

A `baz object is now both a Foo and a Bar.  These could be easily
extended to allow type signatures, to come up with those nice
type-checked data structures that we're using for PIL.  But I'm not
proposing that part yet.

Here's what makes them so useful:  they can be bound against:

sub to_SI (`meters($m)) { `meters($m) }
sub to_SI (`feet($f))   { `meters(feet_to_meters($f)) }

Here's an excerpt from my module (perl6ized):

sub invert ($in) {
my `not($x) := $in ?? $x :: `not($in);
}

Or maybe that's:

sub invert ($in) {
`not(my $x) := $in ?? $x :: `not($in);
}

Anyway, the point is that bindings can fail.  In boolean context, they
return whether they succeed; in void context, they blow up if they
fail (probably fail).

As multimethods:

multi invert (`not($x)) { $x }
multi invert ($x)   { `not($x) }

Which I like the best.

Pairs are values: like numbers.  `foo =:= `foo.  They can just have sub-values.


Re: undef.chars?

2005-08-04 Thread Brent 'Dax' Royal-Gordon
Luke Palmer [EMAIL PROTECTED] wrote:
 On 8/4/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
  my $undef = undef;
  say $undef.chars?   # 0? undef? die?
  say chars $undef;   # 0? undef? die?
 
  I'd opt for undef.chars to be an error (no such method) and chars
  undef to return 0 (with a warning printed to STDERR^W$*ERR).
 
 Well, I think that chars $undef should be exactly equivalent to
 $undef.chars.  In fact, I think it is: chars $undef is just the
 indirect object form.

Didn't $Larry rule that method calls on undef return undef, for the
same reason array and hash subscripting does?

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker