Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature wish #3278

Closed
vicuna opened this issue Mar 27, 2002 · 4 comments
Closed

feature wish #3278

vicuna opened this issue Mar 27, 2002 · 4 comments

Comments

@vicuna
Copy link

vicuna commented Mar 27, 2002

Original bug ID: 1031
Reporter: administrator
Status: closed
Resolution: won't fix
Priority: normal
Severity: feature
Category: ~DO NOT USE (was: OCaml general)

Bug description

Bonjour,

quand on abstrait un type, on n'a plus accès aux constructeurs... normal.
Mais on aimerait pourtant parfois en garder certains, tandis que d'autres
restent cachés. Les abstraire par une fonction pour les rendre public
n'est pas toujours efficace : on perd alors la construction de valeurs
polymorphes, et toute possibilité de pattern matching. Est-il possible
d'avoir une construction équivalente à val dans les modules, mais pour des
constructeurs ? (les variants polymorphes n'aident pas ici, on voudrait
que le type reste abstrait)

par exemple, dans le .ml :
type ('a,'b) bar = Cons of 'a | Blop of 'a * 'b

dans le .mli :
type ('a,'b) bar (* abstrait *)
val Cons : 'a -> ('a,'b) bar

(* tel que (Cons x) soit polymorphe, et même puisse être filtrer. *)

@vicuna
Copy link
Author

vicuna commented Mar 28, 2002

Comment author: administrator

From: lvibert@irisa.fr

quand on abstrait un type, on n'a plus accès aux constructeurs... normal.
Mais on aimerait pourtant parfois en garder certains, tandis que d'autres
restent cachés. Les abstraire par une fonction pour les rendre public
n'est pas toujours efficace : on perd alors la construction de valeurs
polymorphes, et toute possibilité de pattern matching. Est-il possible
d'avoir une construction équivalente à val dans les modules, mais pour des
constructeurs ? (les variants polymorphes n'aident pas ici, on voudrait
que le type reste abstrait)

C'est un souhait qui apparait regulierement, mais pour lequel il n'y a
pas de solution jolie.

par exemple, dans le .ml :
type ('a,'b) bar = Cons of 'a | Blop of 'a * 'b

dans le .mli :
type ('a,'b) bar (* abstrait *)
val Cons : 'a -> ('a,'b) bar

(* tel que (Cons x) soit polymorphe, et même puisse être filtrer. *)

Le probleme est que pour pouvoir filtrer, on a besoin de connaitre la
representation physique du type, et pour ca on a besoin d'avoir tous
les constructeurs. (Je sais, on pourrait permettre de cacher les
constructeurs de queue, mais ca devient un hack affreux, et reste le
probleme de la completude du filtrage)
A remarquer cependant que les variantes polymorphes peuvent etre utiles pour ce type de filtrage: let coerce : ('a,'b) bar -> [Cons of 'a] = function
`Cons _ as x -> x
| _ -> failwith "Cannot coerce"
et on peut filtrer le resultat de coerce (surtout interessant s'il y a
plusieurs constructeurs non abstraits)

Sur le polymorphisme, il pourrait y a avoir quelque chose a faire. Par exemple avoir des fonctions "pures" a un certain degre', qui
peuvent etre appliquees a` n arguments tout en restant polymorphiques.
Il arrive qu'on en aie besoin, et c'est plus general que le cas des
seuls constructeurs.

let cons x = Cons x
val cons : 'a -> ('a,'b) bar <= pure(1)

Comme l'information peut ne pas etre dans le type lui-meme, mais dans
les informations concernant une valeur, c'est relativement facile a`
faire.

Cordialement,

    Jacques

Le trait dont j'ai toujours rêvé dans le domaine des types abstraits
est beaucoup plus simple à implémenter et cependant plus général: il
s'agit d'exporter tous les constructeurs d'un type pour le filtrage,
mais pas pour la construction. En effet, la plupart des types
abstraits que j'utilise ont des invariants forts lors de la
construction des valeurs (construction qui n'est donc possible qu'en
passant par des fonctions qui mettent en place ces invariants). En
revanche, lorsque les valeurs sont construites, il n'y a pas de
problème pour laisser les utilisateurs du module filtrer comme bon
leur semble pour imprimer ou construire d'autres valeurs (à l'aide des
fonctions exportées par le module du type abstrait). J'ai très souvent
eu la nécessité de briser la barrière d'abstraction (i.e. d'exporter
concrètement un type abstrait) juste pour pouvoir faire du filtrage
dans un module client. A chaque fois, je prie pour ne pas oublier de
toujours passer par les fonctions de constructions pour construire les
valeurs du type abstrait, alors que le compilateur Caml pourrait,
comme d'habitude, vérifier cela pour moi sans jamais laisser passer
une faute d'inattention ...

Cordialement,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/

@vicuna
Copy link
Author

vicuna commented Mar 28, 2002

Comment author: administrator

From: lvibert@irisa.fr

quand on abstrait un type, on n'a plus accès aux constructeurs... normal.
Mais on aimerait pourtant parfois en garder certains, tandis que d'autres
restent cachés. Les abstraire par une fonction pour les rendre public
n'est pas toujours efficace : on perd alors la construction de valeurs
polymorphes, et toute possibilité de pattern matching. Est-il possible
d'avoir une construction équivalente à val dans les modules, mais pour des
constructeurs ? (les variants polymorphes n'aident pas ici, on voudrait
que le type reste abstrait)

C'est un souhait qui apparait regulierement, mais pour lequel il n'y a
pas de solution jolie.

par exemple, dans le .ml :
type ('a,'b) bar = Cons of 'a | Blop of 'a * 'b

dans le .mli :
type ('a,'b) bar (* abstrait *)
val Cons : 'a -> ('a,'b) bar

(* tel que (Cons x) soit polymorphe, et même puisse être filtrer. *)

Le probleme est que pour pouvoir filtrer, on a besoin de connaitre la
representation physique du type, et pour ca on a besoin d'avoir tous
les constructeurs. (Je sais, on pourrait permettre de cacher les
constructeurs de queue, mais ca devient un hack affreux, et reste le
probleme de la completude du filtrage)
A remarquer cependant que les variantes polymorphes peuvent etre utiles pour ce type de filtrage: let coerce : ('a,'b) bar -> [Cons of 'a] = function
`Cons _ as x -> x
| _ -> failwith "Cannot coerce"
et on peut filtrer le resultat de coerce (surtout interessant s'il y a
plusieurs constructeurs non abstraits)

Sur le polymorphisme, il pourrait y a avoir quelque chose a faire. Par exemple avoir des fonctions "pures" a un certain degre', qui
peuvent etre appliquees a` n arguments tout en restant polymorphiques.
Il arrive qu'on en aie besoin, et c'est plus general que le cas des
seuls constructeurs.

let cons x = Cons x
val cons : 'a -> ('a,'b) bar <= pure(1)

Comme l'information peut ne pas etre dans le type lui-meme, mais dans
les informations concernant une valeur, c'est relativement facile a`
faire.

Cordialement,

    Jacques

@vicuna
Copy link
Author

vicuna commented Mar 28, 2002

Comment author: administrator

On Thu, 28 Mar 2002, Jacques Garrigue wrote:

C'est un souhait qui apparait regulierement, mais pour lequel il n'y a
pas de solution jolie.

Le probleme est que pour pouvoir filtrer, on a besoin de connaitre la
representation physique du type, et pour ca on a besoin d'avoir tous
les constructeurs. (Je sais, on pourrait permettre de cacher les
constructeurs de queue, mais ca devient un hack affreux, et reste le
probleme de la completude du filtrage)

pour la completude du filtrage, on peut déjà filtrer un type abstrait,
(avec une variable ou _). Pour filtrer un type partiellement abstrait, il
suffit donc de finire le filtrage de même, non ?

A remarquer cependant que les variantes polymorphes peuvent etre utiles pour ce type de filtrage: let coerce : ('a,'b) bar -> [Cons of 'a] = function
`Cons _ as x -> x
| _ -> failwith "Cannot coerce"
et on peut filtrer le resultat de coerce (surtout interessant s'il y a
plusieurs constructeurs non abstraits)

Ne peut on pas utiliser les variants polymorphes justement pour contourner
le problème ? C'est à dire avoir une construction dans les signatures :

type ('a,'b) blop = [ Nil | Cons of 'a | _ ]

où le "_" ne représente pas une variable de rangée, mais d'autres
constructeurs, abstraits ceux-ci ?

ie on ne peux pas faire (`C : ('a,'b) blop)

ça ne correspond pas complètement à mon souhait initial, mais c'est déjà
beaucoup !

Avec tous mes remerciements pour le langage Caml, et l'attention que vous
portez à mes remarques,

Laurent

@vicuna
Copy link
Author

vicuna commented Nov 7, 2002

Comment author: administrator

This suggestion brings us quite far -- into the problem of concrete views on
abstract data types. I (XL) don't think we'll address that in the foreseeable
future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant