Parallelism and Concurrency II
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
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
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
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«123» 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)
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
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
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
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
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
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
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
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
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)
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)
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
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
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
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 *)
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 *)
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
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
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
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
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/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
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 /
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
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
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
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
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)
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 $/?
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
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)
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
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?
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))
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))
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
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
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
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
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
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
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
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
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)
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
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
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
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
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)
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
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)
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
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
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?
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
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
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
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
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
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
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
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
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
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)
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)
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
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
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)
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)
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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)
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
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)
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)
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
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
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
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
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
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)
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
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)
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)
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
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