caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Swaroop Sridhar <swaroop.sridhar@gmail.com>
To: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Recursive types
Date: Tue, 15 Nov 2005 22:28:34 -0500	[thread overview]
Message-ID: <437AA762.5060909@cs.jhu.edu> (raw)
In-Reply-To: <20051116.084030.02302710.garrigue@math.nagoya-u.ac.jp>

Jacques Garrigue wrote:
> No, types are just implemented as (cyclic) graphs.
> All functions in the type checker have to be careful about not going
> into infinite loops. There are various techniques for that, either
> keeping a list/set of visited nodes, or using some mutable fields.

Thanks for the clarification. In order to ensure that I understand you 
correctly, can you please look into the following unification algorithm 
and see if it is reasonably correct?

Considering a language with integers, records and type variables.
Let record types be unified by structural unification.

My representation of type is (please forgive my sloppy syntax at times):

type KindUnion = Integer | Tvar | Record
type 'a option = None | Some 'a

type TYPE =
  { id: int;
         (* unique ID *)

    kind: kindUnion;
         (* type of this type: integer/ tvar/ record *)

    components: mutable vector of TYPE
         (* vector of types containing legs of a record *)

    typeArgs: mutable vector of TYPE
         (* vector of types containing type-arguments / type-parameters
            of a record *)
         (* example
               type ('a, 'b) rec = { a: 'a->'b; b: int}
                     typeArgs          components
         *)

    link: mutable (TYPE option)
         (* to link unified types *)

    unf: mutable (TYPE option)
         (* This is a marker used by the unifier.
            Initially, this field is set to `None' for all types.
            If we are attempting to unify t1 and t2, the unifier
            will mark t1-> unf = Some t2, and t2-> unf = Some t1
            so that we detect them next time when we recurse *)
}

I also assume that a function repr is defined that will traverse the 
links so that (repr t) will provide the "final" type.

So, now the Unifier algorithm can be written as (in some hypothetical 
algorithmic language):

Unify (first:TYPE, second: TYPE)
    will return true on Unification false if not.

1. Start
2. let t1 = repr first
    let t2 = repr second

3.  (* The unifier will set unf field on the way in and will
        clear it on its way out. So, first test if we have a
        recursive case *)

    if(t1.unf != None and t2.unf != None)
        if(t1.unf == t2.unf)
	  return true
        endif
        if(t2.unf == t1.unf)
           return true
        else
           return false
        endif
    endif


4. (* set the unf fields *)
    if(t1.unf == None and t2.unf != None)
        t1.unf := Some t2
    else
      if(t2.unf == None and t1.unf != None)
        t2.unf := Some t1
      else
        t1.unf = Some t2
        t2.unf = Some t1
      endif
    endif

5. match (t1.kind, t2.kind) with

    case (Integer, Integer) ->
            return true

    case (Tvar, _ )  ->
            t1->link = Some t2
            return true

    case (_, Tvar) ->
            t2->link = Some t1
            return true

    case (Record, Record) ->
            if the record lengths don't match
               return false

            for each i in 0 to t1.components.size()
               Unify (t1.components[i], t2.components[i])
               if Unification fails, return false

            for each i in 0 to t1.typeArgs.size()
               Unify (t1.typeArgs[i], t2.typeArgs[i])
               if Unification fails, return false
	   return true

    case (_, _)  ->
            return false

6. t1.unf = None
    t2.unf= None

7. Stop

Is this algorithm correct? If not, how should it be fixed?

> A few years ago, infinite loops were a commonly reported bug :-)

I read a couple of postings about this issue. I understand that one can 
hurt oneself with a type being parameterized itself. I also read that 
the type system needs to deal with this in order to support objects. 
Aren't recursive types necessary even to do a simple linked list like:

type llist = {contents: int; link : mutable llist}

Thanks again,
Swaroop.


  parent reply	other threads:[~2005-11-16  3:28 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20050506044107.1698.70519.Mailman@yquem.inria.fr>
2005-11-15 22:44 ` Swaroop Sridhar
2005-11-15 23:40   ` [Caml-list] " Jacques Garrigue
2005-11-16  2:20     ` Keiko Nakata
2005-11-16  6:47       ` Alain Frisch
2005-11-16  7:40         ` Keiko Nakata
2005-11-16  8:55           ` Jacques Garrigue
2005-11-17  1:45             ` Keiko Nakata
2005-11-16  3:28     ` Swaroop Sridhar [this message]
2005-11-16  8:38       ` Jacques Garrigue
2005-11-16 23:00         ` Swaroop Sridhar
2005-11-16 23:56           ` Swaroop Sridhar
2008-03-24  3:16 recursive types Jacques Le Normand
2008-03-24  3:51 ` [Caml-list] " Erik de Castro Lopo
2008-03-24  3:51 ` Erik de Castro Lopo
2008-03-24  8:37 ` Jeremy Yallop
  -- strict thread matches above, loose matches on Subject: below --
2004-12-13  9:44 nakata keiko
2004-12-13  9:58 ` [Caml-list] " Damien Pous
2004-12-13 12:31   ` skaller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=437AA762.5060909@cs.jhu.edu \
    --to=swaroop.sridhar@gmail.com \
    --cc=caml-list@yquem.inria.fr \
    --cc=garrigue@math.nagoya-u.ac.jp \
    --cc=swaroop@cs.jhu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).