The Artima Developer Community
Sponsored Link

Weblogs Forum
A-Posteriori Subtyping and Case Classes

23 replies on 2 pages. Most recent reply: Jan 30, 2006 8:14 AM by James Watson

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 23 replies on 2 pages [ 1 2 | » ]
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

A-Posteriori Subtyping and Case Classes (View in Weblogs)
Posted: Jan 26, 2006 6:47 PM
Reply to this message Reply
Summary
In a recent discussion Kresimir Cosic said the following thing to me: "I think that subtyping a-posteriori is great.". When thinking about case classes ala Scala (which I believe was inspired by Haskell), I couldn't help but wonder, why not have case classes a-posteriori?
Advertisement
The following is lifted from http://scala.epfl.ch/intro/caseclasses.html:
Scala supports the notion of case classes. Case classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. Here is an example for a class hierarchy which consists of an abstract super class Term and three concrete case classes Var, Fun, and App.
abstract class Term;
case class Var(name: String) extends Term;
case class Fun(arg: String, body: Term) extends Term;
case class App(f: Term, v: Term) extends Term;
Okay, that is fine, but why not have something like the following :
class Var { ... }
class Fun { ... }
class App { ... }

casetype Term {  
  Var;
  Fun; 
  App;
}
AFAICT this method seems far more flexible and useful. I currently could use a case type, so I can't really see a good reason for not implementing it this way in Heron. Adding this to the languages is surprisingly simple.


Keith Gaughan

Posts: 17
Nickname: kgaughan
Registered: Feb, 2003

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 2:02 AM
Reply to this message Reply
Is it just me, or does that look strangely like an enumeration?

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 7:47 AM
Reply to this message Reply
> Is it just me, or does that look strangely like an
> enumeration?

It's only a resemblance on the surface. In an enumeration, you define a set of named values which belong to a new type. In the proposed case type, you define a new type, which can accept any value of any of the new supertypes.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 8:13 AM
Reply to this message Reply
Could you give an example how this might be used to solve a problem? Thanks.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 8:58 AM
Reply to this message Reply
> Could you give an example how this might be used to solve
> a problem? Thanks.

Sure, no problem.

In my interpreter I have statement objects. Every statement in Heron is made up of a series of terms and blocks. A term is a sequence of chars (e.g. a symbol, a literal or an identifier), while a block is a sequence of statements delimited by { }. So I want a term object which is either a string or a block object. So how do I represent that? In my opinion the simplest approach is to create a new type which is a subtype of both string and block. I don't want to explicitly modify a string class, so instead I use a-posteriori subtyping to create a new type. One way of thinking about it is as a kind of union type

So my code looks like the following (the syntax for the case type has already changed as one might expect for such a new idea).


subtype term
{
supertype
{
string;
block;
}
}

enum token_type
{
tt_empty;
tt_char;
tt_string;
tt_integer;
tt_float;
tt_ident;
tt_unknown;
}

class statement
{
public
{
def new_statement() : statement* {
terminate_current_token();
return parent.new_statement();
}
def new_block() : statement* {
terminate_current_token();
block* p = new block;
terms.append(p);
return p.new_statement();
}
def close_block() : statement* {
assert(parent != NULL);
return parent.current_statement();
}
def append_char(char c) {
if (is_wspace(c)) {
terminate_current_token();
}
else {
switch (tt) {
// TODO ...
};
token += c;
}
}
}
private
{
def is_wspace(char c) : bool {
return (c == ' ' || c == '\t' || c == '\n');
}
def is_ident_char(char c) : bool {
return (c within range('a','z')) || (c within range('A','Z')) || (c == '_');
}
def terminate_current_token() {
if (token.count() > 0) {
terms.push(new token(tkn));
}
tt = tt_empty;
}
}
fields
{
token_type tt;
token tkn;
block* parent;
stack[term*] terms;
}
}


Note: this is code under development, and is exploiting features which haven't been implemented yet. I am using a feature driven design methodology to evaluate unimplemented features (e.g. "within" and "enum").

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 10:02 AM
Reply to this message Reply
Sorry but I'm confused. I don't see any casetype declarations in the code. Am I missing something?

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 10:05 AM
Reply to this message Reply
> Sorry but I'm confused. I don't see any casetype
> declarations in the code. Am I missing something?

Sorry, I am experimenting with new syntax for the casetype. In the example I am using:


subtype term {
supertype {
string;
block;
}
}


to mean:


casetype term {
string;
block;
}

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 12:00 PM
Reply to this message Reply
OK, I think I've got it.

Then support some syntax similar to this:

def handleTerm(term t) : void {
switch (t) {
case (string) ...
case (block) ...
}
}

And would you allow the creation of methods in a subtype?

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 12:01 PM
Reply to this message Reply
The thing that I really like about this idea is that it improves the usefulness of generic/parametric syntax. Maybe that's your point.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 12:18 PM
Reply to this message Reply
> OK, I think I've got it.
>
> Then support some syntax similar to this:
>

> def handleTerm(term t) : void {
> switch (t) {
> case (string) ...
> case (block) ...
> }
> }
>


Yes, something along those lines.

> And would you allow the creation of methods in a
> subtype?

That is a good question. I see no reason why not. One might be able to write a method such as:


def handleSelf() {
switch (type_of(this)) {
case (string) { handleString(cast<string>(this)); }
case (block) { handleBlock(cast<block>(this)); }
}
}

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 1:01 PM
Reply to this message Reply
> > And would you allow the creation of methods in a
> > subtype?
>
> That is a good question. I see no reason why not. One
> might be able to write a method such as:
>
>

> def handleSelf() {
> switch (type_of(this)) {
> case (string) { handleString(cast<string>(this)); }
> case (block) { handleBlock(cast<block>(this)); }
> }
> }
>


That would be very cool because then you could limit the cases to the subtype itself. I kind of think you should actually make it the only place you could do this and allow this syntax:

def doThing() {
switch (type) { // this type
case (string) { // implicit cast to string
this.doStringThing();
} case (block) { // implicit cast to block
this.doBlockThing();
}
}
}


This basically acts like an adaptor.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 27, 2006 1:31 PM
Reply to this message Reply
One moe thing, would the case (type) syntax be statically bound?

Kresimir Cosic

Posts: 6
Nickname: kreso
Registered: Jan, 2006

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 28, 2006 7:16 AM
Reply to this message Reply
> In my interpreter I have statement objects. Every statement
> in Heron is made up of a series of terms and blocks. A term
> is a sequence of chars (e.g. a symbol, a literal or an
> identifier), while a block is a sequence of statements
> delimited by { }. So I want a term object which is either a
> string or a block object. So how do I represent that?

I don't have much experience with interpreters, but this looks to me like a factory pattern. Make term a supertype of block and string, and then use dynamic cast to access specific functions of string and block. I might easily be wrong.

Kresimir Cosic

Posts: 6
Nickname: kreso
Registered: Jan, 2006

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 28, 2006 5:52 PM
Reply to this message Reply
Oh, I completely misunderstood the article... never mind previous post.

About case types: if Heron is to have support for casetype, then subtyping a-posteriori with syntax you suggested looks ok.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: A-Posteriori Subtyping and Case Classes Posted: Jan 29, 2006 8:31 AM
Reply to this message Reply
> One moe thing, would the case (type) syntax be statically
> bound?

I don't understand precisely what you mean. If you are asking as to whether the type relationships are determined at compile-time the answer is no.

Flat View: This topic has 23 replies on 2 pages [ 1  2 | » ]
Topic: If You're Not Going to Upgrade It, Don't Use It Previous Topic   Next Topic Topic: JavaScript Reference

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use