Re: r25182 - docs/Perl6/Spec

2009-02-04 Thread Daniel Ruoso
Em Qua, 2009-02-04 às 16:45 +, Aaron Crane escreveu:
 pugs-comm...@feather.perl6.nl writes:
  +=item method Int read($buf is rw, int $length)
 I'm not sure that using a native int is the right thing here.  If
 whatever the implementation uses as int is narrower than size_t, that
 forces the programmer to use an Int and do the necessary loop.

native int can't be undefined, failures are undefined. The use of Int
here is to support it returning unthrown exceptions.

  +=head2 IO::POSIX
  +
  +Indicates that this object can perform standard posix IO operations.
 I don't like that wording, but getting it right seems tricky.  The
 problem is that I don't think you mean for IO::POSIX to contain
 methods corresponding to POSIX-ish read(2), write(2), given that
 methods of those names exist in other roles.  But those are precisely
 what I'd think of as most obviously falling into the category of
 standard POSIX I/O operations.

That actually surprised me, for some reason I did think read and write
were standard C, not POSIX (that's what happens when you don't have
experience in non-unix OSs).

And maybe you're indeed right, since you can change the way you access a
file in POSIX, it would be strange to de-compose a Writeable role if you
change the way you access the io.

but having separated roles for read and write would make it easier to
implement application level io objects (not backed by operating system
file descriptors). That probably means IO::POSIX does IO::Readable does
IO::Writeable.

  +=item method Bool flock(:$r,:$w)
 I realise this part of the specification still seems to be at the stub
 stage, but I'll note that:

Yes, it was meant purely as an example, a more carefull planning of that
would be needed.

daniel



Re: r25172 - docs/Perl6/Spec

2009-02-03 Thread Daniel Ruoso
Em Ter, 2009-02-03 às 10:34 +0300, Richard Hainsworth escreveu:
 f) radical suggestion:
 if the syntax '=$filehandle' lazily takes something from the file 
 handle, then
 $filehandle = output;
 should send something to it.

Problem is that this meeses up with assignment, which is an operation in
the container, not on the value, but...

$output == =$input

works just fine (sending one line of $input to $output), as well as

$input == $output

which would connect those filehandles

 We would also have
 $filehandle = map { s/ html_entities / %html_entities/ } @lines;
 as a filtering idiom.

Still using feed operators

$output == map { s/ html_entities / %html_entities/ }, @lines;

daniel



Re: r25172 - docs/Perl6/Spec

2009-02-02 Thread Daniel Ruoso
Em Seg, 2009-02-02 às 09:37 -0800, Larry Wall escreveu:
 It's also not clear how this should interact with buffering systems
 like stdio.  But in any case, speaking directly to the IO stack is
 likelier to give consistent results than playing mix-n-match with
 various calls on the IO stack that make various assumptions.

The question here is, will Perl 6 IO use stdio.h or re-implement its
features?

My first shot at it would be...

role IO {
   has $.fd;
}

role IO::Blocking {
   has Bool $.blocking;
}

role IO::Closeable {
   method close {...}
}

role IO::Readable {
   # no buffer
   method int read($buf is rw, int $count) {...}
}

role IO::Writeable {
   # no buffer   
   method int write($buf, int $count) {...}
}

role IO::Buffered {
   # buffer
   has Bool $.autoflush is rw;
   method flush {...}
}

role IO::Char does IO::Buffered {
   method getc {...}
   method fread {...}
   ...
}





Re: r25172 - docs/Perl6/Spec

2009-02-02 Thread Daniel Ruoso
Em Seg, 2009-02-02 às 13:51 +0100, Leon Timmermans escreveu:
 On Mon, Feb 2, 2009 at 1:05 PM,  pugs-comm...@feather.perl6.nl wrote:
  -the latter case C$! is set).
  +the latter case C$! is set). The C:async flag lets the call
  +return an undefined value if no character is immediately available.
 IMHO it would be better to call that non-blocking IO instead of
 asynchronous IO, but I'm POSIX-biased.

Agreed, it would be async if that was a request for a character that
would be replied using some other call, in that case it is non-blocking
read.

But I should argue that it should be a property of the IO object, not of
every individual method call..

daniel



Re: r25172 - docs/Perl6/Spec

2009-02-02 Thread Daniel Ruoso
Em Seg, 2009-02-02 às 15:12 -0800, Larry Wall escreveu:
 Roles are good, but what is this Char thing of which you speak?  It
 seems good neither for Unicode characters nor for keystroke sequences.  :)

I meant exactly in the sense of providing one of those abstractions, let
me rephrase it:

role IO::Unicode {
   method getc {...}
   method readline {...}
}

role IO::Term {
   method get_keystroke {...}
}

 On this non-blocking keystroke thing, I see a P6ish solution more like:
 get_keystrokes() == my @available;
 # time passes
 if @available { ... }
 That is, use the async capabilities already built into the language.
 (That's assuming the boolean value of @available doesn't block on the
 state of the feed.  If it does, we need some other way of expressing
 that test.  @available.now or some such.)

while the syntax solution is cool, it doesn't actually solve anything,
because in the end it needs to be resolved to some method call in some
object. But I see what you mean...

The problem is that iterators are not about beign async or blocking,
they're just about measuring how much you consume of the stream, which
means that an Iterator still needs to be async for look-aheads and do
blocking IO if it fells short of data.

That actually remembers me of the idea of auto-threading IO and making
it async. Let me try to make some example code of a HTTP handler:

my $io = Net::TCP.listen(:hostlocalhost, :port(1234));
$io does IO::Async[EV];
$io.accepts: - $conn {
   my %headers;
   my $data;
   my $waiting_headers = 1;
   for =$conn - $line {
  if ($line  $waiting_headers) {
 my ($name, $val) = split(/\s*:\s*/, $line);
 $headers{$name} = $val;
  } elsif ($line) {
 $data ~= $line;
  } else {
 $waiting_headers = 0;
  }
   }
   $conn.write(200 OK\n\nSucessfull request\n);
};
EV.loop;

This could autothread the code received by accepts, using async IO.
About one and a half years ago you sent me a paper about something like
that in haskell.

daniel



Re: Writing to an iterator

2009-01-08 Thread Daniel Ruoso
Em Qui, 2009-01-08 às 13:42 +1100, Timothy S. Nelson escreveu:
 On Wed, 7 Jan 2009, Jon Lang wrote:
  How would I define the method for writing to an iterator?
   I guess I'd assumed that writing to an iterator wouldn't be possible, 
 as there are kinds of iterators where writing to them makes no sense; I'd 
 assumed that if you wanted to write to something you'd use a list.  Other 
 than 
 as an interesting exercise, I don't see the point of using an iterator for 
 this purpose (there may *be* uses, but I don't see them).

There is at least one use: Some databases (berkeley db comes to my mind)
allow you to perform inserts using a cursor (which would be an iterator
in this case). The Java API also provides a insert mechanism...

Although in some cases, the update API will be specific to the object
you're dealing with, it can just be a regular object which happens to
implement the Iterator role...

daniel



Re: returning one or several values from a routine

2009-01-06 Thread Daniel Ruoso
Em Seg, 2009-01-05 às 20:32 +0100, Moritz Lenz escreveu:
 Daniel Ruoso wrote:
  would force item context in the capture, and here is the problem, as a
  capture in item context was supposed to return the invocant.
 Maybe we could have a different rule for captures in scalar contexts
 that don't have an invocant?

I've just realized we were missing some spots, so remaking the list of
possibilities

 my $a = sub s1 { return a = 1 }
 my $b = sub s2 { return a = 1, b = 2 }
 my $c = sub s3 { return 1, 2, 3, a = 1, b = 2 }
 my $d = sub s4 { return 1 }
 my $e = sub s5 { return 1, 2, 3 }
 my $f = sub s6 { return 1: # it doesnt matter  }
 my $g = sub s7 { return }

But while writing this email, I've realized that a Capture object is
supposed to implement both .[] and .{}, so maybe we can just simplify...

 $g is an undefined Object
 $f is 1
 $d is 1
 $a is a Pair
 everything else is the Capture itself

daniel



Re: returning one or several values from a routine

2009-01-06 Thread Daniel Ruoso
Em Ter, 2009-01-06 às 11:28 -0800, Jon Lang escreveu:
 Of course, that's only a third of the problem.  What should people
 expect with each of these:

Hmm... I think that takes the discussion to another level, and the
question is:

 what does a capture returns when coerced to a context it doesn't
provide a value for?

The easy answer would be undef, empty array and empty hash, but that
doesn't DWIM at all.

The hard answer is DWIM, and that can be:

 1) in item context, without an invocant
   a) if only one positional argument, return it
   b) if only one named argument, return it as a pair
   c) if several positional args, but no named args,
  return an array
   d) if several named args, but no positional args,
  return a hash
   e) if no args at all, return undefined Object
   f) return itself otherwise
 2) in list context, without positional arguments
   a) if one or more named arguments,
  return a list of pairs
   b) return an empty list otherwise
 3) in hash context, without named arguments
   a) if there are positional arguments,
  return a hash taking key,value.
  if an odd number of positional arguments,
  last key has an undef Object as the
  value and issue a warning.
   c) return an empty hash otherwise

daniel



Re: rfc: The values of a junction

2009-01-05 Thread Daniel Ruoso
Em Seg, 2009-01-05 às 07:57 -0800, Dave Whipp escreveu:
my $ace = 1 | 11;
my $seven = 7;
my @hand = $ace xx 3, $seven;
my $junc_value = [+] @hand;  ## any( 10, 20, 30, 40 )
 There are a bunch of possible values in the junction. The one we care 
 about is the largest that is not greater than 21. Using Perl6 as it 
 stands today, the way to extract this value is brute force:
my $concrete_value = max (0..21).grep: { $^score == $junc_value };

Well, that considering we don't have any introspection into junctions,
but I think it should be quite straight-forward to make junctions behave
as a list of its members...

  my $ace = 1 | 11;
  my $seven = 7;
  my @hand = $ace xx 3, $seven;
  my $junc_value = [+] @hand;
  my $concrete_value = max $junc_value.grep: { $^scope  21 }; 

daniel



Re: use semantics

2009-01-04 Thread Daniel Ruoso
Em Dom, 2009-01-04 às 14:53 +0100, Carl Mäsak escreveu:
 $ parrot languages/perl6/perl6.pbc --target=pir --output=B.pir B.pm
 $ parrot languages/perl6/perl6.pbc --target=pir --output=A.pir A.pm
 Remember, remember, the fifth of November
 current instr.: 'die' pc 14950 (src/builtins/control.pir:204)
 [...]

I might be wrong, but it looks like the consequence of the reasoning I
made in the other post, the problem is that, in order to import B in A,
B needs to be initialized, and as B init fails, the compiling of A
fails.

This is not simply a rakudo bug, but rather a conceptual problem in the
way BEGIN, INIT and use are related.

daniel



Re: Coroutines in Perl 6 (Was: Re: Converting a Perl 5 pseudo-continuation to Perl 6)

2009-01-02 Thread Daniel Ruoso
Em Sex, 2009-01-02 às 08:34 -0300, Daniel Ruoso escreveu:
   token routine_def:coro {...}

Actually, I was just looking at STD, and the correct token would be

  token routine_declarator:coro { sym routine_def }

I was also looking at the spec files, and I realized that DRAFT S17
mentions coroutines, but its definition is a bit different then the one
I suggested, and the example poses a good reason:

  coro dbl { yield $_ * 2; yield $_; };
  (1..4).map:{ dbl($_) }
  # should result in 2 2 6 4

This example suggests that it will not install an alias in the caller
scope, but the code object itself stores its state.

The other difference is that falling out of a coro makes it restart
immediatly without returning any value (this one is a bit weird, I'd
expect it to return the last statement on the routine as well).

But one way or another yield (yes, I wrote it wrong in the previous
post) is still implemented as a control exception that is caught by the
implicit CONTROL block of the coro.

daniel



Coroutines in Perl 6 (Was: Re: Converting a Perl 5 pseudo-continuation to Perl 6)

2009-01-02 Thread Daniel Ruoso
Em Qui, 2009-01-01 às 12:34 -0800, Geoffrey Broadwell escreveu:
 In the below Perl 5 code, I refactored to pull the two halves of the PID
 file handling out of init_server(), but to do so, I had to return a sub
 from pid_file_handler() that acted as a continuation.  The syntax is a
 bit ugly, though.  Is there a cleaner way to this in Perl 6?

Well,

If the STD Perl 6 doesn't support that, you can always declare a
sub-grammar that implements a 

  token routine_def:coro {...}

then you have something in the lines of:

  coro pid_file_handler {
  ... # first half
  yeld $something;
  ... # second half
  }

It's even easy to implement how it should work. Basically, yeld throws a
resumable control exception, the implicit CONTROL block of the routine
will then contain the code to handle that exception by aliasing the coro
in that state in the caller lexical scope, overriding the current
definition. And once the routine is called again, and returns or leaves,
you simply re-binds to the original routine. 

The above solution assumes a coro state is only available in the same
lexical scope as the first call, which may be a good idea to avoid
action-at-a-distance.

But maybe we even convince larry to push that into STD... since it's
such a nice feature...

daniel



Proposal: receiving arguments without enforcing context

2008-12-29 Thread Daniel Ruoso
Hi,

Captures are sensitive things, they can only be used as-is inside a
scalar, otherwise you have to enforce a context and it is no longer a
capture, but one of the views of its content.

for instance...

  sub foo {
...
return @thingy, :named($value);
  }
  sub bar($capture) {
my $named := |$capture;
my @things := |$capture;
...
  }
  bar(foo());

The problem with the above code, is that the :($capture) signature,
already enforces item context, and therefore the two statements in sub
bar will simply fail.

That being said, I'd like to suggest a new syntax:

  sub bar(\$capture) {
  ...
  }

This syntax will mean that you want that positional argument without
forcing any context. This is something different from

  sub bar(|$capture) {
  ...
  }

which takes the entire capture sent to that invocation and store in the
variable, the proposed syntax would allow:

  sub foo {
 return 1,2,3;
  }
  sub bar(\$capture, $other) {
 ...;
  }
  bar(foo(), somethingelse);

This need came out because of

  method postcircumfix:( )($capture)

we need to receive the positional argument for .() without forcing the
context. I understand this method used to have a (|$capture) signature,
and it was changed by a request I made, but I'd like to remember that (|
$capture) and (\$capture) are completely different things, and SMOP
already takes advantage on that, the current signature for .() in SMOP
is:

  method postcircumfix:( )(\$capture, :$cc)

where $cc is there to support call with current contination (currently
used in exception handling).

The other method that requires such concept is

  method dispatch($object, $identifier, \$capture) {...}

in ClassHOW, which will actually call postcircumfix:( ) in the end, so
it needs the capture as-is.

Aditionally to this syntax, one point requires attention. If

 foo((a = 1));

makes the pair a positional argument, it's natural that

 foo((|$capture));

makes the capture a positional argument, instead of expanding it into
the argument list, and thus closing the loop in how to use a capture
object ;)

daniel



Re: use semantics

2008-12-28 Thread Daniel Ruoso
Em Dom, 2008-12-28 às 00:31 -0500, Jeff Horwitz escreveu:
 the modules it uses assume they're embedded in an apache process,
 dlfunc'ing a bunch of apache API functions.

I think that means the 'dlfunc' calls need to be in INIT and not in
BEGIN.

 right now it is impossible to compile such a module to bytecode, which
 i like to do for startup performance.

This is actually something I've been thinking for a long time. The thing
is that in Perl 6, besides all the efforts, the difference between
compile time and run time is not that clear.

The thing is that the usual aliasing of symbols from outer modules to
this module can be understood as static linking, which can raise
issues with modules that cannot be statically linked.

In a dynamic linking, the foreign module only need to declare which
symbols it will provide (i.e. a '.h' file) at compile time, and the
compiled object simply contains a reference this symbol belongs to X.

Then, at run-time, you will load the used module and resolve the symbols
that you linked in this code.

I think this means we need to have two compiling modes, one to generate
the header file and other to generate the executable file, or at
least we need a way to extract the headers from the executable file
without actually loading it.

The problem is that use calls EXPORTALL on the package being loaded,
and there the barrier between compile-time and run-time becomes very
much blurred, because to run EXPORT on the given module, it must be
entirely loaded, and I presume the call to EXPORT can only happen after
INIT has already been called in that module. I think that's a deadlock. 

daniel



returning one or several values from a routine

2008-12-27 Thread Daniel Ruoso
Hi,

As smop and mildew now support ControlExceptionReturn (see
v6/mildew/t/return_function.t), an important question raised:

 sub plural { return 1,2 }
 sub singular { return 1 }
 my @a = plural();
 my $b = plural();
 my @c = singular();
 my $d = singular();

What should @a, $b, @c and $d contain?

Note that the spec says explicitly that a Capture should be returned,
delaying the context at which the value will be used, this allows

 sub named { return :x1 }
 my $x := |(named);

So, this also means that assigning

 my @a = plural();
 my @c = singular();

forces list context in the capture, which should return all positional
parameters, as expected. But

 my $b = plural();
 my $d = singular();

would force item context in the capture, and here is the problem, as a
capture in item context was supposed to return the invocant.

I think this means we should change this bit of the spec, so that a
capture in item context return the first positional argument if there is
only one positional argument or a list coerced to item of all the named
arguments. This would mean that $b in the above code would contain [1,2]
while $d would contain simply 1.

It's important to realize that this is different from p5 because the
argument list to return is not flattened, this means that

  return @a

will always return a list, even if @a has only one element, because as
@a is not flattened, it is still a list inside the capture, and when
that capture is used in item context, it will assign that list in item
context. The same way that

  return 1,;

is always always a list, because you have more than one positional
argument.

What do you think?

daniel



Build and Installation of modules should be implementation specific (Was: Re: 6PAN Spec question)

2008-12-22 Thread Daniel Ruoso
Em Seg, 2008-12-22 às 15:06 +1100, Timothy S. Nelson escreveu:
 On Sat, 20 Dec 2008, Mark Overmeer wrote:
  For ???B.  In the current set-up, you use CPAN.pm to download, and then
  install.  The 'cpan' script is a wrapper around CPAN.pm.  CPAN.pm starts
  the install tool.  A more convient structure would be to have an user
  application (maybe the same 'cpan' script), which calls some download
  backend to retreive the distribution and then calls the right install
  tool per distribution.  I would say: ???B is cpan-NG
   That would be one way of labelling it.  I prefer to leave that 
 labelling up to the people who will actually be writing the software.  For 
 all 
 I know, they might prefer to begin with a direct port of CPANPLUS, and work 
 from there.

While I agree that ???B plays the role that CPAN.pm does today, I do
think we should leave that to be implementation specific, being the
implementation responsability to provide a minimal set of features in
its package manager so you can install standard Perl modules.

This is important because Parrot compiles its code to bytecode, SMOP
might even always run from source code (since separating compile-time
from run-time may be tricky). Mix together the different Operating
Systems where the module should be installed and you get something that
is not really spec-able.

This also makes it really cool for distribution maintainers, since they
know that they can make a custom package manager to create
distro-specific packages for every Perl 6 implementation.

daniel




Re: 6PAN idea

2008-12-18 Thread Daniel Ruoso
Em Qui, 2008-12-18 às 11:38 +0100, Mark Overmeer escreveu:
 In the current state of affairs, CPAN is limited to Perl5 and strongely
 entangled by Perl5 install tools.  Do we want to have people install
 Perl5 on their (maybe small) machine before they can install Perl6 stuff?
 Rpm-tools and deb-tools are simply alternatives to CPAN.pm

I presume the release of (whichever implementation of) Perl 6 should
have deployed a minimal set of features of this package management, so
you can install new modules (which could include build-depends).

I even think each implementation might have its own package manager,
optimized to its needs, and eventually, a distro might want to deploy a
customized version of that package manager (that would build the deb or
rpm and install it integrated with the rest of the system-wide package
management).

In summary, I think CPAN6/6PAN should deal with the content, and not how
the content is built/installed. That is specific to each Perl 6
implementation and each OS, and that is the reasoning behind the
exclusive use of metadata, instead of an embedded build system.

 One trap of S22 is to say: let's try to do our best for ...
 (Debian),

I agree that doing the best for Debian is a bad idea, but I don't think
that's the intended in S22 or in the notes I wrote. But some concepts
indeed come from the experience Debian has in managing such a diverse
universe.

 Do realize that getting things installed on a system can be quite hard.
 Even much harder to express in an abstract meta-data language. So, for
 CPAN6 I decided to strictly seperate the distribution of releases from
 the actual content of those releases.

That's why I believe the meta-data should describe what the content
*is*, and not how it is installed. Deciding how it is installed is
completely implementation/OS dependent, and I think should be delegated
to the implementation/OS.

This will probably mean that we will have some standard way of querying
for files included in some distribution, so we make sure the decision of
where to store the files is completely up to the implementation and OS.

daniel




Re: 6PAN Spec question

2008-12-18 Thread Daniel Ruoso
Em Qui, 2008-12-18 às 13:08 +1100, Timothy S. Nelson escreveu:
   My question is, what sort of information actually belongs in a final 
 version of the 6PAN spec?  I'm assuming it will at least include 6PAN Package 
 format (layout, metadata, etc), and I'd suggest that it also include the 
 layout of packages on the 6PAN server.

I think we have

  1) How is the layout of Perl 6 related content (source package format)

  2) How source packages are uploaded, indexed, mirrored, searched, 
 downloaded etc (6PAN/CPAN6)

  3) How source packages are built

  4) How binary packages are installed 

I think 1 and 2 should be subject of two different specs, I also think 3
and 4 should be implementation and OS specific.

daniel



Re: 6PAN idea

2008-12-17 Thread Daniel Ruoso
Em Qua, 2008-12-17 às 15:00 +1100, Timothy S. Nelson escreveu:
   My basic assumption is that there's going to be some kind of packaging 
 system written around 6PAN.

Please take a look in some notes I've written some time ago:
http://www.perlfoundation.org/perl6/index.cgi?DistributionFormat

daniel



Re: 6PAN idea

2008-12-17 Thread Daniel Ruoso
Em Qua, 2008-12-17 às 23:35 +1100, Timothy S. Nelson escreveu:
 On Wed, 17 Dec 2008, Daniel Ruoso wrote:
  Em Qua, 2008-12-17 às 15:00 +1100, Timothy S. Nelson escreveu:
 My basic assumption is that there's going to be some kind of packaging
  system written around 6PAN.
  Please take a look in some notes I've written some time ago:
  http://www.perlfoundation.org/perl6/index.cgi?DistributionFormat
   I guess I should also say that I'm assuming everyone has at least a 
 vague familiarity with this:
   http://svn.pugscode.org/pugs/docs/Perl6/Spec/S22-cpan.pod
   In particular, I'm not sure that Daniel's ideas align with the Draft 
 S22; I'm hoping Daniel will take a moment to see if they align.

Indeed, for some reason I missed that document. But it's not entirely
unaligned. The major difference seems to be having different packages
for source and binary (or source and installable, as in S22).
S22 mentions the difference, but doesn't split them in different
packages.

The most important argument, IMHO, to have them as different packages is
to allow a binary/installable distribution without the need to
recompile every module when installing. This should help when you have a
target OS that is installed in several machines, then you can re-use the
binary/installable package repository for that specific OS/version.

It also allows one source package to generate different binary packages
(for instance, having scripts, libs and docs splitted), and makes it
easier to do an uninstall, because a binary/installable package
would have a fixed list of files.

One thing that is mostly aligned, is the idea that the building of the
package is external to it, no more Makefile.PL or Build.PL. The package
only lists metadata of which type of things it has, and the running
system should realize how to build and install them. Althought, in my
notes, I expanded the meaning of it a bit more.

In summary, I think inheriting most of the concepts from Debian is
something almost consensual, and there's much alignment in both
documents in that respect. It would probably make sense to refactor S22
into a more spec-like document.

daniel



Proposal: Make @a and @@a different variables

2008-12-16 Thread Daniel Ruoso
Hi,

One of the hardest features in Perl 6 is the slice context. It is
undoubtfully usefull, since it provides semantics to acces each
iteration of a map, for instance.

But there's one thing in the spec that makes not only slices, but the
lists themselves considerably harder to implement, and that is the idea
that a slice is a view of a list.

  my @@a = map { $^a == 2 ?? 1,2,3 !! () }, 1, 2, 3;
  say @a[0]; # this should print 1.
  say @@a[0]; # this should print ().
  say @a[1]; # this should print 2.
  say @@a[1;0]; # this should print 1.

That happens because '@a' and '@@a' are the same variable, just
different views of that variable.

That being said, we should note that this example looks simple because
we have almost no lazyness implied (since there's an assignment in the
first line), every list access requires the evaluation of the flatenning
of the list.

  my @@a = ((),(1,2,3),());
  # the following will require a flatenning to get the actual index
  say @a[3];

This looks much more complicated when you have a lazy list...

  my @a == map { $^a == 2 ?? 1,2,3 !! () }, 1, 2, 3;
  # the line below will require two map iterations to get a value,
  # and at that time, there will be three values available
  say @a[0];
  # having to support a slice view here will require the lazy list
  # to always be a lazy slice, and each access will require a flatenning
  # of the values already obtained to only then decide if it has to
  # obtain more items
  say @a[2];

This all makes me think that it would be much easier if the slice
existed on its own, which would mean:

  # this will provide only a flatenned view
  my @a == map { $^a == 2 ?? 1,2,3 !! () }, 1, 2, 3;
  # and this will provide a slice view
  my @@a == map { $^a == 2 ?? 1,2,3 !! () }, 1, 2, 3;
  # but @a and @@a are different values
  @a =!= @@a :test;
  # and trying to get the slice on @a will fail
  say @a[0;1]; # fail
  # and you still can flatten the slice if you want to...
  # and it can preserve the lazyness
  my @b == @@a;
  # or enforce a mostly eager level
  my @c = @@a;

So, what do you think?

daniel



Re: Proposal: Make @a and @@a different variables

2008-12-16 Thread Daniel Ruoso
Em Ter, 2008-12-16 às 18:47 +0100, TSa escreveu:
# the following will require a flatenning to get the actual index
say @a[3];
 Could we not shift the problem into a more complicated form
 of the size of the array? Here it has size 0+3+0 but each of the
 summands could be lazy and hence infinite or at least finite with
 unknown value.

The number of summands might be also unknown. i.e.: map.

when you have

  my @a == map { ... } == something()

you can't really know how many elements you have in the first
dimension...

 In any case the flat view @a has to step at most the first iterator in
 the array

I'm not sure I see what you mean, but I presume you mean the first
iteration. In that case, if that iteration returns an empty capture, it
will continue iterating until it returns at least one item. But that
iteration can then return several items which need to be stored in the
lazy list.

 whereas @@a can look beyond that when indexed with a slice, that is
 something with semicolon in it.

Or the iterations of map and grep...

 An out of bounds access like @a[3] can be answered without flattening,
 right?

I consider counting the number of items in the inner dimension to be (a
simplified) flattening, think of:

  my @@a == map { $^a == 2 ?? 
  map { $^b == 2 ??
map { $^c == 2  $b == 2  $a == 2 ?? (1,2,3)
  !! () }, 1, 2, 3
!! () }, 1, 2, 3
  !! () }, 1, 2, 3;

That would result in

  (();(();(1,2,3);());())

Which is considerably more complex than the first example and have the
following example slice accesses:

  @@a[1]; # returns (();(1,2,3);())
  @@a[1;1]; # returns (1,2,3) 
  @@a[1;1;0] # returns 1

Trying to access @a[0] would result in a recursive flattening until it
gets to the element that would otherwise be accessed by the slice

  @@a[1;1;0]

So it's not just a matter of counting 0-3-0, because to get the first 0,
you need to recursively flatten the inner dimmension until you realize
it's really empty.

If we allow that to be flattened at the beginning, it will simply
consume the iterator until it gets an element.

 In general I'm in favor of making @a and @@a distinct because
 otherwise the first @ in @@a feels like an operator instead like
 a twigil that belongs to the variable like $ belongs to $a which
 is also distinct from @a.

That's an important point. I think it would be consistent that '@@a'
should be the variable name, just as '@a', '$a' or any other. Specially
since '@@' is not a sigil and a twigil, but a sigil of two characters. 

 Since one could also go with a shaped @a I think the choice of @@a
 versus @a is a bit like the choice between a @a and an anonymous array
 in a $ var ala $a = [] which can be handled through $a almost like @a.

I'm not sure I understood that, but I think you're saying that slice
context could be seen just as a regular context, as scalar and list
context, which is something that I agree.

@a =!= @@a :test;
 BTW, what does the :test mean there?

This is the proposed syntax for integration of test-driven-development
in the language built-ins.

daniel



Re: Where does Foo::Bar.EXPORTALL comes from?

2008-12-13 Thread Daniel Ruoso
Em Sex, 2008-12-12 às 18:40 -0600, Patrick R. Michaud escreveu:
 On Fri, Dec 12, 2008 at 08:42:05PM -0300, Daniel Ruoso wrote:
  [...]
  While all the default exportation is done by the population of the
  EXPORT inner package, that doesn't happen from the outside, S11 implies
  that it happens by the calling of the EXPORTALL routine, it doesn't
  really make it clear where it comes from.
 ...this was also briefly discussed (without definite resolution) 
 on #perl6 back in October:
 http://irclog.perlgeek.de/perl6/2008-10-11#i_617227
 I'm simply providing the reference here -- I haven't looked to see
 if there was any further resolution on the issue (in either IRC
 or the Synopses) after that discussion.

Er... it doesn't really provides a resolution on the issue (besides
TimToady saying that I think sideways), the part that says:

so Foo::Bar.method is more like $x.method than like @x.method

Would imply that EXPORTALL is a  method of Object, which is rather
weird...

The idea of DESTROYALL being a method of Package would be sane, but I'm
pretty sure it would require a different syntax, maybe
Foo::Bar::.DESTROYALL.

daniel








Where does Foo::Bar.EXPORTALL comes from?

2008-12-12 Thread Daniel Ruoso
Hi,

I've been thinking about how I would implement module loading in SMOP
and reached some points that I think need some clarification. The most
important of them being about the EXPORTALL routine.

While all the default exportation is done by the population of the
EXPORT inner package, that doesn't happen from the outside, S11 implies
that it happens by the calling of the EXPORTALL routine, it doesn't
really make it clear where it comes from.

If it was Foo::Bar.EXPORTALL it would mean that this is a method from
Object, but I think this is a reminiscence of the old
method-to-sub-dispatch-fallback, which would mean that EXPORTALL is a
subroutine instead, being called on the package.

But does that mean that there's a default EXPORTALL that is installed in
every package? Does that mean that in the absense of a custom EXPORTALL,
some specific code is called?

daniel



Re: [perl #61126] return should apply to the lexically enclosing routine, map is no exception

2008-12-08 Thread Daniel Ruoso
Em Dom, 2008-12-07 às 18:10 +0100, Carl Mäsak escreveu:
 The above reasoning raises the following question for me: how do I
 return from a sub or a method from within a map block?

I suppose what you want can be achieved with last, it probably should
work in map as well, since map and for are synonims...

daniel



Re: [perl #61126] return should apply to the lexically enclosing routine, map is no exception

2008-12-08 Thread Daniel Ruoso
Em Seg, 2008-12-08 às 12:08 +0100, Carl Mäsak escreveu:
 Daniel (), Carl ():
 That is all good and well for exiting the map itself; but what I want
 to achieve is to exit the surrounding sub or method block. Example:

Er... I mean actually the opposite... it should always return from the
surrounding sub or method, never only from map, if you want to end
the map loop, you should use last... meaning...

sub foo {
   map { last; }, 1, 2, 3; # executes the block only once
   map { return; }, 1, 2, 3; # returns from foo;
} 

daniel



Re: how to write literals of some Perl 6 types?

2008-12-02 Thread Daniel Ruoso
Em Seg, 2008-12-01 às 18:21 -0800, Darren Duncan escreveu:
 I'm wondering how to write anonymous value literals of some Perl 6 basic 
 types, 
 and I didn't see mention of this in synopsis 2.

Getting away from your question entirely, I think the issue here is that
while Perl 6 has support for strong typing, it is not really expected
that you approach your code with such strong typing...

Let me try to rephrase that...

a Bit is something that .^does(Bit), therefore 0 and 1 can
certainly be a Bit, while they can also certainly be an Int... But
most importantly, they are probably going to be something implemented in
low-level that can be used as a Bit, as a Num or as an Int.

I'm not sure this is an aspect that everybody got, but there isn't
really a way to tell the actual implementation type of an Object in Perl
6, you can introspect the object as long as you wish, but you'll be
always asking something to that object, and the object itself is the one
giving the answers, therefore it can lie about itself, and that's fine.

There are even rumors that $obj.WHAT should return a canonical type,
even if its implemented by some low-level optimized version...

So, how to write anonymous value literals of that values? Well, you
won't need to do that...


daniel



Re: Iterators and Laziness

2008-11-28 Thread Daniel Ruoso
Timothy S. Nelson wrote:
 Should laziness/eagerness be a property of the operator?

I'm inclined to believe that the level of lazyness or eagerness is
determined by the operators in question, at least that had worked for
assignment and feeds, I can't think of a case where something else
determines the lazyness

 You write The iterator role represents the lazy access to a list.
 Why only lazy access?

It's not *only* lazy access, but it's how you do lazy access...

 You write:  my $item = =$foo;
 Does that get one item from the iterator object?

It depends on the iterator in question, but it certainly gets something
(unless the iterator is over, of course), I'm thinking on the following:

  my $iterator = @list.Iterator();
  my $capture = =$iterator; # this returns the capture for that iteration;

but

  my $iterator == @list;
  my $item = =$iterator; # this returns one, and only one, item

This is important because

  my @@slice == @list;

Will keep the dimensionality between iterations and items, for instance:

  my @@slice == map { $_ == 2 ?? ( 1, 2, 3 ) !! () }, 1, 2, 3;

the slice would contain

  ( () ; ( 1,2,3 ); () )

And this is possible because the actual Iterator returned by the list
returns capture-by-capture on each iteration.

 you specify that the .Iterator() object on something that does List 
 will return the appropriate iterator.  I changed it to be .iterator() (so 
 that 
 it's lowercase like all the other List.whatever() functions); what's the 
 function signature?

The Uppercase is used to indicate a type coercion, the standard way of
coercing something to some other type is by calling a method of the name
of the type in that object, that's why you have .Iterator on list, and
usually this method has no parameters.

daniel



Re: Iterators and Laziness

2008-11-28 Thread Daniel Ruoso
Sex, 2008-11-28 às 14:23 -0300, Daniel Ruoso escreveu:
  You write:  my $item = =$foo;
  Does that get one item from the iterator object?
 It depends on the iterator in question, but it certainly gets something
 (unless the iterator is over, of course), I'm thinking on the following:

I thought it would be helpful to have a complete implementation of how
an Iterator would work, in this case the proposed implementation for the
map operator in mildew (yes, the amount of indirection in SMOP kinda
requires us to write it in a high-level-language):

That code doesn't use any of the implied lazyness/eagerness of any
operator, it uses the API directly, much of the effort in that code is
going to be simplified to the user by the use of the feed operator...

The code is in the pugs repo:
http://svn.pugscode.org/pugs/v6/mildew/Map.pm


daniel



Re: Files, Directories, Resources, Operating Systems

2008-11-27 Thread Daniel Ruoso
Hi,

First of all, sorry for breaking the thread, but I had some trouble with
my mail provider, and couldn't hit the reply button.

To the point...

I think there are some things that are simply not solved by abstraction.
Some problems are concrete problems that need concrete solutions,
filesystem access is one of them, IMNSHO.

I pretty much think 

if ($*OS ~~ POSIX) { ... }
elsif ($*OS ~~ Win32) { ... }

is much saner than trying to deal with an enormous API that would be the
result of the attempt to get a sane abstraction of all the different
possible scenarios, and that would end up having backward-incompatible
changes after a while because of some use case scenario that wasn't
adrressed.

On the other hand, we really could think on having chmod, chown etc in
the POSIX module, and have the POSIX module imported (where chmod would
be in the default exports) by the prelude when in a posix machine, the
same for the Win32 or whatever counterpart.

Of course it would be very much interesting to have the open
implemented by the POSIX module with the same API as the open
implemented by the Win32 module. But I'm pretty much sure that's not the
case for chown and chmod, and I don't think an abstract API is worth the
trouble for 99% of the cases.

But note that this doesn't stop the people in the 1% case to write the
abstraction API, I just think it doesn't need to be the only way to
access the features, and it certainly doesn't need to be loaded in the
prelude.

daniel



XPath grammars (Was: Re: globs and trees in Perl6)

2008-10-02 Thread Daniel Ruoso
Qui, 2008-10-02 às 12:55 +0100, Tim Bunce escreveu:
 Like applying XPath to an XML DOM, only more general and taken
 further.
 By more general and taken further I'm thinking of the same kind of
 evoltion from simple regular expressions in perl5 to grammars in perl6.
 An XPath query is like a perl5 regular expression. 

During YAPC::EU::2007 (yeah... some time ago...) we had this discussion
motivated by the need to have something easier to transform parse
trees... 

In that case, we were thinking about programming-language-translators
that would take the parse tree of one language, make some modifications
in the tree before emitting the other language (i.e.: turning specific
language dialects, for instance some uses of map and grep in perl5, to a
language that doesn't support map and grep, then turning that into a
different p5 construct that could be effectively translated to the
target language).

One thing we realized at that time is that XPath is good enough, even if
it seems to be adressing XML specifically, it has the concept of
dimension that can be extended to represent arbitrary aspects of
objects.

When we then take XQuery into account, we might have all the tools to
build an coherent tree-oriented Rule system.

xgrammar Foo {
   xtoken bar {
  'some XPath expression' subtoken
  { make 'some XQuery expression' }
   }
   xtoken subtoken {
  'some other Xpath expression'
  { make 'yet another xquery expression' }
   }
}

Of course we still need to think how to compose different xpath
expressions and how to make captures of it, but maybe XQuery already
solves that problem...

daniel



Re: Should $.foo attributes without is rw be writable from within the class

2008-09-21 Thread Daniel Ruoso
Sex, 2008-09-19 às 10:25 -0700, Jon Lang escreveu:
 Daniel Ruoso wrote:
  In SMOP, it is handled based on the package of the Class, the private
  storage inside the object is something like
$obj.^!private_storageA::$!bar
  and
$ojb.^!private_storageB::$!bar
 Note that this ought only be true of class inheritance; with role
 composition, there should only be one $!bar in the class, no matter
 how many roles define it.

er... what does that mean exactly?

   role B {
   has $!a;
   }

   role C {
   has $!a;
   }

   class A does B, C {
   method foo() {
  say $!a;
   }
   }

I think in this case $!B::a and $!C::a won't ever be visible, while the
reference to $!a in class A will be a compile time error.

OTOH...

   role B {
   has $.a;
   }

   role C {
   has $.a;
   }

   class A does B, C {
   method foo() {
  say $.a;
   }
   method bar() {
  say $!a;
   }
   }

In that case, both B and C declare a *method* a which happens to be
visible in class A (and probably a composition error), but $!a in method
bar is still a compile time error, because there's no $!a declared in
class A.

Or does that mean that

class A does B, C {...}

actually makes the declarations in B and C as if it were declared in the
class A?

daniel



Re: Should $.foo attributes without is rw be writable from within the class

2008-09-19 Thread Daniel Ruoso
Qui, 2008-09-18 às 18:11 +0200, TSa escreveu:
 Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar
 without an accessor?

Actually, $!B::bar doesn't overwrite $!A::bar... the problem is simply
that $!A::bar is not visible from inside B, and therefore, there's
nothing to be overriden...

daniel



Re: Should $.foo attributes without is rw be writable from within the class

2008-09-19 Thread Daniel Ruoso
Sex, 2008-09-19 às 17:49 +0200, TSa escreveu:
 Daniel Ruoso wrote:
  Qui, 2008-09-18 às 18:11 +0200, TSa escreveu:
  Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar
  without an accessor?
  Actually, $!B::bar doesn't overwrite $!A::bar... the problem is simply
  that $!A::bar is not visible from inside B, and therefore, there's
  nothing to be overriden...
 May I pose three more questions?
 
 1. I guess that even using $!A::bar in methods of B is an
 access violation, right? I.e. A needs to trust B for that
 to be allowed.

Yes

 2. The object has to carry $!A::bar and $!B::bar separately, right?

Yes

 3. How are attribute storage locations handled in multiple inheritance?
 Are all base classes virtual and hence their slots appear only once
 in the object's storage?

In SMOP, it is handled based on the package of the Class, the private
storage inside the object is something like

   $obj.^!private_storageA::$!bar

and

   $ojb.^!private_storageB::$!bar

daniel



Re: {SPAM} Re: Should $.foo attributes without is rw be writable from within the class

2008-09-19 Thread Daniel Ruoso
Sex, 2008-09-19 às 17:49 +0200, TSa escreveu:
 Daniel Ruoso wrote:
  Qui, 2008-09-18 às 18:11 +0200, TSa escreveu:
  Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar
  without an accessor?
  Actually, $!B::bar doesn't overwrite $!A::bar... the problem is simply
  that $!A::bar is not visible from inside B, and therefore, there's
  nothing to be overriden...
 May I pose three more questions?
 
 1. I guess that even using $!A::bar in methods of B is an
 access violation, right? I.e. A needs to trust B for that
 to be allowed.

Yes

 2. The object has to carry $!A::bar and $!B::bar separately, right?

Yes

 3. How are attribute storage locations handled in multiple inheritance?
 Are all base classes virtual and hence their slots appear only once
 in the object's storage?

In SMOP, it is handled based on the package of the Class, the private
storage inside the object is something like

   $obj.^!private_storageA::$!bar

and

   $ojb.^!private_storageB::$!bar

daniel



Re: {SPAM} Re: How to define a new value type?

2008-09-16 Thread Daniel Ruoso
Ter, 2008-09-16 às 18:04 +0200, TSa escreveu:
 I think that mutating methods of immutable value types just have
 to modify the identity. The problem is how that relates to references.
 Take e.g. the Str type

I really think we are looking at this problem from the wrong
perspective.

For an Object to be a value, it means that if you build an object with
the same value, it will be seen as the same value that some other
object with this value.

A sane requirement for this to happen is that value objects are
read-only, which is something pretty straight-forward.

The thing is that, for a value object, there isn't any difference in
saying:

  my $a := 3;

or

  my $a := 3.clone();

Because the number '3' is a value, and you usually doesn't expect a
value to change its value at a distance, that's why Int is Immutable.

daniel



Re: Iterator semantics

2008-09-12 Thread Daniel Ruoso
Qui, 2008-09-11 às 12:13 -0700, Larry Wall escreveu:
 And I guess the fundamental underlying constraint is that a list cannot
 be considered immutable unless its feeds can be considered immutable,
 at least in some kind of idempotent sense.  This conflicts with the
 whole point of reactive programming, which is that you have to react
 because don't know what's coming.

This is actually something I was talking in the IRC this week. The
amount of polymorphism Perl 6 supports makes it quite impossible to
detect if the feeds can be considered immutable or not (in terms of
concept, I mean, runtime tips could allow optimizations).

But one thing needs to be clear, List is immutable as a type, meaning
that the API for List only allows you to read from it, not write to it,
but it doesn't necessarily means that it is immutable as an instance,
because the List might have a live backend.

Since List is not a native type, the interpreter doesn't really have any
control on what it does to provide its values, and that's what I mean by
saying that we can't infer if the feeds can or cannot be considered
immutables.

 This seems like it's close to the fundamental difficulty we're trying
 to solve here.  And maybe the solution is much like the value/object
 distinction, where lists get to *decide* for themselves where they
 switch from easy eager immutable semantics to hard lazy reactive semantics.
 And if we're pretty clear about the boundary between those, it
 could work out much like the boundary between DFAable regexes and
 side-effectful regexes as defined in S05.  And maybe it's even the
 same boundary in some theoretical sense.

The problem is that this concept should apply to the entire chain, this
means that it can only be considered easy if all the feeds on the chain
are easy, and it is too easy for it to be considered hard... for
instance, is a 'map' considered easy or hard?

In the end, that means that most of the time easy feeds will be made
dirty by hard feeds and all the chain will be made lazy, so we have
little gain.

In SMOP, I'm probably going to presume that everything needs to be lazy,
then even:

  my @o = grep { /\d+/ } =$*IN;
  my @a = (1,2,(3,4,@o));
  my @b = (1,2,(3,4,@a));

Will still allow @b to be seen in slice context, where you would see @a
also in slice context, because @a was not eagerly evaluated when
composing @b, and eventually @o might never be evaluated.

I think this is consistent with the spec that says somewhere that the
only operators that imply eager evaluation are the short-circuit boolean
operators (besides the 'eager' operator, of course, and the use of lazy
values in void context).

Of course the spec only says that it should be lazy with the feed
operators, but in SMOP I tend to think that all this evaluation will be
lazy.

daniel



Re: Iterator semantics

2008-09-09 Thread Daniel Ruoso
Ter, 2008-09-09 às 10:10 -0500, Patrick R. Michaud escreveu:
 I think my question can be best understood by example -- what
 does the following produce?
 my @a = 1,2,3,4,5;
 for @a { .say; @a = (); }

The problem actually becomes more evident with

  my @a = 1,2,3,4,5;
  for @a { .say; @a[5] = 'five' }

because the first code actually replaces the content of the variable @a,
while the second will call .postcircumfix(5), which itself returns a
container which is then STOREd with 'five'.

The basic difference is that in 

  for @a {...}

we take an iterator that point to the array that is stored at that
moment in @a. If we replace the array stored in the variable @a, that
iterator would still point to the original array.

The second example actually modifies the object stored in the variable
'@a'. And that is a different issue.

daniel



Re: Type of literals

2008-06-26 Thread Daniel Ruoso
Qui, 2008-06-26 às 16:03 +0200, Moritz Lenz escreveu:
 In the test suite there are some tests like this:
 is(1.WHAT, 'Int', '1 as a literal is an Int);
 This seems to imply that we guarantee the direct type of literals. But
 do we?
 Actually I see no need for that. All my programs work fine if the
 literal 1 is of type Foo, and Foo isa Int.
 What's our policy on that? Will a 1.WHAT always return Int? do we
 guarantee (1..4).WHAT always to be 'Range'?

This is something I've been thinking about for some time. $a.WHAT is the
way to test for type identity, but allowing the user to expect a literal
to be from a specific given type is probably a bad idea, because

   (1..4).WHAT

should probably be ImplementationSpecificConstantCompactIntRange or
something like that. But I really think it's a matter of user
expectations, if we define that the effective type of the literals are
undetermined, the implementations will be free to use optimized types.

I think we should promote

   (1..4) ~~ Range

test, instead of

   (1..4).WHAT === Range

or even

   (1..4).WHAT eq 'Range'

daniel



Re: fallback semantics of list methods

2008-06-14 Thread Daniel Ruoso
Sáb, 2008-06-14 às 09:20 -0700, Larry Wall escreveu:
 On Sat, Jun 14, 2008 at 01:46:10PM +0200, Moritz Lenz wrote:
 : Fallback semantics in S12 suggest that since no matching multi method is
 : found, subs are tried - that is, the expression is interpreted as
 :join('str', 'other_str')
 : yielding 'other_str'. t/spec/S29-list/join.t disagrees, and wants the
 : result to be 'str'.
 I want the result to be 'str'.

Just a sanity check here... Are we really going to change the order of
the parameters of 'join' from p5?

Are we aware that this is going to be a PITA for most p5 developers?

Do we realise that this is only necessary to support 

  $nonlist.join($separator)

Which, as moritz pointed out on IRC is a very specific corner case,
which only makes sense on something like:

  my $a = $cond ?? ( 1 ) !! ( 2, 3, 4 );
  $a.join(',');

Which would have the desired effect if used with the proper sigil:

  my @a = $cond ?? 1 !! (2,3,4);
  @a.join(',');

If we choose to avoid supporting $nonlist.listmethod (which sounds lame
anyway), we can keep the order of parameters in join

  join $separator, @list;
  join ', ', 1, 2, 3, 4;

Which is considerably saner than:

  join 1, 2, 3, 4, ', ';

Moritz convinced me that there's actually no real reason to support

  $nonlist.listmethod

And if we stop, and think for more two seconds, we realise that
supporting that could end up having a lot of non-interesting side
effects, because an exported sub with the signature :(Any, Str) is most
likely to have a lot of false hits.

daniel



S12 Patch for metacalls, Representation API (Was: Re: Foo.HOW.metamethod vs Foo.^metamethod)

2008-06-11 Thread Daniel Ruoso
Seg, 2008-06-09 às 17:51 -0700, Larry Wall escreveu:
 On Sat, Jun 07, 2008 at 09:49:03PM +0100, Daniel Ruoso wrote:
 : 2) Assume the capture-translation and define that
 : $foo.HOW.can($foo,'bar') keeps the $how as the invocant and must receive
 : the referring object as first argument.
 I prefer this approach, I think.

I took the liberty to write a patch to S12 with this new context. The
extended format $foo.HOW.methods($foo) becomes a little awkward,
specially for Class based OO. Maybe there should be a more extended
modification to promote the .^methods syntax, since $foo.HOW is then
more usefull for prototype-based OO, where $foo.HOW might be, for
instance, Prototype::Delegation::C3 or Prototype::Concatenation.

This actually brings me to another issue, which is how much do we expect
for this prototype-based meta implementations to be exchangeable between
Perl 6 implementations?

The point is that they *must* be representation independent, so that you
can use it with whatever low-level object metainstance (in the Moose
jargon) you like, and for that to be possible, we need a representation
API. SMOP is already pointing in that direction, take a look at:

  * http://www.perlfoundation.org/perl6/index.cgi?smop_oo_api
  * http://svn.pugscode.org/pugs/v6/smop/src-s1p/P6Meta.pm

daniel

__DATA__

Index: S12.pod
===
--- S12.pod (revision 14546)
+++ S12.pod (working copy)
@@ -123,11 +123,15 @@
 CHOW method.  A class object is just considered an empty
 instance in Perl 6, more properly called a prototype object, or just
 protoobject.
-The actual class object is the metaclass object pointed to by the
-CHOW syntax.  So when you say CDog, you're referring to both a
-package and a protoobject, that latter of which points to the
-actual object representing the class via CHOW.  The protoobject
-differs from an instance object not by having a different
+
+In a class-based OO implementation, the actual class object is the
+metaclass object pointed to by the CHOW syntax.  So when you say
+CDog, you're referring to both a package and a protoobject, that
+latter of which points to the actual object representing the class via
+CHOW. In a prototype-based OO implementation, on the other hand, the
+metaclass object is probably going to be shared by several types and
+the methods are most likely going to be stored in the prototypes.  The
+protoobject differs from an instance object not by having a different
 type but rather in the extent to which it is defined.  Some objects
 may tell you that they are defined, while others may tell you that
 they are undefined.  That's up to the object, and depends on how the
@@ -1892,23 +1896,29 @@
 $x === $y
 $obj.bless(%args)
 
-Every class has a CHOW function/method that lets you get at the
-class's metaobject, which lets you get at all the metadata properties
-for the class (or other metaobject protocol) implementing the objects
-of the class:
+Every object, defined or not, has a CHOW function/method that lets
+you get at the metaobject, which lets you get at all the metadata
+properties for the type (or other metaobject protocol) implementing
+the objects of the type:
 
-MyClass.methods()   # call MyClass's .methods method (error?)
-MyClass.HOW.methods()   # get the method list of MyClass
+MyClass.methods()# call MyClass's .methods method (error?)
+MyClass.HOW.methods(MyClass) # get the method list of MyClass
 
 The C^ metasyntax is equivalent to C.HOW:
 
-MyClass.HOW.methods()   # get the method list of MyClass
-^MyClass.methods()  # get the method list of MyClass
-MyClass.^methods()  # get the method list of MyClass
+MyClass.HOW.methods(MyClass) # get the method list of MyClass
+^MyClass.methods(MyClass)
 
-Each object of the class also has a C.HOW or C.^ method:
+When using the C^ metasyntax in the method invocation, it also
+implies a translation in the capture, passing the invocant as first
+argument:
 
-$obj.HOW.methods();
+MyClass.HOW.methods(MyClass) # get the method list of MyClass
+MyClass.^methods()   # equivalent shorter syntax
+
+Each object of the type also has a C.HOW or C.^ method:
+
+$obj.HOW.methods($obj);
 $obj.^methods();
 
 Class traits may include:
@@ -1964,9 +1974,9 @@
 Strictly speaking, metamethods like C.isa(), C.does(), and C.can()
 should be called through the meta object:
 
-$obj.HOW.can(bark)
-$obj.HOW.does(Dog)
-$obj.HOW.isa(Mammal)
+$obj.HOW.can($obj, bark)
+$obj.HOW.does($obj, Dog)
+$obj.HOW.isa($obj, Mammal)
 
 or
 
@@ -1992,7 +2002,7 @@
 
 actually calls:
 
-$obj.HOW.does(Dog)
+$obj.HOW.does($obj, Dog)
 
 which is true if C$obj either does or isa CDog (or isa
 something that does CDog).  If CDog is a subset, any additional




Re: Google index and subsets (two topics for the price of one!)

2008-06-10 Thread Daniel Ruoso
Seg, 2008-06-09 às 23:36 +0100, Ovid escreveu:
 --- Jonathan Worthington [EMAIL PROTECTED] wrote:
  By default, block parameters (including $_) are readonly,
 I hope that is a deep readonly?  In other words, if $_.position returns
 an array reference, can I mutate a value in that reference and the
 state of $_ is thereby changed?

Even having said that in the other mail in this thread, I'd like to
stress the fact that *it's not possible to avoid side-effects of a
method call*, if that method call have a side effect (even if a inside
effect). And again, some neat things will only be possible because of
that.

daniel



Foo.HOW.metamethod vs Foo.^metamethod

2008-06-08 Thread Daniel Ruoso
Hi,

When implementing prototype OO, the HOW for objects with different
behaviours will be shared. This issue is not new, but before we thought
that it would be possible to solve that by forcing $foo.HOW to be a
proxy object that would rewrite the call putting $foo as the invocant.

Me and nothingmuch, during PPW in Braga, got more into that issue, and
we came to the realisation that this is not really possible, as it might
be actually desirable to have a real meta object, storing
meta-information that would be part of that metaobject implementation.

The HOW might be implementing some kind of RPC, for instance, and that
way, it might need to store some meta-meta-information, like the address
of the RPC endpoint. This makes the idea of the proxy object inviable
because the user might need to talk to the HOW as a real object.

That way, 

$foo.^can('bar') cannot be the same as $foo.HOW.can('bar'), because the
first has both $foo and $foo.HOW implied, while, in the last, $foo
cannot be taken from anywhere.

Therefore I suggest making $foo.^method format the only way to get
metamethods related to this object, while $foo.HOW would have a
behaviour which would be implementation dependent (at least until it's
standartized)

SMOP will have $foo.^can('bar') actually translated to
$foo.HOW.can($foo, 'bar'), which will keep $foo.HOW as the invocant, and
prepend the referring object as the first positional argument (following
the example of the sub-dispatch fallback).

In that case, we might either:

1) remove all references of $foo.HOW.can('bar') and say that this is
implementation specific (since Class-based OO can implement it that way)

2) Assume the capture-translation and define that
$foo.HOW.can($foo,'bar') keeps the $how as the invocant and must receive
the referring object as first argument.

daniel



Re: yada yada yada in regex

2008-06-08 Thread Daniel Ruoso
Sáb, 2008-06-07 às 16:01 +0200, Stéphane Payrard escreveu:
 what is the equivalent convention for yadayadayada in regex. Cuz  ...
 is alread meaningful in regex.  Should I use ... or {...} ?
 Should the first be predefined?

If I understand correctly, {...} should already be parsed as a yada yada
yada closure, since ... is 'like' a statement.

I might be missing something, but ... would be a rule with the '...'
name which, I think, is parseable, and could even be implemented

daniel



Re: First look: Advanced Polymorphism whitepaper

2008-05-02 Thread Daniel Ruoso

Sex, 2008-05-02 às 14:38 +0200, TSa escreveu:
 Ovid wrote:
  However, the CGI/CGI::Simple example I posted earlier doesn't fulfill
  this.  CGI::Simple offers a subset of CGI.pm's functionality and it's
  guaranteed to be identical
 Then, since classes are open, the programmer can easily say
CGI does CGI::Simple;
 and let go CGI instances wherever a CGI::Simple is expected.
 As added value you can get a compiler check with

Not really... 'does' will try to compose the CGI::Simple methods to the
CGI class (although I think your example was supposed to be CGI::Simple
does CGI, but anyway). You don't want to change the class
implementation, you just want to annotate an additional 'interface' on
the given implementation.

I'm actually not sure that you can have 'CGI does CGI::Simple', since
CGI::Simple is not a role...

daniel



Re: treatment of isa and inheritance

2008-05-02 Thread Daniel Ruoso

Qua, 2008-04-30 às 12:53 -0400, Brandon S. Allbery KF8NH escreveu:
 It occurs to me that this shouldn't be new keywords, but adverbs, i.e.  
 ``is :strict Dog''.

I don't really see what this is :strict means in the runtime
environment. Perl 6 takes OO so deeply that even the type checking is
implemented as a cal to the object. There isn't really a way of asking
are you trully really a Dog?, there's only do you 'Dog'?.

P.S.: Of course optimizations may be more static, but it should be also
able to pessimize when dealing with an unknown object implementation.

daniel



Re: First look: Advanced Polymorphism whitepaper

2008-05-02 Thread Daniel Ruoso

Sex, 2008-05-02 às 18:55 +0200, TSa escreveu:
 For me, too. But note that we should keep does the ultimate
 type checker that first checks the declared presence of a role,
 then falls back to a declared class inheritance and then falls
 back to a declared emulation. What else should be in this check
 sequence?

You're taking it backwards, it's not the type checker that is aware of
that, but each object's metamodel. The metamodel protocol is just the
do you 'Dog'? thing.

daniel



Re: First look: Advanced Polymorphism whitepaper

2008-05-02 Thread Daniel Ruoso
Sex, 2008-05-02 às 21:49 +0200, TSa escreveu:
 Daniel Ruoso wrote:
  In fact, it simply means that it's up to that object's metaobject to
  answer that, and not to a supra-meta-model to be able to answer to all
  of the possible metamodel implementations.
 Since all three forms are derived from a programmer's declaration
 involving names the problem is simple lookup, indeed. The fact that
 N objects share one meta object is just for reducing the memory
 footprint. You could make every object carry the full meta info
 around.

And more importantly, the fact is that they *can* carry the full meta
info around, and even more importantly, they might even build completely
different set of features.

  You can do that as shortcuts and optimizations that are indeed
  needed in order to actually bootstrap the system, but that's not what
  the type system is.
 Would you be so kind to enlighten me what the type system is, if
 not a type calculation overlaid over a value calculation?

I think that migth be the key point to understand our disagreement.
There's no such thing as *the* Perl 6 type system, there's *a default*
type system declared in the spec, but what Perl 6 has is a *meta object
protocol* that allows you to deal with several type systems at once.

daniel



Re: First look: Advanced Polymorphism whitepaper

2008-05-02 Thread Daniel Ruoso

Sex, 2008-05-02 às 09:08 -0500, John M. Dlugosz escreveu:
 A syntax is needed for this express concept:  accept B as a substitute 
 for A, without changing A.

Which I'm advocating as

   class CGI::Simple realises CGI { ... }

or

   CGI::Simple is also { realises CGI }

or even...

   $cgi_simple realises CGI;

daniel





Re: First look: Advanced Polymorphism whitepaper

2008-05-02 Thread Daniel Ruoso

Sex, 2008-05-02 às 21:22 +0200, TSa escreveu:
 Or do you mean backwards in the sense that the priority is with the
 object somehow?

In fact, it simply means that it's up to that object's metaobject to
answer that, and not to a supra-meta-model to be able to answer to all
of the possible metamodel implementations.

 I understand that you implement Perl 6 with a fully OO system. But
 the all objects are equal doesn't work out. You need some Orwellians
 which are more equal. The type-checker is one of these. Of course
 there can be more than one checker but in a scope there's exactly one
 in charge at any given point in time. Other Orwellians are the compiler,
 the namespace manager, the grammar engine, the dispatcher etc.

You can do that as shortcuts and optimizations that are indeed
needed in order to actually bootstrap the system, but that's not what
the type system is.

daniel



Pragma for type matching alternative implementations (Was: Re: treatment of isa and inheritance)

2008-04-30 Thread Daniel Ruoso

Ter, 2008-04-29 às 21:03 -0500, John M. Dlugosz escreveu:
 In response to questions on my whitepaper, I made this companion
 to bring people up to speed on the issue.
 http://www.dlugosz.com/Perl6/web/isa-inheritance.html

Very interesting reading... :)

It actually made me think that it would be possible to implement it as a
pragma.

   class A { has $.a };
   class B { has $.b };
   sub foo { A $a } { ... }
   {
   foo(B.new()); # FAIL
   use typematch 'like';
   foo(B.new()); # OK
   use typematch 'does';
   foo(B.new()); # FAIL 
   }

This could be achieved simply by scope-redefining
infix:~~(Object,Object) to use another implementation.

(Note that I'm trying at all costs to avoid adding that as a signature
trait, because that would complicate the dispatching ;)

daniel



Re: treatment of isa and inheritance

2008-04-30 Thread Daniel Ruoso

Qua, 2008-04-30 às 15:55 +0200, TSa escreveu:
 But the type system is part of the language core.
 As such 'isa' and 'like' or assignment and binding semantics
 need a definition.

Actually, this is one of the hardest parts of implementing Perl 6,
because even 'isa', 'like', assignment and binding are dependent on the
representation of the given objects, so even such basic operations are
polymorphic.

This makes the bootstrap of the type system harder, but not impossible.
What happens is that, as it is polymorphic, I can provide known
low-level implementation of higher-level types that will interoperate
transparently with them. By doing that I can bootstrap by special-casing
the low-level implementations and getting out of the water that way.

This also allows some other interesting features, like the fact that I
may have a constant identifier that interoperates with Str while I still
can compare to of them simply by comparing their pointer addresses, or
by providing a shadow object that points to the inner data structure of
other object in order to expose the expected API.

In fact, that is the exact point that makes it possible for Perl 6 to
have a *fully* boostrapped type system. What defines native types in
Perl 6 is not that they have a incompatible lowlevel structure (because
they don't, unless optimized), but that they are the only types that the
interpreter may expect to know how they look like. Everything else
should be opaque to the interpreter (but eventually the optimizer may
have a catalog to inspect the internals directly).

Take a look at 

http://www.perlfoundation.org/perl6/index.cgi?smop_p6opaque_implementation

and at

http://www.perlfoundation.org/perl6/index.cgi?smop_oo_api

To see how that's being implemented in SMOP.

daniel



Re: First look: Advanced Polymorphism whitepaper

2008-04-30 Thread Daniel Ruoso

Qua, 2008-04-30 às 08:56 -0700, Ovid escreveu:
 I had initially thought this, but think about the case where someone
 wants to rewrite something to be compliant to another interface.  If I
 pass a CGI::Simple object to a method expecting a CGI object, there's
 an excellent chance that it will *just work*, even though there's no
 relation between the two.  In this case, a role really doesn't work.

This makes me think that 'realises' has a considerably more common usage
than I thought... Every time you implement something like CGI::Simple,
you would like to say 'CGI::Simple realises CGI'.

Of course that, in an ideal OO world, CGI would be an abstract role that
both the default CGI implementation and CGI::Simple would 'do'. But that
seems to javaish to me (read that as something I hate;), and having how
to 'lie' about who you are seems more like a Perl thing to do...

daniel



Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)

2008-04-29 Thread Daniel Ruoso

Ter, 2008-04-29 às 09:28 +0200, TSa escreveu:
 The thing is the .^does  traverses the meta information
 to find the *named* concept Point. The FoxPoint in John's
 example doesn't have that and thus nominally fails the
 Point test. The idea is now to also have

.^does *might* traverse the information as well as simply return true if
the object says so.

The point here is whom to delegate the association between FoxPoint and
Point...

If we are to define an operator to declare that some arbitrary object
conforms to some API, I would think the following as saner...

sub foo(Point $p) {...};
FoxPoint $fp = ...;
$fp realises Point;
foo($fp);

This way, the dispatching mechanism is still the same (and still typed),
but the object now also answers true to .^does(Point).

Which means that the typed code remains typed and the feature is
implemented as a trait that can be used to any object, thus leaving the
fragile type inference to the code calling the method and not to the
method that wants a stronger typing...

daniel 



Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)

2008-04-29 Thread Daniel Ruoso

Ter, 2008-04-29 às 11:54 +0200, TSa escreveu:
  If we are to define an operator to declare that some arbitrary object
  conforms to some API, I would think the following as saner...
  sub foo(Point $p) {...};
  FoxPoint $fp = ...;
  $fp realises Point;
  foo($fp);
 Here the spec is quite clear that 'realises' is spelled 'does'.
 This is the infix operator that composes a role into an object's
 class at runtime.

Not really... 'does' is a composition operation, 'realises' would be
just a type annotation that doesn't change the actual composition.

  This way, the dispatching mechanism is still the same (and still typed),
  but the object now also answers true to .^does(Point).
 But note that
 FoxPoint $fp = ...;
 $y = $fp;
 $y === $fp; # obviously true
 $fp does Point;
 $y === $fp; # false because of different HOW?

Wrong. $fp is still the same object and $y would also answer true
to .^does(Point). it's an in-place change, not a copy. you would need to
do

  $y = $fp.clone();

to keep the non-typed version.

 Unfortunately S03 doesn't say if === checks for the same WHAT or the
 same HOW as precondition to checking the WHICH.

It doesn't. By definition. === only checks WHICH.

 Generally WHAT is also quite underspecced.

WHAT is implementation specific, it's underspecced for that reason.

  Which means that the typed code remains typed and the feature is
  implemented as a trait that can be used to any object, thus leaving the
  fragile type inference to the code calling the method and not to the
  method that wants a stronger typing...
 I don't understand what you want to say here.

I mean, the code that is calling the method would be the one doing the
untyped-typed mapping, not the calling sub signature (which would make
the dispatch much slower).

daniel



Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)

2008-04-29 Thread Daniel Ruoso
[ I'm using this message to reply, because I didn't receive your
reply... I'm taking it from the list history... There really seems to be
something wrong with this list... ]

TSa wrote:
 BTW, is WHICH globally unique? Or is that also an
 implementation detail?

This is not specced apparently to leave room for decision in the
implementation. But there's an important question to be answered before
that...

what is the type returned by WHICH?

I haven't implemented that in SMOP yet (because I have the constant
identifiers that allow me to make simple pointer comparison), but I
think in the low-level it will end-up being something like a native
binary blob.

Which means that every non-native type will, in the end, have to be
reduced to native types in the WHICH call to provide a proper value for
comparison.

TSa wrote:
 So, even though the WHICH stays the eqv check has to change:
 $a = A.new( a = 0); # your class A
 $b = A.new( a = 0);
 $a === $b; # False, but
 $a eqv $b; # True because of snapshot semantic
 $b does Point;
 $a eqv $b; # False because HOW or WHAT is different

But it's important to keep in mind that eqv behaviour might also be
overriden by the object, that might give a canonical representation that
matches the other object.

An implementation of the 'realises' trait could make its canonical
representation unchanged.

As I said earlier, 'does' is an composition operator, it will change the
class composition, therefore making it a different object.

On the other hand, a 'realises' trait could change the object in order
that it would still match with both 'eqv' and '===', while still '~~' to
an additional type.

This would be done simply by creating an anonymous class that isa the
original class while overriding .^does, WHICH and eqv to shadow to the
original class, and then re-blessing the object to this anonymous class.

TSa wrote:
 But I would like to reserve infix:like for a type check without
 subsequent canonical value comparison. That is continuing from above
$b.inc;
$a like $b; # still true even though $a.a != $b.a

It doesn't need to be part of the spec, it's a simple module that
traverses .^methods to check if $a implements all methods described by
$b. You might want to implement it already in other to reserve the
name ;).

daniel



Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)

2008-04-29 Thread Daniel Ruoso
Ter, 2008-04-29 às 14:21 +0200, TSa escreveu:
 Daniel Ruoso wrote:
  Not really... 'does' is a composition operation, 'realises' would be
  just a type annotation that doesn't change the actual composition.
 OK, but that is not in the spec yet. To me that is like the
 proposed 'like' operator but with the programmer taking full
 responsibility. Like reinterpret_cast in C++.

It doesn't need to be. New traits can be implemented later.

 First of all assignment has copy semantics. That is after $y = $fp,
 $y =:= $fp is false. I agree that

It will copy the scalar, which means that later change in the value cell
won't propagate to the other variable. But both cells point to the same
value.

 $a = $b;
 $a === $b; # TRUE
 $a =:= $b; # FALSE
 $b = $c;
 $a === $b; # FALSE

As opposed to

 $a := $b;
 $a === $b; # TRUE
 $a =:= $b; # TRUE
 $b = $c;
 $a === $b; # TRUE

In the later, the scalar itself is copied, which means that both
variables *are* the same scalar, and changing the cell value in one is
the same as changing the cell value in the other.

So...

 class A { has $.a; method inc { $.a++ } };
 $a = A.new( a = 0);
 $b = $a;
 $b.inc();
 $a.inc();
 say $a.a; # 2
 say $b.a; # 2

Will work as expected.

 But either the HOW, the WHAT or both of $fp have to change

That is true

 which implies that $y === $fp can't remain true after
 $fp does Point

Not really... see below...

 BTW, an interesting question is if a typed
 binding could become invalid:
subset AntiPoint of Any where {not .^does(Point)}
my AntiPoint $ap := $fp; # fine for now
$fp does Point; # now $ap is bound to a Point which
# violates the AntiPoint constraint

This is a composition error that generates an exception. It even
provides enough information for a compile-time error.

  It doesn't. By definition. === only checks WHICH.
 Then we must read different versions of S03. Mine has the
 sentence Two values are never equivalent unless they are
 of exactly the same type.

*Value types*!!! Which is not the case here, we are talking about
*Object types*, also in S03:

   for two mutable types (object types), checks whether they have the
   same identity value. (For most such types the identity is simply the
   reference itself.)

Which means that (continuing the code starting with class A)...

   $a = A.new(a = 0);
   $b = $a;
   $a === $b; # TRUE
   $b.inc;
   $a === $b; # TRUE

daniel



Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)

2008-04-28 Thread Daniel Ruoso

Seg, 2008-04-28 às 10:15 -0700, Jon Lang escreveu:
 Ah; that clears things up considerably.  If I understand you
 correctly, John is using '£' to mean use Duck Typing here.  _That_,
 I can definitely see uses for.

hrmm... I might just be overlooking something... but...

sub foo (Point $p) {...}

means...

$signature ~~ $capture

means...

Point $p := $capture[0]

means...

$capture[0] ~~ Point

means...

$capture[0].^does(Point)

which is implementation specific, but as for what it's worth, might be
abasolutely anything that says true to that call, even if it's just a
reference to a pointer in a low-level binding of some library...

The point I'm trying to make is that Perl 6 already accepts anything
that does Point, even if it isn't a Point, that happens basically
because Perl 6 have polymorphic representation.

That actually means that you *never* can count on knowing how the
object is implemented (except for native types, of course). So there's
actually no need for the like idiom, because there's no true isa in
Perl 6.

In Perl 6 one object isa something as long as it says true to isa
something. The only exceptions are the native types, see
http://www.perlfoundation.org/perl6/index.cgi?smop_native_types for a
little longer reasoning on that.

daniel





<    1   2