tracker issue : CF-4202132

select a category, or use search below
(searches all categories and all time range)
Title:

[ANeff] ER for: final immutability

| View in Tracker

Status/Resolution/Reason: Needs Review//EnhancementRequired

Reporter/Name(from Bugbase): Aaron Neff / ()

Created: 04/26/2018

Components: Language

Versions: 13.0

Failure Type: Others

Found In Build/Fixed In Build: CF 2018 RC /

Priority/Frequency: Normal /

Locale/System: /

Vote Count: 8

This ER is for final immutability

Note: Currently 'final' blocks reference change. It does not block complex value data change. It'd be MUCH more useful if 'final' meant the data structure was immutable.

Repro:

<cfscript>
  final myStruct = {key="value"}
  myStruct.key = "changed"
  writeDump(myStruct)
</cfscript>

Actual Result: {key="changed"}

Expected Result: coldfusion.compiler.FinalVariableMutationException

Related thread: https://forums.adobeprerelease.com/coldfusionpr/discussion/111/final-doesnt-work-on-structs

Attachments:

Comments:

'final' not being immutable makes zero sense to me. +1 to make it value change, not simply reference change.
Vote by Denard S.
27412 | April 30, 2018 02:53:31 AM GMT
This works just fine, in my opinion. <cfscript> final myStruct = {key="value"} //myStruct.key = "changed" myStruct = {key="value"} // trying to reassign a final // ERROR: Final variable MYSTRUCT value change exception. on line 4 writeDump(myStruct) </cfscript> Final means you cannot reassign (and that error proves it's working fine). What you are asking for an immutable struct - something different.
Comment by Jamie P.
27602 | April 30, 2018 10:49:41 AM GMT
-1 don't think final should magically change other classes. Instead you might want mystruct = immutableStructNew({"key" : "value"}) for that sort of behaviour.
Vote by Jamie P.
27603 | April 30, 2018 10:53:47 AM GMT
Copying Sean's msg from Slack: ---- The only benefit that `final` would bring on variables really would be to make them immutable. Consider ```final var v = 1; final var s = { x : 1 }; v = 2; // not allowed s.x = 2; // allowed :( s = { x : 2 }; // not allowed``` Disallowing the "allowed" line is far more useful than disallowing that last line there ---- Thanks!, -Aaron
Comment by Aaron N.
27640 | May 02, 2018 11:18:50 AM GMT
Copying Ryan Guill's msg from Slack: ---- I agree that final making things immutable would be nicer, but I doubt very seriously that they would ever make immutable data structures[….]. This use of final is more like `const` in js, which I think has its uses, but agreed that its far less useful than immutability. ---- Thanks!, -Aaron
Comment by Aaron N.
27641 | May 02, 2018 11:21:54 AM GMT
Also noting that Ryan Guill, Brad Wood and Matt Brown agree with Jamie Purchase. So, there's mixed feelings. I agree the current behavior has its uses. BUT, I also agree that the current behavior is less useful than immutability. So this feature needs discussed a bit more. If 'final' remains as-is, then immutability must also be supported somehow. Thanks!, -Aaron
Comment by Aaron N.
27642 | May 02, 2018 11:25:26 AM GMT
While I support the addition of immutable data structures, I do NOT support the final keyword having that effect.
Comment by Kama S.
27650 | May 03, 2018 02:48:42 AM GMT
Totally agreed with Jamie Purchase, Sean (as mentioned by Aaron) and other that final should not stop someone to change internal structure. On the other side, I am not sure how a struct can be made immutable. For example, if you store a cfc object to a struct and that cfc is modified by other function/thread, I doubt struct can the track this optimally.
Comment by Awdhesh K.
27652 | May 03, 2018 05:59:22 AM GMT
Given the opinions voiced thus far, it is clear that no change is needed in the implementation. We will be closing this ticket.
Comment by Vamseekrishna N.
27653 | May 04, 2018 09:24:24 AM GMT
Hi Awdhesh, Sean said `final` _SHOULD_ stop someone from changing the internal structure. Thanks!, -Aaron
Comment by Aaron N.
27684 | May 05, 2018 03:23:05 AM GMT
Hi Awdhesh and Vamsee, I spoke again w/ Sean. We feel this is what makes sense in CF: <cfscript> s1 = {simple="simple"} final s2 = {simple="simple", complex=s1} s2.simple = "changed"//this should fail s2.complex.simple = "changed"//this should not fail s2.complex = {something="else"}//this should fail </cfscript> <cfscript> final s3 = {simple="simple"} final s4 = {simple="simple", complex=s3} s4.complex.simple = "changed"//this should fail </cfscript> Could you please consider? Thanks!, -Aaron
Comment by Aaron N.
27685 | May 05, 2018 05:14:14 AM GMT
Hi Adobe, Any feedback on my last comment? i.e. Inside a complex variable (struct/array/query/etc), simple values are immutable but complex variables are mutable. Thoughts? If that cannot be done, then the feature isn't very useful to most ppl and we'd need another way to implement that expected behavior just described. Thanks!, -Aaron
Comment by Aaron N.
27786 | May 13, 2018 09:45:31 AM GMT
*bump*
Comment by Aaron N.
27876 | May 18, 2018 09:52:50 PM GMT
*bump* This is more feedback: Brad Wood: "I think Final has little to no place in CFML. Immutable data structures [....] would have been a better way to spend our efforts." Adam Cameron: "I agree with Brad on all counts. Immutable objects would be useful. Final ones: not so much." James Mohler: "When I have something locked down, I want it to stay locked down." Sean Corfield and I agree w/ the above and proposed: <cfscript> s1 = {simple="simple"} final s2 = {simple="simple", complex=s1} s2.simple = "changed"//this should fail s2.complex.simple = "changed"//this should not fail s2.complex = {something="else"}//this should fail </cfscript> <cfscript> final s3 = {simple="simple"} final s4 = {simple="simple", complex=s3} s4.complex.simple = "changed"//this should fail </cfscript> See? We are not asking for final to make a complex object immutable. We are asking for final to make a complex object's simple values immutable. Related discussion: https://coldfusion.adobe.com/2018/04/final-immutable-or-not/ Thanks!, -Aaron
Comment by Aaron N.
29045 | June 15, 2018 05:30:08 AM GMT