Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Allow existential types introduced in a constructor pattern to be bound without tuple type constraints patterns #11491

Closed
ebresafegaga opened this issue Aug 15, 2022 · 4 comments

Comments

@ebresafegaga
Copy link
Contributor

ebresafegaga commented Aug 15, 2022

Currently, if we have this:

module type Printable = sig
  type t
  val print : t -> unit
end

type printable = Printable : 'a * (module Printable with type t = 'a) -> printable

let print_list ps =
  ps
  |> List.iter (fun (Printable (type a) ((item : a), (module P))) -> P.print item)

We will get an error:

 Existential types introduced in a constructor pattern
   must be bound by a type constraint on the argument.

This is the only correct way:

let print_list ps =
  ps
  |> List.iter (fun (Printable (type a) ((item, (module P)) : a * _)) -> P.print item)

It would be nice if we could do this both ways.

@hyphenrf
Copy link

When I needed a locally abstract type like this, I found myself naturally reaching out for the ((a : t), b) syntax before the (a, b : t * _) one. +1 here.

@gasche
Copy link
Member

gasche commented Nov 19, 2022

Not really an answer to this issue, but it may help to consider the history of this fairly-recent feature, that prominently features syntax discussions. (Basically: this syntax is a bit annoying on users but also very predictable and simple to implement, so it managed to gather consensus when more convenient and complex proposals did not.)

Some examples of syntaxes that have been considered in the process:

let f = function type b. D ((x:b), f) -> f x

function D (type a) (x, f) -> f x (* using definition order for existential variables *)

let f (type b) (D ((x: b), f)) = ...

fun (C : type a b. a * (a -> b list) -> t. (x, f)) -> ...
fun (C (type a b) ((x : a), (f : a -> b list))) -> ...

function 'a. C ((x : 'a), f) -> ...

function <'a> Dyn (w,(x:'a)) -> ...

function Dyn (type a) (w, x : a ty * a) -> ...
function Dyn (type a) ((w : a ty), (x : a)) ->

Generally:

  • Suggestions to not require any annotation on the pattern arguments and use the type-declaration variable order to give meaning to the names have been abandoned.
  • People recognized the lack of flexibility of the current syntax from the start, but no more flexible syntax gathered consensus.
  • Currently only "toplevel" annotations are easy to implement; we currently require (type a) (w, x : a ty * a), we could instead allow (type a) ((w : a ty), (x : a)) for GADTs with two constructors, and we could even possibly allow say (type a) ((w : a ty), x) (making some toplevel annotation optionals), but we cannot allow (type a) (Some (x : a)), with an annotation in-depth in the pattern -- not without a significant change to the implementation strategy.
  • Due to this "toplevel" restriction, there is a feeling that syntaxes that look like they allow for in-depth annotations are not great as they suggest something that the programmer cannot do -- they are not obviously restrictive, they are sneakily restrictive.

Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label Nov 22, 2023
@Octachron
Copy link
Member

I am moving this feature wish to a discussion, since this is not really planned (and as far as I remember possibly much harder to implement that it looks).

@ocaml ocaml locked and limited conversation to collaborators Jan 24, 2024
@Octachron Octachron converted this issue into discussion #12935 Jan 24, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

4 participants