Re: Multimethod dispatch?
On Sun, Jun 01, 2003 at 10:44:02PM -0600, Luke Palmer wrote: You must not be following Perl 6 closely enough, then. Perl 6 is a real programming language now, as opposed to a scripting language. Um, I've followed Perl6 closely enough to know that the distinction between real langauge and scripting language is meaningless and artificial when you're talking about Perl. Perl is quite simply a 'programming language', and it has been for years. It will still have a lot of power in text processing, and still be a powerful quicky language, but that's no longer its primary focus -- not to say that highly structured programming is. Some applications want strong typing, some don't. That's why typing is optional (which is still driving me nuts as to how that's going to work). You seem to have Perl5 confused with bash, sed or awk. The main principles behind Perl are: 0: Get the job done (before the boss fires you) 1: TMTOWTDI 2: Use what works for you (i.e., Perl has no ideological bias) I don't see what typing has to do with any of that. And I don't see why optional typing or moving towards 'highly structured programming' is the solution to fixing all of Perl5's warts. Well, type signatures are the only relevant information we have, so that's what we'll use. See below. They're *not* the only relevant information that *we* have. They're the only relevant information that a Java/C++ compiler has at compile time. We can do better, since we're dispatching at runtime. Perl will easily be (is) powerful enough for someone to write a dispatcher class. Whether that will be easy to do doesn't matter, because some Damian will write a module to make it easy. That's not my concern. My concern is that there's a huge body of ideas and literature out there that's worth stealing and putting into Perl6. MMD is one of those ideas. However, the foundations of MMD are solving problems in the context of limitations that do not necessarily exist in Perl6. Furthermore, concepts that are roughly similar to MMD are *harder* to convey the because classic MMD is baked in and taking up so much mindshare when it comes to dispatching. What the A6 MMD's accomplish are the common case. There's one most common kind of dispatch that it implements. But Perl's not going to stop you from redefining the multi declarator, registering the routines, and using your own dispatcher. Perl 5 sure didn't :-) That's a cop-out. Of course I can write my own dispatcher or warp the syntax to make my pet idiom work. If the solution to every hard or unforseen problem is warp the syntax, then Perl6 is doomed to failure[*]. Don't forget that Perl has many masters, and if the work-a-day Perl5 programmer is left in the dust, then Perl6 will not have fufilled its mission. The whole point behind Perl6 is to remove the warts and make easy things easier. To me, this is a wart: my %dispatch = ( param1 = sub {...}, param2 = sub {...}, ); sub foo { my $param = shift; if (my $sub = $dispatch{$param}) { $sub-(@_); } else { warn No such parameter: $param\n; } } It's structurally similar to MMD, yet it is unsupported by MMD. And a very easy technique for cleaning up Perl programs. Z. *: JBoss 4.0 is coming out, and if the pre-press reports are even remotely correct, it was implemented using a high degree of AOP. The JBoss team didn't need to warp Java syntax to accomplish it; instead, they rewrote the class loader to support :before and :after subs dynamically appearing and disappearing. I predict that this kind of extension, along with macros, are going to be *MUCH* more useful than hacking the grammar. The 'warping the syntax' escape hatch should only be used for hacking in things like v-strings or lexical filehandles, *not* every pet extension hook that someone could possibly want to see in the language.
Re: Multimethod dispatch?
Adam Turoff writes: On Sun, Jun 01, 2003 at 10:44:02PM -0600, Luke Palmer wrote: It will still have a lot of power in text processing, and still be a powerful quicky language, but that's no longer its primary focus -- not to say that highly structured programming is. Some applications want strong typing, some don't. That's why typing is optional (which is still driving me nuts as to how that's going to work). You seem to have Perl5 confused with bash, sed or awk. The main principles behind Perl are: 0: Get the job done (before the boss fires you) 1: TMTOWTDI 2: Use what works for you (i.e., Perl has no ideological bias) Those are the general principles, yes, and the ones that make Perl so enjoyable to use. But if you take a closer look, say at the builtins and the features of Perl, you'll see that it's quite clearly a text processing language. And that's fine -- it doesn't keep you from doing non-text related stuff; it seems to find a way to make anything text-related. It's easy to get all those other non-text related things done with CPAN. That's when text becomes less important, because there are extensions written for everything. I don't see what typing has to do with any of that. And I don't see why optional typing or moving towards 'highly structured programming' is the solution to fixing all of Perl5's warts. I don't think it's trying to fix all of Perl5's warts. And I don't see what typing doesn't have to do with any of that. TMTOWTDI. There are people who don't consider typing a programmer's aid at all, and think that it's just there to help the compiler generate code without working as hard. On the other hand, some people consider typing a good error-checker and an idiom-enabling mechanism. Again, that's why it's optional. [snip] What the A6 MMD's accomplish are the common case. There's one most common kind of dispatch that it implements. But Perl's not going to stop you from redefining the multi declarator, registering the routines, and using your own dispatcher. Perl 5 sure didn't :-) That's a cop-out. Of course I can write my own dispatcher or warp the syntax to make my pet idiom work. If the solution to every hard or unforseen problem is warp the syntax, then Perl6 is doomed to failure[*]. Don't forget that Perl has many masters, and if the work-a-day Perl5 programmer is left in the dust, then Perl6 will not have fufilled its mission. I didn't say warp the syntax (though that is a useful one :-). The whole point behind Perl6 is to remove the warts and make easy things easier. To me, this is a wart: my %dispatch = ( param1 = sub {...}, param2 = sub {...}, ); sub foo { my $param = shift; if (my $sub = $dispatch{$param}) { $sub-(@_); } else { warn No such parameter: $param\n; } } It's structurally similar to MMD, yet it is unsupported by MMD. And a very easy technique for cleaning up Perl programs. And I don't see what's stopping someone from writing Dispatch::Value. use Dispatch::Value; sub foo($param is value('param1')) {...} sub foo($param is value('param2')) {...} What it seems you're wanting is it to be in the core. And I'm saying that's irrelavent. There are thousands of great ideas out there, and they can't all fit into Perl's core. That's why there's thousands of modules on CPAN. And I'm not saying it won't be in the core, either. It'll probably be in the core module set. Oh, sorry if I've turned this into too much philosophy. I'll happily talk about more concrete things like ways it might be possible to extend the standard dispatcher. Give me some more code to work with -- more hypothetical examples -- and I'll talk about that. Z. *: JBoss 4.0 is coming out, and if the pre-press reports are even remotely correct, it was implemented using a high degree of AOP. The JBoss team didn't need to warp Java syntax to accomplish it; instead, they rewrote the class loader to support :before and :after subs dynamically appearing and disappearing. I predict that this kind of extension, along with macros, are going to be *MUCH* more useful than hacking the grammar. The 'warping the syntax' escape hatch should only be used for hacking in things like v-strings or lexical filehandles, *not* every pet extension hook that someone could possibly want to see in the language. Again, I never said warp the syntax. Luke
Re: Cothreads
Michael Lazzaro [EMAIL PROTECTED] writes: On Monday, May 26, 2003, at 06:10 PM, Dave Whipp wrote: So, in summary, its good to have a clean abstraction for all the HCCCT things. But I think it is a mistake to push them too close. Each of the HCCCT things might be implemented as facades over the underlying othogonal concepts of data management and execution management (hmm, we mustn't forget IO and other resource managers). Yeah, that. What I STRONGLY SUGGEST WE AVOID is a situation where _some_ of those interfaces are object-based, using new Thread: or similar, and others of those are trait or keyword based, such as coro foo or sub foo is coroutine, and others are implicit and invisible (closures).[*] I would be very, very surprised to see a situation where you don't have an object interface to the various things which are more usually made with the various bits of syntactic sugar. A nice, consistent OO API for these things will make the life of macro/refactoring brower/SmalltalkLikeIDE/whatever author so much easier. -- Piers
Re: Multimethod dispatch?
On Mon, Jun 02, 2003 at 10:34:14AM -0600, Luke Palmer wrote: And I don't see what's stopping someone from writing Dispatch::Value. use Dispatch::Value; sub foo($param is value('param1')) {...} sub foo($param is value('param2')) {...} What it seems you're wanting is it to be in the core. Actually, no. I expected that there'd be a way to extend runtime behavior through modules like this hypothetical Dispatch::Value, Dispatch::Multimethods, or Dispatch::Agent::Smith, but I'm seeing precious little evidence of that, just allusions to MMD with the 'multi' keyword and all that. As I said earlier, MMD is starting to give me a big case of The Fear because it's predicated on offering behavior that heretofore hasn't been widely used in Perl, and it's based around limitations that don't necessarily exist in Perl. It's nice that Perl6 will extend its dynamic range, but the whole reason for Perl6 in the first place is to fix some of the warts in the current problem domain. With some recent focus on MMD (mostly thanks to Dan's WTHI post, and my discovery of TAMOP), I started to feel like MMD was good for a certain style of programming, but necessarily ignores a native Perl5 idiom that's equally powerful and perhaps preferable for a large set of problems. I'm not trying to throw out the type system or cast MMD as pure evil. Rather, I'm just poking around to make sure the dispatch machinery isn't wired in for single dispatch/MMD without opening it up for extensions via simple dispatch classes. *That* feature seems much more important to me than wiring in MMD, since MMD could be implemented through Dispatch::Multimethods or something. It's been done before with Class::Multimethods, and I'll buy that there's a benefit to adding a 'multi' keyword to the language, but not if that's the last word for variant dispatching... If some dispatch class can use some syntax vaguely approximating the straw man above, then this is just a tempest in a teapot and I'll move along. But I haven't heard or seen anything concrete that dispatch behavior in Perl6 can be user-defined without resorting to serious magic. Instead, it's starting to sound suspiciously like you can have any dispatching behavior you want, so long as it's either single dispatch (modulo sub/method semantics) or MMD. And that would be a net loss for Perl6. Z.
Re: Multimethod dispatch?
A better fitting solution wouldn't focus on classic MMD, but simply Dispatch, where type- and value-based dispatching are two of many kinds of dispatching supported. I've always liked the sound of Linda's tuple spaces and view that as a nice generalized dispatch approach. Procedure calls are thrown into a tuple space, then other (mop) code grabs one or more tuples and dispatches them. Grep like code is used for the grabbing. -- ralph mellor
Re: interthread signaling
Luke Palmer wrote: I think it would fall trivially out of the events mechanism, which is planned for Parrot. I have heard rumours of such a thing, but no details of how it will be exposed in the language... Dave.
Timely object destruction
Piers Cawley wrote: The Perl 6 Summary for the week ending 20030601 Another Monday, another Perl 6 Summary. Does this man never take a holiday? (Yes, but only to go to Perl conferences this year, how did that happen?) We start with the internals list as usual. More on timely destruction The discussion of how to get timely destruction with Parrot's Garbage Collection system continued. Last week Dan announced that, for languages that make commitments to call destructors as soon as a thing goes out of scope, there would be a set of helpful ops to allow languages to trigger conditional DOD (Dead Object Detection) runs at appropriate times. People weren't desperately keen on the performance hit that this entails (though the performance hit involved with reference counting is pretty substantial...) but we didn't manage to come up with a better solution to the issue. http://xrl.us/iu5 I'd like to reiterate (and clarify) my idea, of a hybrid scheme combining refcounting and DoD. All values needing timely destruction would inherit from a class RefCounted. They should (in the normal scheme of things) be stored in variables with an is refcounted trait (or a trait which inherits or includes that trait, if that's possible). Hopefully, only a *small* number of objects in a system need timely destruction, and (for best performance) all variables which will hold those objects will have the is refcounted trait set on them. (If most or all objects needed timely destruction, then we wouldn't be moving away from perl5's pure-refcount GC, would we?) All operations on a variable or variables having the is refcounted trait result in opcodes to call the refcount(inc|dec) method(s) of the values in those variables. Under normal circumstances, when a refcounted value's refcount goes to zero, it self destructs^W^W cleans itself up. This is quite perl5-esque, and of course slower than simply letting the DoD-GC handle everything, BUT, in the absence of circular reference loops, it does produce timely cleanup of those objects which need it, which pure-DoD wouldn't, and DOESN'T result in numerous, and thus expensive, requests for full DoD runs. For all of the other schemes, full DoD runs would be run on every scope exit, even if there's only one single variable in scope which needs timely destruction. Here's where the non-normal circumstances are described, and how they're handled: It's legal for a refcounted value to end up referenced by a non- refcounted variable. This has to be so, since adding the is refcounted trait everywhere would get cumbersome; also we may sometimes *need*, for one reason or another, to store refcounted values in the same containers which also hold non-refcounted values. Thus, if a refcounted value gets stored in a non-refcounted variable, then that value could quite easily still be reachable when it's refcount goes to zero. Obviously, when this is the case, we need to avoid a premature cleanup. To avoid premature cleanup, any time that the contents of a refcounted variable is assigned to a non-refcounted variable, an opcode to set a reachable by non-refcounted variable flag on the value precedes the assignment. If a refcounted values's refcount goes to zero, and it has this flag set, it does NOT self-destruct[*]. A global counter keeps track of how many values have a refcount of zero and have this flag set. From here, we are in a similar situation as other proposals -- for the timeliest possible destruction, then on every single scope exit, we check if this global counter is nonzero, and if so, do a DoD run. For potentially less timely destruction, we do this check whenever we leave a scope where a refcounted variable was declared, but not when we leave other scopes. Which of these two is done is a choice of the language designer, but might possibly be controlled by a pragma. Note that in the absence of marking any variables with the is refcounted trait, and with the use of the first option here (at every scope exit, check the counter and maybe do DoD), this scheme behaves *identically* with one of the other schemes proposed. It would be *no* slower at run time, since the refcount(inc|dec) methods are only called when doing operations dealing with variables with the is refcounted trait, and if noone uses that trait, there's no extra work. DoD would be a tiny bit slower with my scheme than the other, due to the extra flag checking, but (assuming that *most* code with objects needing timely destruction properly marks it's variables with the necessary is refcounted trait) that's a small price to pay for doing fewer DoD runs. [*] How does this flag get cleared, you might ask? Simplest would be to not clear it at all. This would be mostly harmless in terms of when objects get destructed, but would probably result in more DoD runs than we really need -- blech. [**] A more proper solution would be to clear
Re: Timely object destruction
On Mon, 2 Jun 2003, Benjamin Goldberg wrote: All values needing timely destruction would inherit from a class RefCounted. I like this concept a lot, but maybe we can take it a little further and make it transparent to the programmer. Suppose that the internals only tracked objects that have a DESTROY method (or whatever it will be called in Perl6)? You get the same benefit without the additional brain-overhead of manually indicating that the class needs to be tracked. -Miko Miko O'Sullivan Programmer Analyst Rescue Mission of Roanoke
interthread signaling
Piers Cawley [EMAIL PROTECTED] wrote Threads and Progress Monitors Dave Whipp had some more thread questions, and wondered what would be a good Perl 6ish way of implementing a threaded progress monitor. Whilst the discussion of all this was interesting, I'm not sure that it's really much to do with the language, more something that one would implement according to taste and the particular requirements of a given project. A quick summary of what came out of it: On the basis that perl makes simple things simple, we drilled down on the example of a simple progress monitor. This morphed into the question of how to implement a timeout: sub slow { TIMEOUT(60) { throw TimeoutException } # TIMEOUT(60) { return undef but reason(timeout) } ... # slow stuff, maybe calls out to 3rd-party code return ...; } The implementation of the TIMEOUT macro proposed a Timer object. It was _assumed_ that Perl6 would provide a signaling mechanism to allow such timer objects to be implemented. $SIG{ALRM} probably isn't sufficient -- perhaps timers will actually be parrot-level concepts. Precisely how such a mechanism would work is unresolved. Second, it requires the timeout block to be able to kill off the mainline of execution, but in a way that cleans up nicely and allows execution to resume at the caller of the timed-out block. The more general case is that one thread may wish to inject an exception into another -- again, this assumes some form of inter-thread signaling machanism. Dave.
Re: interthread signaling
Piers Cawley [EMAIL PROTECTED] wrote Threads and Progress Monitors Dave Whipp had some more thread questions, and wondered what would be a good Perl 6ish way of implementing a threaded progress monitor. Whilst the discussion of all this was interesting, I'm not sure that it's really much to do with the language, more something that one would implement according to taste and the particular requirements of a given project. A quick summary of what came out of it: On the basis that perl makes simple things simple, we drilled down on the example of a simple progress monitor. This morphed into the question of how to implement a timeout: sub slow { TIMEOUT(60) { throw TimeoutException } # TIMEOUT(60) { return undef but reason(timeout) } ... # slow stuff, maybe calls out to 3rd-party code return ...; } The implementation of the TIMEOUT macro proposed a Timer object. It was _assumed_ that Perl6 would provide a signaling mechanism to allow such timer objects to be implemented. $SIG{ALRM} probably isn't sufficient -- perhaps timers will actually be parrot-level concepts. Precisely how such a mechanism would work is unresolved. I think it would fall trivially out of the events mechanism, which is planned for Parrot. Luke Second, it requires the timeout block to be able to kill off the mainline of execution, but in a way that cleans up nicely and allows execution to resume at the caller of the timed-out block. The more general case is that one thread may wish to inject an exception into another -- again, this assumes some form of inter-thread signaling machanism. Dave.
This week's Perl 6 Summary
The Perl 6 Summary for the week ending 20030601 Another Monday, another Perl 6 Summary. Does this man never take a holiday? (Yes, but only to go to Perl conferences this year, how did that happen?) We start with the internals list as usual. More on timely destruction The discussion of how to get timely destruction with Parrot's Garbage Collection system continued. Last week Dan announced that, for languages that make commitments to call destructors as soon as a thing goes out of scope, there would be a set of helpful ops to allow languages to trigger conditional DOD (Dead Object Detection) runs at appropriate times. People weren't desperately keen on the performance hit that this entails (though the performance hit involved with reference counting is pretty substantial...) but we didn't manage to come up with a better solution to the issue. http://xrl.us/iu5 Bryan C. Warnock, patchmonster of the week Bryan C. Warnock seems to be attempting to outdo Leo Tötsch in the patchmonster stakes this week. He put in a miscellany of patches dealing with the Perl based assembler, opcode sizes, debugging flags and probably others. Most of them were applied with alacrity. The Perl 6 Essentials book Dan Sugalski gave a rundown of how the Perl 6 Essentials book came about, what's in it and all that jazz. He started by apologizing for not mentioning it before, but he thought he had. This led Clint Pierce to wonder if there was something up with Dan's Garbage Collection system. The existence of the book probably goes some way to explaining Leo Tötsch's relative silence over the last few weeks. Nicholas Clark wondered if it explains why Parrot doesn't have objects yet. Brent Dax wondered when it would be available (by OSCON this year apparently). http://xrl.us/iu6 IMCC, PASM and constants/macros Clint Pierce had some big headaches with moving his BASIC interpreter over to IMCC owing to problems with .constant which is legal for the assembler, but not for IMCC. Leo Tötsch pointed Clint at IMCC's .const operator. Bryan Warnock wondered if IMCC and the assembler's syntax couldn't be unified. Leo noted that it wasn't quite that straightforward because .constant declares an untyped constant, but .const requires a type as well. It turns out that .const wasn't quite what Clint needed, so Leo pointed him at .sym and .local which do seem to do what he needs. http://xrl.us/iu7 3-arg opens Bryan Warnock wondered if open I3, temp.file, r was valid code. Answer, no, the right way to do it is the Perlish open I3, temp.file, . Jürgen Bömmels promised more and better documentation for the Parrot IO system. Eventually. http://xrl.us/iu8 Smaller PMCs Leo Tötsch's work on the new PMC layout continues apace. I'm afraid I don't quite understand what's going on in this area, which does make it rather tricky to summarize things. It seems to have a good deal to do with memory allocation and garbage collection... Leo thinks that it's the right thing, but there seem to be issues involved with good ways of allocating zeroed memory. http://xrl.us/ijt An experimental Wiki for parrot development Mitchell N Charity has put up an experimental Wiki for Parrot and primed it with a few things. Stéphane Payrard pointed out that it's rather hard to make a WikiWord from, for example, PMC. (10 points to the first person to email [EMAIL PROTECTED] with the expansion of PMC). http://xrl.us/iu9 IMCC packfile bug While toying with pbc2c.pl, Luke Palmer discovered that it doesn't want to play with IMCC generated .pbc files. Apparently this is because we currently have two bytecode file formats. Leo Tötsch thought the problem lay with assemble.pl which is old and slow and doesn't produce 'proper' parrot bytecode. Leo also thought that the way pbc2c.pl worked wasn't actually any use. Dan reckoned the time had come to ditch assemble.pl too, and reckoned there was a case for renaming IMCC as parrot since it can run either .pbc or assembly files. Leo liked the idea, but is concerned about the state of the Tinderbox. http://xrl.us/iva Method Calling Dan tantalized all those waiting eagerly for objects in Parrot by discussing how to make method calls. This, of course, means a few new ops, called findmeth, callmeth and callccmeth for the time being. Jonathan Sillito had a few naming consistency issues with the ops. Dan agreed there were issues and asked for suggestions for an opcode naming convention. http://xrl.us/ivb Simple Constant Propagation in IMCC Matt Fowles posted a patch to add simple constant propagation to IMCC. Essentially this means that, say set I0, 5 set I1, 2 set I2, I1 add I2, I0 would