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.
next prev 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