Re: The Pie-thon benchmark
Dan Sugalski wrote: it's not exactly exciting watching two people hit return three times in front of a roomful of people. Although watching two people hit each other in the face with custard pies three times in front of a roomful of people may be a lot more fun. Progamming language benchmarks vs pie throwing. No contest. A
Re: Events (I think we need a new name) - Parcel?
Butler, Gerald wrote: How about: tocsin [...thinking out loud...] I'm not sure it's a good idea to use an obscure word, even if it is appropriate to the usage. It should be a word that the average user would recognise, and hopefully be able to intuit some sense of what it does. How about Parcel? Like Packet and Message it provides a sense of what it is doing. The metaphor extends to sending and receiving parcels, wrapping and unwrapping them, and so on. On a more trivial note, the first three letters make it a prime candidate for a corny acronym: PARrot Communication Event Layer PARrot Container for Event Lobbing PARrot Commissioner for Event Liaison A
Re: Initializers, finalizers, and fallbacks
Dan wrote: Should be FINALIZE. Although some in the non-US English speaking world might say it should be FINALISE. Perhaps FINAL might be a better choice? That would please more of the people for more of the time (or displease them for less of the time). A
Funky «vector» operator
I'm so happy! I just found out, totally by accident, that I can type the « and » characters by pressing AltGr + Z and AltGr + X, respectively. Apologies if this is common knowledge, but it was news to me, and I thought I'd share this little Perl6 of wisdom. Your mileage may vary, of course, but now that I know that it's been hiding there in my keyboard all along and I didn't need to do anything special to set it up, I don't feel so uneasy about it being a Perl 6 operator. A
Re: Mutating methods
Larry Wall wrote: multi sub *scramble (String $s) returns String {...} [...] Or you can just call it directly as a function: scramble(hello) Can you also call scramble as a class method? class String is extended { method scramble { ..etc... } } String.scramble(hello) A
Re: Mutating methods
Larry Wall wrote: Yet another approach is to *replace* dot with something that mutates: @array!sort @array?sort Either of those would work syntactically in that case, since neither ! nor ? is expected as a binary operator. What about ? is as a ternary operator: @foo?bar:baz; Or am I missing.something? A
Re: Semantics of vector operations
Luke Palmer wrote: But I'm still sure that the unicode-deficient would rather write: I suspect the unicode-deficient would rather write Ruby. Adding unicode operators to Perl will just reinforce its reputation as a line noise language. I know it has been said before, and I'm sure it will be said again, but this is a really bad idea, IMHO. Sure, make Perl Unicode compliant, right down to variable and operator names. But don't make people spend an afternoon messing around with mutt, vim, emacs and all the other tools they use, just so that they can read, write, email and print Perl programs correctly. A
Re: Compiler writing tools
Luke Palmer wrote: I think $() will help somewhat, as will interpolating method calls, but for a compiler, I'd really like PHP-like parse switching. That is, I could do something like (I'll use $ and $ for ? and ?): Check out the new scanner module for Template Toolkit v3. It does this exactly that. It allows you to specify as many different tag styles as you like and uses a composite regex to locate them in a source document. It extracts the intervening text, and then calls back to your code to do whatever you like with them. It takes care of the surrounding text and handles things like counting line numbers so that you don't have to worry about it. The code is still in development so you'll need to get it from CVS. See: http://tt3.template-toolkit.org/code.html Everything is raw and undocumented, but examples/scanner.pl shows an example of what you want to do. Be warned that I'm working on this right now, so things are changing often. Having said that, the scanner is pretty much stable, although the handler object that it interacts with isn't. A
Re: This week's summary
Uri Guttman wrote: i say we just sell them a license to use the US constitution. Bill Gates wrote: What is it with these Linux guys? i say we just sell them a license to use Windoze. :-) A
Re: enums and bitenums
Larry Wall wrote: Anyway, this all implies that use of a role as a method name defaults to returning whether the type in question matches the subtype. That is, when you say: $foo.true $bar.red [...] $bar.red [...] $baz.Byte it's asking whether the Int property fulfills the Byte constraint, but that's getting kind of strange. If the roles are first class objects then their traits are defined as methods, right? Boolean.true($foo) Color.red($bar) Int.byte($baz) Then assuming that certain objects inherit certain roles, you could use something like the Perl 5 $self-SUPER::new() syntax. Only it would look more like this: $foo-Boolean.true $bar-Color.red $baz-Int.byte Another implication is that, if properties are subtypes, we can't use the same name as a cast method. Since $baz.Byte only returns true or false, we'd need something like (yuck) $baz.asByte [...or...] $baz.as(Byte) Or: $baz-Byte That would make something like this: $foo-Color.red the same kind of thing as: $foo.as(Color).red A
Re: Next Apocalypse
chromatic wrote: The thinking at the last design meeting was that you'd explicitly say Consider this class closed; I won't muck with it in this application at compile time if you need the extra optimization in a particular application. In Dylan, this is called a sealed class. It tells the compiler that it's safe to resolve method names to slot numbers at parse time, IIRC. Seems like a nice idea. A
Re: Next Apocalypse
Jonathan Scott Duff wrote: This is mostly just a gratuitous message so that Piers has something to talk about in the next summary I bet Leon has something to say about that. Better would be We're working on X and have hashed out the details of Y but are having problems with Z Something like: We're working on Perl 6 and have hashed out the details of Perl 6 but are having problems with users who keep wanting regular updates :-) A
Re: Embedded foreign syntax (was Re: P6ML?)
Miko O'Sullivan wrote: We already have the ability to embed foreign languages (XML, HTML, whatever) using here docs: $myml = MyXmlParser-new( '(MARKUP)'); thingy blahblah blah/blah /thingy (MARKUP) True, but what kind of magic is hiding inside MyXmlParser? One problem is that writing MyXmlParser to parse and validate XML and then generate some corresponding Perl data structure is difficult and error prone. In the simple case, XML::Simple is your friend. But as Robin points out, the simple approach falls down work when you need finer control over what you're doing. You can use the XML::Schema modules (if you're feeling brave) and that will generate a validating parser with control over the generated data structure. But it's big and bulky and the complexities of XML Schema itself make it a daunting task. There are various other modules and techniques which can acheive the desired result, but I've yet to find one that was both easy to use and powerful (although I need to check out those links that Robin posted). So I'm thinking that if the Perl 6 parser is as flexible and powerful as promises, then can we adapt it to simplify the task of parsing XML into internal data structures? One benefit of inlined XML over the example above is that it would be parsed at compile time, not runtime. When our modified parser sees this: use Perl6::XML; thingy blahblah blah/blah /thingy It would effectively re-write it as if written: my $thingy = { blah = 'blah blah', } and then generate the appropriate opcodes to implement it at runtime. A further benefit would be that your parsed and validated XML markup could then be stored as Parrot bytcode. You would effectively be compiling XML into bytecode that you could load into other programs with a simple use. That would be neat. As and when we need more control over the XML validation or code generation, we would write our own modified XML grammar modules. Apocalypse 5 suggests this would be a simple matter of defining a few new 'rule' constructs. For example, we might want to add a rule for matching thingy/blah that constructs a list rather than a scalar. Thus, the XML would be parsed as if written: my $thingy = { blah = [ 'blah blah' ], } This is all largely hypothetical, of course. Hence the continued hand waving and general lack of detail. Consider it an open thought in process. :-) A
Re: P6ML?
Robin Berjon wrote: I just have yet to see someone point at one place where Perl 5 hinders XML processing in such a way that Perl 6 could help. If my understanding of the design of Perl 6 is correct, the lexer, parser and any other related components will be highly configurable and/or replaceable. The goal is to provide support for little languages by separating Perl the language from perl the interpreter. It will be possible to modify or replace Perl the grammar so that perl the program can parse other languages, including Python, Ruby and presumably, XML. So instead of writing Perl programs to parse and manipulate XML, it should be possible to modify Perl itself so that it parses the XML directly into some internal form suitable for programmatical manipulation. I presume that it should also be possible to extend the rules of a default non-validating XML parser grammar with additional rules to encode an XML schema. On top of that it should be possible to define further production rules that are invoked as the source document is parsed, i.e an XML schedule (schema/schedule ~= pattern/action). How exactly this will manifest itself, I cannot tell. Nor can I say if this is actually a sensible thing to do or not. But unless my understanding is warped, support for parsing XML and other markup languages could be moved down into the core of the parser internals for Perl 6. For example, it might be possible to do something like this: use Perl6::XML; thingy blahblah blah/blah /thingy use Perl6; print $thingy.blah; This is all speculation and hand-waving, of course. But the point is that Perl 6's extending parsing capabilities could well provide a much greater level of integration between Perl, XML and various other programming and markup languages. My rant against the XML machine was really an aside. Take everything I say with a pinch of salt. :-) A
Re: P6ML?
Robin Berjon wrote: But as someone that also had to parse other people's random formats before we had XML, I would like to stress strongly the fact that the current situation is *much* better than it was. True, but you're also missing the point that XML is a festering pile of steaming camel turds that has been over-designed and over-engineered by committee for 4 decades and still isn't any closer to being pleasant or easy to use. Convergence is good, unless you're converging in a bad place. Now all our markup is verbose, difficult to parse, memory hungry, tiresome to manipulate, and so on, (unless you're using YAML of course). XML is Yet Another Silver Bullet Bandwagon that we all jumped on because the XML software vendors told us to. Anyway, this isn't the time or place for an anti-XML rant. Suffice it to say that at least one of us is hoping that we can do markup better in Perl 6. A
Re: Parrot 0.0.10 feature freeze
Steve Fink wrote: [...] does fit well with the -Oj flag. Parrot -- now with extra juice! -Oj Simpson? Parrot -- now get away with murder! :-) A
Re: Object spec
Sam Vilain wrote: Associations *are* fundamental object things. Presenting them in terms of attributes is the real hack. Associations *are* fundamental things, but I don't think they are part of an object. They describe relationships between objects and should exist independantly and orthogonal to them. Dave Whipp wrote: An association is a mechanism that permits one object to navgigate to another. If the association is bidirectional, then it is possible to also navigate from the target back to the source. Each direction of navigation should be given a unique identifer. Category theory has something to say about this. I hope I can provide an essence of it, despite my limited understanding of the subject... A category is defined by a collection of elements (objects in this case) and a number of morphisms (relations) that provide mappings between the different elements. There are many different kinds of morphisms: epimorphisms (one-to-), monomorphisms (-to-one), isomorphisms (one-to-one), polymorphisms (-to-many) and so on. In category theory, morphisms are dual, so that for each relationship represented by an arrow between two objects, there is a reciprocal relationship travelling back down the arrow in the opposite direction. Traditional databases and object systems are based on set theory. Set theory is in fact just one kind of theory that is described by category theory (think of Category Theory as a class and Set Theory as an instance). The category morphisms that are defined by set theory are 'identity' and 'contains' (insert general paraphrasing and hand-waving warning here). The 'identity' isomorphism gives each element in the set a unique identifier so that you know which one you're talking about at any time. 'contains' is a polymorphism that defines which elements are contained by which other elements. If you want to make it an ordered set, then you need to add another morphism, 'before' (and its dual morphism 'after') which tells you which of any two elements in a set is ordered before the other. If you want to make a tuple, hash, queue, stack, bag, stream or multi-coloured, cross-referenced, hyper-indexed, double-camel Larry space in 9 + 3i dimensions, then you just need to add a few more morphisms that define those extra relations that are characteristic of that kind of information space. In summary: Category == [ Elements, Morphisms ]# math terminology == [ Objects, Associations ] # programming == [ Records, Relations ] # database An association is either consitant, or inconsitant. I think it is better to assume that there is no such thing as an inconsistent morphism. If the shoe doesn't fit, then don't wear it! Find another shoe or go barefoot. :-) While it it is obvious that associations can be implemented using attributes, it seems to me that, to do so, is [ ...not so good... ] Agreed. Associations are no more part of an object than an electric current is part of an electron. The field is defined by the interaction between fundamental particles but is not an inherent part of the particles themselves (wave/particle duality and other quantum mechanical chicanery aside). The only reason that we are currently forced to use attributes to represent our relations is because our OO systems and databases are based on set theory. An object or database record is conceptually nothing more than a set containing attributes. We define relations using attributes as foreign keys because there's no other way to do it. If instead we borrow the conceptual model from category theory and provide a mechanism for defining elements and relations *separately*, then it should be possible to build all kinds of fancy information spaces with any number of different inter-element relationships defined. The only language that I'm aware of that implements something like this is CAML (although I'm sure there must be others). Reading from http://caml.inria.fr/ercim.html : It is possible to define a type of collections parameterized by the type of the elements, and functions operating over such collections. For instance, the sorting procedure for arrays is defined for any array, regardless of the type of its elements. Anyway, the gist of this long rambling post is that In My Humble Opinion, if Perl 6 is to provide the ability to define associations between objects, then it should do so as part of a larger category mechanism rather than as an extension to the class/object mechanism. A
Re: Multiple Inheritance eq Interfaces [was: Re: Object spec]
Sam Vilain wrote: No. All I'm saying is that this sort of construct: *{$_} = \{Class::$_} foreach (qw(method method2 method3)); Like mixins? Perhaps something like this: class My::Class; mixin My::Random::Number::Generator qw( rand ); mixin My::Serialisation::Marshall qw( freeze thaw ); # ...class def... A
Re: newline as statement terminator
Allison Randal wrote: It's a balance, like everything else in design. use Yin::Yang; s/design/life/g; A
Re: Objects, methods, attributes, properties, and other related frobnitzes
Dan Sugalski wrote much sense, including these gems: *) Method: Some sort of action that an object can do. Methods are global and public--only one foo method for an object. Methods may be inherited from parent classes, or redefined in a particular class. Redefined methods hide parent class methods of the same name What about redefining methods for a particular object instance? It's something that Ruby does and can be extremely useful. Properties and methods share a namespace, and methods win. If I do: a = foo.bar; I'll call the bar method of foo if foo has a bar method, otherwise I'll fetch the bar property. Python does this (right?) and Perl 6 will do this. (Yes, it will. Inside information, trust me. Unless that changes this week...) Will there be some way to explicitly indicate that one is required but not the other? I can imagine times when you would want to access a property but not have it masked by a method, or call a method if it exists but not fall back on a property. Code must be able to fetch a handle on a particular method for later calling By this I presume you mean that the handle would be frozen to the method as it was when then handle was fetched? If you later re-define the method, the handle would remain pointing at the original method, not the new one. Or not? A
Re: Arc: An Unfinished Dialect of Lisp
Adam Turoff wrote: The problem with cons/car/cdr is that they're fundemental operations. Graham *has* learned from perl, and is receptive to the idea that fundemental operators should be huffman encoded (lambda - fn). It would be easy to simply rename car/cdr to first/rest, but that loses the huffman nature of car/cdr. Good point, but I can't help thinking that list/head/tail or list/item/rest (for example) would be preferable to cons/car/cdr. More meaning at the cost of a character or two. I doubt there are few people who remember, ever knew or even care that car is Contents of the Address Part of the Register and cdr is Contents of the Decrement part of the Register (yes, I had to look them up :-). Even when you know what the acronyms stand for, they still doesn't make a great deal of sense. A
Re: Arc: An Unfinished Dialect of Lisp
On Tue, Jan 21, 2003 at 12:55:56PM -0800, Rich Morin wrote: I'm not a Lisp enthusiast, by and large, but I think he makes some interesting observations on language design. Take a look if you're feeling adventurous... I can't help feeling slightly deflated. Given the chance to re-design Lisp from scratch, the tasks on the top of my TODO list to address would be: * getting rid of some/all those damn parenthesis * renaming cons/car/cdr to something meaningful Alas, these are about the only parts he's not changing. He promises that Arc will have a syntax one day, but there isn't one yet. The other comments that caught my eye were that Arc is designed for Good Programmers[tm] and that it was particularly targetted at developing web applications. Alas, my experience seems to suggest that most of the people writing web applications are monkeys who would rather have something designed for Bad Programmers, like PHP. A
Re: L2R/R2L syntax (was Re: Everything is an object.)
Paul Johnson wrote: When I later saw it using mutt in an xterm, the tilde was at the top of the character, where I was more used to seeing it and it didn't look like an arrow any more, nor did it look very good to me. Ah yes, that's the problem. On all my fonts, the tilde appears at the top and it doesn't look anything like an arrow. Viewing it on a web browser with the tilde centered vertically does indeed bring out the arrow-ness of it. A
Re: L2R/R2L syntax (was Re: Everything is an object.)
Damian Conway wrote: Really? We don't have any trouble in Perl 5 with an = character being used in various unrelated operators: == comparison =assignment ~= match s/~=/=~/ = comma = less than or equal to But these are all roughly related to the concept of equality, be it testing equality, enforcing equality by assignment, equality in terms of matching a pattern, setting a parameter to equal a value, testing is something is equal or less than equal to something else. The use of '=' seems entirely consistent in these operators. -- decrement -difference -= subtraction - dereference -X file op The first 3 all relate to the familiar concept of 'minus', or more precisely a delta between two values. The last uses '-' as 'dash', another familiar concept which doesn't grate against the first usage, IMHO. The arrow is a special case. I don't read that first character as '-', I think of the operator as one. I guess the visual cue forces me to see it like that. These operators may not be internally self-consistent, but I don't think it's a problem having different meaning for '-', given that both meanings are well understood to anyone who knows basic math and has used a command line program with a -x argument. I'm just suggesting the same for the ~ character: ~~ smart-match ~concatenate ~| stringy bitwise OR ~ append args ~ invocate This is where I get lost. I see 4 different concepts being overloaded onto '~'. In the first it indicates 'match' just as it always has for =~ and !~. In the second, it is being used for concatentation - nothing to do with matching. In the third it is being used to cast stringwisely - nothing to do with matching or concatenation. In the fourth and fifth it is being used to re-order arguments - nothing to do with matching, concatenation (well, possibly concatenation of argument lists) or stringwise casting. Now that I look at it again, the '~~' operator bothers me in particular. The first '~' seems to indicate 'stringwise' in keeping with '~|' and the second implies 'match' in keeping with '=~'. I find it questionable to use the same character twice in one operator and have different semantics implied for each. '~' should either be 'match' or 'stringwise' but not both. I would like to see '~' kept for matching and just matching. It is well known in this role and is analogous to the roughly equals operator in the Real World (extended ASCII character 247 - just don't ask me to type it). I also think '_' should be used for concatenation because it's in keeping with the existing use of 123_456. As a prefix character to indicate stringwise (numberwise, bitwise, etc) casting, can we not use a single character prefix, e.g. 's' for string, 'n' for number, 'b' for bitwise, 'v' for 'vector', and so on? $a s| $b;# stringwise $a b| $b;# bitwise $a n| $b;# numberwise @a v| @b;# vector @a vsn| @b; # vector stringwise bitwise I see these as being similar to regex flags. In a regex we don't have two separate metacharacters for matching \w case sensitively or insensitively. Instead we use the 'i' flag outside the regex or within the regex, scoping the parts of the pattern to which it applies: m/foo/i m/(?i:foo)/ m:i/foo/ I think we should adopt the same strategy for regular operators. Rather than create umpteen new operators to perform every operation in every different style, we should keep the operation orthogonal to the context in which the operator is applied. So instead of having a vector addition operator, we have an addition operator and a vector flag which can be applied to it. I mean, compare: @a ~ grep {...} ~ map {...} ~ sort ~ @a; with: @a | grep {...} | map {...} | sort | @a; I don't know about *your* font, but in mine the ~ and ~ versions are at least twice as readable as the | and | ones. In my font, or perhaps more importantly, to my eye, the | and | are more readable. But regardless, I think it's more important to make the operators consistent with each other, than to make them look pretty or easy to read. The latter is important, of course, but I personally believe that it's no use making something easy to read if the meaning is still hard to comprehend. Better to make something harder to read but easier to understand. A
Re: L2R/R2L syntax (was Re: Everything is an object.)
Damian Conway wrote: [...] ~ and ~ Michael Lazzaro wrote: I too think this idea is fabulous. You are my hero. I also think this is semantically fabulous but syntactically slightly dubious. '~' reads 'match' in my book, so I'm reading the operators as 'match left' and 'match right'. Or perhaps even 'stringify left' and 'stringify right' with a different reading of '~'. I would prefer something like | and | which has a more obvious connotation (to me at least) of pipe left or pipe right. Damian is my hero regardless. :-) A
Re: PRE / POST in loops
Luke Palmer wrote: The difference between POST and NEXT is simply that POST fails to refrain from executing after the final iteration, while NEXT does not. Or in other words: The difference between POST and NEXT is that POST executes after the final iteration, while NEXT does not. NEXT happens before the next item, POST happens after each item. I hope this clarified things. It has failed to refrain from unenlightening me. :-) A
Re: Register scanning
Steve Fink wrote: (UNPIN would probably be better than RELEASE, huh?) Maybe ATTACH / DETACH or AQUIRE / RELEASE? A
Re: Everything is an object.
Simon Cozens wrote: Once again we're getting steadily closer to inventing Ruby. Agreed, but I don't think this is necessarily a Bad Thing. Larry said ~~ People have been borrowing ideas from Perl for a long time, now it's time to borrow some back. I like Ruby, I like dot ops, and I like being able to chain them together from left to right. I would really like it if these were some of the ideas that we borrow back from Ruby (and other places). As it happens, I've already borrowed them for the Template Toolkit. Of course, TT doesn't count as a Real Programming Language, but it does support the same syntax for accessing data and it's very useful. myhash.keys.sort.join(', ') # valid in both Ruby and TT Of course, this is semantically no different to the Perl 5 equivalent: join(', ', sort keys %$myhash) but I find it easier to read as it progresses more naturally, to me at least, from left to right. Take myhash, get the keys, sort them, then join them together. This is essentially a pipeline style of processing: a -- b -- c whereas the usual right to left is technically a nested form: a ( b ( c ) ) which effectively reverses the order of evaluation of the pipeline: c -- b -- a I think both are equally valid and should be supported, if possible. Sometimes it makes sense to think about a problem from start to finish (input driven or push). Other times it's better to think about the desired goal and work backwards towards the beginning (output driven or pull). In one situation you might think I want to take myhash, extract the keys, sort them and then join them together to make a string and write C$myhash.keys.sort.join(', '). In another you'll think I need a string containing the sorted keys of myhash and instead write Cjoin(', ', sort keys %$myhash). It seems to me that L.R syntax falls out naturally in Perl 6 from the dotop. Hash objects will have 'keys' methods, Array objects will have 'sort' and 'join' methods and everything should just work as expected. $hash.keys.sort.join(', '); The sticky issue is how to pass a block to sort, map, grep, etc. Well, if we can't come up with anything better than explicitly passing a block as an argument, e.g. $hash.keys.sort({ ... }).join(', '); then I still think this is better than nothing at all. If you end up writing pathological cases where you're passing lots of blocks as arguments, then perhaps it would be better written in a regular Perl 5 right to left (nested), or even a mixed style. join( ', ', sort { ... } $hash.keys ); If we can come up with something that makes this syntactic pill a little easier to swallow, then that's great. But even if we can't, I don't think it's the end of the world, or even the world.end :-) A
Re: right-to-left pipelines
Michael Lazzaro asked: foo $a, $b, $c, $d; # how many args? Damian Conway wrote: Yep. Can't be known unless predeclared and hence compile-time discernible. And methods can't be discerned in the presence of run-time dispatch. Is that not the purpose of an interface? That is, to specify at compile time that a given object conforms to a particular set of method signatures? The method is still resolved for dispatch at runtime, depending on the object type, multimethod arguments, etc. At compile time we don't know which method will be called, but, thanks to the interface, we do know what argument(s) it will be expecting. A
Re: Unifying invocant and topic naming syntax
Me wrote: Well, I could argue that c) already exists in the form of passing parameters in parens. This reminds me of the Law of Demeter. It specifies what your methods should and shouldn't be able to do if you want to build a bright, shiny system that never has bugs, maintains itself, turns water into wine, etc. The essence is about limiting what you can access (and therefore screw up) from a particular scope. It's like a mild form of the no side effects policy of certain functional programming languages. I'm not sure how applicable it's going to be to Perl 6, but here's the view from 30,000 feet. Object Form of Law of Demeter - Do not talk to strangers. Within a method, messages can only be sent to the following objects: 1. A parameter of the method, including the enclosing object (this or self); 1.1. For pragmatic reasons: a global object; 2. An immediate part object (computed or stored): 2.1 An object that a method called on the enclosing object returns, including attributes of the enclosing object; 2.2 An element of a collection which is an attribute of the enclosing object; 3. An object created within the method. Usenet Form of Law of Demeter - * You can play with yourself. * You can play with your own toys (but you can't take them apart), * You can play with toys that were given to you. * You can play with toys you've made yourself. Interested parties should Google[ law of demeter ] for the full story. A
Re: Unifying invocant and topic naming syntax
Larry Wall wrote: So I was thinking it'd be better to use something different to represent the outer topic... How about this: $_ # current topic $__ # outer topic $___ # outer outer topic ...etc... I also wondered if $= might be a suitable alias to the current iterator. It has a nice mnemonic, looking as it does like a '_' stacked on top of another. while $something { if ($=.first) { # first iteration } elsif ($=.last) { # last iteration } } You could then use $==, $===, etc., to access outer iterators: while $foo { while $bar { if ($==.first) { # first foo } if ($=.first) { # first bar } } } A
String concatentation operator
Quoted from Seven Deadly Sins of Introductory Programming Language Design [1] by Linda McIver and Damian Conway: We have shown over one thousand novice programming students the C/C++ expression: the quick brown fox + jumps over the lazy dog and asked them what they believe the effect of the + sign is. Not one of them has ever suggested that the + sign is illegally attempting to add the address of the locations of the first two characters of the two literal strings. Without exception they believed that the + should concatenate the two strings. Makes perfect sense to me. Can we overload + in Perl 6 to work as both numeric addition and string concatenation, depending on the type of the operand on the left? I realise the answer is probably not, given the number/string ambiguity of Perl variables: my $a = 123; my $b = 456; $a + $b; # 579 or 123456? I quite like '_' as the string concatenation operator (so much so that I added it to the Template Toolkit some time ago, confidently telling people that it's what Perl 6 would use :-). It ties in nicely with the 123_456 numerical style. On the other hand, I'm not a big fan of using '~' to indicate string context. The tilde (aka wobbly operator) seems much better suited to smart matching, IMHO, being reminiscent of the almost equal to operator (which I would attempt to include here if I had the slightest clue how to make my keyboard speak Unicode). Another option: could we quote operators to indicate string context? $a + $b This would tie in nicely with using [ ] to indicate vectorised operators, although I realise that particular syntax has been disvogued of late. a [+] b A [1] http://www.csse.monash.edu.au/~damian/papers/ [2] [2] Good paper, well worth a read. That Conway chap seems to know his cookies. His name rings a bell, too...
Re: perl6-lang Project Management
Michael Lazzaro wrote: [...some good points...] and has resulted in us revisiting decisions *repeatedly* Simon Cozens wrote: [...some good ideas...] [1] You can tell I've been rereading MMM... Maybe there's some benefit to be had from revisiting old material? :-) I can't think of any non-trivial piece of software I've written without going over the design several times... just like I can't think of any great book that I've fully appreciated without reading through it several times. Sometimes the Perl 6 design process looks like a machine that's running fast but moving forward slowly, churning over the same ground. But in this case, the purpose of our vehicle is to plough the ground. We're more concerned about tilling the soil than getting to the other side of the field as quickly as possible. From that perspective, it looks to me at least, like we're making much better progress. Well, we meaning you. I'm no use to anyone - my head exploded days ago in a big mess of Unicode operators. *[BOOM]*8-| Keep up the good work. A
Re: Interfaces
Nicholas Clark wrote: I think that the first syntax class Car::Q is Car renames(eject = ejector_seat) is CD_Player renames(drive = cd_drive); makes it more clear that I'd like to pick and choose which methods the composite object gets from which parent. But now you've turned composition back into inheritance, and I think it's important to be able to distinguish between the two. The car is definately not a CD player, it just has one. I think we need a more flexible syntax for specifying how interfaces should be constructed in the case of composed objects, rather than turning composition into inheritance to avoid the problem. A
Re: Delegation syntax? (was: Re: Private contracts)
John Williams wrote: Reaction #2: Inheritance would automatically delegate all those methods, so again, in what way does inheritance _not_ solve the problem? Many real life systems are composed from elements, not inherited from elements. A car is not a wheel, but is composed from 4 (or more). As a simple example, a wheel might implement an inflate() method, but it probably wouldn't make much sense for the car to inherit that method. Rather, you would define inflate_tyres() which delegates to the inflate() method on the tyres on each of the the 4 wheels. Further still, the airbag might also have an inflate() method. If you're not careful and don't inherit all your objects in exactly the right order then you might find your tyres inflating instead of your airbag when you hit a truck. False inheritance leads to method madness. In what way is an interface different from a pure abstract class (i.e. containing only method declarations, but no code)? Inheritance and interfaces are two different things. The end result would be pretty much the same in this example, but reaching it by different routes. With inheritance, your derived object inherits all the methods that you don't explicity re-define. With interfaces, you are stating that your object will implement all the methods, either directly or by inheriting from, or delegating to other classes. Thus, inheritance, delegation and interfaces are separate, orthogonal concepts. Inheritance : is Delegation : has Interface : can A
Re: Subject-Oriented Programming
On Mon, Sep 30, 2002 at 11:22:02PM -0400, Michael G Schwern wrote: Last year at JAOO I stumbled on this thing called Subject-Oriented Programming which looked interesting. There are a bunch of advanced programming techniques like this that all fit under the same umbrella: * Subject Oriented Programming (IBM) * Aspect Oriented Programming (Xerox Parc) * Composition Filters * Adaptive Programming - Demeter Method and Propagation Patterns They're all attempting to achieve the same goal - a clear separation of concerns - and although the details are different, the overlying principal is the same. They are all metaprogramming layers which allow you to put wrappers around your code, and in particular your objects. These wrappers intercept method calls and can modify them, redirect them, and otherwise jiggle around with them in all sorts of interesting ways. For example, AOP identifies cross-cutting aspects (like error handling, logging, etc) which cut across an entire system. It's considered bad form to implement logging is each of the 20 object classes you're using because you've lost the separation of concerns. If you want to change the way logging is handled, you have to go and change 20 classes. You can use inheritance or delegation to acheive a clear separation of concerns, but these have their own problems. The inheritance route tends to lead to large and cumbersome object hierarchies that are fragile to change and beset with the problems of multiple inheritance. Delegation is sometimes better, but tends to lead to highly fragmented programs where it is difficult to see the wood for the trees. AOP tackles this problem by allowing you to define different aspects of your program (e.g. database access, user interface, error handling, logging, etc.) and then weave them together by defining join points and leaving the pre-processor to join up the dots. Template processing systems are a simple example of AOP. If you write a CGI script with Perl code and HTML fragments interleaved then you make it hard to read, update and understand. Better is to define your Perl code in one place (the implementation aspect, or model in another parlance) and your HTML markup in another (the presentation aspect, or view) and then leave it to your favourite template processor to weave the two together. The approach of SOP is to define an object-like entity, the subject which is a wrapper around one or more objects. This acts like a facade around the inner objects, allowing method calls to the subject to be directed to the appropriate inner object, possibly with various forms of manipulation taking place en route. For example, you might have an employee object defined by your accounts department which includes payroll number, employee information, salary, etc. You might want to reuse this object in another application but without exposing salary details for employees. By defining a subject to enclose the object, you can effectively hide these fields. You can also create composite subjects where an employee has a dozen fields, methods, etc., which are implemented by 3 different underlying object classes. Or you might want to implement some kind of security layer in your subject so that only certain privileged people have access to sensitive information. You do all these things in the subject wrapper and don't need to change your underlying objects. Composition Filters are very similar but substitute subject for filter. You compose collections of object and define how the method calls to them should be filtered. Adaptive Programming is slighty different in that it defines a methodology for modelling a problem domain, and provides tools for generating code (C++) to implement it. The Demeter Method is a best-practice approach for designing your underlying objects so that they fit nicely together. Propagation patterns are used to say, in effect, the shoulder bone is connected to the arm bone, you turn the handle and out comes your code, with everything connected together and working in harmony as it should be. This is a form of Generative Programming, which is the general term for any process whereby you define a high-level model of a program and have generators actually write the program for you (or more commonly, just the wiring code between existing objects). This is slightly different from the usual metaprogramming approach of AOP and SOP which make extensive use of C++ templates to pre-process your program code. As for Perl implementations... hmmm. The key step is to identify/implement a mechanism whereby we can put hooks into object vtables, allowing user code to intercept methods called against objects. Ruby has an AOP module (AspectR ISTR) which does this, making it trivially easy to intercept calls to a particular object method and perform some action on the way. For things like debug tracing, logging, security layers, etc., this is invaluable. With such a
Perl 6 types: ref() vs isa() (was: Just reading up on Pike...)
[EMAIL PROTECTED] wrote: [...] whose type is simultaneously Cstr and Cint. Has any thought yet gone into the builtin Perl types and what they will be called in Perl 6? Will there be a difference between the Cref() of something and the type(s) that Cisa() returns? In keeping with the lower case Cstr and Cint examples above, will the builtin Perl types ARRAY, HASH, SCALAR, etc., have lower case equivalents? Is this an opportunity to replace the ill-named CARRAY with CLIST, or rather Clist? (I'm sure I've heard Larry say that, with hindsight, he wishes he had spelled 'ARRAY' as 'LIST', so I hope I'm not speaking out of line). Could we also come up with a snappier name than CSCALAR to denote a single item reference? Perhaps Citem, or just plain Cref? Presumably, Cref() would continue to work as it always has, while Cisa() returns the most specific type for a variable when called in scalar context, or a list of the type and all supertypes when called in list context. var ref isa - \@foo ARRAYlist / ref \%bar HASH hash / ref \$baz SCALAR item / ref my Dog $spotDog Dog / Animal / obj / ref blah blah -str 3.14-num 42 -int / num The only RFC I can find that's related is 224, where Damian talks about making ref() more magical. http://dev.perl.org/rfc/224.pod Any other thoughts on this floating around out there? A
The Past, Present and Future of Continuations (was: Perl 6 Summary)
A short time ago, in a nearby thread, Larry Wall wrote: Perhaps we should just explain continuations in terms of time travel. Funny. I wrote a message to this effect the other night, but decided not to send it (too tired to decide if I was talking sense or nonsense). I was about to propose that 'continuation' is too long a word for lazy Perl folk to bandy around at will, and possibly too ivory tower for most people to grok. Another way of looking at it is that a continuation is a hypothesis about the future, and calling the continuation is a way of saying oops about that hypothesis. My suggestion was along the lines of using .past, .now and .future to reference the calling, current and future continuations, respectively. I also wondered if .here and .there would somehow fit in to reference the current context, or remote context of a continuation. I was thinking along the lines of a continuation being a here and now, a collection of space and time (or in the context of a continuation, the shape and state of the program) bundled up to be transported safely over there to a future now where it can be unpackaged and used much like a wormhole. Maybe a continuation is like a nipple pierced in the fabric of space and time through which many different threads can be strung? Or like a Quantum Entanglement - a Bose-Einstein Condensate spread along the length of an camel's hair, merrily transporting perlons back and forth? But I must admit that my understanding of continuations (and the fabric of reality) is incomplete, and quite possibly flawed, being limited to what I've read on this list and read (but mostly not understood) in Appel's book. I'm sure I don't yet understand how it all fits together, and I certainly can't see how to make the syntax fall into place. That's a job for a linguist and a mad scientist. :-) Basically, we need to find the right oversimplification to make people think they understand it. Absolutely. But talking about time travel, particuarly in the future, half-past-imperfect, stepping-sideways-through-time tense will never having to had been a simple matter for us to hoov comprehended. [*] Now I know I'm talking nonsense, so I'll stop right here and now. :-) A [*] said with a tip of the hat to the fond memory of Douglas Adams
Ruby iterators and blocks (was: Perl 6 Summary)
On Tue, Jul 02, 2002 at 03:20:35PM -0500, Dan Sugalski wrote: I'm pretty sure the iterators they build are just closures with named arguments, and behave as any other closure would behave. Not quite. Ruby iterators expect a block. This is very much like a closure except that block parameters are local to the scope in which the block is defined, not lexically scoped within the block. Or in other words, any existing variable of the same name as a block parameter will be updated when the block is called. An example: n = 10 def twice yield 1 yield 2 end twice { |n| puts Hello World #{n} } puts n is now #{n} The result of this is: Hello World 1 Hello World 2 n is now 2 I personally believe this approach is flawed, especially considering the fact that there is no way (that I know of) to force block parameters to be truly lexically scoped or temporary (i.e. 'my' or 'local' in Perlspeak). Much too easy to mangle existing variables like this. A
Re: Apoc 5 questions/comments
On Sat, Jun 08, 2002 at 06:51:19AM +1000, Damian Conway wrote: I have no doubt that, once Perl 6 is available, we'll see a rash of modules released in the Grammar:: namespace. Including Grammar::HTML and Grammar::XML. I have no doubt that, once Perl 6 is available, we'll see a rash of modules released in the Grammar:: namespace. Including Grammar::Romana, Grammar::Klingon, Grammar::Buffy, Grammer::Mispelt, and others... :-) A
Cellular Automata in Parrot
I've written a small parrot program which implements a simple deterministic cellular automata of the kind described in Stephen Wolfram's new book, A New Kind of Science. Code is attached. You can also find it along with examples of output at http://andywardley.com/parrot/automata.html A # # # automata.pasm # # Parrot assembly program to implement a cellular automata of the form # described in Stephen Wolfram's book A New Kind of Science, Wolfram # Media Inc., 2002, ISBN 1-57955-008-8, http:://www.wolframscience.com/ # # Written by Andy Wardley [EMAIL PROTECTED] # # This is free software; you can redistribute it and/or modify it under # the same terms as Perl and/or Parrot. # # # -- configurable options -- # I0 specifies the automata rule as an integer from 0 to 255. # Some interesting rules are: 45, 57, 75, 86, 105, 109, 110, # 129, 131, 150, 154, 182, 225 set I0, 154 # I1 specifies the line width (x) # I2 the number of iterations (y) set I1, 78 set I2, 35 # for wide-terminal users set I1, 150 set I2, 60 # I3 defines the seed cell position which is, by default, the # middle of the row (I1 / 2). You might prefer to set it # manually, e.g. to 77 (the last cell, or I1 - 1) for rules # like 110 that only expand to the left div I3, I1, 2 # -- end of configurable options -- bsr init loop: bsr display bsr iterate dec I2 if I2, loop end # # init # # Initialise P0 to be hold cells, P1 to define evolution rules. # init: # define new array of line width new P0, .Array set P0, I1 # iterate over array to initialise set I10, 0 initloop: # at seed point? eq I10, I3, initon initoff: set P0, I10, 0 branch initnext initon: set P0, I10, 1 initnext: inc I10 ne I10, I1, initloop # For the 3 parent cells that we examine, there are 8 possible # states: 000, 001, 010, 011, 100, 101, 110, 111. Each bit of # the automata code number set in I0 indicates the state of the # next-generation cell for each of those states. We extract # these into the array P1 new P1, .Array set P1, 8 set I10, 0 # loop iterator set I11, 1 # bitmap maploop: and I12, I0, I11 set P1, I10, I12 inc I10 mul I11, I11, 2 lt I10, 8, maploop ret # # iterate # # Perform an iteration of the cellular automata # iterate: set I10, 0# index of previous item set I11, 1# index of current item set I12, 2# index of next item set I20, P0, 1# left parent, dup cell 1 first time round set I21, P0, 1# above parent iterloop: set I22, P0, I12 # right parent # duplicate penultimate cell for last cell set I13, I12 inc I13 ne I13, I1, iteron set I13, I12 dec I13 set I22, P0, I13 iteron: # calculate function lookup number from parents # is there an easier way to do this? set I13, 0 bit1: unless I22, bit2 set I13, 1 bit2: unless I21, bit3 add I13, I13, 2 bit3: unless I20, bitend add I13, I13, 4 bitend: set I14, P1, I13 if I14, iterblack branch, iterwhite iterblack: set I14, 1 branch itermain iterwhite: set I14, 0 itermain: set I20, I21 set I21, I22 set P0, I11, I14 set I10, I11 inc I11 inc I12 lt I12, I1, iterloop ret # # display # # Display the current state of the cellular automata. # display: set I10, 0 disploop: set I11, P0, I10 if I11, dispon dispoff: print branch dispnext dispon: print + dispnext: inc I10 ne I10, I1, disploop print \n ret
Re: Loop controls
On Fri, Apr 26, 2002 at 08:49:23AM +1000, Damian Conway wrote: for $results.get_next() { FIRST { print Results:BR; } NEXT { print HR; } LAST { print Done.; } print $_; } How about something like this: for $results.each() { print Results:BR if $results.first; print $_; print $results.last ? Done. : HR; } or perhaps foreach $item ($results.each) { print Results:BR if $item.first; print $_; print $item.last ? Done. : HR; } Calling each() on a list (or a hash?) should somehow transmogrigfy it, or provide an attribute interface around it, which makes it look more like a classic iterator. The psuedo-iterator can implement methods like first(), last(), index(), count(), size(), max() and so on for providing information about, and control over loops. This is an approach I've used to great effect in the Template Toolkit. In this case, the iterator controlling a 'FOREACH' loop is aliased to the 'loop' variable [% FOREACH x = y %] [% table\n IF loop.first %] tr td[% loop.count %]/td td[% x.key %]/td td[% x.val %]/td /tr [% /table\n IF loop.last %] [% END %] Builtin support for iterators can make difficult things easy. Ruby's implementation is worth a look for inspiration (as indeed is most of the Ruby language :-) A
Re: Unary dot
On Mon, Apr 15, 2002 at 07:24:13PM -0700, Larry Wall wrote: So the main reason that objects can function as hashes is so that the user can poke an object into an interface expecting a hash and have it make sense, to the extent that the object is willing to be viewed like that. AKA the uniform access principle. This was something that I was very keen to exploit in the Template Toolkit where foo.bar is interpreted as Do(t) The Right Thing to access the 'bar' part of 'foo', be it the 'bar' key in the 'foo' hash or the 'bar' method of the 'foo' object. The result is, of course, that you can use a hash of static data one day (great for mocking up web pages for example) and later upgrade it to an object which fetches/generates data on demand (e.g. from a database) when you put your pages into production. Alas, I also designed a flaw into the system by introducing virtual methods that TT automatically applies onto various data types, equivalent to various Perl functions, e.g. somehash.keys or somelist.size. As convenient as this is, the problem lies in the fact that you can't differentiate somehash.keys between the Perl equivalents of Ckeys %$hash or C$hash-{keys}. So my thought for version 3 of TT is to introduce somehash.{keys} as a syntax to mean only the 'keys' key/method of the 'foo' hash/object but *NOT* the 'keys' virtual method and to leave somehash.keys resolving to the virtual method as it currently does. Am I right in thinking that this would then be (roughly) consistent with the Perl 6 syntax? e.g. TT3 Perl 6 Perl 5 (hash) Perl 5 (obj) foo.keys $foo.keys keys %$foo $foo-keys() foo.{keys} $foo.{keys} $foo-{keys} $foo-keys() Hang on, now I'm a little confused - I thought that hashes were supposed to keep their % sigil. So shouldn't that be %foo.keys or %foo.{keys}? But then that would then violate the uniform access principle because hash/key access has a different syntax from object/method? Have I missed a vital clue? A
Re: [PATCH] Assembler Strings
On Tue, Apr 16, 2002 at 02:57:42PM -0400, Dan Sugalski wrote: b) 'a\b' was printing being stored as a\b and not ab The patch for the first looks good, but I'm not sure about the second. Have we settled on the behavior of single-quoted strings? Don't know about settled but I suggest that the previous behaviour was the correct one. The only characters that should be escaped in a single quoted strings are C' and C\. Anything else is literal. e.g. 'foo\'bar\\ping\pong' = foo'bar\ping\pong ^^ ^ yep yep nope A
[OT] Parrot Logo
I came across a nice picture of a parrot in New Scientist while riding the train home one night and it inspired me to sketch up a quick parrot logo. By chance, a new version of Photoshop landed on my desk the very next day, giving me the perfect opportunity to dust off the graphics tablet. Here's the result: http://andywardley.com/parrot/ Feel free to use it or abuse it (no cruelty to animals, please :-), if only as a stop-gap until something better comes along. A
Re: Apocalypse 4 : The Strange Case of the STRANGE CASE
On Wed, Jan 23, 2002 at 08:30:41AM -0800, Larry Wall wrote: : INIT, DESTROY, AUTOLOAD, etc., all make sense to me. They really are : special blocks that normally only occur once in a file. But CATCH and : NEXT are part of normal syntax. I don't think they're any more unusual : in their flow control than try, while, loop or foreach. Yes, they are unusual. They're more like come froms than gotos. They need to stop people cold from trying to read them as inline code. People are naturally uncomfortable when they get shouted at, and that's as it should be. A little bit of shouting is OK, but it's easy to switch off when you get shouted at all the time. These constructs are likely to be used right throughout a typical Perl program and I don't want to be made to feel uncomfortable *all* the time when I'm trying to concentrate on what the program does. It is distasteful that a policeman should have to turn on his lights and siren when he wants to get your attention, but the practice is a useful bit of society nonetheless. But if he kept doing it all day, every day, it would be police harrassment. :-) A
Re: RFC 118 (v1) lvalue subs: parameters, explicit assignment, and wantarray() changes
On Aug 16, 8:21pm, Perl6 RFC Librarian wrote: # this is perl6 sub foo :lvalue ($new) { $variable = $new; } A nice idea, but one of the reasons for the original proposal was to make $foo-bar = $x; behave the same as: $foo-bar($x); Your proposal provides a neat solution for lvalues, but at the cost of the original aim (or my aim, at least). If you wanted to accept either of the above then your code would end up looking something like this: sub foo($argnew) : lvalue($rvalnew) { $variable = want('lvalue') ? $rvalnew : $argnew; } I think that's likely to make things more complicated in the long run. I'm inclined to say that assignments of the form: $foo-bar(@baz) = @boz; Are allowed, but just plain stupid. It's the same as: $foo-bar(@baz, @boz) and you're right, Perl can't tell the lvalues and rvalues apart. So don't do that. If we can fix Perl so that it can tell the above apart, then good, but I think it's a separate problem to the lvalue subs. A -- Andy Wardley [EMAIL PROTECTED] Signature regenerating. Please remain seated. [EMAIL PROTECTED] For a good time: http://www.kfs.org/~abw/
Re: RFC 109 (v1) Less line noise - let's get rid of @%
I thought very carefully about this before writing the Highlander Variables RFC, and came to the conclusion that it's a bad idea. I've read your proposal, but I'm afraid I still think it's a bad idea. Those funny characters tell the programmer what's going on, and they tell the compiler what the programmer thinks is going on. I'm all in favour of cleaning up some of the syntax and removing some of the ambiguity (hence RFC 9) but I've long since learnt that the funny characters are a strength of Perl, and the concept is sound even if the implementation is a little shaky in places. A -- Andy Wardley [EMAIL PROTECTED] Signature regenerating. Please remain seated. [EMAIL PROTECTED] For a good time: http://www.kfs.org/~abw/