Parallelism and Concurrency II

2010-05-21 Thread Daniel Ruoso
Hi,

After lots of debates off-list (specially with BrowserUk), I got to the
following conclusions:

 - Each OS thread runs a cooperative-event-scheduler where coroutines
   might be enqueued.

 - map returns the buffer immediatly and enqueues a coroutine to process
   the data.

 - Explicit parallel markings such as the feed operator, means a new OS 
   thread with its own cooperative scheduler is spawned.

 - Data that is shared between thread is selectively marked that way to 
   make sure they are thread safe.

 - The actor model can be implemented in a different module.

So, a quick summary of how the following code would run is attached:

  my @a := map { cheap_op($_) } == map { expensive_op($_) }, $*IN

The value sharing framework is still to be designed, but it's clear
that forcing actor model for everything was too intrusive, so we allow a
balance of shared state and massage-passing concurrency. This
balance will be implemented by modules.

comments are appreciated.

daniel
attachment: Perl6ThreadingModel.svg

Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message (nntp: message 18 of 20) 14 of 20) Object-Belongs-to-Thread threading model

2010-05-18 Thread Daniel Ruoso
Em Dom, 2010-05-16 às 19:34 +0100, nigelsande...@btconnect.com escreveu:
 3) The tough-y: Closed-over variables.
 These are tough because it exposes lexicals to sharing, but they are so  
 natural to use, it is hard to suggest banning their use in concurrent  
 routines.

This is the point I was trying to address, actually. Having *only*
explicitly shared variables makes it very cumbersome to write threaded
code, specially because explicitly shared variables have a lot of
restrictions on what they can be (this is from my experience in Perl 5
and SDL, which was what brought me to the message-passing idea).

 However, interpreters already have to detect closed over variables in  
 order to 'lift' them and extend their lifetimes beyond their natural  
 scope.

Actually, the interpreter might choose to to implement the closed-up
variables by keeping that entire associated scope when it is still
referenced by another value, i.e.:

 { my $a;
   { my $b = 1;
 { $a = sub { $b++ } } }

this would happen by the having every lexical scope holding a reference
to its outer scope, so when a scope in the middle exits, but some
coderef was returned keeping it as its lexical outer, the entire scope
would be kept.

This means two things:

1) the interpreter doesn't need to detect the closed over variables, so
even string eval'ed access to such variables would work (which is, imho,
a good thing)

2) all the values in that lexical scope are also preserved with the
closure, even if they won't be used (which is a bad thing).

 It doesn't seem it would be any harder to lift them to shared  
 variable status, moving them out of the thread-local lexical pads and into  
 the same data-space as process globals and explicitly shared data.

It is still possible to do the detection on the moment of the runtime
lookup, tho...

 My currently favoured mechanism for handling shared data, is via  
 message-passing, but passing references to the shared data, rather than  
 the data itself. This seems to give the reason-ability, compose-ability  
 and controlled access of message passing whilst retaining the efficiency  
 of direct, shared-state mutability.

That was part of my idea too, I wasn't trying to address remote
processes or anything like that, I was considering doing the queues in
shared memory for its efficiency.

 Only the code that declares the shared  
 data, plus any other thread it choses to send a handle to, has any  
 knowledge of, and therefore access to the shared state.

If we can overcome the limitations we have in Perl 5 shared values, I'm
entirely in agreement with the above statement (assuming closed-over
values become shared transparently)

 Effectively, allocating a shared entity returns a handle to the underlying  
 state, and only the holder of that handle can access it. Such handles  
 would be indirect references and only usable from the thread that creates  
 them. When a handle is passed as a message to another thread, it is  
 transformed into a handle usable by the recipient thread during the  
 transfer and the old handle becomes invalid. Attempt to use an old handle  
 after it has been sent result in a runtime exception.

This is exactly what I meant by RemoteValue, RemoteInvocation and
InvocationQueue in my original idea. 

daniel



Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message (nntp: message 18 of 20) 14 of 20) Object-Belongs-to-Thread threading model

2010-05-18 Thread Daniel Ruoso
Em Dom, 2010-05-16 às 19:34 +0100, nigelsande...@btconnect.com escreveu:
 Interoperability with Perl 5 and  
 is reference counting should not be a high priority in the decision making  
 process for defining the Perl 6 concurrency model.

If we drop that requirement then we can simply go to the
we-can-spawn-as-many-os-threads-as-we-want model..


daniel




Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message (nntp: message 18 of 20) 14 of 20) Object-Belongs-to-Thread threading model

2010-05-18 Thread Daniel Ruoso
Em Ter, 2010-05-18 às 15:15 +0100, nigelsande...@btconnect.com escreveu:
  1) the interpreter doesn't need to detect the closed over variables, so
  even string eval'ed access to such variables would work (which is, imho,
  a good thing)
 You'd have to explain further for me to understand why it is necessary to  
 keep whole scopes around:
 - in order to make closures accessible from string-eval;
 - and why that is desirable?

I have no strong opinion on that, actually... Pointing to the outer
scope was simply an easy way to have it working... 

But this is currently, iirc, a requirement for the language, and
supported by rakudo and pugs...

ruoso perl6: my $a; { my $b = 1; $a = sub { return eval '$b++' } };
say $a.(); say $a.(); say $a.();
p6eval ..pugs, rakudo 689429: OUTPUT«1␤2␤3␤»


  2) all the values in that lexical scope are also preserved with the
  closure, even if they won't be used (which is a bad thing).
 Please no! :)
 This is essentially the biggest problem with the Perl 5 iThreads  
 implementation. It is the *need* (though I have serious doubts that it is  
 actually a need even for Perl 5), to CLONE entire scope stacks every time  
 you spawn a thread that makes them costly to use.

hmmm... I wasn't expecting to clone the entire scope stack, but rather
to ask the owner of the outer scope for a value...

But I have to admit that importing the symbols used from outer scopes to
the current scope and making them shared (or a RemoteValue in my
original idea) is probably prettier. Accessing the OUTER scope in
run-time (via string eval, OUTER::{$var} or CALLER::{$var}) could be
subject to additional restrictions.

daniel



Re: Re: Parallelism and Concurrency was Re: Ideas for aObject-Belongs-to-Thread (nntp: message 4 of 20) threading model (nntp: message 20 of 20 -lastone!-) (nntp: message 13 of 20)

2010-05-18 Thread Daniel Ruoso
Em Ter, 2010-05-18 às 12:58 -0700, Alex Elsayed escreveu:
 You are imposing a false dichotomy here. Neither 'green' threads nor kernel
 threads preclude each other. In fact, it can  be convincingly argued that they
 work _best_ when combined. Please look at the GSoC proposal for hybrid
 threading on the Parrot list.

While I agree that there isn't a dichotomy, the point here is more in
the lines of:

 1) Green threads are usually related to the requirement of serialized 
access to data so you can share all data in the thread without 
resorting to locks for every value.

 2) If that requirement is dropped, once only data that is explicitly   
marked as shared can be seen by both threads, the point for green 
threads is moot, since the OS threads are always going to be better 
performant then a manually implemented scheduler.

My original idea was pointing in creating a shared memory space that
would be seen by every green thread in the same os thread, where some
lines would be drawn to allow OS threading with different memory spaces
- message passing would be used to communicate between two different
memory spaces.

But what we might be getting here is at the point where we don't need
green threads at all... I'm still not sure about one point or another,
tho..

daniel



Re: Parallelism and Concurrency was Re: Ideas for a Object-Belongs-to-Thread threading model

2010-05-14 Thread Daniel Ruoso
Em Sex, 2010-05-14 às 15:48 +0400, Richard Hainsworth escreveu:
 The less, or rather the more abstract, the specification in perl6, the
 less likely perl6 will 'age'.

I think the important thing to realize here is that the Perl 6 language
keeps its definitions mostly abstract. Junctions, Hyper Operators, even
the async block, specify almost no requirements on the concurrency
model.

The discussion is more about *one* specific threading model designed to
support all the Perl 6 features in a scalable way.

daniel



Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message 14 of 20) Object-Belongs-to-Thread threading model

2010-05-14 Thread Daniel Ruoso
Em Sex, 2010-05-14 às 18:13 +0100, nigelsande...@btconnect.com escreveu:
 The point I(we)'ve been trying to make is that once you have a reentrant  
 interpreter, and the ability to spawn one in an OS thread,
 all the other bits can be built on top. But unless you have that ability,  
 whilst the others can be constructed, the cannot make
 use of SMP. Eg. They cannot scale.

Okay, this is an important point... Having a reentrant interpreter is a
given already, The form I tried to implement that in SMOP was by using
CPS.

The idea of using green threads is just to enforce serialized access to
some data in order to avoid locking (locking with the amount of
polymorphism required by Perl 6 is too expensive), and then the regular
threads wouldn't share data between them.

Of course we could try to have the data structures thread-safe, I didn't
try to go that path since I was trying to get Perl 5 interoperability
and therefore used refcount garbage collector.

The other possibility would be to use processor affinity to force
different threads to spawn in the same processor and that way ensure
serialized access to the non-thread-safe data.

daniel



Re: Ideas for a Object-Belongs-to-Thread threading model

2010-05-12 Thread Daniel Ruoso
BrowserUK wrote:
  -there are the interpreter processes.
  Inventing (overloaded) terminology will just create confusion. Very
  unhelpful in a context that suffers more than its fair share already.

Okay, I should probably call them Actors to use a more precise
terminology - since this is highly inspired in two Actor Model
languages.
 
 - The interpreter implements a scheduler, just like POE.
  POE does *NOT* implement a scheduler. 

Okay, mentioning POE was just a side comment, it doesn't interfere
directly in the model.

   -3 - The scheduler, ulike POE, should be able to schedule in
   several OS threads, such that any OS thread may raise any
   waiting process.
  And how are you going to implement that? 

That was the part I took directly from the inspiring languages, just
take a look in how Erlang and the IO language schedule their actors.

  The only way would be for there to be multiple concurrent (kernel
  threaded) instances of the state-machine running sharing (as in shared
  state concurrency) their controlling state.   

But maybe each actor is tied to a particular OS thread, which would
simplify a bit... Also, it is possible to suspend an actor in order to
implement a time-sharing scheduler as well... 

daniel



Second Version of Ideas for a Object-Belongs-to-Thread threading model

2010-05-12 Thread Daniel Ruoso
Em Ter, 2010-05-11 às 21:45 -0300, Daniel Ruoso escreveu:
 The threading model topic still needs lots of thinking, so I decided to
 try out some ideas.

After BrowserUK feedback and some more reading (including
http://www.c2.com/cgi/wiki?MessagePassingConcurrency ) and links from
there on, I decided to rewrite that ideas in a bit different model, but
still with the same spirit.

0 - The idea is inspired by Erlang and the IO Language. Additionally
to OS threads there are the Coroutine Groups.

1 - No memory is shared between Coroutine Groups, so no locking is
necessary.

2 - A value and a coroutine always belong to a Coroutine Group,
which should be assigned to a single OS thread, thus naturally
implementing synchronized access to data.

3 - The interpreter implements a scheduler, which will pick one of the
waiting coroutines that belong to the groups assined to the
current thread. The scheduler may also suspend a coroutine in
order to implement time-sharing. The scheduler should support
blocking states in the coroutines.

4 - When comparing to Perl 5, each coroutine is an ithread, but memory
is shared between all the coroutines in the same group, given that
they will always run in the same OS thread.

5 - When a coroutine group is created, it is assigned to one OS
thread, the interpreter might decide to create new OS threads as
necessary, it might optionally implement one OS thread per
coroutine group.

6 - In order to implement inter-coroutine-group communication, there
are:

6.1 - A MessageQueue works just like an Unix Pipe, it looks like
  a slurpy array. It has a configurable buffer size and
  coroutines might block when trying to read and/or write to
  it.

6.2 - A RemoteInvocation is an object that has a identifier, a
  capture (which might, optionally, point to a MessageQueue
  as input) and another MessageQueue to be used as output.
  New coroutines are created in the target group to execute
  that invocation.

6.3 - An InvocationQueue is a special type of MessageQueue
  that accepts only RemoteInvocation objects.
  
6.4 - A RemoteValue is an object that proxies requests to
  another coroutine group through a RemoteInvocation.

7 - The coroutine group boundary is drawn by language constructs such
as async, the feed operator, junctions, hyper operators.

8 - A value might have its ownership transferred to another group if
it can be detected that this value is in use only for that
invocation or return value, in order to reduce the amount of
RemoteInvocations.

9 - A value might do a special ThreadSafe role if it is thread-safe
(such as implementing bindings to thread-safe native libraries) In
which case it is sent as-is to a different group.

10 - A value might do a special ThreadCloneable role if it should be
 cloned instead of being proxied through a RemoteValue when sent
 in a RemoteInvocation.

11 - The MessageQueue notifies the scheduler whenever new data is
 available in that queue so the target coroutine might be raised.

12 - Exception handling gets a bit hairy, since exceptions might only
 be raised at the calling scope when the value is consumed.

13 - List assignment and Sink context might result in synchronized
 behavior.

comments are appreciated...

daniel



Third and simplified version of Ideas for a Object-Belongs-to-Thread threading model

2010-05-12 Thread Daniel Ruoso
Em Ter, 2010-05-11 às 21:45 -0300, Daniel Ruoso escreveu:
 he threading model topic still needs lots of thinking, so I decided to
 try out some ideas.

After I sent the second version, I just realized I could make it simpler
by just assuming one OS thread per Coroutine Group... so here goes the
new version.

0 - No memory is shared between threads, so no locking is necessary.

1 - A value and a coroutine always belong to a thread, thus naturally
implementing synchronized access to data.

2 - Coroutines are, conceptually, the equivalent to green threads,
running in the same OS thread. Coroutines waiting for a return
value are blocked.

3 - The interpreter implements a scheduler, which will pick one of the
waiting coroutines, it may also suspend a coroutine in order to
implement time-sharing.

4 - In order to implement inter-thread communication, there are:

4.1 - A MessageQueue works just like an Unix Pipe, it looks like
  a slurpy array. It has a configurable buffer size and
  coroutines might block when trying to read and/or write to
  it.

4.2 - A RemoteInvocation is an object that has a identifier, a
  capture (which might, optionally, point to a MessageQueue
  as input) and another MessageQueue to be used as output.
  New coroutines are created in the target thread to execute
  that invocation.

4.3 - An InvocationQueue is a special type of MessageQueue
  that accepts only RemoteInvocation objects.
  
4.4 - A RemoteValue is an object that proxies requests to
  another coroutine group through a RemoteInvocation.

5 - The thread group boundary is drawn by language constructs such
as async, the feed operator, junctions, hyper operators.

6 - A value might have its ownership transferred to another thread if
it can be detected that this value is in use only for that
invocation or return value, in order to reduce the amount of
RemoteInvocations.

7 - A value might do a special ThreadSafe role if it is thread-safe
(such as implementing bindings to thread-safe native libraries) In
which case it is sent as-is to a different thread.

8 - A value might do a special ThreadCloneable role if it should be
 cloned instead of being proxied through a RemoteValue when sent
 in a RemoteInvocation.

9 - Exception handling gets a bit hairy, since exceptions might only
 be raised at the calling scope when the value is consumed.

10 - List assignment and Sink context might result in synchronized
 behavior.


daniel



Re: Ideas for a Object-Belongs-to-Thread threading model

2010-05-12 Thread Daniel Ruoso
Em Qua, 2010-05-12 às 10:12 -0700, Dave Whipp escreveu:
 Before discussing the implementation, I think it's worth while
 stating 
 what it is that you are attempting to abstract. For example, is the 
 abstraction intended for a mapping down to a GPU (e.g. OpenCL) with a 
 hierarchical address space, or is it intended for a multicore CPU
 with 
 linear address space, or is it intended to abstract a LAN, with 
 communication via sockets (reliable TCP? unreliable UDP?), or is it 
 intended to abstract the internet/cloud?

Initially I'd consider regular OS threads and queues implemented in the
process address space. I'd consider other abstractions to be possible,
but probably better implement them as separated modules...

daniel



Ideas for a Object-Belongs-to-Thread threading model

2010-05-11 Thread Daniel Ruoso
Hi,

The threading model topic still needs lots of thinking, so I decided to
try out some ideas.

Every concurrency model has its advantages and drawbacks, I've been
wondering about this ideas for a while now and I think I finally have a
sketch. My primary concerns were:

 1 - It can't require locking: Locking is just not scalable;
 2 - It should perform better with lots of cores even if it suffers
 when you have only a few;
 3 - It shouldn't require complicated memory management techniques that 
 will make it difficult to bind native libraries (yes, STM is damn 
 hard);
 4 - It should suport implicit threading and implicit event-based  
 programming (i.e. the feed operator);
 5 - It must be easier to use then Perl 5 shared variables;
 6 - It can't use a Global Interpreter Lock (that already said in 1, 
 but, as this is a widely accepted idea in some other environments,
 I thought it would be better to make it explicit).

The idea I started was that every object has an owner thread, and only
that thread should talk to it, and I ended up with the following,
comments are appreciated:

0 - The idea is similar to Erlang and the IO Language. Additionally
to OS threads there are the interpreter processes.

1 - No memory is shared between processes, so no locking is
necessary.

2 - The interpreter implements a scheduler, just like POE.

3 - The scheduler, unlike POE, should be able to schedule in
several OS threads, such that any OS thread may raise any
waiting process.

4 - Each process is run in only one OS thread at a time, it's
like a Global Interpreter Lock, but it's related only to one
specific process.

5 - A process may block, and the scheduler must become aware of
that blocking. That is implemented through Control
Exceptions.

6 - In order to implement inter-process communication, there are:

6.1 - A MessageQueue works just like an Unix Pipe, it looks
  like a slurpy array. It has a configurable buffer size
  and processes might block when trying to read and/or
  write to it.

6.2 - A RemoteInvocation is an object that has an identifier, a
  capture (which might, optionally, point to a MessageQueue
  as input) and another MessageQueue to be used as output.

6.3 - An InvocationQueue is a special type
  of MessageQueue that accepts RemoteInvocation
  objects.
  
6.4 - A RemoteValue is an object that proxies requests to
  another processes through a RemoteInvocation.

7 - The process boundary is drawn at each closure, every closure
belongs to a process, every value initialized inside a
closure belongs to that closure. You might read coroutine instead
of closure if you like.

8 - A value might have its ownership transferred to another closure if
it can be detected that this value is in use only for that
invocation or return value, in order to reduce the amount of
RemoteInvocations.

9 - A value might do a special ThreadSafe role if it is thread-safe
(such as implementing bindings to thread-safe native libraries) In
which case it is sent as-is to a different thread.

10 - A value might do a special ThreadCloneable role if it should
 be cloned instead of being proxied through a RemoteValue
 when sent to a different process.

11 - The MessageQueue notifies the scheduler through a Control
 Exception whenever new data is available in that queue so the
 target process might be raised.

12 - Exception handling gets a bit hairy, since exceptions might only
 be raised at the calling scope when the value is consumed.

13 - List assignment and Sink context might result in synchronized
 behavior.

comments? ideas?

daniel



Re: Methodicals: A better way to monkey type

2010-04-21 Thread Daniel Ruoso
Em Qua, 2010-04-21 às 00:16 -0700, Stefan O'Rear escreveu:
 Normally, when you write a method call, the definition of the method is
 entirely in the domain of the receiver's class:
 $object.make-me-a-sandwich;  # $object gets to decide what this means

Actually, this is delegated to the dispatcher, which is composed in at
least three different parts:

  1 - The general dispatching mechanism which iiuc, is lexically 
  defined and which, by default, implements something like:

@*current_invocation_candidates = $object.^can($capture);
@*current_invocation_candidates.shift.postcircumfix:( )($capture);

  2 - The MRO resolver, which is implemented inside ^can, and is
  completely internal to the class.

  3 - The actual routine invocation, which is internal to the actual 
  method object.

 However, this is not always how things work.
 $object.WHAT;  # Larry says that WHAT should return the protoobject
 WHAT, WHENCE, postcircumfix:[ ], and similar operators have semantics
 (although not implementation) defined by the language itself.

Actually WHAT, WHENCE and the like are considered macros, not method
calls.

Postcircumfix:[ ] is actually an operator, not a method, so they are
always lexically dispatched.

 Currently, Perl 6 fakes this by having all values inherit from Any or
 Mu or Cool, which define the basic, overridable versions of these
 method-like operators.

Hmm... I never thought of it as a fake, it's a simple fact, every value
in Perl 6 should derive from Mu, every non-special type is derived from
Any.

 This cheat actually works pretty well in a homogeneous environment,
 but it fails if we have to consider objects from outside Perl 6.
 $parrot-array.WHAT;  # Method WHAT not found for invocant of type ...

This is actually a rakudobug, a $parrot-array should be properly boxed
into a value that provides a protoobject... Again, .WHAT is not a
method.

 The problem here is that scopes are conflated - WHAT is defined by the
 language, which is approximately a lexical scope, while methods on an object
 are in some entirely different scope.

AFAIU, method dispatch is also lexically controlled - to some extent.

 A methodical is an operator which syntactically behaves as a method but is
 subject to scoping rules.  Methodicals are defined using the ordinary method
 keyword, qualified with my or our.  (TODO: This seems the most natural syntax
 to me, but it conflicts with existing usage.  Which is more worth having on
 it?)  Methodicals do not need to be declared in classes, but they should
 generally have declared receiver types.
 Thoughts?

Apparently you're trying to override the default dispatching mechanism
which, I think, is something already supported by Perl 6 (although not
yet fully spec.

daniel



Re: underscores vs hyphens (was Re: A new era for Temporal)

2010-04-11 Thread Daniel Ruoso
Em Dom, 2010-04-11 às 07:54 -0700, Damian Conway escreveu:
 The relevant suggestion regarding hyphens vs underscores is:
 ...to allow both characters, but have them mean the same thing.

er... this smells like :: and ' in Perl 5... Which, while I find
Acme::Don't amusing, cannot be stated as sane design...

daniel



Re: underscores vs hyphens (was Re: A new era for Temporal)

2010-04-10 Thread Daniel Ruoso
Em Sáb, 2010-04-10 às 19:53 -0400, John Siracusa escreveu:
 I'm having trouble imaging any convention that involves mixing word
 separators being successful.

But the convention Damian is proposing is simply use underscores.

Basically camelCase and with_underscores are conventions on how to
circunvent the fact that we can't use spaces in our identifiers. What
is proposed here is that the p5 convention should be preserved.

The hyphen is *not* a space, so it doesn't even get into the discussion
of this convention. The basic difference is that when a programmer with
sufficient communication skills have a composed word (i.e.: week-day),
he will have the ability to use the hyphen instead of either supress it
or use an underscore...

daniel



Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-07 Thread Daniel Ruoso
Em Ter, 2010-04-06 às 22:19 -0700, Damian Conway escreveu:
  I kinda hope we can get a bit further away from the machine code
  level of reality one of these decades.  Perl 6 should not be
  optimized for C semantics.
 Agreed. But it should at least support those who need to work at
 the machine code level, but would prefer not to have to do so in C.

While I agree with all the reasoning...

I just like to point that currently they are not required to do so in C.
Using bitsets in Perl 6 is just as easy as using in Perl 5 -- which
happens to be the same as using in C, but it's not C...

constant PERM_WRITE = 0b0001;
constant PERM_READ  = 0b0010;
constant PERM_EXEC  = 0b0100;
constant PERM_NAMES = { PERM_WRITE = 'Write',
PERM_READ  = 'Read',
PERM_EXEC  = 'Exec' };
subset Perm of Int where *  8;
my Perm $perm = PERM_WRITE +| PERM_READ;
if ($perm + PERM_WRITE) { say 'can write' }
my @names =
  map { PERM_NAMES{$_} },
  grep { $_ + $perm },
  (PERM_WRITE, PERM_READ, PERM_EXEC);

 That said, I'd be perfectly happy to encourage the use of proper set
 abstractions for this purpose, so long as the long-suffering hardware
 engineers can still easily convert the final set to an appropriate
 bit-pattern when it's time to pump the results out to the hardware.

The thing that bugs me is that sets have way more uses then bitsets, and
we might be overspecializing sets to support that semantics.

Because proper set abstractions won't allow you to explicitly define how
the bitset is composed (which member has each value) -- at least I dont'
see it at this point -- since that's just an optimization because you're
dealing with a set of small integers.

If there's a strong case for bitsets, maybe it's worth having a
specialized declarator.

daniel




Re: You never have privacy from your children in Perl 6

2010-03-23 Thread Daniel Ruoso
Em Ter, 2010-03-23 às 19:41 +0100, Carl Mäsak escreveu:
 masak um, so 'protected' is when the deriving classes can see the
 attribute?
 jonalv yup
 masak that's what 'private' means in Perl 6.
 jonalv what? so there's only really 'public' and 'protected', but no
 'private'?
 masak basically, yes. although 'protected' in Java is called
 'private' in Perl 6.

Au contraire. In Perl you only have 'protected'. There is no public in
the same sense as java. There is no direct access to object's
attributes, it is always accessed through methods.

In java, a public attribute is accessed without the mediation of any
method.

daniel



Re: You never have privacy from your children in Perl 6

2010-03-23 Thread Daniel Ruoso
Em Ter, 2010-03-23 às 20:53 +0100, Moritz Lenz escreveu:
 unless you count 'trusts'
 traits, which are specific to single classes, not groups of subclasses

Yes, that was what I meant...

daniel



Versioned Dependencies (Was: Re: Stability domains in rakudo *)

2010-03-20 Thread Daniel Ruoso
Em Sáb, 2010-03-20 às 12:16 +0300, Richard Hainsworth escreveu:
 Suppose we define a domain of stability as syntax/functionality/features 
 that will not be changed until a milestone is reached, with the 
 guarantee that if the language specification changes before then, 
 backwards compatibility will be retained so that the 
 syntax/feature/functionality will continue to function without a need to 
 change it or the surrounding code.

I think this is more a case for versioned dependencies. 

I'm not sure this is written down anywhere in the spec, but I guess
there should be a way to tell this code was written targetting version
$x of the implementation $y - if the code is compiled to bytecode that
is really easy.

Then the implementation might have a way to adapt itself to provide the
intended semantics.

Of course this requires an entire different set of maintainance
challenges, including a very precise delta documentation and probably a
lot of coercion functions, i.e: coerce from Int version 0.003 to Int
0.004 back and forth.

That way we have both the grammar, the CORE and the setting being
versioned, and it will be easier to adapt for the future...

daniel



Re: Versioned Dependencies (Was: Re: Stability domains in rakudo *)

2010-03-20 Thread Daniel Ruoso
Em Sáb, 2010-03-20 às 22:23 +0300, Richard Hainsworth escreveu:
 Here it is the very language that is changing.
 For instance, =$fh was used to generate input from a file. Now it is 
 $fh.lines

Note that I did mention versioned dependencies for grammar, CORE and
setting. So yes, considering the code was properly tagged with the
specific version, running it would either:

 1) Run normally if the implementation provides backward emulation of an
older version.
 2) complain upfront that the version is not available in backward
emulation and it would be subject to failure. or even
 3) complain upfront that the version os not available in backward
emulation, but try to get the closest version that could be emulated and
give it a try.

daniel



Re: Functional-style pattern matching

2010-03-09 Thread Daniel Ruoso
Em Seg, 2010-03-08 às 12:45 -0800, Little Walker escreveu:
 I've been looking around to see if there's been any discussion of
 introducing functional programming-style pattern matching for method/
 function dispatch.  Could someone point me to any such discussions?

a Tree matching language is on discussion for about three years already
(I remember discussing this during YAPC::EU 2007). We have considered
several things including XPath/XSLT but haven't come to any viable
conclusion.

 This is a contrived example of what I'm referring to:
 sub traverse([Leaf $a]) {
   # do something
 }
 sub traverse([Tree $left, Tree $right]) {
   traverse($left);
   traverse($right);
 }
 my $t = Tree(...);
 traverse($t);

You seem to refer to that as if it wasn't supported by Perl 6, but your
code is almost - except for the Tree initialization code, that probably
should look like Tree.new(...) and you also need to replace sub by
multi.

One other aspect is map/grep/reduce with varying-arity multies which
would allow some very interesting things - The example is how to reduce
a list of tokens for a URL to the action processing (I've implemented
something in this line in http://github.com/ruoso/faz)

multi handle(HTTP::Request $r) {
   return RootAction.new(:req($r), :code({ 
  # here the code to process this action.
   });
}

multi handle(RootAction $a, $category_name) {
   return Action.new(:name/$category, :outer($a), :code({ 
  # here the code to process this action.
  # $category_name is visible in the closure
   });
}

multi handle(Action $a where { .name eq '/$category' }, $post) {
   return Action.new(:name/$category/$post, :outer($a), :code({
  # here the code to handle this action,
  # $post is visible in the closure
   });
}

my @tokens = ($request, 'perl', 'tree_matching');
my $action = @tokens.reduce: handle;
$action.execute;


This will get even better as custom grammars get into the play...

daniel



Re: Temporal seems a bit wibbly-wobbly

2010-02-22 Thread Daniel Ruoso
Em Dom, 2010-02-21 às 21:09 -0800, Larry Wall escreveu:
 I now see that the most important determinant of DateTimes is
 neither the Dates nor the Times themselves, but which TZ you're in.
 I propose renaming Temporal to TZ, so we get TZ::Date, TZ::Time, etc,
 since they're all dependent primarily on exactly where on earth you
 are, which determines how civil (or incivil) your cultural time is.
 It will also tend to prevent people from assuming anything universal
 about such types.

This issue was addressed when we got into the difference between Instant
and DateTime.

The thing is, much like a Str can't be seen as a Buf without an
encoding... a Instant can't be seen as a Date without a timezone...

That's the barrier between Instant and DateTime, as currently stated at
S32/Temporal.pod...

Take a look at all the classes and roles declared there...

daniel



Re: Temporal seems a bit wibbly-wobbly

2010-02-22 Thread Daniel Ruoso
Em Dom, 2010-02-21 às 21:28 -0800, Larry Wall escreveu:
 On Sat, Feb 20, 2010 at 10:39:20AM -0500, Mark J. Reed wrote:
 : I just want to know what Perl 6 time zero is.
 Well, there's no such thing as time 0 in Perl 6, in the sense that
 Instant is more-or-less opaque.

I'd just like to add that Instant is not more-or-less opaque. It is
entirely opaque. That basically means it probably is architecture and
implementation dependant.

The point is... asking for the amount of seconds since 01/01/1970
requires you to convert that date, in a particular timezone in a
particular calendar (gregorian) to an instant, then ask for the amount
of seconds elapsed from that instant to the current instant (and that
will return you a Duration object (which conceptually only know about
TAI), which in turn can be converted (provided a timezone and a
calendar) to a Gregorian::Duration.

daniel



Re: Temporal seems a bit wibbly-wobbly

2010-02-22 Thread Daniel Ruoso
Em Seg, 2010-02-22 às 13:31 -0500, Mark J. Reed escreveu:
  I'd just like to add that Instant is not more-or-less opaque. It is
  entirely opaque.
 Not according to S02, which says that an Instant will numify to the
 number of TAI seconds since the TAI epoch.  That's not opaque.

I'd just like to quote a bit from the same doc..

If pressed for a number, an Instant will return the length of
time in atomic seconds from the TAI epoch, but it will be
unhappy about it. [...] Systems which cannot provide a steady
time base, such as POSIX systems, will simply have to make their
best guess as to the correct atomic time.

 And since it apparently wasn't clear, all I'm asking for is what the
 TAI epoch is.  Again, I *assume* it's January 1, 1958 at midnight
 UT2, at which point TAI was synchronized to have exactly that same
 value, but it's not stated as such in the spec, and there are other
 reasonable values (onset of UTC in 1972; switch to modern relativistic
 corrections to the measured SI seconds in 1977).

And my point is precisely that the spec doesn't define it because it is
implementation and architecture dependant.

The point is that you shouldn't use a number alone to represent an
instant, the coercion from instant to numeric is just a convenience,
and, in fact, could actually be removed since Instant can override most
math operators.

Note that not even the TAI coordination happens in terms of number of
seconds since X, but rather happens in terms of Gregorian or Julian
dates.

This is the same mindset as why you can't see a Str as an array of bytes
without an explicit conversion (which requires an encoding).

The biggest difference proposed by the use of TAI is that when you ask
for the number of seconds between 2008-12-31T23:59:59+ and
2009-01-01T00:00:00+ you'll get 2 because of the leap second. But
you don't need to know how many seconds there were in the TAI scale
since the 1958 epoch to find that out, you just need to know when we had
leap seconds.

 Two different problems.  The TAI epoch is defined as a point on the
 TAI scale, and the number of TAI seconds since that point is always
 well-defined.   When asking for epoch-based time, you're not starting
 with a Gregorian DateTime and trying to convert it.

The thing is, most operating systems would require extra conversions in
order to get there, when in most cases the need is:

 a) Get the Duration of the difference from another instant obtained in
the same process...

 b) Get the Duration of the difference from another DateTime (in a given
calendar, in a given time zone)

or

 b) Get it as a Gregorian DateTime in some timezone (local or UTC)

That way, an implementation can keep it's Instant objects using time_t
(unless high-resolution time is requested) and convert directly to a
Gregorian DateTime without ever worrying about TAI seconds (in fact,
modern POSIX time_t *is* Gregorian::DateTime compatible without any
conversion)...

 But even if you did do such a conversion, as long as you assume that
 the input date is UTC, the conversion to TAI is well-defined, too.
 (And if you don't make that assumption, then you're opening a large
 can of worms; see
 e.g.http://www.ucolick.org/~sla/leapsecs/epochtime.html ).

Important point. I can't assume the input date is UTC, I can't even
assume it uses the gregorian calendar. So yes, we already openned that
large can of worms...

daniel



Re: Temporal seems a bit wibbly-wobbly

2010-02-22 Thread Daniel Ruoso
2010/2/22 Mark J. Reed markjr...@gmail.com

 If the interface between Perl time and human time is going to be done
 through UTC, then I don't see the point in specifying that it's TAI
 behind the scenes.  Especially if you're not specifying the epoch.
 The number of seconds between two points in time in UTC is exactly the
 same as the number of seconds between two points in time in TAI, by
 definition. Only the labels differ.  And if, as you imply above, the
 labels will be UTC - which they pretty much have to be since that's
 what humans use - then Perl6 is using UTC, not TAI.  It's just using
 *real* UTC, not POSIX's broken idea of it that claims 24 seconds out
 of the past 40 years never happened.


Okay, most replies are in the same tone, so I'll reply just here...

The problem is with the idea that TAI or UTC are the interface between Perl
time and Human Time, because that implies we could neglect the semantics of
the input type and store everything in a number of TAI seconds since the
epoch (after converting from the localtime to UTC) and store it like that.

DatesTimes are just not that simple, if I say 2009-01-01T00:00:00-0300 it
can't simply be converted to UTC then to TAI and be stored like that.
because that would mean a different year, and that semantic is not
neglectable.

That is why the Instant is not just a number, but a full specification of a
given instant. Which might say 2009-01-01T00:00:00 BRT which happens to be
GMT-3 but a few years ago had DST (it's in the south emisphere, so summer
time), but it doesn't have it nowadays.

More importantly, an Instant is not a Duration since some epoch. Instant and
Duration are completely different beasts, for instance... a Gregorian
duration of 1 day is not the same as 86400 seconds, simply because we have
days with 23 hours and days with 25 hours. and adding a day should ignore
the number of seconds in that day. As well as adding a month should ignore
the numbers of days in the month and so on...

So, there isn't one interface between Perl time and Human time, simply
because there isn't just one Human time, so we deal with all human times...

Note that the same way we have Gregorian::DateTime and Gregorian::Duration,
we can have TAI::DateTime and TAI::Duration, Instant and Duration are just
the most abstract roles for that types (also note that TAI doesn't have
timezones, it started aligned with UTC and drifted away ever since).

So why have the duration TAI-based?

Simply because TAI is supposedly immutable as a scale, so it's predictable.
Gregorian time is not immutable and timezone definitions are not anyhow
predictable. So when you get a duration (in the precision of seconds) it
specifies an immutable amount of time. But if it's not in the precision of
seconds, then well... it can be anything...

daniel


Re: 99problems-31-to-40 failure

2009-10-01 Thread Daniel Ruoso
Em Qui, 2009-10-01 às 12:22 -0400, Kevin Phair escreveu:
 This test fails for me with the latest Rakudo.  It looks like this is 
 because when a variable is pushed onto an array, and then 
 auto-incremented, it is also auto-incremented inside the array.
 my @stuff;
 my $w = 1;
 @stuff.push($w);
 @stuff.say;
 $w++;
 @stuff.say;
 gives an output of:
 1
 2

This is a rakudo bug, what's probably happening here is that rakudo is
just adding the push *...@args to the end of @stuff, while it was supposed
to get an iterator for it and consume it while copying the values into
@stuff, which is basically the difference between assign and bind.

daniel



Re: s/ DateTime - Instant / TAI /

2009-09-09 Thread Daniel Ruoso
Em Qua, 2009-09-09 às 14:49 +0400, Richard Hainsworth escreveu:
 Carl Mäsak wrote:
  I fear that the Instant from S02 is a fossil. Instant was renamed
  by Dave Rolsky to DateTime on 2009-02-19.
 There was fairly extensive discussion. My recollection was that 
 'Instant' and 'Duration' were preferred.
 Since a TAI epoch value is the underlying metric, how about a 'TAI' as 
 the type (in place of DateTime)?

One thing that needs to be clarified here is that DateTime provides
semantics that Instant doesn't. Instant is a TAI epoch value, DateTime
is a fully-qualified date and time specification according to some
specific Calendar.

I'm comitting a new revision of the Temporal spec now that should make
this distinction even clearer...

daniel



Re: r28213 - docs/Perl6/Spec/S32-setting-library

2009-09-09 Thread Daniel Ruoso
Em Qua, 2009-09-09 às 09:07 -0400, Mark J. Reed escreveu:
 I would change the doc to refer to TAI as a time scale, and also
 avoid referring to the numerical value of an Instant as an epoch.

I knew there was something wrong in my use of that terms, please fix it
if you like...

daniel



Re: Synopsis 02: Range objects

2009-08-24 Thread Daniel Ruoso
Em Seg, 2009-08-24 às 23:50 +0200, Michael Zedeler escreveu:
 The most elegant solution would be if the data types themselves 
 indicated their capabilities.

One thing I think you missed entirely is the fact that the infix:..
operator is a multi sub, so it falls to regular dispatch semantics, in a
way that any new class can export its own version of it with the desired
semantics...

 my $range = 1.14 .. 1.82 :by {* + 0.01};

Including mandatory named arguments...

 Another option is to provide a completely different operator for 
 constructing Intervals.

The other thing you're missing is that Range is a role, not a class,
which means that any type can behave like a range even if it provides a
completely different behavior, which might include

method list {
  fail This type of Range cannot be used as a list...
}

daniel



Re: Custom object constructors

2009-08-19 Thread Daniel Ruoso
Em Qua, 2009-08-19 às 15:37 -0700, Kevan Benson escreveu:
 Should there not be a way to define object constructors with custom 
 signatures that can be usefully invoked like a normal constructor?

What's the problem with

method new(Str $timestamp) {
   self.SUPER::new(ts = strptime('...',$timestamp));
}

?

 Currently, defining a BUILD method for a class with a specific signature 
 doesn't seem to allow for the object to be invoked by new with that 
 signature and be correctly passed to the right BUILD method.  It seems a 
 whole chain of new - bless - BUILDALL - BUILD would need to be 
 defined with specific signatures just to get a custom constructor.

BUILD allows you to tweaken the initialization of known attributes. Your
BUILD submethod will only receive then named arguments for the
attributes locally defined in your class.

The purpose of BUILD is *not* to provide alternative signatures to the
constructor.

 Two possible thoughts on how to achieve this were put forth in the 
 #perl6 discussion.  One, auto build the chain on definition of a BUILD 
 method, which was thought be some to be a bit too magical (me included, 
 even though it was my suggestion at first).  Alternatively, pass the 
 capture of arguments as supplied by new down the chain of initialization 
 methods so any that were defined as multi's can be called correctly by 
 multiple dispatch at the correct point.

The bless-BUILDALL-BUILD chain uses the positional arguments as the
candidate protoobjects that define additional parameters for the
builders. the named parameters are passed to each BUILD method for
initialization.

Again, if you want a custom signature for new, just write a custom new.

daniel



Re: xml grammar

2009-08-04 Thread Daniel Ruoso
Em Seg, 2009-08-03 às 11:04 +1000, Timothy S. Nelson escreveu:
   However, my main reason for modifying it was that I needed actions for 
 what I'm doing.  So I'll keep working on that.

http://gist.github.com/161467

just to tease :) -- this making the grammar closer to the XML spec...

daniel



RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)

2009-07-12 Thread Daniel Ruoso
Em Sex, 2009-07-10 às 15:39 -0700, Jon Lang escreveu:
 The key to understanding roles is to note that roles don't implement
 methods; classes implement methods.

Er, while I see your point, Roles are not just interfaces... they are OO
components that can be plugged into other classes. They often are used
for type identity exactly because of that attribute, since you won't be
enforcing any hierarchy.

 Roles define which methods must be implemented, and suggest ways that
 they might be implemented; classes decide which implementation to use.
 Anything that breaks this paradigm is a Bad Thing.

That's not the common conception in Roles usage, specially in Moose. As
I said, Roles are not just interfaces, they are OO reuseable components.
The spec itself says:

Classes are primarily for instance management, not code reuse.
Consider using Croles when you simply want to factor out
common code.

The key issue here is Perl 6 wasn't yet used to the extent that
Moose::Roles are, and Moose people have identified that the use of Roles
as reusable components raised the issue when the class inadvertedly
overrides one of the methods that are implemented by one of the composed
roles.

I did think that this should be the expected behavior, but when the
people that is heavily using it says it took me a lot of time to
debug, it indicates that there's something wrong with the behavior.

So now I changed my mind, inheritance is about overriding behavior, so
when you implement a method in the subclass it is a natural thinking
that this should override the superclass, but when you think about it
really carefully this logic doesn't really map well to Roles
(considering roles as OO reuseable components).

That being said, I'd think the following as an interesting solution:

 role R1 {
   method foo() {...} # degenerates to interface
 }
 role R2 does R1 {
   method bar() {
 # some implementation
   }
   method baz() {
 # some implementation
   }
 }

 class Bla does R2 {
   method foo {
 # implementing here is natural, since the role only
 # declared a stub, it's even a warning not to implement it
   }
   supersede method bar  {
 # explicitly tells that I want to ignore the implementation
 # in the role. nextsame wouldn't find the role implementation.
   }
   augment method baz {
 # explicitly tells that I want to provide an additional
 # implementation besides the one in the role. nextsame would find
 # the role implementation.
   }
 }

In the above example, declaring a method without either supersede or
augment would result in a compile-time warning, while using augment
semantics by default.

dainel



Re: .match and .subst set outer $/?

2009-07-12 Thread Daniel Ruoso
Em Dom, 2009-07-12 às 22:51 +0200, Moritz Lenz escreveu:
 I setting of OUTER::$/ considered syntactic sugar?
 I don't care either way, I'd just like some clarification so that I can
 write tests and submit tickets (if appropriate).

As far as I remember, it's not really OUTER::$/, but each routine
implicitly declare

 my $/ is contextrw;
 my $! is contextrw;

so what happens inside m// or s/// is that inside that it should look
for $*/, as well as the process of failing should look for $*!. This
also has the advantage of:

 {
   'abc' ~~ /abc/;
   say $/; # prints abc
   {
 my $/ is contextrw;
 'bcd' ~~ /bcd';
 say $/; # prints bcd;
   }
   say $/; # still prints abc;
 }

I'm pretty sure that was just said by TimToady on IRC a lot of time ago
and no spec actually defines it.

That being said, I don't think there's a reason for .match and .subst
not to look and set $*/.

daniel



Re: Re-thinking file test operations

2009-07-10 Thread Daniel Ruoso
Em Qui, 2009-07-09 às 22:50 -0400, Buddha Buck escreveu:
 Both the separate pathname type and the stat($str, :e) proposal
 salvage the purity of Str, so either would be acceptable to your
 argument.

The bigger problem of using a different type is that 

 /etc/passwd ~~ :e

Would dispatch to Str, which means that you'd need to

 PathName(/etc/passwd) ~~ :e

which doesn't seem much interesting huffman-wise.

On the other hand, a multi would allow more clear semantics, and
wouldn't require an explicit typecast, as in:

 stat /etc/passwd, :e

This still allow the existance of the most specific PathName type, and a
signature like

 multi stat(PathName $name, *%switches) { ... }

where...

 role PathName {
   multi method ACCEPTS(Str $path where { .defined }) {
 $path ~~ /PathName::token/
   }
   multi method ACCEPTS(Str $path where { not .defined }) {
 1;
   }
 }

daniel



Private methods in Roles (Was: Re: YAPC::EU and Perl 6 Roles)

2009-07-08 Thread Daniel Ruoso
Em Qua, 2009-07-08 às 12:49 -0700, Ovid escreveu:
 Behavioral:  if you are primarily relying on roles to provide behavior
 (as we do at the BBC), then silently discarding the role's behavior by
 providing a method of the same name in your class can lead to very
 confusing bugs.  I've lost a lot of time debugging this behavior.

That's actually a tipping point, and I'm thinking we never conceptually
extrapolated the use of Roles to a point that competing Roles in a
composition are bringing methods to the class that are actually relevant
to that roles, but doesn't mix well with the semantics of the composed
class.

Maybe what we need is a way to define methods that are not composed to
the class at all, but are there just for implementation sake. That could
probably mean that methods declared as privates in the role should not
be composed in the class, and the lookup of private methods should honor
the original place of declaration...

daniel



Re: [perl #66352] reduce with user-defined sub fail

2009-06-14 Thread Daniel Ruoso
Em Dom, 2009-06-14 às 10:09 -0500, Patrick R. Michaud escreveu:
 On Sat, Jun 06, 2009 at 08:01:50AM -0700, Daniel Ruoso wrote:
  ruoso rakudo: multi a (Str $a, Str $b) { [+$a, +$b] }; multi a (Array
  $a, $b where '+') { [+] @($a) }; ('1', '2', '+').reduce: a;
  p6eval rakudo fb2fd4: OUTPUT«Unknown introspection value
  'pos_required'␤in method Any::reduce (src/gen_setting.pm:3226)␤called
  from Main (/tmp/MvPkx61zJn:2)␤»
 At present Creduce doesn't work well with multisubs, as it's
 not certain how to find the arity of the (multi)sub to pass
 along to reduce.

This is a different problem indeed. We still don't know what to do in
reduce with varying arity multis, but this specific example shows a case
with fixed arity in all the candidates.

 It may be that we want reduce to simply assume arity 2.

I'm not sure that is a sane option... Since we have the ... operator
(which I like to think as the inverse of reduce), that should be able to
work with multies as well...

daniel



Re: Why pass by reference?

2009-06-14 Thread Daniel Ruoso
Em Dom, 2009-06-14 às 15:53 -0500, John M. Dlugosz escreveu:
 In Perl 6, the default parameter passing is to make a read-only alias 
 for the caller's lvalue.  This means that the function may not change 
 the caller's variable, but must track changes to it made by other means.
 What is the point?
 It is a contrivance to illustrate how the variable can be changed by 
 other means, and requires a global variable, the same variable passed as 
 two different parameters, or the variable and a closure that affects the 
 variable be passed.

Actually, it only looks complicated while you think only on the callee
side. Because when you take the caller side, you'll note that it builds
a capture to send to the call, and the capture is always a reference, so
the signature just makes sure that references becomes read-only. To
illustrate:

 my $a = 1;
 foo($a);

In this case, the capture sent must contain a direct reference to the
scalar held in '$a', so both signatures with is ref or signatures with
is copy can work.

So, if foo has the signature

 sub foo($a is ref) {...}

it will be able to change the scalar outside foo. If it is

 sub foo($a) {...}

It will be a read-only access to that scalar

 sub foo($a is rw) {...}

Works almost like is ref, but encloses immutables into a container in
order to always provide rw semantics.

 sub foo($a is copy) {...}

Is the completely opposite to is ref, copying the actual value to a
new container.

So, it is not at all complicated, it's just oriented to the Capture, and
the capture provides semantics to the call that are not present in any
other language I'm aware of.

daniel



Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-12 Thread Daniel Ruoso
Ok, There's one thing that is not clear in the thread, which is when an
array is multidimensional or not...

For instance:

 @a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

Will produce a flatten array, because list assignment causes flattening,
so the dimensionality was lost.

It is important to remember that this was a change in the spec that
happened some time ago. Before that, @a and @@a did refer to the same
variable, but this is no longer the case. Now @a and @@a are different
variables (in fact the @@ sigil is probably going to be replaced, since
it's not just list slice but it's actually a capture)

So, in the @a = (1,(2,(3,4)); example, @a will be a flat list with 4
elements.

So, how do I deal with a multidim array? Well, TIMTOWTDI...

 my @a = 1,[2,[3,4]];
 say @a[1][1][1];
 say @a[1;1;1]; # I'm not sure this is correct

Or.. (I'm using the proposed capture sigil here, which has '@%a' as its
expanded form)

 my ¢a = 1,(2,(3,4);
 say ¢a[1][1][1];
 say ¢a[1;1;1];

I think that makes the semantics of the API more clear...

daniel



Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-12 Thread Daniel Ruoso
Em Sex, 2009-06-12 às 11:52 -0700, Jon Lang escreveu:
 On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruosodan...@ruoso.com wrote:
  Ok, There's one thing that is not clear in the thread, which is when an
  array is multidimensional or not...
  For instance:
   @a = (1, 2, 3; 4, 5, 6; 7, 8, 9);
  Will produce a flatten array, because list assignment causes flattening,
  so the dimensionality was lost.
 Right.  I should have said:
 @@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

The important point here is that it means we're dealing with a different
type, so it can actually behave differently, so @@a.rotate would
rotate the first dimension only..

maybe @@a.rotate(1;1) would mean to rotate by 1 in the first dimension
and by 1 in the second, producing

 (5, 6, 4; 8, 9, 7; 2, 3, 1)

daniel




Re: RPN calculator in Perl 6

2009-06-08 Thread Daniel Ruoso
http://sial.org/pbot/37077
A slightly improved syntax, as per jnthn++ suggestion...

Em Sáb, 2009-06-06 às 18:08 +0200, Daniel Carrera escreveu:
 Daniel Carrera wrote
  Ok, try again:
  % perl6 rpn.pl 2 2+
  2 2
 You can probably fix that with a different split() line. I tried using 
 ws instead of \s+ but the program just hangs forever.

Hmm.. it certainly is in the split, I'm not sure how to get the barrier
between the 2 and the +

 I also tried a more complex expression, and the calculator didn't like it:
 % perl6 rpn.pl 5 4 + 3 / 5 3 - *
 Error parsing expression near *

er... that's because I didn't tried to implement it... but it certainly
is possible to, just by declaring the :(@a, Num $a) variant...

daniel



Re: RPN calculator in Perl 6

2009-06-08 Thread Daniel Ruoso
Em Sáb, 2009-06-06 às 19:45 -0400, Minimiscience escreveu:
 my $ls = @a.shift;
 my $rs = @a.shift;
 To:
 my $rs = @a.pop;
 my $ls = @a.pop;

Thanks... this was already solved in the latest version I sent

http://sial.org/pbot/37089

daniel



Re: RPN calculator in Perl 6

2009-06-08 Thread Daniel Ruoso
Em Dom, 2009-06-07 às 00:07 +0200, Daniel Carrera escreveu:
 Daniel Ruoso wrote:
  Are you planning to write a post explaining how your program works?
  Maybe, but if you want to beat me to it, feel free ;)
  I figure that the explanation is as useful as the example. I sure
  spent a lot of time writing the blog post.
  I'm not sure I'll have the time to write it soon, but it will certainly
  be on my list, unless you kindly post about it first ;)
 Honestly, I don't really know how your version works.

I'll take the code as in http://sial.org/pbot/37089
Feel free to post it if you like...

Ok, I think I can skip the first part, where I declare a token Num,
since your example explain it in great detail.

At first I'm using multi subs, the declaration is just

 multi name ($a, $b) {...}

and is just a shortcut for

 our multi sub name ($a, $b) {...}

which means we're declaring a sub named 'name' which will also be
registered in the current package (our), with the signature inside the
parens. This will work mostly as multis work in other languages, it will
invoke the variant which signature matches the parameters.

The second point is the use of the infix:rpn name in the multi. This
is how you declare new operators in Perl 6. infix describe the syntatic
category of the operator, in this specific case, it means the operator
stays between two values. So, after defining the multi sub, I could just
use:

 5 rpn 4

and this would invoke

 infix:rpn(5, 4)

If you're following until here, you probably realize that I could also
do

 ((5 rpn 4) rpn '+') rpn 3

but Perl 6 has the reduce meta operator, which takes any infix
operator and builds the above grouping for an arbitrary list, and that's
the last line of the code

  [rpn] @*ARGS[0].words;

This takes the list of words in @*ARGS[0] (which means I require a space
between every token) and reduces it using the infix:rpn operator,
which is implemented by each of the variants in the code.

The reduce meta-op works by taking the first two elements of the list
and running the infix:rpn with them as parameters, take the result of
that and the next element of the list and call it again, then do it
again until the list ends.

The last thing you need to know to understand this is about subsets, as
used in the signature of most variants

 multi infix:rpn ($a where /Num/, $b where /Num/) {...}

This signature will take two arguments where both must match the Num
token. This happens to be the variant that matches the start of the
list, and it is the only one that doesn't expect an Array as the first
argument, because it will itself return an Array with the two numbers.
As the reduce metaop takes the result from this call and the next
element on the list to call the sub again, the next call will receive an
array with the two first numbers as the first argument and the next
token as second argument, then the signature match does its trick and we
go on until we reach the end of the list, and the last calculation is
made.

This solution is mostly a functional solution. Probably if you ask the
LISP guys to work on a program to do RPN, it will probably look like
this...

daniel



Re: RPN calculator in Perl 6

2009-06-08 Thread Daniel Ruoso
Em Sáb, 2009-06-06 às 14:06 +0200, Daniel Carrera escreveu:
 I just wrote a blog post showing how to make a reverse polish notation 
 calculator in Perl 6. In the process I show some of Perl 6's grammar 
 features.

TIMTOWTDI ;)

http://sial.org/pbot/37075

daniel



Re: RPN calculator in Perl 6

2009-06-08 Thread Daniel Ruoso
Em Sáb, 2009-06-06 às 18:22 +0200, Daniel Carrera escreveu:
 Daniel Ruoso wrote:
  er... that's because I didn't tried to implement it... but it
 certainly
  is possible to, just by declaring the :(@a, Num $a) variant...
 Well, * is implemented, so I guess you are talking about complex 
 expressions.

Yes... that's what wasn't implemented... But now it is ;)

http://sial.org/pbot/37085

daniel



Re: RPN calculator in Perl 6

2009-06-08 Thread Daniel Ruoso
Em Sáb, 2009-06-06 às 19:51 +0200, Daniel Carrera escreveu:
 Daniel Ruoso wrote:
  Yes... that's what wasn't implemented... But now it is ;)
  http://sial.org/pbot/37085
 Close, but...
 % perl6 rpn.pl 5 4 + 3 / 5 3 - *
 -6
 That should be a positive 6.

Fixed now!
http://sial.org/pbot/37088

(with a op trace included, so one can see what's happening...)

 Are you planning to write a post explaining how your program works?

Maybe, but if you want to beat me to it, feel free ;)

 I figure that the explanation is as useful as the example. I sure
 spent a lot of time writing the blog post.

I'm not sure I'll have the time to write it soon, but it will certainly
be on my list, unless you kindly post about it first ;)

daniel



Implicit threading vs Imperative barriers

2009-06-04 Thread Daniel Ruoso
Hi,

Following my last reasoning on implicit threading and implicit
event-based programming[1], I came to two interesting realizations...

 1 - Every object is potentially lazy, not only lists.
 2 - Lazy doesn't mean wait until I need the data, but don't stall me
because of that data.

That basically means that

 my @a == map { some() }, grep { thing() }, $*IN;

Will read the data as it is available from $*IN even if you don't
request it. But it will happen concurrently with the rest of your code,
of course trying to access an element of the array that wasn't still
produced will cause your code to block, but only this specific code will
block, every other continuation will proceed as events arise.

That's fair, and the use of the feed operator makes it pretty explicit. 

But... We already stated in the DRAFT S07 that the assignment operator
will be mostly eager, which means that it will consume as much data as
it can before proceeding, but it won't wait for $*IN to end before
proceeding, so this kinda means that

 my @a = map { some() }, grep { thing() }, $*IN;

Will try to read as much as it can from $*IN (which, if you happen to
have piped in a file, will mean the whole file), before it goes to the
next statement, but if you have your console just waiting there, the
code will move forward, while implicit event-based programming will wait
for new data in $*IN...

That being said, let me take it to the next level...

 my $a = map { some() }, grep { thing() }, $*IN;

This is going to provide you with the same degree of lazyness than the
feed operator, since that's just storing the capture returned by map
into the scalar named '$a'. Now, that really means that

 my $a = foo();

is a potentially lazy object with implicit threading and implicit
event-based programming, and that's just a plain function call, if, for
instance the code for foo is:

 sub foo {
  for ^Inf { say $^n };
 }

The really important thing here is that, contrary to my initial belief,
the magic is *not* in the feed operator. The feed operator is simply a
capture constructor that fits well with slurpies.

So the questions are:

 * Are there any imperative barriers in Perl 6?
 * Does that mean we need to spec a common way of implementing
implicit-threading and implicit event-based programming?

daniel

[1]
http://www.nntp.perl.org/group/perl.perl6.language/2009/05/msg31682.html



Re: The game of life

2009-05-31 Thread Daniel Ruoso
Em Qui, 2009-05-28 às 00:26 -0500, John M. Dlugosz escreveu:
 Mark J. Reed markjreed-at-gmail.com |Perl 6| wrote:
  Perhaps Perl 6 should not aspire to the expressiveness of APL. :)  As
  nice as it is that you can write Conway's Life in a one-liner(*), I
  think that a little verbosity now and then is a good thing for
  legibility
  (*) life ←{↑1 ω⌵.^3 4=+/,‾1 0 1◦.ϕ⊂ω}
 So how would that translate to Perl 6?  Both as an exact translation, 
 and how to do it better in a Perl way?

I didn't try to translate it, but rather I simply tried to implement it
in a way rakudo already runs So... here's my shot!

CODE
class Game {
  # XXX: rakudo doesn't know how to initialize arrays properly yet.
  has $.seed;
  has $.width;
  has $.height;
  multi method generation(Int $generation where 0) {
return @($.seed);
  }
  multi method generation(Int $generation) {
my @previous = self.generation($generation - 1);
my @new;
# XXX: rakudo doesn't autovivify arrays properly yet.
@new.push: [] for ^$.width;
for ^$.width X ^$.height - $x, $y {
  # XXX: there's an extra set of parens for rakudo
  my $value = [+] map { @previous[$^i][$^j] },
 ((grep { 0 = $_  $.width }, ($x-1)..($x+1))
  X
  (grep { 0 = $_  $.height }, ($y-1)..($y+1)));

  if @previous[$x][$y]  2 = ($value - 1) = 3 {
@new[$x][$y] = 1;
  } elsif !...@previous[$x][$y]  $value == 3 {
@new[$x][$y] = 1;
  } else {
@new[$x][$y] = 0;
  }
}
return @new;
  }
}

my $game = Game.new(
 :width(15), :height(15),
 :seed([
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 ]
 ]));

my @g = $game.generation(4);
say .perl for @g;
/CODE


I guess my mindset is too much imperative for me to think in a more
elegant solution...

daniel



Is the Perl community just about Code? (Was: Re: New CPAN)

2009-05-30 Thread Daniel Ruoso
Em Sex, 2009-05-29 às 23:37 +0200, Daniel Carrera escreveu:
 Your idea of using CPAN to share holiday pictures is one of the things 
 that really turned me off from your CPAN6 proposal.

If you replace holiday pictures by 'YAPC pictures', 'Talk slides',
'Code Snippets', 'Perl related scientific articles' it does look much
more closer to a very good use of CPAN.

A few days ago I posted[1] on Perlmonks about how we could extend the
tools our community uses to get it even closer, and maybe this is one
interesting answer to that.

daniel

[1] http://www.perlmonks.org/?node_id=765024



Re: CPAN -- moving forward

2009-05-30 Thread Daniel Ruoso
Em Sáb, 2009-05-30 às 22:54 +0200, Daniel Carrera escreveu:
 In the hopes of helping the CPAN discussion move forward, in the 
 direction of tangible work, I have made a wiki page with a proposal:
 Please read the Basics section, which is quite short. The main point 
 of this section is to divide the issue into three parts:

Daniel,

The leap you make from the source package to the different binary
formats is overlooking a lot of details. It would be interesting if you
could take a look in the previous discussions on the matter.

 1) A package format.

This is supposed to be a source format, but different from current model
used in CPAN, it's pretty clear already that it can't include a build
system, like ExtUtils::MakeMaker or Module::Install.

There's already some consensus that this source package format should
describe what it contains, not how it should be built or installed. For
instance, it should only say something like in the lib directory
there's a set of STD Perl 6 modules that don't require any low-level
integration.

 2) A low-level install tool, analogous to rpm or dpkg, that converts the 
 package (2) into a local package format (rpm, deb, ebuild).

2.0) Build tool

Before installing it, you need to create a installable package, or
binary package (that's what CPAN plus does today). The thing here is
that the process of transforming the source package into an
installable package will be specific to the Perl implementation, to
the Operating System and to the vendor of the Operating system.

That basically means it's implementation specific, and each
implementation should do its best to provide that support. For instance,
rakudo might want to compile the modules to Parrot Bytecode, while
mildew might want to compile down some things to C.

If you're in an OS that provides a rich package management system, it
means you can generate native packages, otherwise you need to implement
the next step as well, which is:

2.5) Install tool

In systems where we don't generate native packages, we need a package
manager on our own. It should be capable of taking any installable
package and making it available in the system, checking all
dependencies and other requirements..

 3) A high-level install tool, analogous to yum or apt, that uses the 
 CPAN network and resolves dependencies.

I do think this is very much implementation-specific, for instance, in
Debian, with little work you could simply use apt-build to get your
packages built and available for installation with apt-get.

In summary,

The part 1 is really the critical issue, 2.0, 2.5 and 3 are mostly
implementation specific and are considerably easier to adapt than the
things in the part 1. We do need to find a very solid way of describing
what the package contains in order that implementation-specific build
tools can make them work.

daniel



Re: [RFC] CPAN6 requirements analysis

2009-05-29 Thread Daniel Ruoso
Em Sex, 2009-05-29 às 01:54 +0200, Daniel Carrera escreveu:
 Larry Wall wrote:
  I support the notion of distributing binaries because nobody's gonna
  want to chew up their phone's battery doing unnecessary compiles.  The
  ecology of computing devices is different from ten years ago.
 By binaries, I assume you mean native binaries, as opposed to Parrot 
 bytecode. The only problem I see is that it may be impractical to ask 
 CPAN mirrors to hold multiple binaries of each module for every OS and 
 every CPU.

I really don't think it will be CPAN's job to distribute the binary
packages, CPAN should only distribute the source package, as it does
today. Binary dependency is something that needs to be handled too
closely to the underlying operating system to be made generic.

So, I'd expect to have a Debian archive, in the Debian case, hosted by
the Debian Perl group (which packages about ~ 500 CPAN modules to Debian
today) with the binary packages targetting each of the Debian
versions...

The same would go for RedHat and other linux distros, while for the
Win32 world, we would have something in the lines of what ActiveState
already does...

But, I insist, CPAN should only store the source packages and the source
metadata should only describe what are the sources, and not how to
compile and install them...

daniel



Re: Illustration of stuff we've been discussing

2009-05-28 Thread Daniel Ruoso
Em Qui, 2009-05-28 às 00:24 -0500, John M. Dlugosz escreveu:
 Please see http://www.dlugosz.com/Perl6/web/info-model-1.html
 and talk to me about it.

The illustratino is cool, but it doesn't take into account the
possibility of:

 @a[0] := $x;

which means that an array is, theoretically, an array of item
containers. Consider the following:

 @a[1] = 0;
 @a[1] := 1;
 @a[1] = 2;

The first line store 0 in the item container initially created at
position 1 of array @a, the second line replaces that container by the
value itself, and the third line fails because 1 is a readonly value,
not a container, so you can't store into it.

Of course this is the theoretical model, and implementations should
optimize whenever they can... 

daniel



Re: Amazing Perl 6

2009-05-28 Thread Daniel Ruoso
Em Qui, 2009-05-28 às 21:36 +1000, Damian Conway escreveu:
 Mark J. Reed asked:
  ?  And if [+] means infix:+, how do I refer to the Code of the
  list operator [+]?
 prefix:[+]

Is that really? I mean... [ ] is a meta-operator, so

 [+] 1, 1, 2, 3

isn't a prefix, but a [ ] meta with + inside and the list as argument...

daniel



RFC: How does using CPAN with Perl 6 would look like (Was: Re: New CPAN)

2009-05-28 Thread Daniel Ruoso
Em Qui, 2009-05-28 às 16:18 +0200, Daniel Carrera escreveu:
 Hello all,
 There was some talk on IRC about a new version of CPAN to match the new 
 version of Perl.

I just wanted to point out some previous conclusion on this issue.

What currently we generically name CPAN is actually composed of:

 1 - A repository for source archives
 2 - A build-system (ExtUtils::MAkeMaker, Module::Build)

For Perl 6, there is already some kind of consensus that we need an
architecture that goes in the following lines

 1 - A repository for source archives (that's markov's CPAN6)
 2 - An abstract representation for the source's metadata (describing
what the archive has, instead of how to build and install)
 3 - A per-implementation per-architecture infra-estructure that knows
how to take this abstract metadata and build a installable package
(for that implementation and architecture)
 4 - A per-implementation per-architecture package manager (in some
cases the native package manager can be used) that install and handles
dependencies of installable packages.

So, a regular scenario would look like:

 1 - You search for something, find Some::Module and download
Some-Module-0.1.tar.gz it from CPAN6

 2 - Some-Module-0.1.tar.gz contains a META.yml like file containing a
description of what composes this archive

 3 - You run rakudo-build Some-Module-0.1.tar.gz if you're in rakudo
or smop-build Some-Module-0.1.tar.gz if you're in smop. If you're in a
Debian machine that should build libsome-module-parrot_0.1_i386.deb or
libsome-module-smop_0.1_i386.deb.

 4 - As in the Debian case, you would use the native package manager,
you could simply apt-get install libsome-module-rakudo (considering the
above step put the file in a local repo, as apt-build does today). If
you're in Win32, a package manager is probably going to written so you
can install the 'installable' package in a similar manner.

daniel



Re: Illustration of stuff we've been discussing

2009-05-28 Thread Daniel Ruoso
Em Qui, 2009-05-28 às 09:27 -0500, John M. Dlugosz escreveu:
 Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote:
  Em Qui, 2009-05-28 às 00:24 -0500, John M. Dlugosz escreveu:
  Please see http://www.dlugosz.com/Perl6/web/info-model-1.html
  and talk to me about it.
  The illustratino is cool, but it doesn't take into account the
  possibility of:
   @a[0] := $x;
 Where in the synopses does it say anything like that is possible?  := is 
 applied to a _name_.

I don't recall if it is in the synopsis... but it is a general
expectation, and, I think, this was discussed in IRC for a long time.
But certainly is a good time to either put on the spec or drop the
expectation...


daniel



RFC: Implicit threading and Implicit event-loop (Was: Re: Continuations)

2009-05-27 Thread Daniel Ruoso
Em Ter, 2009-05-26 às 19:33 -0700, Jon Lang escreveu:
 The exact semantics of autothreading with respect to control
 structures are subject to change over time; it is therefore erroneous
 to pass junctions to any control construct that is not implemented via
 as a normal single or multi dispatch. In particular, threading
 junctions through conditionals correctly could involve continuations,
 which are almost but not quite mandated in Perl 6.0.0.
 What is a continuation?

Continuation here is meant in the most generic sense, which is:

The rest of the thread of execution

It doesn't imply any specific API on manipulating the continuations, nor
it implies that the continuations are re-invocable, cloneable or
anything like that.

It basically means that the interpreter can choose to interrupt your
code at any point and continue it later, after running some other code.
This has the basic effect that Perl 6 points toward *implicit threading*
rather than explicit, and also that it points toward *implicit event
loop* rather than explicit.

In practical terms:

 sub baz (*...@input) {
   for @input - $element {
 say BAZ!;
 $element + 1;
   }
 } 

 sub foo (*...@input) {
   for @input - $element {
 say FOO!;
 $element - 1;
   }
 }

 sub bar (*...@input) {
   for @input - $element {
 say BAR!;
 $element * 2;
   }
 }

 say BEFORE!;
 my @a == baz == foo == bar == $*IN;
 say AFTER;

Is going to open 5 implicit threads (which might be delegated to any
number of worker threads), besides the initial thread. So, at first,
you'll immediatly see in the output:

 BEFORE!
 AFTER!

The implicit threads are:

  1 - read from $*IN and push into a lazy list X
  2 - read from the lazy list X, run an iteration of the for in the sub 
  bar, and push to the lazy list Y
  3 - read from the lazy list Y, run an iteration of the for in the sub
  foo, and push to the lazy list W
  4 - read from the lazy list W, run an iteration of the for in the sub
  baz, and push to the lazy list Z
  5 - read from the lazy list Z and push into the lazy list that
  happens to be stored in '@a'

That basically means that this lazy lists are attached to the
interpreter main-loop (yes, Perl 6 should implement something POE-like
in its core), which will allow the read of IO to be non-blocking, so you
don't need a OS thread for that. It also means that every lazy list
should be somehow attached to that event-loop.

So, as you enter data in $*IN, you should get something like that:

 I entered this line!
 BAR!
 FOO!
 BAZ!
 I entered this other line!
 BAR!
 FOO!
 BAZ!

On the implementation side, I think there is going to be a
ControlExceptionWouldBlock, which is raised by every lazy object when
the data is not immediatly available, allowing the interpreter to put
this continuation in a blocked state, somehow registering a listener
to the event that blocks it.

One of the attributes of the ControlExceptionWouldBlock would be a
Observable object, this Observable object is the thing that is waiting
for the specific event to happen and register additional listeners to
that event. The interpreter itself will register itself as an Observer
to that Observable, so it can re-schedule the thread, marking it as
waiting.

That being said, I think we have a continuation pool which are in
either running, blocked or waiting state. And a scheduler that
takes this continuations and assign to the worker threads, while you
can use a command line switch to control the minimum/maximum number of
worker threads as well as the parameter for when to start a new worker
thread and when to deactivate it...

Well, this is my current view on the state of affairs, and is thougth a
lot in the context of SMOP, so it would be really interesting to have
some feedback from the parrot folks...

daniel



Amazing Perl 6

2009-05-27 Thread Daniel Ruoso
Hi,

As I recently mentioned in IRC, I'm going to give a talk about Perl 6 in
the International Free Software Forum in Porto Alegre, Brazil. For those
who don't know FISL, it's one of the biggest events in the world with ~
5k people attending (http://www.fisl.org.br).

This talk is not targetted only to Perl people, but to the general
public of the event (which is one of the most diverse events I ever
participated). Of course it's on the Development/Perl track, but it
should get a lot of non-Perl people as well.

I'm planning to do a presentation to highlight the most impressive
aspects to Perl 6, in some way explaining why we are working on it for 9
years while still being excited about it.

So, as illustrations to my presentation, I'd like to show code snippets
in the slides, which comes to the subject of this mail.

Please post impressive Perl 6 code snippets, we all know there are
several, and I really would like to give people some idea of why Perl 6
is so cool.

I started a page in the Perl 6 wiki for that:

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

daniel



Re: Amazing Perl 6

2009-05-27 Thread Daniel Ruoso
Em Qua, 2009-05-27 às 18:46 +0200, Daniel Carrera escreveu:
 Hi Daniel,
Hi Daniel, :P

 Sounds very interesting. Can you post slides? It'd be cool if the talk 
 was taped, like the Google tech talks. Will it be in English? I don't 
 speak Portuguese (I do speak Spanish and some German).

It will be taped, as every talk in FISL is...

The talk will be in portuguese, as the audience of the forum is moslty
portuguese speaker, and submitting it in english would require being in
the main auditorium (the one with simultaneous translation) and getting
that approved would be harder...

But I guess subtitles can be made later... 

  I'm planning to do a presentation to highlight the most impressive
  aspects to Perl 6, in some way explaining why we are working on it for 9
  years while still being excited about it.
 Note: By trying to get things that are impressive, you don't want to do 
 things that are so complicated that the audience gets the feeling that 
 Perl 6 is too hard.

That's a thin line, but I'm aware of it...

 I know this is not the approach you had in mind, but what do you think?

Well, you really made me realize that I'm looking for things that make
me impressed, and probably I don't get impressed that easy nowadays ;)

daniel



Re: How to write this properly in Perl 6?

2009-05-27 Thread Daniel Ruoso
Em Qua, 2009-05-27 às 23:46 +0200, Carl Mäsak escreveu:
 Not sure if I grokked the whole set of rules, but here's a one-liner
 that does it:
 $ perl6 -e 'say (bon digi bon digi, bon xx ++$*n, digi xx
 $*n).join(, ) while *'

It does, but it would be prettier if it was lazy...

for 2..* - $n {
(bon digi bon digi, bon xx $n, digi xx $n).join(, )
} == $*OUT;

Or put that into an array for more controlled fun...

my @a == map {
(bon digi bon digi, bon xx $n, digi xx $n).join(, )
}, 2..*;
say @a[5];

But that still doesn't run in rakudo, since it doesn't support lazyness
yet...

daniel





Re: Question for Larry

2009-05-25 Thread Daniel Ruoso
Em Seg, 2009-05-25 às 11:36 -0500, John M. Dlugosz escreveu:
 Can you tell me if I'm missing something fundamental here?

While I'm not larry, I think I can help you out here ;)

 Regarding item containers ...
 my @A = (1, 2, 3);
 my $x;  # default to is Scalar
 $x = @A;

'$x' is the name of a variable that is in the lexpad. The sigil is part
of the name, and means little at runtime... The sigil is only important
at compile time for explicit context sensitiveness.

So, at the end of this snippet, the lexpad contains a scalar stored at
the name '$x', which then holds the array inside its cell.

A few facts:

* A Scalar in item context returns its value;
* The dotty operator implies item context;
* A list in item context returns itself;

so... what happens, in detail, in the above snippet is:

* an Array X is created and stored in the lexpad as the name '@A'
* The contents of the list (1,2,3) is iterated, copying the values to
the Array X;
* an Scalar Y is created and stored in the lexpad as the name '$x'
* The name '@A' is resolved to the Array X, which is used in item
context, returning itself
* The Scalar Y receives the rvalue to be STOREd in its cell.

 Now $x is BOUND TO an item container of type Scalar, which CONTAINS an 
 Array which itself CONTAINS 3 items of type Int.

Exactly. but it would probably be more clear to state that the name
'$x' in the lexpad is bound to a item container, binding is something
that happens to the variable as stored in the lexpad, so it's an
operation that happens in the lexpad, not in the container...

(that simplifying the point where the lexpad is also a container) 

 @A is BOUND TO a list container of type Array.
 my $y := @A;
 $y is BOUND TO the Array, same as @A is.

Again,

binding to a variable is an operation in the lexpad, much the same way
as:

  %ab := 1;

is an operation in the hash itself, not in that specific cell of the
hash.

daniel



Re: Meditations on a Loop

2009-05-22 Thread Daniel Ruoso
Em Sex, 2009-05-22 às 01:25 -0500, John M. Dlugosz escreveu:
 @primes = do $_ if prime($_) for 1..100;
 becomes
 @primes = $_ when prime($_) for 1..100;


you gained one stroke, it's certainly better... I think it's time to
play golf with Perl 6 already ;)

jokes aside, $_ when prime($_) looks more natural than do $_ if
prime($_)

daniel



Re: Meditations on a Loop

2009-05-22 Thread Daniel Ruoso
Em Qui, 2009-05-21 às 20:21 -0500, John M. Dlugosz escreveu:
 but it was crudly inserted, so just before it the text still reads, The 
 dot form and the indirect object form DEFAULT to method calls.  All 
 other prefix calls DEFAULT to subroutine calls. (emphasis mine),

That's because dot is an operator as well and might be subject to be
overriden... but don't tell anyone that...

daniel



Re: Meditations on a Loop

2009-05-22 Thread Daniel Ruoso
Em Sex, 2009-05-22 às 18:27 -0500, John M. Dlugosz escreveu:
 Daniel Ruoso wrote:
  That's because dot is an operator as well and might be subject to be
  overriden... but don't tell anyone that...
 You mean by installing a different dispatcher for the object?  By 
 hooking the grammar at a lower level?  Or will it be as simple as 
 defining a multi sub for that?

Last time I heard about it, it was a simple multi sub...

daniel



Re: Meditations on a Loop

2009-05-21 Thread Daniel Ruoso
Em Qua, 2009-05-20 às 20:58 -0500, Patrick R. Michaud escreveu:
 On Wed, May 20, 2009 at 07:55:55PM -0500, John M. Dlugosz wrote:
  If you would be so kind, please take a look at  
  http://www.dlugosz.com/Perl6/web/med-loop.html.  
 The reason this [.prime] works is because the method-call 
 syntax will call an ordinary non-member sub also.
 I think this is no longer the case (and hasn't been for some time).

It is no longer the case. I was about to send a mail about this... so
I'll just make sure that is noticed ;)

daniel



Re: Meditations on a Loop

2009-05-21 Thread Daniel Ruoso
Em Qua, 2009-05-20 às 19:55 -0500, John M. Dlugosz escreveu:
 If you would be so kind, please take a look at 
 http://www.dlugosz.com/Perl6/web/med-loop.html.  I spent a couple days 
 on this, and besides needing it checked for correctness, found a few 
 issues as well as more food for thought.

Some issues...

* The way to get an iterator is to ask for .Iterator() (this is in S07)
* It's not the capture itself that presents two different versions of
being a list, but rather the assignment in itself that traverses the
capture while flattening it.

i.e.:

 my $x := map { $_ * 2 for 1,2,3 }, 1,2,3;
 say $x[0]; # (1,2,3)
 say $x[0;0]; # 1
 say $x[1]; # (2,4,6)
 say $x[1;0]; # 2

as a contrast to

 my @x = map { $_ * 2 for 1,2,3 }, 1,2,3;
 say @x[0]; # 1;
 say @x[0;0]; # ERROR
 say @x[1]; # 1;
 say @x[1;0]; # ERROR

So, the list assignment really looks like

 my $iterator = (map { $_ * 2 for 1,2,3 }, 1,2,3).Iterator();
 my @x := Array.new;
 while ((my $it = $iterator.get) !=== Nil) { @x.push($it) }
 
Where the map is consumes an iterator by itself, so you could expand it
as...

 # this happens inside the map function installed in CORE
 my $map_input = (1,2,3).Iterator();
 my $map_output = $MapIteratorInternalType.new(
   :input($map_input),
   :code({ $_ * 2 for 1,2,3 })
 );
 # this happens in the assignment
 my $iterator = $map_output.Iterator();
 my @x := Array.new;
 while ((my $it = $iterator.get) !=== Nil) { @x.push($it) }
 

The text is fantastic... it's really awesome how you got into the guts
of Perl 6 while still preserving brevity and clarity...

daniel



Re: Meditations on a Loop

2009-05-21 Thread Daniel Ruoso
Em Qui, 2009-05-21 às 21:33 -0300, Daniel Ruoso escreveu:
  my @x = map { $_ * 2 for 1,2,3 }, 1,2,3;
  say @x[0]; # 1;
  say @x[0;0]; # ERROR
  say @x[1]; # 1;
  say @x[1;0]; # ERROR

er... there should be a 2 as output of the fourth line there...

daniel



Re: Call for review: traits, lift

2009-05-05 Thread Daniel Ruoso
Em Dom, 2009-05-03 às 21:15 -0700, Larry Wall escreveu:
 On Sun, May 03, 2009 at 08:20:17PM +0200, Moritz Lenz wrote:
 : If I understood the specs correctly, variables can be lifted, so you can
 : write
 : 
 : sub f() {lift $a + $b};
 : {
 : my $a is context = 3;
 : my $b is context = 4;
 : say f();
 : }
 : 
 : Is that correct?
 : And if yes, do these variables need to be context variables?
 Excellent question.  I think the conservative thing to say is yes,
 but it's possible that the lift mechanism can't easily distinguish,

In fact, i really think there isn't a sane way of distinguishing...
lifting really means looking up from the perspective of the caller, so
you see what the caller sees, so no need for $a and $b to be context...

daniel



Re: FYI - modern Muldis D code examples

2009-04-09 Thread Daniel Ruoso
Em Qua, 2009-04-08 às 01:04 -0700, Darren Duncan escreveu:
 To recap, Muldis D is my new programming language part of whose purpose is to
 eventually succeed SQL as the query+DDL language of choice for relational 
 DBMSs,
 in the same manner that Perl 6 is intended to eventually supplant Perl 5.   
 (And
 yes, I am being pragmatic and realize it won't happen overnight.)  The design 
 of
 Muldis D is like a cross between SQL and Perl 6 and it should be easy to 
 learn.

Sorry for bitching, but...

What exactly is the problem you're trying to solve? I mean, what is so
bad about SQL? and how does Muldis D solves it?

Honestly, it feels weird to me that you propose a query as simple as 

 SELECT 1

turning itself into a function declaration, with a lot of boilerplate
around...

daniel



Re: S08 Draft questions (Captures and Signatures)

2009-04-01 Thread Daniel Ruoso
Em Ter, 2009-03-31 às 22:54 -0700, Jon Lang escreveu:
 Yes, I know that there is no S08.  I'm working on writing one, and I'd
 like some feedback to help me do so.

++

 My draft is going to be about Signatures and Captures.  Thus, my questions:
 Invocants:

The concept of invocant only exists in terms of syntax now. In runtime
the invocant is simply the first positional argument. This simplifies
things a lot.

 * Is it illegal to specify an invocant in a sub, or is it merely
 nonsensical?

There's nothing wrong about it. In fact, every time you do my method
or our method, you end up with a sub that has an invocant in its
signature.

 silently treat the invocant as the first positional parameter?

Yes, that is basically the major side-effect on the latest capture
change. As I said before, the invocant only exists in terms of syntax,
it doesn't exist in terms of runtime.

 * Likewise, if I interpolate a signature with an invocant into another
 signature (somewhere other than at the start), is this an error, or
 will the invocant be silently converted into an ordinary positional
 parameter?

What does interpolate a signature mean?

But anyway, the invocant is the first positional argument, period.

 * What types are you allowed to assign to an invocant?

It's just a positional argument. But I suppose that on method
declarations, the type of the invocant is ::?CLASS. (Although there is
some debate if it's going to make some declarations too narrow
unintentionally.

 * Does anyone object to roles having an invocant, and that invocant
 referring to the class that is doing the role?

You mean methods declared in a role? Yes, they have an invocant, but the
invocant type in the signature could be just the role, I guess...

 * Why are we using ;; to denote the end of a multi function's
 longname?

Because a capture may have more than one dimension, which would be
delimited by ;.

 * Can any required parameter be part of the longname, or are only
 positional parameters allowed?  (I'm expecting the latter; but I'd
 like confirmation.)

I suspect you meant named parameter in place of required parameter.

For Perl 6.0.0, it is accepted that named parameters don't take part in
multi dispatch.

 * Are placeholder parameters ever considered to be part of a
 function's longname?  (I'm expecting that they aren't: if you want a
 longname, you ought to specify it in a formal signature.)

placeholder variables are just a simplified way of writing a signature,
after they are compiled, the routine has a regular signature, which
means that it should work as if the signature was explicit.

 * Must required named parameters be defined before optional named
 parameters are, or are we allowed to interleave the two?

named parameters order are, most of the time, irrelevant. But you can
have the same named parameter twice, iirc. So, I don't think you need to
put mandatory named parameters before the regular ones...

 * does the use of placeholder parameters interfere with the use of the
 slurpy parameters normally provided by the default signature (i.e.,
 *...@_ and *%_)?  I'm guessing not.

Yes, it does. The default signature is the *default*. Having placeholder
parameters imply defining a signature, one could argue that *...@_ and *%_
are still part of that generated signature, but @_ certainly won't
contain the values that were in the placeholder parameters.

daniel



Re: S08 Draft questions (Captures and Signatures)

2009-04-01 Thread Daniel Ruoso
Em Qua, 2009-04-01 às 05:41 -0700, Jon Lang escreveu:
 On Wed, Apr 1, 2009 at 5:07 AM, Daniel Ruoso dan...@ruoso.com wrote:
  The concept of invocant only exists in terms of syntax now. In runtime
  the invocant is simply the first positional argument. This simplifies
  things a lot.
 I think you're confusing signatures with captures here.  Captures and
 the arguments that they, well, capture, don't care about the invocant;
 but signatures and the parameters that they define still do.

Not at all, if you declare a method with my or our, it is seen as a
sub (as with is export), but it will still have the same signature.
So, the invocant only exists in the syntax even for signatures, in
runtime, they are simply the first argument... Which, in terms of code,
means:

 my method foo($b,$c) {...}
 $a.foo($b,c);
 foo($a,$b,$c);

In both invocations, $a is seen by foo as self, because that is how
the signature is defined.

  * Why are we using ;; to denote the end of a multi function's
  longname?
  Because a capture may have more than one dimension, which would be
  delimited by ;.
 Note that I didn't propose ; as the longname terminator.

I see, but the idea of using ;; is to be something invariably stronger
than ; .

 ...nor would I expect it to.  I'm just wondering if (@_, %_) _are_
 still part of a placeholder-generated signature.  In short, is there a
 way to access a slurpy array or hash in a block that uses placeholder
 parameters?

I'd guess not, but I think it's a plain design decision. In my head, the
default slurpy only makes sense when no signature is provided at all,
and only for some mindset compatibility with Perl 5.

In fact... cases like:

  for 1,2,3,4,5,6 { say $^a, $^b }

Imply that you can't have the slurpies there, otherwise the for loop
would be run only once...

daniel 



Re: On Junctions

2009-03-30 Thread Daniel Ruoso
Em Dom, 2009-03-29 às 22:57 -0700, Mark Lentczner escreveu:
 What I see here is that there is a tendency to want to think about,  
 and operate on, the eigenstates as a Set, but this seems to destroy  
 the single value impersonation of the Junction.
 Further, if one ever calls .!eigenstates() on a Junction, then you  
 have really bollox'd your code up, as then this code fails if the  
 value you thought was a Junction happens to be, actually, just a  
 single value!  (Unless .!eigenstates() is defined on Object, and  
 returns a Set of self...)

++

This is the most important semantic deadlock, thanks for putting it so
clearly.

 I think what is needed is a single value threshing function, which  
 can be applied to, well, single values.  Such a function would take a  
 value and a predicate, and if the predicate applied to the value is  
 true, returns the value, else it returns... nothing. If such a  
 function were applied to a Junction, then the result would be a  
 Junction of just those those eigenstates that passed this function.   
 The nothings would not end up contributing to the Junction.

Well, that can be thought as grep. 

my @i = 1|11, 9, 1|11;
my @j = 6,9,6;
my $a = [+] @i;
my $b = [+] @j;
my $va = $a.grep: * = 21;
my $vb = $b.grep: * = 21;
if ($va  $vb) {
   if ($va  $vb) {
  # a wins
   } elsif ($vb  $va) {
  # b wins
   } else {
  # draw
   }
}

If we have grep as a method in Any, the call to grep will autothread,
returning a junction of the values, so, as $a is any(11, 21, 31), $va
would be any(11,21,()), which should collapse as expected.

 Now, I'm not sure I know how to return nothing in Perl6, but I'll  
 guess that undef can serve the purpose, since I can't think of a  
 useful use of undef as part of a Junction.

Well, you return nothing simply by calling return; it will produce an
empty capture, which could be seen simply as ().

daniel



Re: On Junctions

2009-03-28 Thread Daniel Ruoso
Em Sáb, 2009-03-28 às 16:17 +1100, Damian Conway escreveu:
 Nested heterogeneous junctions are extremely useful. For example, the
 common factors of two numbers ($x and $y) are the eigenstates of:
 all( any( factors($x) ), any( factors($y) ) )

I think that's the exact case where we should be using sets instead...

  my $common_factors = factors($x) ∩ factors($y)

Assuming we have...

  multi infix:∩(List @a, List @b -- Set) {...}
  multi infix:∩(Set @a, Set @b -- Set) {...}
  ... and variants ...

But the semantics of sets are still somewhat blurry... there are some
possibilities:

  1) Sets are in the same level as junctions, but have no collapsing and
 allow you to get its values. The problem is if it autothreads on 
 method calls or not... It also makes $a  $b confuse...

  2) Set ~~ Any, and all the inteligence is made implementing multis, 
 it has the disadvantage that new operators will need to have 
 explicit implementations in order to get Set DWIMmery...

I have been unsure about that, but lately I'm mostly thinking option 2
is the sanest, which means we only get as much DWIMmery as explicitly
implemented (which may or may not be a good idea).

daniel



Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Daniel Ruoso
Em Sáb, 2009-03-28 às 13:36 +0300, Richard Hainsworth escreveu:
 Daniel Ruoso wrote:
  The thing is that junctions are so cool that people like to use it for
  more things than it's really usefull (overseeing that junctions are too
  much powerfull for that uses, meaning it will lead to unexpected
  behaviors at some point).   
 What are the general boundaries for junctions?

Junctions are superposition of values with a given collapsing type.

The most important aspect of junctions is that they are a singular
value, which means that they are transparent to the code using it. You
always use it as a singular value, and that's what keep its semantics
sane.

The boundary is where you try to use a junction as a plural value, and
that's where the semantics get weird...

 Perhaps, it might help to see some more examples of how junctions should 
 be used?

They should be used as a singular value... which means that the
blackjack example is only a good example for junctions, as far as to
know if the user has busted.

my @hand = 1|11, 9, 1|11;
my $sum = [+] @hand;
if ($sum = 21) {
   # valid game
} else {
   # busted!
}

The semantic is sane that way because it doesn't make a difference if
there is a junction or not...

my @hand = 6, 9, 6;
my $sum = [+] @hand;
if ($sum = 21) {
   # valid game
} else {
   # busted!
}

But even to compare two hands it gets weird...

my @a = 1|11, 9, 1|11;
my @b = 6,9,6;
my $pa = [+] @a;
my $pb = [+] @b;
if ($pa = 21  $pb = 21) {
   if ($pa  $pb) {
# B0RK3D
   }
}

That happens because $pa and $pb are a singular value, and that's how
junctions work... The blackjack program is an example for sets, not
junctions.

Now, what are junctions good for? They're good for situation where it's
collapsed nearby, which means, it is used in boolean context soon
enough. Or where you know it's not going to cause the confusion as in
the above code snippet.

Sets can provide the cool DWIMmery junction provides for the blackjack
case and still provide sane semantics for you to get its compound
values.

daniel



On Sets (Was: Re: On Junctions)

2009-03-27 Thread Daniel Ruoso
Em Sex, 2009-03-27 às 13:36 +0300, Richard Hainsworth escreveu:
 On #perl6, rouso, masak and moritz_ explained that I am incorrectly 
 thinking about junctions as sets and that for this task I should be 
 using another perl idiom, namely lists.

Sorry for not taking each individual point on your mail, but I think
this basically narrows down to the fact that we need some more
definitions of what kinds of things we would do with sets.

The thing is that junctions are so cool that people like to use it for
more things than it's really usefull (overseeing that junctions are too
much powerfull for that uses, meaning it will lead to unexpected
behaviors at some point).

So I get that we do need some cool support for sets as well, I mean...
no collapsing, no autothreading... but maybe some specific behaviors...

taking the blackjack example...

# using the set function as illustration only...
my @hand = set(1,11),3,set(1,11);
my $sum = [+] @hand;

This operation could use some magic so $sum could become

set(5,15,25)

Where it doesn't autothread, nor collapses... but it still provides the
DWIMmery people like so much in junctions...

So... which magic happened here?

1 - multi infix:+(Set $set, Num $a)
This would return another set, with each value of $set summed with $a.

2 - multi infix:+(Set $a, Set $b)
This would return another set, with $a.values X+ $b.values, already
removing duplicated values, as expected from a set.

So... what do you think?

daniel



Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Daniel Ruoso
Em Sex, 2009-03-27 às 08:57 -0300, Daniel Ruoso escreveu:
 So I get that we do need some cool support for sets as well, I mean...
 no collapsing, no autothreading... but maybe some specific behaviors...

As an aditional idea...

multi infix:⋃(Set $a, Set $b) {...}
multi infix:⋂(Set $a, Set $b) {...}
...as well as the rest of the set theory...

daniel



Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Daniel Ruoso
Em Sex, 2009-03-27 às 09:17 -0400, Mark J. Reed escreveu:
 From a high-level perspective, the blackjack example seems perfect for
 junctions.  An Ace isn't a set of values - its one or the other at a
 time.  It seems to me if you can't make it work with junctions - f you
 have to use sets instead - then there's something wrong with the
 implementation of junctions.

It would be a junction if the only question was is it bigger than
21?...

but that is not the case, it looks more like...

Given S as the set of possible sums,
Given V as a subset of S where  21
Given I as a subset of S where  21
If V is empty, Define X as the minimum value of I
Else, Define X as the maximum value in V

Which really looks like set operations...

daniel



Re: use v5 Support

2009-03-26 Thread Daniel Ruoso
Em Qua, 2009-03-25 às 23:11 -0500, jason switzer escreveu:
 S01 says that perl5 code will be supported via use v5. Can someone confirm
 that embedded perl5 code is still required of any valid implementation?

I wouldn't think it would be a really bad idea if inline use v5 inside
Perl 6 code to be optional for 6.0.0

 If so, how will XS code be supported?

Well, XS code certainly needs to be ran inside a perl5 interpreter.

 Will the namespace between v5 code and v6 be shared?

the definition of namespace in Perl 6 is very much different from the p5
one. In Perl5 all namespace is global... which is not the case for Perl
6, where the namespace is lexically built (of course you still have
GLOBAL::, but that's a minor issue).

So, in my head, you have the Perl 6 GLOBAL:: package as a different
thing than the p5 ::main namespace... maybe somehow we alias it as
GLOBAL::v5::main or something like that... but when you use
Foo:fromperl5, it certainly doesn't automatically get into the
GLOBAL:: Perl 6 namespace (unless you are in GLOBAL::, of course), so
the p5 package is imported as a lexical alias in the current scope.

 Will this be accomplished by linking libperl

linking libperl is certainly the most sane way to implement such
backward compatibility. The biggest challenge is the support for
reentrancy, since p5 is not entirely stackless. the case of a p6 module
that uses a p5 module that uses a p6 module will be the most challenging
situation (since p5 recurses in the C stack in that case).

There's already a specific plan of merging the p5 runloop with SMOP, in
order to make it work:
http://www.perlfoundation.org/perl6/index.cgi?smopp5

 I want to propose another idea (that seems better to me at least). This
 sounds like a good place where a user module could create a perl5 grammar (a
 version of STD.pm). I'm not too familiar with how the perl6 STD.pm works,
 but I've heard there were efforts to attach actions to its YAML output,
 similar to how Parse::RecDescent does in perl5 to yacc-like grammars.

Having a p5 grammar implemented in Perl 6 is not that all a bad idea, to
solve the inline problem (even if using libperl to build SV* for the
variables)... but I still wonder why would someone write p5 code inlined
inside a p6 module?

daniel



Re: Logo considerations

2009-03-24 Thread Daniel Ruoso
Em Seg, 2009-03-23 às 21:47 -0700, Darren Duncan escreveu:
 If you're going for sciencey or mathey illustrations, then I think its 
 important 
 to include something that speaks quantum physics in there, since quantum 
 superpositions aka Junctions are one of the big central user features that 
 Perl 
 6 provides which is relatively new to languages in general.

A zombie cat?



sorry... couldn't resist...

daniel



Re: Logo considerations

2009-03-24 Thread Daniel Ruoso
Em Ter, 2009-03-24 às 09:01 -0300, Daniel Ruoso escreveu:
 A zombie cat?

While I wasn't really serious about it...



attachment: cat.svg

Re: Logo considerations

2009-03-24 Thread Daniel Ruoso
Em Ter, 2009-03-24 às 09:17 -0400, Mark J. Reed escreveu:
 Are we seeking a logo for Perl 6 in general or Rakudo in particular?
 It seems like the latter should be derived from the former, perhaps
 with the Parrot logo mixed in.

are you suggesting that the cat should be eating a parrot in the rakudo
logo?

...


sorry, couldn't resist... again...

daniel



Re: r25891 - in docs/Perl6/Spec: . S32-setting-library

2009-03-20 Thread Daniel Ruoso
Em Qua, 2009-03-18 às 18:50 -0700, Larry Wall escreveu:
 On Wed, Mar 18, 2009 at 06:32:18PM -0700, Jon Lang wrote:
 :  +method !eigenstates (Junction $j: -- List)
 : 
 : Shouldn't that be lowercase-j junction?
 Maybe, though there might be a Junction role involved for subtype
 matches like that one.

Actually, if we support that, we kinda loose the point of making it a
native type...

daniel



Re: r25891 - in docs/Perl6/Spec: . S32-setting-library

2009-03-20 Thread Daniel Ruoso
Em Sex, 2009-03-20 às 14:08 +0100, Jonathan Worthington escreveu:
 It's probably a minor issue, but part of me wants Junction to be OK too 
 for explaining stuff. Telling people the default parameter type is Any, 
 to accept anything they can write Object and to accept just junctions 
 you write Junction is pretty clear...having to then explain why you 
 write Any and Object but then junction (lowercase) feels awkward.

everything is an Object.
not everything is Any. That is still true.

junction is a native type that doesn't do Any, and so far it seems to be
the only one. The capital vs lowercase J does not change that, it only
tells you that you cannot subclass junction as you can with non-native
objects.

  Actually, if we support that, we kinda loose the point of making it a
  native type...
 I don't quite follow this.

The point of having it as native is that you don't need to do a
high-level method call to implement the autothreading, since it's a
native type, you can assume its representation format and go directly
into its guts to get the values...

 But it does bring an interesting point - if we have a Junction role
 then it's probably something that people can do on their own classes
 to make their own thingies that auto-threading.

Meaning the auto-threading need to do a high-level method call to do
that...

 It had perhaps better require things doing the role to provide the !
 eigenstates private though, otherwise the dispatcher is going to be
 rather unhappy...

But... if the dispatcher needs to call it, it shouldn't be private
right? or is the dispatcher a specific class that Junction
implementation can trust?

daniel



Re: Recursive Runtime Role Reapplication Really Rebounds

2009-03-12 Thread Daniel Ruoso
Em Qui, 2009-03-12 às 10:28 -0700, Larry Wall escreveu:
 On Thu, Mar 12, 2009 at 08:51:45AM -0700, Ovid wrote:
 :  From: David Green david.gr...@telus.net
 :  I suppose, but is there a reason why you want to apply roles instead of 
 coercing 
 :  the results?
 : Because I am coming from Moose instead of Perl 6 and didn't know about this 
 :) 
 Note however that coercions require parens these days, since types parse
 as values, not as routine names.
 $x = Role::Serializable::XML($resultset);
 $y = Role::Serializable::YAML($resultset);

Er... wouldn't that create a proto-object sending $resultset as the
attribute for the only attribute that the Role can have? being the
equivalent to:

  $x = Role::Serializable::XML{ :attr($resultset) }

It is even supposed to fail if that Role declares more than one
attribute...

Or am I missing something?

daniel



Re: Recursive Runtime Role Reapplication Really Rebounds

2009-03-12 Thread Daniel Ruoso
Em Qui, 2009-03-12 às 19:07 +0100, Jonathan Worthington escreveu:
 IIRC, that's a special syntactic form that only counts when it is on the 
 RHS of but or does. (And yes, in this case it fails if the role has more 
 than one attr...) I think in all other cases, it's a coercion.

hmm...

for some reason I always thought you would do

  my $x = $resultset but Role::Serializable::XML;

in that kind of situation... it feels awkward to have the exact same
syntax to mean two completely unralated things...

daniel



Re: Recursive Runtime Role Reapplication Really Rebounds

2009-03-12 Thread Daniel Ruoso
Em Qui, 2009-03-12 às 11:49 -0700, Larry Wall escreveu:
 In addition to what Jonathan said, it is possible that the ability
 to coerce multiple arguments depends on the type itself, since we
 probably want to allow Foo(1,2,3) and such for listy types that
 don't necessarily want to use the [1,2,3] shortcut.
 But my main point is that $x = Foo $bar is a two-terms-in-a-row
 error when Foo is anything resembling a type, enum, or value, none
 of which expect to be turned into a listop or prefix.  This is
 independent of how the object might respond to (), if at all.

I see, but I insist... isn't it weird that we use the absolutely same
syntax for unrelated meanings?

 Oh, btw, re irc conversation the other day, .() and () are always
 identical in postfix position, just as .++ and ++ are the same.
 The . carries no semantics when qualifying a postfix, even when
 accessing attributes $.foo.() vs $.foo(), which mean exactly the
 same thing because such postfixes are part of the special form.

Just a quick paste for those not following IRC...

ruoso so do I always need to use two sets of parens when I'm accessing
an attribute that happens to contain a closure that I want to invoke?
TimToady yes

daniel



Re: .map/.reduce with larger arity

2009-03-10 Thread Daniel Ruoso
Em Seg, 2009-03-09 às 12:24 -0700, Larry Wall escreveu:
 On Mon, Mar 09, 2009 at 02:40:43PM -0300, Daniel Ruoso wrote:
 :   ... $capture ~~ $signature ...;
 :   my $args_matched = @($/).elems;
 :   code.(|$/);
 That API still would not tell the match whether signature must match the
 entire capture (what you want for normal binding) or can stop part way
 (what you want for map and friends).

if $capture ~~ $signature :partial {
  $capture = $remaining;
  code.(|@($/));
}

daniel



Re: .map/.reduce with larger arity

2009-03-09 Thread Daniel Ruoso
Em Dom, 2009-03-08 às 21:31 -0700, Larry Wall escreveu:
 I think the basic rule has to be simply can the signature bind to
 the remaining arguments.  If not, we get a warning on unused arguments.

Just to put here an idea I sent on irc...

What if Signature.ACCEPTS set $/ with the matched arguments?

That way we can both know how many arguments the Signature can receive
as well as allow us to use the match as the capture to that call...

  ... $capture ~~ $signature ...;
  my $args_matched = @($/).elems;
  code.(|$/);

daniel



Re: new Capture behavior (Was: Re: r25685 - docs/Perl6/Spec)

2009-03-06 Thread Daniel Ruoso
Em Qui, 2009-03-05 às 18:43 -0800, Jon Lang escreveu:
 OK; let me get a quick clarification here.  How does:
 say Hello, World!;

This is the equivalent to

 say.postcircumfix:( )( \(Hello, World) );

 differ from:
 Hello, World!.say;

This is just

  Hello, World!.say;

Meaning, the first dispatch is private to the sub, the second to the
object.

 or:
 say $*OUT: Hello, World!;

  $*OUT.say(Hello, World!);

dispatch is private to $*OUT...

 And more generally, would there be a
 reasonable way to write a single routine (i.e., implementation) that
 could be invoked by a programmer's choice of these calling
 conventions, without redirects (i.e., code blocks devoted to the sole
 task of calling another code block)?

This is exactly what this change has enabled. Now it doesn't matter if
your signature had an invocant or not, if that code is available as a
method it can be dispatched as a method, if it is available as a sub, it
can be dispatched as a sub, which means that you can install a sub as a
method and a method as a sub, it doesn't mattter...

 Could you use binding?
 my sub say (String *$first, String *...@rest, OStream :$out = $*OUT,
 OStream :$err = $*ERR)
 { ... }
 role String {
 has say:(String $first: String *...@rest, OStream :$out = $*OUT,
 OStream :$err = $*ERR)
 := OUTER::say;
 }

semantically, yes... but I don't think there's a syntax to bind a sub as
a method... You need to do it through the meta api at this moment...

maybe we could have something in the lines of

  method bar ::= bar;

or even

  method bar is external bar;

daniel



Re: [pugs-commits] r25698 - docs/Perl6/Spec/S32-setting-library

2009-03-06 Thread Daniel Ruoso
Em Sex, 2009-03-06 às 18:51 +0100, TSa escreveu:
 I know that the use of 'is also' is called monkey patching but I can't
 understand why this is regarded as a bad thing. Having a class assembled
 from multiple modules is a rather normal affair.

You're describing Roles here, which is something you can do. First
declare the roles, than declare the class being composing with that
roles.

Monkey patching is a bad thing because it is action at a distance,
code that already seen the class will, without any notice, start dealing
with a different behavior. Subclassing and composition are the proper
way of dealing with that, that's why Perl 6 allows you to lexically
replace the meaning of a name...

daniel



new Capture behavior (Was: Re: r25685 - docs/Perl6/Spec)

2009-03-05 Thread Daniel Ruoso
Em Qua, 2009-03-04 às 20:21 +0100, pugs-comm...@feather.perl6.nl
escreveu:
 Simplify meaning of Capture and Match in item context to preserve sanity
 (an object in item context is always just itself, never a subpart)

  sub foo { return 1 }
  my $a = foo();

That is currently expressed as taking the capture (in this case \(1))
and coerce it to the appropriate context, in order for that to work,
Capture need to do some DWIMmery when used in item context.

What I have in mind is:

  A capture in item context returns the first positional argument if 
  there is only one (named or positional), otherwise it returns itself 
  (so it can be used as both an array and a hash).

 The invocant (if any) of a Capture is now always considered 1st positional.

Unless you're a method, then it's really an invocant...

That seems to mean that you actually have two different APIs to talk to
a capture, which are:

  * I don't care about invocant, gimme the positional args
  * I do care about invocant, gimme the positional args

So, if you don't care about invocant, it is just a regular positional
argument, but if you do care, it is not a positional argument. It looks
like the old my $self = shift...

What really got me confused is that I don't see what problem this change
solves, since it doesn't seem that a signature that expects an invocant
(i.e.: cares about invocant) will accept a call without an invocant, so
method foo($b,$c) is export still need to have a transformed signature
in the sub version of foo.


daniel



Re: new Capture behavior (Was: Re: r25685 - docs/Perl6/Spec)

2009-03-05 Thread Daniel Ruoso
Em Qui, 2009-03-05 às 12:58 -0300, Daniel Ruoso escreveu:
 What really got me confused is that I don't see what problem this change
 solves, since it doesn't seem that a signature that expects an invocant
 (i.e.: cares about invocant) will accept a call without an invocant, so
 method foo($b,$c) is export still need to have a transformed signature
 in the sub version of foo.

Thinking again,

Unless that actually means that we're really removing all the runtime
semantics around the invocant... and methods implicitly do my $self =
shift all the time...

That'd be sad... we loose invocant semantics... SMOP will require a
HUGE refactoring... :(

daniel



Re: $?OS change

2009-03-02 Thread Daniel Ruoso
Em Seg, 2009-03-02 às 17:04 +1100, Timothy S. Nelson escreveu:
   Hi.  I note that we have $?OS, $?VM, and $?DISTRO (and their $* 
 counterparts).  I'd like to recommend that we eliminate $?OS, and replace it 
 with $?KERNEL (ie. Linux) and maybe $?ARCH (ie. i386).  Thoughts?

The usual way to handle this is by something called arch triplet,  as
you can find out if you call

  gcc -dumpmachine

This triplet is formed by the Instruction Set (usually called CPU),
the Platform (pc for most people) and the Operating
System (linux-gnu in my case, while the -gnu specifies that you're
using the gnu libc). (gcc omits the pc part, usually).

So, I think the proper name to the variables would be

  $?ARCH and $*ARCH

Where they would stringify to the arch triplet, while providing
convenience methods for .cpu, .platform and .os.

But thinking about it, I wonder if we shouldn't have actually two
compile-time variables, which are HOST_ARCH and TARGET_ARCH so cross
compiling is possible, or at least make $?ARCH to mean TARGET_ARCH while
still providing $?HOST_ARCH, and since we're talking about compiling
Perl code, we should probably have $?HOST_PERL and $?TARGET_PERL as
well..

daniel




Re: $?OS change

2009-03-02 Thread Daniel Ruoso
Em Seg, 2009-03-02 às 23:47 +1100, Timothy S. Nelson escreveu:
 On Mon, 2 Mar 2009, Daniel Ruoso wrote:
  So, I think the proper name to the variables would be
   $?ARCH and $*ARCH
  Where they would stringify to the arch triplet, while providing
  convenience methods for .cpu, .platform and .os.
   Hmm.  But we want versions for Platform and OS as well.

I don't really think this information is that all easy to get. For the
platform I'm pretty sur you can't get versions, if you have a
config.guess script anywhere, you'll see the amount of effort it does
to try to recognize what it already does recognize. Believe me, if there
was a way to get more information in a generic way, it would be in that
script.

OTOH, the dependency on the libc for instance pretty much tells you
which version of the OS you have (in Linux, at least).

But one way or another, what do you want to achieve that wouldn't be
solved by the arch triplet (and that would be solved by having the OS
version)?

  But thinking about it, I wonder if we shouldn't have actually two
  compile-time variables, which are HOST_ARCH and TARGET_ARCH so cross
  compiling is possible, or at least make $?ARCH to mean TARGET_ARCH while
  still providing $?HOST_ARCH, and since we're talking about compiling
  Perl code, we should probably have $?HOST_PERL and $?TARGET_PERL as
  well..
   Are we talking about $?VM vs. $?XVM here?

Well, yes... that adresses $?HOST_PERL and $?TARGET_PERL... but still
leaves $?HOST_ARCH and $?TARGET_ARCH, assuming not all compiled Perl
modules are platform independent.

daniel



Re: $?OS change

2009-03-02 Thread Daniel Ruoso
Em Seg, 2009-03-02 às 10:39 -0300, Daniel Ruoso escreveu:
 Em Seg, 2009-03-02 às 23:47 +1100, Timothy S. Nelson escreveu:
  Are we talking about $?VM vs. $?XVM here?
 Well, yes... that adresses $?HOST_PERL and $?TARGET_PERL... but still
 leaves $?HOST_ARCH and $?TARGET_ARCH, assuming not all compiled Perl
 modules are platform independent.

So, thinking about it a bit more, I'd say the variables could be called

  $?ARCH and $?XARCH

daniel



Re: Exceptions question

2009-02-26 Thread Daniel Ruoso
Em Qui, 2009-02-26 às 22:26 +1100, Timothy S. Nelson escreveu:
 given(any(@!)) {
 }

using junctions on exception handling doesn't seem like a good idea to
me, because it is too much of a basic feature... but...

for @! {

}

might provide the needed semantics...

OTOH, I think it would be sane to have $! representing the last
exception, so you can still use

 my $file = open 'file.txt' or die $!;

no matter how many unthrown exceptions you have in that block.

daniel 



Re: Exceptions question

2009-02-26 Thread Daniel Ruoso
Em Qui, 2009-02-26 às 08:55 -0300, Daniel Ruoso escreveu:
 for @! {}
 might provide the needed semantics...

After sending this mail I've just realized I don't know exactly which
are the needed semantics...

what happens if you have several unthrown exceptions in the block, does
it throw every one of them? in sequence? autothreading? what happens if
one CATCH handles one of the exception but only an outer CATCH handles
the other?

I'm not sure there is a sane way of having several unthrown exceptions
at the same block, so I think the best thing we can do is to throw the
first unthrown exception if a second exception happens...

meaning... if $! is already set with an unhandled exception that
exception is thrown. If that happens to be a resumable exception, the
code can be resumed and the other exception will be stored in $! for a
later evaluation.

daniel 



Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Daniel Ruoso
Em Qui, 2009-02-26 às 17:01 +0100, TSa escreveu:
  $y.error = 0.001;
  $x ~~ $y;

Looking at this I just started wondering... why wouldn't that be made
with:

  my $y = 10 but Imprecise(5%);
  $x ~~ $y;

daniel



Re: Signals question for S16: IPC / IO / Signals

2009-02-24 Thread Daniel Ruoso
Em Seg, 2009-02-23 às 19:49 -0800, Larry Wall escreveu:
 On Tue, Feb 24, 2009 at 04:01:40PM +1300, Martin D Kealey wrote:
 : Conceptually I think they should all go in add-on(s), however I suspect that
 : when an exception is thrown inside a signal handler, cleanly unwinding the
 : call chain will need special support in the core.
 Which should already be there, presumably, as defined in S04 and such.
 Some signals like CONT want to get translated to resumable exceptions
 and others like SEGV to non-resumable.

Agreed, every signal could just be a control exception with no special
behavior (except being potentially resumable), simply:

 * ControlExceptionSigHUP
 * ControlExceptionSigTERM
 * ControlExceptionSigINT
 * and so on...

Then defining a signal handler is just a matter of a CONTROL block that
catches that exception. This would mean something that is very important
in terms of concurrency, which is that the signal handling code that is
registered in the OS is simply there to raise the exception, once that
happens, the regular execution flows to the CONTROL block.

We would just need to decide if a signal should be seen by all of the
concurrent threads (green-threads or os-threads), or if there is a
main thread that would receive the exceptions or how the user can
tweak that behavior...

Then the outermost dynamic scope would define a CONTROL that would
implement the default behavior for each control exception (as it already
does for ControlExceptionWarn, for instance.

 These signal events will
 presumably be processed by some kind of underlying event handler that
 mediates among any and all user-visible event handlers within the
 process.
 
Now *that* made my eyes shine. ;)

Adding a library-agnostic event loop at the core is something that might
be very much powerfull. The AnyEvent p5 modules is one of the most
interesting things in this regard in CPAN, it works with any event loop
(including POE, Event and EV). 

So the default code that raises the control exception for each signal
would be registered in this event loop, as well as any code that wanted
to perform asynchronous IO, which would just register a listener for
can_read in soe IO handle.

We just need to sketch an API around that...

daniel



Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Daniel Ruoso
Em Ter, 2009-02-24 às 08:59 -0800, Larry Wall escreveu:
 I'm using ±  more in the engineering sense than the mathematical
 sense.

What about...

  if $x ~~ [..] $x ± $epsilon {...}

That would mean that $x ± $epsilon in list context returned each value,
where in scalar context returned a junction, so the reduction operator
could do its job...

daniel



Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Daniel Ruoso
Em Ter, 2009-02-24 às 13:34 -0800, Jon Lang escreveu:
 Daniel Ruoso wrote:
   if $y ~~ [..] $x ± $epsilon {...}
 Junctions should not return individual values in list context,

It is not the junction that is returning the individual values, but the
infix:± operator...

daniel



Re: More trees and roles

2009-02-20 Thread Daniel Ruoso
Em Sex, 2009-02-20 às 11:19 +1100, Timothy S. Nelson escreveu:
   if(! defined($footree.root)) { warn Unrooted tree; }

There are some other very interesting possibilities:

  unless ($footree.can(root)) { warn Unrooted tree; }

or even better

  unless ($footree ~~ RootedTree) { warn Unrooted tree; }

or yet even better

  my RootedTree $footree = something()

and it fails automatically...

*That's* what Roles are for...

daniel



  1   2   >