Open pirrmann opened 2 years ago
I think the problem is this
We add InlineIfLambdaAtttribute to use on parameters of inlined functions and methods, indicating to the compiler that, if a lambda is supplied as a parameter, it should be inlined. The attribute is indicative only and may be ignored by the F# compiler.
I had missed that "indicative only" part. In practice in my code I haven't noticed any use case where this isn't inlined, but I understand why considering this as indicative only makes it less of a constraint on the compiler. I guess that unless that design decision is revisited, we can close this suggestion.
As I indicated in the description:
This relates to https://github.com/fsharp/fslang-suggestions/issues/688, but I believe that this is a different issue and not a duplicate, as this only relates to inlined lambdas, not regular inlined functions (even though I don't know how complicated or different that is during the compile process).
@NinoFloris are you certain that this is a duplicate?
Sorry I missed that link!
The issue is that inlining happens after type checking, irrespective of a function being let bound or a lambda.
Effectively meaning: to support byref in any inlined functions the compiler would have to blend the phases to inline and type check. It needs to type check, run into byref issues, then inline that to see if the end result now type checks or needs to be inlined further
Additionally - just to give an example of some of the complexities involved - just as there could be another call to an inline function in the body of the initial inline fuction. There could also be a mix of calls, some inline
while others aren't. What's the error for that? "This inline
function does not support byref inlining due to generic call sites in its body not supporting inlining"? Should we require an attribute on functions to signify byref support?
Doing something here would either be a very small hack to allow it for, say, pipelining operators or full language support like SRTP. Anything in between would lead to a language where it would be very hard to understand when you can and cannot use byref generically.
This would be amazing for the work that I am doing. This limitation keeps me from using Array.iter
and Array.map
in many of my use cases and leads to messier code.
I propose we allow using byrefs in inlined lambdas, which we known won't create any closure, and don't generate an FS0406 error.
For instance, when using a lock pattern (which now uses
InlineIfLambda
), we currently can't write:Using this code generates an FS0406 error: "Byrefs cannot be captured by closures or passed to inner functions".
The existing way of approaching this problem in F# is to not use a lambda, and "manually" inline the code to
This relates to #688, but I believe that this is a different issue and not a duplicate, as this only relates to inlined lambdas, not regular inlined functions (even though I don't know how complicated or different that is during the compile process).
Pros and Cons
The advantages of making this adjustment to F# are that this allows writing code that is more concise and less error-prone
I currently don't see any disadvantages of making this adjustment to F#.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.