From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: jyh@cs.caltech.edu
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Pure visitor patterns
Date: Thu, 28 Dec 2006 15:17:53 +0900 (JST) [thread overview]
Message-ID: <20061228.151753.38663586.garrigue@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <DD63B67D-4F25-4DDE-8C08-213EED0A9BD7@cs.caltech.edu>
From: Jason Hickey <jyh@cs.caltech.edu>
> I've been trying to write pure visitors (visitors that compute without
> side-effects). The main change is that a visitor returns a value.
> Here is a (failed) example specification based on having only one kind
> of thing "foo".
>
> class type ['a] visitor =
> object ('self)
> method visit_foo : foo -> 'a
> end
>
> and foo =
> object ('self)
> method accept : 'a. 'a visitor -> 'a
> method examine : int
> end
>
> This fails because the variable 'a escapes its scope in the method
> accept.
> It can be fixed by breaking apart the mutual type definition.
>
> class type ['a, 'foo] visitor =
> object ('self)
> method visit_foo : 'foo -> 'a
> end
>
> class type foo =
> object ('self)
> method accept : 'a. ('a, foo) visitor -> 'a
> method examine : int
> end
>
> The second form works, but it is hard to use because of the number
> of type parameters needed for the visitor (in general).
>
> Here are my questions:
>
> - Why does 'a escape its scope in the recursive definition?
Because during recursive definitions parameters of these definitions
are handled as monomorphic. So you cannot generalize the 'a locally.
> - Is there some other style that would solve this problem?
Not really. Using private rows and recursive allow for some more
expressiveness (in particular you can then define pure visitors on
extensible on an extensible collection of classes), but they are a bit
tricky to use in this context, so I'm not sure this is an improvement
for simple cases.
Another trick to make this pattern more scalable is to use constraints
for parameters.
class type ['a, 'cases] visitor =
object ('self)
constraint 'cases = <foo: 'foo; bar: 'bar; ..>
method visit_foo : 'foo -> 'a
method visit_bar : 'bar -> 'a
end
class type foo =
object ('self)
method accept : 'a. ('a, cases) visitor -> 'a
method examine : int
end
and bar =
object ('self)
method accept : 'a. ('a, cases) visitor -> 'a
method examine : bool
end
and cases = object method foo : foo method bar : bar end
> P.S. Here is an alternate scheme with non-polymorphic visitors, where
> the returned value is just a visitor. The accept method needs to
> preserve the type, so this one also has the "escapes its scope"
> problem.
>
> class type visitor =
> object ('self)
> method visit_foo : foo -> 'self
> end
>
> and foo =
> object ('self)
> method accept : 'a. (#visitor as 'a) -> 'a
> end
> ...
Same reason: #visitor has an hidden type parameter, so it cannot be
generalized in a mutually recursive definition.
Jacques Garrigue
next prev parent reply other threads:[~2006-12-28 6:18 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-27 19:31 Jason Hickey
2006-12-28 6:17 ` Jacques Garrigue [this message]
[not found] ` <d86ee07e0612272325g4209dfb5s8276f8b5e08ffd63@mail.gmail.com>
2006-12-28 8:06 ` [Caml-list] " Jason Hickey
2006-12-30 18:27 ` brogoff
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=20061228.151753.38663586.garrigue@math.nagoya-u.ac.jp \
--to=garrigue@math.nagoya-u.ac.jp \
--cc=caml-list@inria.fr \
--cc=jyh@cs.caltech.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