fslang-suggestions
fslang-suggestions copied to clipboard
Allow let-bound fields in object expressions
Currently when we use object expressions, the outer mutable variable will be promoted to Ref
, if multiple variable variables are used, multiple Ref
will be generated. In fact, most of the time, we don’t share these variables, can any way to add variable variables directly in the object is provided?
For example, in the following code
let foo() =
let mutable isDisposed = false
{
new IDisposable with
member __.Dispose() =
if not isDisposed then
isDisposed <- true
}
can the variable isDisposed
be moved inside
let foo() =
{
let mutable isDisposed = false
new IDisposable with
member __.Dispose() =
if not isDisposed then
isDisposed <- true
}
or else alternatives?
I believe that a more sensible approach would be to allow let
and member val
bindings in object expressions just like in classes, with the same syntax.
let foo() =
{
new IDisposable with
let mutable isDisposed = false
member val K = 1
member __.Dispose() =
if not isDisposed then
isDisposed <- true
}
Promoting the mutable value to a ref
when it's closed over in an object expression like that is by design. Object expressions are objects that are allocated on the heap, so we need to promote this to the heap. It's just like when we promote a mutable value to a ref
when it is passed to a lambda.
I agree with @Happypig375 that any work in this area would be to allow scoping mutability to the expression itself. Is that what you'd like to suggest?
Promoting the mutable value to a
ref
when it's closed over in an object expression like that is by design. Object expressions are objects that are allocated on the heap, so we need to promote this to the heap. It's just like when we promote a mutable value to aref
when it is passed to a lambda.I agree with @Happypig375 that any work in this area would be to allow scoping mutability to the expression itself. Is that what you'd like to suggest?
Yes, I think, the object generated by the object expression has already been allocated in the heap, if the field is not shared, there is no need to generate another object
I believe that a more sensible approach would be to allow
let
andmember val
bindings in object expressions just like in classes, with the same syntax.let foo() = { new IDisposable with let mutable isDisposed = false member val K = 1 member __.Dispose() = if not isDisposed then isDisposed <- true }
If it is written below, it is necessary to distinguish between member
and override
. Currently, member
and override
are the same, And if you use object + interface
, you need to consider more permissions, as I mentioned in another discussion
I agree let mutable
should be usable inside the scope of the object expression
Marking this as approved in principle.