microsoft / Power-Fx

Power Fx low-code programming language
MIT License
3.18k stars 321 forks source link

Deep mutations of records, squashed #2457

Closed gregli-msft closed 3 months ago

gregli-msft commented 3 months ago

Adds support for deep mutation through the Set function. Set( a, {b:1} ) doesn't change and will assign a reference to the record {b:1} to the variable a. After a has been established, it now supports mutation through Set( a.b, 2 ). This is an optional facility that is disabled by default and there are no semantic changes. When creating variables the host has the option to enable this with SymbolProperties.CanSetMutate.

This also fixes two related bugs. First, really deep mutations were not being properly copied on write, where t should be unaffected by the Patch https://github.com/microsoft/Power-Fx/issues/2450:

>> Set( deep, [[[[1,2,3],[4,5,6]]]] )
deep: [[[[1, 2, 3], [4, 5, 6]]]]

>> Set( t, deep )
t: [[[[1, 2, 3], [4, 5, 6]]]]

>> Patch( First(First(First(deep).Value).Value).Value, {Value:2}, {Value:99} )
{Value:99}

>> deep
[[[[1, 99, 3], [4, 5, 6]]]]

>> t
[[[[1, 99, 3], [4, 5, 6]]]]

And this should not return a casting error, instead returning Blank() https://github.com/microsoft/Power-Fx/issues/2451:

>> Patch(Blank(),Blank(),Blank())
Unable to cast object of type 'Microsoft.PowerFx.Types.BlankType' to type 'Microsoft.PowerFx.Types.RecordType'.
jas-valgotar commented 3 months ago
        }

Does this mean if variable existed, we won't honor newVarProps new properties for symbol?


Refers to: src/libraries/Microsoft.PowerFx.Interpreter/RecalcEngine.cs:161 in 0d27448. [](commit_id = 0d2744882c57ee74d03924a8b6c78ba3ffcb43f7, deletion_comment = False)