Re: derived class generators and introspection
At 5:31 AM +0100 8/31/06, Nigel Hamilton wrote: Rather, the proposal is focusing on what users of these data structures would / could see. The idea is that relational structures have the same ease of use and flexability that things like hashes or arrays or sequences or sets do now. They can of course just be stored in RAM like the aforementioned, when the working set of data is appropriately small, but just as a hash-doing class can have a disk-tied implementation as well, for scalability and/or persistence so can a relation-doing class. And this is one main reason why Relation etc is a role rather than a class, so people can choose how it works. OK. I can see that a tied-relation could help solve the talking to disk problem. But I wonder about some of the other RBMS things on offer - locking, indices etc? Some of these features are there to assist with getting data efficiently to and from the disk. Although they are not artefacts of the relational model they are important parts of what makes a database work. Could your relational model be "tied" to an existing physical database? NIge Yes it could. First of all, note in my explanation that I mentioned indices already, as examples of "non significant" (non value affecting) extra data that an object could hold or be tied to; these can be stored on disk and/or in memory as is appropriate. Next, the Software Transactional Memory concepts / interfaces in Perl 6, such as the concept of atomic code blocks or routines, would be mapped to ACID features of a disk store; the start of an atomic operation is like a "start transaction" and the successful completion of one is a "commit"; a retry or fail involves a "rollback" etc. Note that a proper system will need to (or will ideally) support nested transactions, so any given atomic block won't have to know whether it is inside another one or not to be itself atomic. As for locks, the Perl 6 interface / functionality for managing shared data between multiple threads or processes would map to appropriate locks or other mechanisms on disk where applicable. Truly, a database was never supposed to be a world separate from an application; as I recall, Cobol or something introduced the idea of databases and applications being at arms length, and it stuck, but that isn't the way things should be; how they should be is integrated, or at least to the point that a generic reusable module within an application is integrated; eg, DBM or BDB; also, the concept of servers is orthogonal to this; anything can be relegated to a server. Using the DBM analogy, what I propose is that the relational analogy of an in-memory Hash is built-in to Perl, and any extensions that make it tied to something external like a disk be language extensions / CPAN modules; all Perl 6 iteself has to do is make it easy to attach such extensions, and I think it more or less does so, save edge cases to hash out. -- Darren Duncan
Re: derived class generators and introspection
On Wed, 30 Aug 2006, Nigel Hamilton wrote: > HI Darren, > Generally I really like the idea of fixing the relational/OO > mismatch problem by swallowing the relational model whole. :-) > But I wonder if we are ready to say goodbye to the tyranny of disk > seek? How will your proposed system use the disk? And if it does use the > disk what about pesky problems like: indexing, locking, seek time etc? > The days of limitless RAM are yet to arrive - until then databases > must rely on the disk - what is the plan for storing the data? > NIge While it is true that the broader design I am addressing should do away with any relational/OO impedence mismatch, since a complete relational model would by definition handle data types of arbitrary complexity (unlike many of today's pseudo-RDBMS products), I am certainly not proposing doing away with the disk. Rather, the proposal is focusing on what users of these data structures would / could see. The idea is that relational structures have the same ease of use and flexability that things like hashes or arrays or sequences or sets do now. They can of course just be stored in RAM like the aforementioned, when the working set of data is appropriately small, but just as a hash-doing class can have a disk-tied implementation as well, for scalability and/or persistence so can a relation-doing class. And this is one main reason why Relation etc is a role rather than a class, so people can choose how it works. -- Darren Duncan
Re: Contextual::Return (was Re: could 'given' blocks have a return value?)
Trey Harris asked: This is eerily like Contextual::Return, which made me wonder if it's even required in Perl 6. Obviously we can do return do given want { when :($) { ... } ... }; But "return do given want" flows so badly, I desperately want some sugar for this. Is there some and I missed it? No, the sugariest you'll find at the moment is probably: return want.rw ?? $lvalue :: want.count == 2 ?? (7,11) :: want.item ?? 42 :: want.list ?? 1..10 ::die "Bad context; but that still doesn't have the Awesome Power of C::R. ;-) The simple answer is that C::R is probably the first module I will port to Perl 6 (since it's the module I find myself using the most nowadays). The Perl 6 version will be cleaner and more efficient that the Perl 5 version, since I'll be able to take advantage of macros. Damian
Re: could 'given' blocks have a return value?
Agent Zhang wrote: > > According to S04, given {} is at statement level, so you can't use it > directly as an expression. But Perl 6 always allow you to say > > my $foo = do given {...} > > As well as > > my $foo = do if foo {...} else {...} I confirmed this both work now with pugs! I think the 'do given' case is useful enough to document more officially along with 'given'. If you are thinking about the if/else case, ?? ... !! would be a simpler way to write it. Mark
Re: derived class generators and introspection
HI Darren, Generally I really like the idea of fixing the relational/OO mismatch problem by swallowing the relational model whole. :-) But I wonder if we are ready to say goodbye to the tyranny of disk seek? How will your proposed system use the disk? And if it does use the disk what about pesky problems like: indexing, locking, seek time etc? The days of limitless RAM are yet to arrive - until then databases must rely on the disk - what is the plan for storing the data? NIge In closing for now, I imagine that a lot of this stuff is connected to the meta-model, though doing it well will have clean support in the language syntax as well. Feedback is appreciated.
derived class generators and introspection
All, This email is part of a brain dump from my thoughts over the last week while I was away from a computer. If anything doesn't make sense, I will clarify or expand it in the following days. I believe that Perl 6 already has basically all of the necessary parts built-in for implementing a true relational database, and that any needed remainder can be added and integrated in an elegant fashion, as I will outline and/or ask about. -- At the center of this idea is the thought that the "Tuple" and "Relation" of the relational data are not each single classes, but rather are each roles / abstract interfaces that many classes can be composed of / implement. This is much the same as how I see the existing "Array" and "Hash" of Perl 6, where each is a role, and eg, that "Array of Int" and "Array of Str" are 2 different actual classes (or roles) that .does(Array); in this context, saying "Array of ..." is acting as a class generator which defines a new class that composes the Array role. I say that "Array of Int" and "Array of Str" are 2 different classes because the Perl 6 type system would treat each as being a repository for different sets of possible values, and would reject the assignment of one to the other. And so, a "Tuple" type is essentially defined using an ordinary class (or classless object type) definition that .does(Tuple) but that that it also has certain restrictions. A Tuple value is then simply an object of that class. The routines that the Tuple class provides are essentially just wrappers over certain meta-class and/or class routines, and Tuple does not add any new attributes nor hide any existing class functionality. The attributes of the Tuple and the attributes defined by the class are one and the same. The design restrictions that a Tuple doing class must obey, or appear to obey as far as its users can see, are such as these: 1. All significant attributes which together define the Tuple object's value must be public and/or have accessors with the same names as the attributes (extra implicit attributes that eg index those are not significant in this sense); an introspection method should also exist where one can inquire what the names and types of the significant attributes are; conceptually, a Tuple class is transparent. 2. The Tuple class must have a constructor that takes values for all significant attributes of the new object. Every logically distinct Capture of that constructor must produce a logically distinct new object. 3. A Tuple class needs to provide the interface details necessary that the Perl 6 type system can treat it as a value type. The === operator should return True just for 2 Tuple objects that are of the same class and where all pairs of corresponding significant attributes using === return True. Conjecture: As well, 2 Tuple objects that are of different classes, where at least one is anonymous, should compare like they were of the same class if their significant attribute definition sets are identical; this is so a system where most classes are generated from other classes DWIM correctly, like two distinct "Array of Int" have the same definition. 4. Conjecture: all Tuple classes should be immutable following their construction, either actually or in appearance, but this may not be essential for all uses of it. 5. Each significant Tuple attribute is mutually exclusive from all of the others, in that the interface to an attribute conceptually maps 1:1 to the attribute; reading or changing any of them does not have visible side-effects on any others. This is similar to how array or hash elements are exclusive. Now, a "Relation" type is one step removed; it is simply or in appearances to the user a "Set of " or some-such that also .does(Relation), or perhaps alternately, a "Relation" type could be declared with "Relation of ", which looks more natural. A "Relation" is a "Set" that is restricted to all of its members being of the same single class that is specified in the Relation type definition, and within that constraint, it is useable like any Set, and the Relation role adds several additional routines that wrap meta-class or class methods of the Set, but don't hide any existing features. Presumably any Tuple used in a Relation has to be immutable, since changing a Tuple that is a member of a Relation would have the same issues to contend with as when you change a mutable object that is used as a Hash key. Inherited from Set, a Relation class must have the necessary details that the Perl 6 type system can treat it as a value type, including that === works. It goes without saying that any attribute of a Tuple can be either a class that .does(Tuple) or that .does(Relation), as it can be any other class. Note that many of the methods which the Tuple and Relation roles provide will have the effect of generating new anonymous classes, along
Contextual::Return (was Re: could 'given' blocks have a return value?)
In a message dated Tue, 29 Aug 2006, Mark Stosberg writes: my $rm = sub { given $rm_param { when Code { $rm_param(self) } when Hash { %rm_param } default{ self.query.param($rm_param) } }}(); This is eerily like Contextual::Return, which made me wonder if it's even required in Perl 6. Obviously we can do return do given want { when :($) { ... } ... }; But "return do given want" flows so badly, I desperately want some sugar for this. Is there some and I missed it? Trey
Re: multi subs with identical signatures: should be a warning ?
Since nobody else has answered yet, I'll try to say something. I'll post this also to perl6-language so that those who know better can comment on this. On 8/28/06, Mark Stosberg <[EMAIL PROTECTED]> wrote: First, what's the recommended reference for learning how dispatching to the right 'multi' sub is resolved. ? http://dev.perl.org/perl6/doc/synopsis.html S12 seems most relevant (e.g. the section "Multisubs and Multimethods") S06 might also be relevant I'd like to know the expected behavior in this case: multi sub foo () { say "b: " } multi sub foo () { say "a: " } foo(); I would expect it would throw an error or at least a warning, since there's no clear way to choose a correct sub to dispatch to. IMHO this is either the case where you define same sub twice, which is an error (and so foo() would never get called) according to S06: Redefining a stub subroutine does not produce an error, but redefining an already-defined subroutine does. If you wish to redefine a defined sub, you must explicitly use the "is instead" trait. or, if not that case, then this is defining two multi-subs which have the same "long-name". According to S12 the later multi-sub will then hide the earlier one, and foo() would then allways call the second multi-sub, saying "a: " For subs or methods declared multi, only one instance of the long name can be in any namespace, and it hides any outer (or less-derived) routines with the same long name. Pugs currently dispatches to one anyway, without a warning. If Pugs allways dispatches to the second one, then this might be the right behaviour. A more insidious version of the same case is the following, which I accidentally wrote more than once already...and then wondered why my code wasn't working as expected... multi sub foo (%names?) { say "b: " } multi sub foo (@pos?) { say "a: " } There, I have distinct arguments, but they are both optional, making them the same as the case above. This isn't exactly the same as above. In this case the two multi-subs just might have different "long-names" and so one would not hide the another. I'm not 100% sure about whether these have different "long-name" or not as I don't know how exactly the "long-name" is created. If I'm right that these do have different "long-name" then IMHO the call to foo() would throw an exception because there's a tie between two equally-good candidates for multi-dispatch and S12 says that in such a case an exception is thrown: When you call a routine with a particular short name, if there are multiple visible long names, they are all considered candidates. They are sorted into an order according to how close the run-time types of the arguments match up with the declared types of the parameters of each candidate. The best candidate is called, unless there's a tie, in which case the tied candidates are redispatched using any additional tiebreaker long names (see below). If a tie still results, only candidates marked with the default trait are considered, and the best matching default routine is used. If there are no default routines, or if the available defaults are also tied, a final tie-breaking proto sub is called, if there is one (see above). Otherwise an exception is thrown. -- Markus Laire
Re: Implicit current-index variable, scoped inside for-loops
Damian Conway schreef: > [for @array -> $index, $value {...}] > > No. There's no such magic. I simply screwed up. I should have written: > for @array.kv -> $index, $value {...} > :-( Ah, much clearer now. -- Affijn, Ruud "Gewoon is een tijger."
Re: return Types: what are the enforcement details?
On Tue, Aug 29, 2006 at 19:49:38 -0500, Mark Stosberg wrote: > I'm interested in helping to write some tests for "return types", but > I'd like some clarifications about them first. Are they just > "declarations" that help Perl optimize stuff, or they actually contracts? 'of' is the contractual form, 'returns' is a constraint but it's more like a cast. > demo: > > sub foo of Array { > my %h = ( a => 1 ); > return %h; > } > sub zoo returns Array { > my %h = ( a => 1 ); > return %h; > } > > # Hashes are happily returned, despite the Array return types. > my %b = foo(); say %b.perl; > my %c = foo(); say %c.perl; ^-- z ? Intuitively I would say that both subroutines force the hash into an array, at minimum, and foo might be checked more thoroughly. In the case of foo(), foo itself might not compile, or my %b = foo() might not compile, or both. In the case of zoo(), i think it's just a runtime conversion to an array. There's no reason why this conversion can't happen explicitly as well as implicitly, like with my %h = () = %other_hash. However, conversions that cannot be made could be cought at compile time, emitting a warning on an error depending if the runtime is a warning or an error. -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418 pgpZuk0rgo5oy.pgp Description: PGP signature