-
Notifications
You must be signed in to change notification settings - Fork 794
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
Null pointer reference (NRE) when referencing a point free function (FSharpFunc?) from a console app without a main method #18259
Comments
The issue stems from missing module-level initialization - the function is compiled as a property, but it does not get initialized. That does sound strange, why does placement of the file matter? For a console project, the necessary initialization for the last file comes from invoking the main method. If no main present, contents of the last file act similar to it. However, when a test project references your app project, it does not call main - it only accesses members as if it was a library. What do point-free functions have to do with it? To fix this we would need to change initialization of properties for last file of a console app - to make it work even when the code is not executed, but just referenced.( without breaks or performance regressions for the dominant use case of using console apps, which should be "running them" :) ) |
More at page 204 and 205 of the F# spec: |
Yes, I see, if it is in a module it even works, so it has to be the last file AND no main method. |
That is an interesting idea. Let's see if someone can propose a template change that would not reduce simplicity of it (it can have comments!), while making it more difficult to get into this problem. |
As I re-read the comments in the console app template, of course I found that the link points to descriptions of the implicit style of console apps, and that the explicit version does mention it is suited for unit testing the last file in a console apps... I don't know what such a template could say, but I like the "Are your lights on?" approach which is to ask if you have checked, not telling a driver what to do (if night and then tunnel then keep lights on, if day and driving lights are on then turn lights etc...) https://www.amazon.com/Are-Your-Lights-Figure-Problem/dp/0932633161 II think there are tweaks that could make it more clear, I could propose some changes and see. I think typically the language is often positive in docs, saying that "this method is suited for unit testing the last file in the console app" and the implicit does not say that "this will have issues with for example unit testing the last file in the app, as special rules apply to the initialization of the last file in a console app with implicit entry points", which I think would make pitfalls slightly more clear. Just stating something in a comment that is true (what style the template is in) and ask the user if this is what they want and then the docs could have more details on pros and cons... I don't know, but I am trying to think on something that would be universally useful and not targets this specific issue, and even if this would be a small change, perhaps it would be a tiny improvement. The docs could have more on pitfalls specific for implicit entry points or weird edge cases, also mention this issue as a con.
Ideally of course it would just not fail, but I think links to specific docs is universally a good idea and would be good even if the issue got fixed later. |
Repro steps
I added a repository here to describe the issue, without xunit for clarity. This is a stranger use-case than with a test project, but it makes it clear that xunit is not involved https://github.com/bjartwolf/fsharpnull
Part of the reason for this to show now, I guess, is that console apps now have no main method by default.
Instructions similar to this below, but using xunit as that is a more typical use-case.
dotnet new console -lang "F#" -o consoleapp
dotnet new xunit -lang "F#" -o test
cd test
dotnet add reference ..\consoleapp\consoleapp.fsproj
and a test like
Expected behavior
I expect it to work, or perhaps some warning that point free functions can cause issues across assemblies?
Actual behavior
Null pointer reference when invoking the function (as shown in the repository, this happens also without xunit, but the use-case where this happens is typically a console app with xunit or some other test framework. This can make it a bit more tricky to see what is going on, it is easy to blame the testrunner for the behavoir.)
Known workarounds
Do not use point-free function, add a named argument to the function when exposing it outside assemblies, as pr language guidelines. This avoids the FSharpFunc
or
Add a main method like so in the console app. This somehow causes something to initialize differently?
or
Add the code to a classlib and reference that in the console app. Classlibs work too.
Related information
Asked for some input in the discord first https://discord.com/channels/196693847965696000/441274967607214091/1331376422555746347 and was asked to submit. Nice to have someone to discuss with before posting issues directly. Seems like from the comment that it might has been observed before (or maybe that was something else...)
The text was updated successfully, but these errors were encountered: