Re: derived class generators and introspection

2006-08-30 Thread Darren Duncan

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

2006-08-30 Thread Darren Duncan
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?)

2006-08-30 Thread Damian Conway

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?

2006-08-30 Thread Mark Stosberg
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

2006-08-30 Thread Nigel Hamilton


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

2006-08-30 Thread Darren Duncan

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?)

2006-08-30 Thread Trey Harris

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 ?

2006-08-30 Thread Markus Laire

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

2006-08-30 Thread Dr.Ruud
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?

2006-08-30 Thread Yuval Kogman
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