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

'let open' in class expressions #6271

Closed
vicuna opened this Issue Dec 14, 2013 · 10 comments

Comments

Projects
None yet
2 participants
@vicuna
Copy link
Collaborator

vicuna commented Dec 14, 2013

Original bug ID: 6271
Reporter: @yallop
Assigned to: @alainfrisch
Status: resolved (set by @alainfrisch on 2017-07-20T06:20:09Z)
Resolution: fixed
Priority: low
Severity: feature
Fixed in version: 4.06.0 +dev/beta1/beta2/rc1
Category: language features
Has duplicate: #7477 #7529
Monitored by: @gasche @hcarty @Chris00

Bug description

It'd be useful to have 'let open' available in class expressions:

class c =
let open M in
object ... end

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Dec 16, 2013

Comment author: @alainfrisch

Note that the following achieves the same effect:

include struct
open M
class c = object
...
end
end

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Dec 17, 2013

Comment author: @yallop

Thanks, Alain! That's a useful workaround, and adequate for my use case.

There are a few other benefits in allowing 'let open' in class expressions. For one thing, there's a pleasing uniformity about having 'let open ... in' available everywhere that 'let ... in' is available. It also handles a few cases that the 'include' approach doesn't: for example, it supports recursive classes where you want careful control over the scope. Perhaps these aren't enough to justify its inclusion, though.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Dec 18, 2013

Comment author: @garrigue

Well, "let open" should be simple enough to do, so I'll consider seriously doing it.
Note that on the other hand "let module" would be really difficult.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Dec 18, 2013

Comment author: @lpw25

On a related note, it might be nice to allow open statements within class definitions:

class c = object
  open M
  ...
end
@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Jul 18, 2017

Comment author: @alainfrisch

#1249

@vicuna vicuna closed this Jul 20, 2017

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Nov 12, 2018

Comment author: @trefis

I stumbled upon this because I was about to extend #1506 to classes (well, to Tcl_open).
But the remark from Jacques made me pause:

Note that on the other hand "let module" would be really difficult.

So I will send a first version without extending Tcl_open, but I'm curious about what would be difficult.
Jacques: do you remember?

When I asked Leo he pointed me in the direction of Translclass.const_path, but looking at it we think that "let module" could be handled the same way as "let" (i.e. keep an environment), so that can't be it.
What are we missing?

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Nov 13, 2018

Comment author: @garrigue

I'm not sure I thought that in that much detail, but my main concern was how to check that a local module would not escape, particularly when you want to be able to store values with its type in value fields, which are visible in the interface of the class. Actually my conclusion was that one would need something like "module fields", like in Scala, to be able to express that properly. If you only want to be able to introduce a local module, without allowing it to appear anywhere in the interface, this should be easier, but again tracking that it does not escape is probably going to be harder than in the expression case. You at least need an extra pass on the inferred class type. And it's not as expressive as what I had in mind.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Nov 13, 2018

Comment author: @trefis

That makes sense, thanks!

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Nov 13, 2018

Comment author: @yallop

Jacques: for escape tracking, is something additional needed beyond what's currently done to eliminate functor arguments in class definitions? e.g. in definitions like this:

module M(X: sig type t end) =
struct class c = object val x : X.t list = [] end end

module N = M(struct type t = T end)

i.e. is something other than Ctype.nondep_class_declaration needed?

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Nov 14, 2018

Comment author: @garrigue

You would rather have to ask Xavier, since he is the one who used a different approach for "let module" in expressions.
At first sight, a potential problem is that nondep_class_declaration is currently only used on "finished" classes, whereas we would have to use it during the construction of a class.
I'm not sure it is really a problem (nondep_type_rec does handle non-generalized type nodes), but there may be hidden invariants.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.