r26941 - docs/Perl6/Spec
Author: moritz Date: 2009-05-27 09:47:44 +0200 (Wed, 27 May 2009) New Revision: 26941 Modified: docs/Perl6/Spec/S05-regex.pod Log: [S05] document action stubs Modified: docs/Perl6/Spec/S05-regex.pod === --- docs/Perl6/Spec/S05-regex.pod 2009-05-26 23:59:45 UTC (rev 26940) +++ docs/Perl6/Spec/S05-regex.pod 2009-05-27 07:47:44 UTC (rev 26941) @@ -3714,6 +3714,30 @@ token funnylang { '{' [ :lang($funnylang.unbalanced('}')) expr ] '}' } +=item * + +A string can be matched against a grammar by calling C.parse on the grammar, +and optionally pass an Iaction object to that grammar: + +MyGrammar.parse($str, :action($action-object)) + +Whenever a closure within the grammar returns a CWhatever object, the +grammar engine tries to call a method of the same name as the name of the +current regex on the action object, passing along the current Match object as +the first positional argument. + + grammar Integer { + token TOP { + \d+ {*} + } + } + class Twice { + method TOP($/) { + make 2 * $/; + } + } + Integer.parse('21', :action(Twice.new)).ast # 42 + =back =head1 Syntactic categories
Re: Unexpected behaviour with @foo.elems
yary wrote: I'm a relative beginner at perl6, but pretty good with perl5 (and C and a few others), so I read for 0...@foo.elems as saying Give me a list with one item longer then @foo, not give me the indexes of @foo. But a Perl non-beginner did make that mistake. The problem is that it looks a lot like the Perl 5 for my $k (0..$#foo). Anyways, I am not suggesting a change. I am pointing out a possible confusion and letting the experts decide what to do. for @foo.values - $k { do_something($k,@foo[$k]) } try @foo.keys instead! Yeah... I noticed after I hit send. Changing the meaning of elems to mean anything other then the number of elements seems likely to cause even more confusion! I did not say let's change the meaning of 'elems'. I was very careful to suggest nothing. I simply raised a point of confusion and I can prove that it is a point of confusion because someone who does know about Perl 6 got confused. But what to do about it is something I leave to the experts. Daniel.
Re: Unexpected behaviour with @foo.elems
Patrick R. Michaud wrote: An even cleaner shortcut might be to use ^...@foo instead of ^...@foo.elems: for ^...@foo - $k { do_something($k, @foo[$k]) } Somewhat clearer could be: for @foo.keys - $k { do_something($k, @foo[$k]) } And some may prefer: for @foo.kv - $k, $v { do_something($k, $v) } I think the anti-pattern of 0...@foo.elems (or its incorrect form 0...@foo.elems) should probably disappear in favor of the above forms instead. Even if there is no language change, at least it'd be good to ensure that 0...@foo.elems doesn't appear in the documentation. Instead, whoever writes the docs should use @foo.keys and @foo.kv. Those are *very* clear, and they do the right thing. Daniel.
Re: Unexpected behaviour with @foo.elems
I don't see how you could interpret the name elems as something returning index of the last element. If your IRC interlocutor confused @foo.elems with $#foo, then it seems more likely that they were confused about the semantics of $#foo than of .elems , whose p5 equivalent is just scalar(@foo). Of course, arrays itemify to references in p6, but they still numify to their length, so +...@foo is a synonym for @foo.elems, and I suspect it will be the more common form. Namewise, @foo.elems isn't obviously distinct enough from @foo.values, IMO, whereas numeric context is unambiguous. Anyway, this feels like the common confusion of natural numbers vs offsets. P6 mitigates that confusion somewhat by providing ^N as a shortcut for the commonly-needed 0..N-1 range, and I don't think that idiom should be eschewed by the doc. Yes, @foo.keys and @foo.kv are better in the particular case of looping over a single array's indices, but ^ and .elems can be useful together, too. Consider the case of processing unequal-length arrays in parallel: for ^max(@foo.elems,@bar.elems) On 5/27/09, Daniel Carrera daniel.carr...@theingots.org wrote: Patrick R. Michaud wrote: An even cleaner shortcut might be to use ^...@foo instead of ^...@foo.elems: for ^...@foo - $k { do_something($k, @foo[$k]) } Somewhat clearer could be: for @foo.keys - $k { do_something($k, @foo[$k]) } And some may prefer: for @foo.kv - $k, $v { do_something($k, $v) } I think the anti-pattern of 0...@foo.elems (or its incorrect form 0...@foo.elems) should probably disappear in favor of the above forms instead. Even if there is no language change, at least it'd be good to ensure that 0...@foo.elems doesn't appear in the documentation. Instead, whoever writes the docs should use @foo.keys and @foo.kv. Those are *very* clear, and they do the right thing. Daniel. -- Sent from my mobile device Mark J. Reed markjr...@gmail.com
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: Unexpected behaviour with @foo.elems
On Tue, May 26, 2009 at 04:38:21PM -0700, yary wrote: perl4-perl5.8 or so had a variable that let you change the starting index for arrays, so you could actually make the above work. But then everyone who'd re-arranged their brains to start counting at 0, and written code that has a starting index of 0, would have problems. That was $[ and it goes back to perl 1 or so. I recall experimenting with it a couple of times. Using it, though, means that you have to use $[ as the lower range limit for *every* array everywhere. That gets stale very quickly, and I then decided that I would just never change the setting of $[ and would remove such a change from any code that I called. This single global value for the initial index of all arrays was one of the things that lead to the greater understanding that action at a distance is hazardous to your sanity as a code maintainer.
Re: Continuations
Andrew Whitworth wrote: The issue mentioned in the Synopses is that junctions autothread, and autothreading in a conditional could potentially create multiple threads of execution, all of which are taking different execution paths. At some point, to bring it all back together again, the various threads could use a continuation to return back to a single execution flow. Hmm. If that's the case, let me suggest that such an approach would be counterintuitive, and not worth considering. When I say if any of these books are out of date, review your records for inconsistencies; otherwise, make the books available for use, I don't expect to end up doing both tasks. In a similar manner, I would expect junctions not to autothread over conditionals, but to trigger at most one execution path (continuation?). The real issue that needs to be resolved, I believe, is illustrated in the following statement: if any of these books are out of date, review them. The question, as I understand it, is what is meant by 'them'? Is it these books, or is it the ones that are out of date? In perl 6 terms: $x = any(@books); if $x.out-of-date { $x.review } Is this equivalent to: if any(@books).out-of-date { any(@books).review } or: if any(@books).out-of-date { any(@books.grep {.out-of-date} ).review } I don't mean to reopen the debate; though if we can get some resolution on this, I won't mind. But I _would_ at least like to see the summary of the issue stated a bit more clearly. -- Jonathan Dataweaver Lang
Re: Unexpected behaviour with @foo.elems
On Wed, May 27, 2009 at 7:05 AM, John Macdonald j...@perlwolf.com wrote: On Tue, May 26, 2009 at 04:38:21PM -0700, yary wrote: perl4-perl5.8 or so had a variable that let you change the starting index for arrays, so you could actually make the above work. But then everyone who'd re-arranged their brains to start counting at 0, and written code that has a starting index of 0, would have problems. That was $[ and it goes back to perl 1 or so. I recall experimenting with it a couple of times. Using it, though, means that you have to use $[ as the lower range limit for *every* array everywhere. Is it still a global in Perl 6? I've noticed a trend toward using less expansive scopes, so that setting $[ to 1 might mean that arrays that are defined in the current scope are 1-based instead of 0-based, whereas arrays defined in other scopes (such as inside a function imported from a module) might continue to be 0-based. That gets stale very quickly, and I then decided that I would just never change the setting of $[ and would remove such a change from any code that I called. ...which is probably the cleanest way to handle it. It's for a similar reason that postcircumfix:[ ] always uses $[-based consecutive integers for indexing: you always have a consistent way of referring to, e.g., the first element (@x[0]) or the last element (@x[*-1]), without having to worry about which indexing scheme any particular array might be using. That's also the reason for custom indexing: if you _want_ to use 1-based indexing for a given array, you can always define a custom index and then refer to the first element by saying @x{1}'. -- Jonathan Dataweaver Lang
Re: Unexpected behaviour with @foo.elems
On Tue, May 26, 2009 at 9:03 PM, Patrick R. Michaud pmich...@pobox.comwrote: On Tue, May 26, 2009 at 06:43:40PM -0500, John M. Dlugosz wrote: Daniel Carrera daniel.carrera-at-theingots.org |Perl 6| wrote: The following construction doesn't do what a user might expect: for 0...@foo.elems - $k { do_something($k,@foo[$k]) } Write ^...@foo.elems as a shortcut of 0...@foo.elems, which is the variation to exclude that endpoint if you would rather not write 0...@foo.elems-1. An even cleaner shortcut might be to use ^...@foo instead of ^...@foo.elems: for ^...@foo - $k { do_something($k, @foo[$k]) } Somewhat clearer could be: for @foo.keys - $k { do_something($k, @foo[$k]) } And some may prefer: for @foo.kv - $k, $v { do_something($k, $v) } I think the anti-pattern of 0...@foo.elems (or its incorrect form 0...@foo.elems) should probably disappear in favor of the above forms instead. Or perhaps for 0...@foo.end - $k { ... } @foo.keys may not be what the user wanted if @foo is a sparse array. -Scott -- Jonathan Scott Duff perlpi...@gmail.com
Re: Unexpected behaviour with @foo.elems
Is it still a global in Perl 6? It's not even global in perl5.10. perldoc says: As of release 5 of Perl, assignment to $[ is treated as a compiler directive, and cannot influence the behavior of any other file. (That's why you can only assign compile-time constants to it.) Its use is highly discouraged. Note that, unlike other compile-time directives (such as strict), assignment to $[ can be seen from outer lexical scopes in the same file. However, you can use local() on it to strictly bind its value to a lexical block. perl6's S28 Special Names [DRAFT] says under Perl5 to Perl6 special variable translation: $[ - This feature has been removed
Re: Amazing Perl 6
Hi Daniel, 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). 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 said, lazy lists like 0..Inf is something that is both impressive and easy to understand. You could try to think of things that are made easier or simpler by the new Perl 6. The only examples I can think of right now are: sub foo($x,$y) { ... } if $a $b $c { .. } for @people - $dude { do something } for %people.kv - $key, $value { do something } Back on the subject of impressive, I really like lambdas: $code = - $x { say $x } $code(hello world); I know this is not the approach you had in mind, but what do you think? Daniel.
Re: Unexpected behaviour with @foo.elems
Jonathan Scott Duff wrote: Or perhaps for 0...@foo.end - $k { ... } @foo.keys may not be what the user wanted if @foo is a sparse array. IIRC, you have to explicitly ask for the custom index in order to get sparse array keys. By design, the normal index is never sparse; only the custom index. That said, a case could be made that the custom index rules as currently presented are too restrictive to implement sparse arrays. In particular, the fact that you must map the custom index to the standard index when the array is first created, and that you are not permitted to adjust things later on, kills much of the power inherent in sparse arrays. To implement a sparse array, I'd recommend using hashes. In particular, allow hashes that have sortable keys to be able to access them by number as well as by name - E.g.: my %x = { 'b' = 2, 'c' = 3 } say %x[0]; # same as say %xb %xa = 1; say %x[0]; #same as say %xa -- Jonathan Dataweaver Lang
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: Amazing Perl 6
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 ;) Well, maybe you should relax your expectations. People who haven't been following P6 development for the last near-decade may be impressed by stuff that seems trivial to veterans. :) I really like the factorial example on the wiki page. That really gets across the expressiveness of P6, without being too hard to understand despite its brevity. It's not often you find an elegant yet non-recursive solution to that problem. I do think captures are inherently impressive, but not easy to explain...
Re: Amazing Perl 6
Daniel Ruoso wrote: 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 ;) I understand. Your experience with Perl 6 makes you harder to impress. So you are probably not impressed by the fact that you can do this: if $a $b $c { ... } But what if I told you that my university professor (while I was in university) chose to teach in Python because he saw that in Python you could do if a b c: and he thought oh! that's so cool!. You know what you might want to do? Start with simple but neat examples that everyone can understand (such as the if statement) and work upward to more complex examples, so that your last example is something really impressive. I figure that if you work up to it gradually, the audience will not be intimidated when they see a large powerful example. Daniel.
Re: Amazing Perl 6
Mark J. Reed wrote: I really like the factorial example on the wiki page. That really gets across the expressiveness of P6, without being too hard to understand despite its brevity. sub postfix:! { [*] 1..$^n } say 5!; WOW!! That *IS* cool. Can you explain to me how it works? I figured out postfix: myself, but the rest is obscure to me. I do think captures are inherently impressive, but not easy to explain... Got a link? Daniel.
Re: Amazing Perl 6
On Wed, May 27, 2009 at 1:42 PM, Daniel Carrera daniel.carr...@theingots.org wrote: sub postfix:! { [*] 1..$^n } say 5!; WOW!! That *IS* cool. Can you explain to me how it works? I figured out postfix: myself, but the rest is obscure to me. Key concepts: 1. placeholder variables. The ^ in $^n means it's a placeholder: no predeclaration required, and placeholders in an expression are assigned the passed-in arguments in serial order. (The sub could also have been written more traditionally as sub postfix:!($n) { [*] 1..$n } .) 2. the range operator .. : $x..$y for integers $x and $y generates, in list context, a list of the integers from $x to $y, inclusive. 3. the reduction meta-operator [...] : [OP](@list) collects the result of applying OP to the elements of the list in order. That is, assuming foo() is a binary sub, [foo](1,2,3,4) = foo(foo(foo(1,2),3),4). So [+](@list) generates a sum of the listed values, [*] generates their product, etc. So, given the argument to !: 1. create a list of integers from 1 to that value (1..$^n) 2. multiply them all together ([*]) and of course a sub without an explicit return statement returns the value of the last expression. I do think captures are inherently impressive, but not easy to explain... Got a link? Daniel. -- Mark J. Reed markjr...@gmail.com
Re: Amazing Perl 6
Daniel Carrera wrote: sub postfix:! { [*] 1..$^n } say 5!; WOW!! That *IS* cool. Can you explain to me how it works? I figured out postfix: myself, but the rest is obscure to me. Here is another idea: Is it possible to declare a circumfix function that calculates the magnitude of a vector? $magnitude = |@vector|; You know how in math, two vertical bars are a standard notation for magnitude. Oh oh oh... is it possible to define a circumfix function for the dot product? Something like: $dot_product = @vector1,@vector2; Is that possible? That would be uber-cool. Daniel.
Re: Amazing Perl 6
Mark J. Reed wrote: 3. the reduction meta-operator [...] : [OP](@list) collects the result of applying OP to the elements of the list in order. That is, assuming foo() is a binary sub, [foo](1,2,3,4) = foo(foo(foo(1,2),3),4). So [+](@list) generates a sum of the listed values, [*] generates their product, etc. Wow... That's a foldl! In a functional language, that would be called a fold. It's very popular in Haskell. I like that Perl 6 seems to be taking steps in the direction of functional languages. First lazy lists (0..Inf) and now a fold. :-D Daniel.
Re: Amazing Perl 6
Note that of the examples given, only Perl 6 and Common Lisp do two things that help immensely simplify the result: 1. reference the built-in * operator directly, without having to wrap it in a lambda expression; 2. actually name the function ! The Lisp version suffers from the lack of a built-in range constructor. On Wed, May 27, 2009 at 2:21 PM, Mark J. Reed markjr...@gmail.com wrote: In Haskell it may be called fold (well, foldl and foldr), but the concept has has a variety of names. Two of the more common ones are reduce and inject; I believe Perl6 chose reduce for consistency with the Perl5 List::Util module. Common Lisp and Python also call it reduce: (defun ! (n) (reduce #'* (loop for i from 1 to n collecting i))) def fact(n): return reduce(lambda x,y: x*y, range(1,n+1)) While Ruby calls it inject. def fact(n) (1..n).inject { |x,y| x*y } end Perl 6 has a lot of functional features. IMO the nice thing about its version of reduce is the way it's incorporated into the syntax as a metaoperator. -- Mark J. Reed markjr...@gmail.com -- Mark J. Reed markjr...@gmail.com
Re: Amazing Perl 6
On Wed, May 27, 2009 at 02:21:40PM -0400, Mark J. Reed wrote: On Wed, May 27, 2009 at 1:59 PM, Daniel Carrera daniel.carr...@theingots.org wrote: Wow... That's a foldl! In a functional language, that would be called a fold. In Haskell it may be called fold (well, foldl and foldr), but the concept has has a variety of names. Two of the more common ones are reduce and inject; I believe Perl6 chose reduce for consistency with the Perl5 List::Util module. Common Lisp and Python also call it reduce: (defun ! (n) (reduce #'* (loop for i from 1 to n collecting i))) def fact(n): return reduce(lambda x,y: x*y, range(1,n+1)) While Ruby calls it inject. def fact(n) (1..n).inject { |x,y| x*y } end Perl 6 has a lot of functional features. IMO the nice thing about its version of reduce is the way it's incorporated into the syntax as a metaoperator. Historically, the name reduce was used (first?) in APL, which also provided it as a meta-operator. op/ would use op to reduce the array on the right of the meta-operator. (Although, in APL, it could be an n-dimensional object, not necessarily a 2-dimensional array - the reduce would compute an (n-1)-dimensional object from it. This could be used to generate row-sums and column sums. APL was extremely terse, you could compute almost anything in a single line - Perl golfing afficionados have never really caught up, although with the addition of Unicode operators Perl 6 could now go ahead.)
Re: Amazing Perl 6
Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: 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. Of late, new languages have been created that are going backwards. That is, they are regressing to a more primitive form. C# is just Java with a different syntax. Java is for people who can't handle the complexities of C++. begin barbe voice Multiple inheritance is hard!/end. So don't provide multiple inheritance, just rip it out, without replacing it with ANY other way to reuse implementation, so everyone uses copy/paste to build concrete classes that should have common code with others. But... language science and research did not stop after OO was introduced. Why don't new language use new, better ways of doing things? Well, Perl 6 does. That's what's cool about it, for me: it looks toward newer ideas on a deep level, not just some shallow change but otherwise the same old stuff. Look at Roles to showcase that. Also, there is full delegation of methods with a terse syntax, useful for aggregating things that provide a desired interface. And hopefully it will realize more of the ramifications behind allowing generic types, as my own research (see http://www.dlugosz.com/Perl6/web/isa-inheritance.html suggests. It will embrace multi-core computers with implicit threading constructs. It's not just cool because its new features -- they are fundamental ideas that should have been with us for some time, but other languages refuse to accept. --John
Re: Amazing Perl 6
On May 27, 2009 01:52:58 pm Mark J. Reed wrote: On Wed, May 27, 2009 at 1:42 PM, Daniel Carrera daniel.carr...@theingots.org wrote: sub postfix:! { [*] 1..$^n } say 5!; WOW!! That *IS* cool. Can you explain to me how it works? I figured out postfix: myself, but the rest is obscure to me. Key concepts: 1. placeholder variables. The ^ in $^n means it's a placeholder: no predeclaration required, and placeholders in an expression are assigned the passed-in arguments in serial order. (The sub could also have been written more traditionally as sub postfix:!($n) { [*] 1..$n } .) 2. the range operator .. : $x..$y for integers $x and $y generates, in list context, a list of the integers from $x to $y, inclusive. 3. the reduction meta-operator [...] : [OP](@list) collects the result of applying OP to the elements of the list in order. That is, assuming foo() is a binary sub, [foo](1,2,3,4) = foo(foo(foo(1,2),3),4). So [+](@list) generates a sum of the listed values, [*] generates their product, etc. So, given the argument to !: It might have been implied, but you kind of missed the discussion about the ability to add new operators (and how they relate to other operators). To recap (slightly differently) there are several impressive features that are easier to explain and can be part of the build up to the factorial example: Placeholder variables: non-declared and descriptive Ranger operators: not so impressive and inherited from perl5 (etc.) The reduction meta-operator [...]: nice syntax and no need to provide a identity/seed element A side discussion of other interesting meta-operators User defined operators: overloading and novel mechanism of declaring precedence (looser, tighter, etc.) Finally, a simple slide where the factorial definition takes up the whole slide and let the audience have a few moments of silence to let them figure it out and to start to really appreciate the expressiveness/impressiveness of perl6 Henry 1. create a list of integers from 1 to that value (1..$^n) 2. multiply them all together ([*]) and of course a sub without an explicit return statement returns the value of the last expression. I do think captures are inherently impressive, but not easy to explain... Got a link? Daniel. -- Henry Baragar Instantiated Software 416-907-8454 x42
Re: Amazing Perl 6
Mark J. Reed wrote: In Haskell it may be called fold (well, foldl and foldr), but the concept has has a variety of names. Two of the more common ones are reduce and inject; The terms I've seen are fold and reduce. The fold term is not just from Haskell. I've seen it elsewhere. If you had said inject I wouldn't have known what you meant. Daniel.
Re: Amazing Perl 6
Mark J. Reed wrote: Note that of the examples given, only Perl 6 and Common Lisp do two things that help immensely simplify the result: 1. reference the built-in * operator directly, without having to wrap it in a lambda expression; 2. actually name the function ! Yes, very neat. Haskell does that too, but I don't know if you can make the function a postfix in Haskell. Daniel.
Re: Amazing Perl 6
On Wed, May 27, 2009 at 3:38 PM, Daniel Carrera daniel.carr...@theingots.org wrote: The terms I've seen are fold and reduce. The fold term is not just from Haskell. I've seen it elsewhere. If you had said inject I wouldn't have known what you meant. The name inject comes from Smalltalk, where you :inject the initial value :into the operation, whose arguments are the accumulator and the new item (it has no fold-1 variant). Wikipedia mentions accumulate (C++) and compress (no example cited) as additional names. In Perl6, I assume [...] automatically folds left on left-associative operators and right on right-associative ones? -- Mark J. Reed markjr...@gmail.com
Re: RFC: Implicit threading and Implicit event-loop (Was: Re: Continuations)
Sounds like threads to me. What I see that's different from common threads in other languages is that they are all the same, rather than one master and many new threads that have no context history above them. In Perl 6, every thread sees the same dynamic scope as the original. It doesn't matter which one is left standing to continue and eventually return up the context chain. --John Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: 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
Re: Amazing Perl 6
On Wed, May 27, 2009 at 07:56:42PM +0200, Daniel Carrera wrote: Here is another idea: Is it possible to declare a circumfix function that calculates the magnitude of a vector? $magnitude = |@vector|; You know how in math, two vertical bars are a standard notation for magnitude. Oh oh oh... is it possible to define a circumfix function for the dot product? Something like: $dot_product = @vector1,@vector2; Is that possible? That would be uber-cool. The problem with that is the presence of an existing prefix:| operator. One could fake it with a postfix:| macro that rewrites the AST produces by the prefix, except no one implements macros yet. But circumfix openers have to share longest-token space with prefixes. You could maybe use broken bar instead, circumfix:¦ ¦. Larry
How to write this properly in Perl 6?
Hi cool people, the Amazing Perl 6 thread was amazing. It reminded me how Perl 6 looks interesting and fun. So... how can I write properly, for some meaning of properly, the Perl 6 equivalent of this: http://search.cpan.org/dist/Games-BonDigi/ ? ( if it's not clear, you can run the example http://cpansearch.perl.org/src/COSIMO/Games-BonDigi-0.02/examples/generate_bondigi.pl ) -- Cosimo
Re: Amazing Perl 6
Sorry, only answered half of your question. On Wed, May 27, 2009 at 07:56:42PM +0200, Daniel Carrera wrote: Oh oh oh... is it possible to define a circumfix function for the dot product? Something like: $dot_product = @vector1,@vector2; Is that possible? That would be uber-cool. More likely just use sub infix:· (@a,@b) { ... } $dot_product = @vector1 · @vector2; Or some such. Larry
Re: How to write this properly in Perl 6?
Cosimo (): the Amazing Perl 6 thread was amazing. It reminded me how Perl 6 looks interesting and fun. So... how can I write properly, for some meaning of properly, the Perl 6 equivalent of this: http://search.cpan.org/dist/Games-BonDigi/ ? 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 *' // Carl
Re: How to write this properly in Perl 6?
Cosimo Streppone cosimo-at-streppone.it |Perl 6| wrote: Hi cool people, the Amazing Perl 6 thread was amazing. It reminded me how Perl 6 looks interesting and fun. So... how can I write properly, for some meaning of properly, the Perl 6 equivalent of this: http://search.cpan.org/dist/Games-BonDigi/ ? ( if it's not clear, you can run the example http://cpansearch.perl.org/src/COSIMO/Games-BonDigi-0.02/examples/generate_bondigi.pl ) Anything in the existing implementation that's hostile to Perl 6? Just port it over by lightly editing the text or using a p5 module importer. To write from scratch, I suppose it's just a recursive function that talks and drinks beer. You need external libraries for those, but the recursion is easy. --John
Re: Unexpected behaviour with @foo.elems
You're assuming he's using an instance of the built-in Array class. I would think one reason for implementing your own class that does Positional is to do something out of the ordinary. So what exactly does Positional promise? I think it should be as general as possible, and avoid thinking of Array implicitly. Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: Jonathan Scott Duff wrote: Or perhaps for 0...@foo.end - $k { ... } @foo.keys may not be what the user wanted if @foo is a sparse array. IIRC, you have to explicitly ask for the custom index in order to get sparse array keys. By design, the normal index is never sparse; only the custom index. That said, a case could be made that the custom index rules as currently presented are too restrictive to implement sparse arrays. In particular, the fact that you must map the custom index to the standard index when the array is first created, and that you are not permitted to adjust things later on, kills much of the power inherent in sparse arrays. To implement a sparse array, I'd recommend using hashes. In particular, allow hashes that have sortable keys to be able to access them by number as well as by name - E.g.: my %x = { 'b' = 2, 'c' = 3 } say %x[0]; # same as say %xb %xa = 1; say %x[0]; #same as say %xa
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: How to write this properly in Perl 6?
You can write a sub to return the next step: sub bondigi { state $n=1; return (Bon Digi Bon Digi, Bon xx $n, Digi xx $n++); } but I think an idiomatic Perl 6 solution would have a proper lazy Iterator. How do we write one of those?
Re: Amazing Perl 6
Larry Wall wrote: $dot_product = @vector1,@vector2; Is that possible? That would be uber-cool. More likely just use sub infix:· (@a,@b) { ... } $dot_product = @vector1 · @vector2; Thanks. And for Daniel R. and other observers, how about this: # Courtesy of Larry sub infix:· (@a,@b) { [+] @a »*« @b } my @vector1 = (1,2,3); my @vector2 = (2,3,4); say @vector1 · @vector2; I think that's really nifty. So you can talk about Hyper operators and then show the dot product. What do you think? Daniel.
Re: Amazing Perl 6
Mark J. Reed markjreed-at-gmail.com |Perl 6| wrote: 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 ;) Well, maybe you should relax your expectations. People who haven't been following P6 development for the last near-decade may be impressed by stuff that seems trivial to veterans. :) I really like the factorial example on the wiki page. That really gets across the expressiveness of P6, without being too hard to understand despite its brevity. It's not often you find an elegant yet non-recursive solution to that problem. I do think captures are inherently impressive, but not easy to explain... captures are inherently impressive, but not easy to explain... Since nobody's done so yet, I suppose so. As for fun and expressive, have you seen my APL and Lisp inspired stuff? In the latter, I found out for myself just how expressive it is in a deep appreciation I didn't have before. In particular, why is the Perl 6 version even shorter than Lisp? Because it has the fully overarching self-descriptive features, but lets you leave out excess verbage.
Re: Amazing Perl 6
Mark J. Reed markjreed-at-gmail.com |Perl 6| wrote: In Haskell it may be called fold (well, foldl and foldr), but the concept has has a variety of names. Two of the more common ones are reduce and inject; I believe Perl6 chose reduce for consistency with the Perl5 List::Util module. Common Lisp and Python also call it reduce: (defun ! (n) (reduce #'* (loop for i from 1 to n collecting i))) def fact(n): return reduce(lambda x,y: x*y, range(1,n+1)) While Ruby calls it inject. def fact(n) (1..n).inject { |x,y| x*y } end And APL calls it |¨ (two little dots high up) |
Re: Amazing Perl 6
Mark J. Reed markjreed-at-gmail.com |Perl 6| wrote: On Wed, May 27, 2009 at 6:05 PM, John M. Dlugosz 2nb81l...@sneakemail.com wrote: And APL calls it |¨ (two little dots high up) Mr. MacDonald just said upthread that the APL reduce metaoperator was spelled /. As in: +/1 2 3 6 So how does |¨ differ? Sorry, the two dots is APL's equivilent of the hyper operators, not the reduction operators. Easy to get those mixed up! For example, |1 2 3 ⍴¨ 10| would natively be written in Perl 6 as |10 »xx« (1,2,3)|. --John
Re: Amazing Perl 6
Here are a few of my favourite Perl 6 selling points: * Compactness of expression: say 'Hello, World!'; * Compactness of expression + semi-infinite data structures: @fib = 1,1...[+]# The entire Fibonacci sequence * Junctions make comparisons much more natural: if $dice_sum == 7 | 11 { say 'Natural!' } elsif $dice_sum == 2 | 3 | 12 { say 'Craps!' } * Given/when takes that even further: given $dice_sum { when 7 | 11 { say 'Natural!' } when 2 | 3 | 12 { say 'Craps!' } } * Junctions + n-ary comparison help too: if 0 all(@coefficients) = 1 { say 'Coefficients are already normalized.'; } * Junctive comparisons + the max operator: if any(@new_values) all(@existing_values) { $upper_limit = [max] @new_values; } * .invert and .push makes hashes (especially hoa's) vastly more useful (and .perl makes debugging vastly easier): my %comments = perl6 = Amazing Revolutionary, perl5 = Essential Amazing, perl4 = Classic, perl1 = Classic; my %epithets; %epithets.push(%comments.invert); say %comments.perl; say %epithets.perl; * Unicode source and data overthrows US cultural hegemony! (oh, and Hinrik has the coolest name in the entire Perl community :-) my @recepción; my $Gruß = 'olá' my $óvoµa = 'Hinrik Örn Sigurðsson'; push @recepción, $Gruß, $óvoµa!; * Unary method call + topicalization simplifies multiple operations on objects: for @parcels { .address; .weigh; .ship; while .shipping { .fold; .spindle; .mutilate; } .deliver; } * Subtypes make typing far more precise (and hence more useful): my $filename of Str where /\w**8 '.' \w**3/; my $octet of Int where { 0 = $^value = 255 } * Command-line parsing using standard language features: sub MAIN ($text, Bool :f($foo), Str :B($bar), *...@files) { ... } # Can then be invoked as: my_prog.p6 -f -Bbaz 'two words' file1 file2 etc * Grammars built into the language: grammar Expr::Arithetic { rule Expression { Mult ** $OP= + -} rule Mult { Pow ** $OP= * / % } rule Pow{ Term ** $OP= ^ } token Term { Literal | '(' Expression ')' } token Literal { [+\-]? \d+ [ \. \d+ ]? } } * Grammar inheritance: grammar Expr::Algebraic is Expr::Arithetic { token Literal { alpha+ | Expr::Arithetic::Literal } } * Only perl can parse Perl 5 but Even Perl 6 can parse Perl 6: given $source_code { $parsetree = m:keepall/Perl::prog/; } And that's without even mentioning all the new OO features, multiple dispatch, roles, delegation, macros, etc., etc. The problem with demo- ing the awesomeness of Perl 6 is always running out of demo time before running out of demo-able awesomeness. Damian PS: A really mean, but very effective, way of emphasizing the ease, expressiveness, compactness, and readability of Perl 6 code is to take each of the examples and show the same thing written in Java. ;-)
Re: Amazing Perl 6
On Wed, May 27, 2009 at 2:39 PM, John Macdonald j...@perlwolf.com wrote: Historically, the name reduce was used (first?) in APL, which also provided it as a meta-operator. op/ would use op to reduce the array on the right of the meta-operator. It's quite possible that APL was the first use of the term reduce in that sense - I know that (reduce) didn't make it into LISP until relatively late, possibly not until Common Lisp. APL was extremely terse, you could compute almost anything in a single line - Perl golfing afficionados have never really caught up, although with the addition of Unicode operators Perl 6 could now go ahead.) 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 -- Mark J. Reed markjr...@gmail.com (*) life ←{↑1 ω⌵.^3 4=+/,‾1 0 1◦.ϕ⊂ω} I haven't tested it, but the above will allegedly compute the next generation from a Life configuration (input and output represented as a matrix of 1s and 0s).
Illustration of stuff we've been discussing
Please see http://www.dlugosz.com/Perl6/web/info-model-1.html and talk to me about it. --John
The game of life
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? --John