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

Allow typeof<Module> or something equivalent #730

Open
Frassle opened this Issue Mar 30, 2019 · 7 comments

Comments

Projects
None yet
5 participants
@Frassle
Copy link

Frassle commented Mar 30, 2019

Allow typeof<Module> or something equivalent

I propose a mechanism is added to allow us to get the CLR type of a module as easily as it is for normal types with typeof<>.

This is to solve two recurring situations we have in our code base that we currently have to workaround.

The first is logger factory methods expect a CLR type to be passed in to set their context. We currently workaround this by declaring a private dummy types in modules so that we can do typeof.GetDeclaringType() to get the module type to pass to the logger.

The second is reflection based tests that check our api hasn't changed between builds, most of our tests just do typeof.Assembly to pass to the api checker, but projects with only modules in them have to instead Assembly.Load("Module").

Initial ideas for this are to somehow extend typeof<> to allow module names to be passed in, or via a new keyword like moduleof<>.

Pros and Cons

The advantages of making this adjustment to F# are we'll no longer need workarounds to get the CLR type of modules. This would trim a significant amount of boilerplate, and also stop new F#ers hitting this confusing limitation.

The disadvantages of making this adjustment to F# are that this may be a breaking change based on how it's decided to implement it.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): S-M

Related suggestions: I found no related suggestions.

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this
@7sharp9

This comment has been minimized.

Copy link
Member

7sharp9 commented Mar 31, 2019

@Rickasaurus

This comment has been minimized.

Copy link

Rickasaurus commented Apr 4, 2019

Yes please. I've wanted this for so long.

@7sharp9

This comment has been minimized.

Copy link
Member

7sharp9 commented Apr 4, 2019

@Tarmil

This comment has been minimized.

Copy link

Tarmil commented Apr 5, 2019

Of course, there's potential ambiguity if you have both a module and a type with the same full name.

A possible syntax to disambiguate could be typeof<module Foo>. In fact, we could even introduce <module Foo> as a valid syntax to pass a module as type parameter in any context. Although I doubt it would be used much for anything else than typeof.

Another solution would be to use typeof<FooModule>, but that feels like exposing a quasi-implementation detail.

@FraserWaters-GR

This comment has been minimized.

Copy link

FraserWaters-GR commented Apr 5, 2019

@Tarmil I thought it was no longer the case that module types always ended with Module? That's only added if there's a clash with another type now isn't it?

@Tarmil

This comment has been minimized.

Copy link

Tarmil commented Apr 5, 2019

@FraserWaters-GR More specifically, what happens is that if there's a clash, it used to be a compile error and you had to add an attribute that appends Module, and now Module is appended automatically. And if there is no clash, then Module isn't (and never was) appended automatically.

And yeah, that's why I think handling clashes with typeof<FooModule> is a worse solution than always using a different syntax for types and modules: typeof<FooModule> means you'd have to do something different depending on whether there's a clash or not. I just mentioned the possibility for completeness.

@Frassle

This comment has been minimized.

Copy link
Author

Frassle commented Apr 7, 2019

Allowing "module Foo" in locations that expect a type would solve this. I guess it opens up the possibility that someone might try to declare a value of a module (i.e. let odd (x : module Foo) = ...), could it be restricted to allowed only in generic parameters that would also allow it for other reflection based methods, like things such as GetLogger<T>

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.