From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL,HTML_MESSAGE autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 7581DBC69 for ; Thu, 18 Oct 2007 19:22:03 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ah4FADIzF0dCm3xr/2dsb2JhbACCPDaNQA X-IronPort-AV: E=Sophos;i="4.21,296,1188770400"; d="scan'208,217";a="3224203" Received: from janestcapital.com (HELO smtp.janestcapital.com) ([66.155.124.107]) by mail1-smtp-roc.national.inria.fr with ESMTP; 18 Oct 2007 19:22:02 +0200 Received: from [172.25.129.161] [38.96.172.125] by janestcapital.com with ESMTP (SMTPD-9.10) id A639077C; Thu, 18 Oct 2007 13:22:01 -0400 Message-ID: <47179638.6080605@janestcapital.com> Date: Thu, 18 Oct 2007 13:22:00 -0400 From: Brian Hurt User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Dario Teixeira Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Smells like duck-typing References: <824282.32870.qm@web54605.mail.re2.yahoo.com> In-Reply-To: <824282.32870.qm@web54605.mail.re2.yahoo.com> Content-Type: multipart/alternative; boundary="------------020702060905090005020108" X-Spam: no; 0.00; semantics:01 semantics:01 invoke:01 invoke:01 wrote:01 wrote:01 caml-list:01 defined:02 defined:02 fewer:02 fewer:02 inheritance:03 inheritance:03 languages:03 languages:03 This is a multi-part message in MIME format. --------------020702060905090005020108 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Dario Teixeira wrote: >>So now you've defined full_story, blurb_story, and fresh_story as >>types. Now, I write: >> >>let get_body (story: full_story) = story#get_body;; >>let my_blurb = new blurb_story(id, "A Title", "An Intro");; >>let my_body = get_body my_blurb;; >> >>what happens? >> >> > >Hi, > >Well, that's only a problem if you insist in thinking in terms >of inheritance. Remember that the semantics of marble-carving >are NOT "all that works on full_story should also work on blurb_story", >but the other way around. > > > So all full stories are also blurbs, but blurbs are not full stories. So full stories are a more specific type than blurbs are, because while we can always use a full story as a blurb, we can't use a blurb as a full story. >Also, imagine you were to add the "get_body" method to the root >"story" class. The type system in Marble-Caml is smart enough >to tell you that since the blurb_story carved out the "body" field, >then it must also carve out methods that use it. Aren't imaginary >languages wonderfull?... :-) > > > It's much easier, rather than detecting when things have to be removed, to simply detect when things can be added. Every "remove members" relationship can be expressed as an "add members" relationship going the other direction. Start with the simpler (fewer members) type and then create the derived type by adding members to make the more complex (more members) type. Anything you can do with one direction of deriving types you can do with the other direction of deriving. Which is why Robert said you had just reinvented inheritance. >(In addition, note that in any real world situation, it wouldn't >make any sense for the user to want to invoke get_body on a blurb >object -- after all, by definition blurbs have no body). > > Yep. Brian --------------020702060905090005020108 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit Dario Teixeira wrote:
So now you've defined full_story, blurb_story, and fresh_story as 
types.  Now, I write:

let get_body (story: full_story) = story#get_body;;
let my_blurb = new blurb_story(id, "A Title", "An Intro");;
let my_body = get_body my_blurb;;

what happens?
    

Hi,

Well, that's only a problem if you insist in thinking in terms
of inheritance.  Remember that the semantics of marble-carving
are NOT "all that works on full_story should also work on blurb_story",
but the other way around.

  
So all full stories are also blurbs, but blurbs are not full stories.  So full stories are a more specific type than blurbs are, because while we can always use a full story as a blurb, we can't use a blurb as a full story.

Also, imagine you were to add the "get_body" method to the root
"story" class.  The type system in Marble-Caml is smart enough
to tell you that since the blurb_story carved out the "body" field,
then it must also carve out methods that use it.  Aren't imaginary
languages wonderfull?... :-)

  
It's much easier, rather than detecting when things have to be removed, to simply detect when things can be added.  Every "remove members" relationship can be expressed as an "add members" relationship going the other direction.  Start with the simpler (fewer members) type and then create the derived type by adding members to make the more complex (more members) type.  Anything you can do with one direction of deriving types you can do with the other direction of deriving.

Which is why Robert said you had just reinvented inheritance.
(In addition, note that in any real world situation, it wouldn't
make any sense for the user to want to invoke get_body on a blurb
object -- after all, by definition blurbs have no body).
  
Yep.

Brian

--------------020702060905090005020108--