Path: archiver1.google.com!postnews1.google.com!not-for-mail From: mdmko...@yahoo.com (Michael D. Adams) Newsgroups: perl.perl6.language Subject: Re: Perl 6 and Set Theory Date: 13 Dec 2002 03:08:07 -0800 Organization: http://groups.google.com/ Lines: 154 Message-ID: References: <20021206210300.DE96032A@babylonia.flatirons.org> NNTP-Posting-Host: 129.237.94.182 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Trace: posting.google.com 1039777687 27731 127.0.0.1 (13 Dec 2002 11:08:07 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: 13 Dec 2002 11:08:07 GMT fibon...@babylonia.flatirons.org (Luke Palmer) wrote in message news:<20021206210300.DE96032A@babylonia.flatirons.org>... > For instance, to declare a variable that can represent either an > integer or a string: > > my (Int | Str) $var; > > The type of that variable is the union of the sets of integers and > strings. The value of $var must be a member of at least one of those > sets. This concept I think has great potential. In fact one idea that I have been playing around with for quite some time is similar. Consider: my (Car & Boat) $var; Only something that was both a Car and a Boat could be assigned to $var. For example an amphibious car. Especially useful if you want to have a function that takes as argument something that implements two interfaces. For example in a 3D game, you may have your renderable objects class tree and your physical objects class tree. Then if you want a physical and renderable object as a parameter you have a problem in traditional OOP. You could make a subclass for every combination of parents but that grows exponentially and every class has to inherit from every class the represents every subset of parents it has. Suppose you have the following classes (psudo-C/Java code because I don't know the Perl6 for classes): class A {...} class B {...} class C {...} class D extends A, B {...} class E extends A, B {...} class F extends A, C {...} class G extends A, C {...} class H extends B, C {...} class I extends B, C {...} class J extends A, B, C {...} class K extends A, B, C {...} In order to specify a function that takes a parameter that implements both A and B you could write: sub f($var is (A and B)) {...} Which D, E, J, and K would satisfy. I just finished a project where something like this would have been very useful. In traditional OOP, you would have to make several dummy classes for each combination like so: class A {...} class B {...} class C {...} class AB extends A,B; class AC extends A,C; class BC extends B,C; class ABC extends A,B,C,AB,AC,BC; class D extends AB {...} class E extends AB {...} class F extends AC {...} class G extends AC {...} class H extends BC {...} class I extends BC {...} class J extends ABC {...} class K extends ABC {...} Then declare the function as: sub f($var is AB) {...} This works however it starts to get messy when the hierarchy starts to get large so next we might have: class ABD extends AB,D; class ABK extends AB,K; class ABDK extends ABD,ABK; class Q extends D,K {...} The number of dummy classes grow as 2^n where n is the number of "real" classes you have. That is what you would have to do in a traditional OOP. However in this new syntax no dummy are classes required. It is easy as: sub f($var is (A&B)) {...} sub g($var is (K&D)) {...} This could be extended to other boolean ops. For example to numbers suppose there are the predefined classes Number, Int, Real, Positive, Negative, and Zero. Then the following useful classes can be defined. I'm sure you can think of more ideas. class ArrayIndex extends (Int & (Zero | Positive)); class AnotherArrayIndex entends (Int & ~Negative); class AbsoluteTemperature (Real & ~Negative); class Year extends (Int & (Positive | Negative)) # Year zero doesn't exist One thing this example brings out is that "extends" is a bad keyword because it is more of an implicature. I'm only using it to make clear what I mean. But if we take the keyword "is" to mean implicature then we have symmetry of class and variable declaration. Even named constants and enumerations work within this scheme. my class A; my class B is A; # if I hand you a B that implies that I am handing you an A my $a is A; # if I hand you $a that implies that I am handing you and A my $constVar is 24; # if I hand you $constVar that implies # that I am handing you 24 (i.e. a named constant!) my class C is (1|2|3|4); # An enumeration. I think the syntax needs some work # on this one like ?... is (Ignore=1|On=2|Off=3)? my class D; my class E is (A|D); # A C style union If anyone has any ideas, I would be interested to see what other uses this could be put to use for. Not all combinations seem to be desirable or even possible. For example the following probably should not be allowed: my 17 is A; my $var is (A & ~A); I'm curious. Has anyone seen any other language that does this sort of thing? It would be very interesting as a comparison (and useful to me on some research I'm doing :-) ). > Since a derived object can be used in place of its parent anywhere, it > must represent an improper superset of its parent. This seems > backwards, but if you think about it logically: Every member of the > parent set needs to be a member of the child set; every member of the > child set need not be a member of the parent set. Q.E.D. > > Multiple inheritance represents a superset of multiple sets. I think that my nomenclature for things is slightly different than what you are using. I'm not sure what you mean by "derived object", but when I have referred to derivation/extends/inheritance I have meant the OOP since. The child would have to be the subset of the parent, because the set of objects that are of the child class are a subset of the set of objects that are of the class of the parent. For example the all SportsCar objects are also Car objects, but not all Car objects are SportsCar objects. SportsCar inherits from Car. SportsCar is a subclass of Car. Please let me know if I'm miss understanding something here. Michael D. Adams mdmko...@yahoo.com