UUIDs.. you know you want them
Posted: Fri May 03, 2013 11:07 am
Posting the UUID proposal discussed on the dev list here as it's a more open forum:
UUID proposal
For those that haven't been listening in on the lcVCS discussion there are many issues with LiveCode IDs that make them an unreliable solution for object references when merging stackfiles. They also happen to have significant namespace issues with referencing image IDs via icons. An example of this can be seen when using the icon picker in the IDE. Quite often the icons shown in the icon picker are not the right ones because they are out of context. There also must be other issues too because for some reason the revGeometry library uses a (fairly fragile) unique id based on the milliseconds but I haven't investigated why that was deemed necessary.
To cut a long story short I think we need to transition to a UUID rather than a sequential integer ID for our controls.
The current situation is stacks have objects with unique IDs in the scope of the stack. For a VCS we still don't need unique IDs of any greater scope than the stack. We don't care about ID collisions outside the stack scope but we do need to ensure there are no ID collisions when working on the same stack in a distributed environment. So the current IDs that the engine has assigned are all fine until we want to start working in a distributed way. At that point the problem is not the current IDs in the stack it's the new ones. So a scheme that changed the way that IDs were assigned to objects when they were created wouldn't need to change existing IDs.
This is all quite helpful because it would be very hard/impossible for us to create an ID scheme that was unique in a greater scope than the individual stack anyway because of the conundrum of what to do when a stack is cloned. Obviously there would be many properties that rely on the ID so just having the engine change all the IDs silently will break the cloned stack. So while UUIDs are globally unique we can only 100% reliably say that a rugged UUID will only ever refer to a single object in the stacks in memory.
All we need then is for ID to be upgraded to a 128 bit integer (which is what UUID is) and be generated using one of the UUID schemes moving forward. Then for convenience we could have ID object references accept either a UUID form or a number form of the same integer.
When getting ID object references we would either use some adjective to get the UUID form if we wanted that or the engine would just return the UUID form when we request IDs. I'm not convinced that anyone would have code that relies on the ID being returned as an integer so I'd prefer the latter because it would really deprecate integer IDs from the language but I've left the adjective in the code examples because I think it will be easier for people to swallow....
An example of how this would work for an object created before the change
Let's say card 1 of a stack is currently 1002.
After the change:
the ID of card 1 is 1002 is true
the unique ID of card 1 is 00000000-0000-0000-0000-0000000003EA is true
because baseConvert(1002,10,16) = 3EA
Also..
set the ID of card 1 to 00000000-0000-0000-0000-0000000003EA
the ID of card 1 is 1002 is true
And...
set the ID of card 1 to 1002
the unique ID of card 1 is 00000000-0000-0000-0000-0000000003EA is true
Now the above example is obviously not a real UUID but it really doesn't matter as long as everything works does it. Over time these legacy IDs fade into history but if a developer really wanted to clean them out of their stacks they could do so quite easily.
For objects created after the change
The object is assigned a globally unique ID using one of the UUID schemes when it's created so no matter how many developers are working in parallel on the same stack there won't be an ID collision.
UUID proposal
For those that haven't been listening in on the lcVCS discussion there are many issues with LiveCode IDs that make them an unreliable solution for object references when merging stackfiles. They also happen to have significant namespace issues with referencing image IDs via icons. An example of this can be seen when using the icon picker in the IDE. Quite often the icons shown in the icon picker are not the right ones because they are out of context. There also must be other issues too because for some reason the revGeometry library uses a (fairly fragile) unique id based on the milliseconds but I haven't investigated why that was deemed necessary.
To cut a long story short I think we need to transition to a UUID rather than a sequential integer ID for our controls.
The current situation is stacks have objects with unique IDs in the scope of the stack. For a VCS we still don't need unique IDs of any greater scope than the stack. We don't care about ID collisions outside the stack scope but we do need to ensure there are no ID collisions when working on the same stack in a distributed environment. So the current IDs that the engine has assigned are all fine until we want to start working in a distributed way. At that point the problem is not the current IDs in the stack it's the new ones. So a scheme that changed the way that IDs were assigned to objects when they were created wouldn't need to change existing IDs.
This is all quite helpful because it would be very hard/impossible for us to create an ID scheme that was unique in a greater scope than the individual stack anyway because of the conundrum of what to do when a stack is cloned. Obviously there would be many properties that rely on the ID so just having the engine change all the IDs silently will break the cloned stack. So while UUIDs are globally unique we can only 100% reliably say that a rugged UUID will only ever refer to a single object in the stacks in memory.
All we need then is for ID to be upgraded to a 128 bit integer (which is what UUID is) and be generated using one of the UUID schemes moving forward. Then for convenience we could have ID object references accept either a UUID form or a number form of the same integer.
When getting ID object references we would either use some adjective to get the UUID form if we wanted that or the engine would just return the UUID form when we request IDs. I'm not convinced that anyone would have code that relies on the ID being returned as an integer so I'd prefer the latter because it would really deprecate integer IDs from the language but I've left the adjective in the code examples because I think it will be easier for people to swallow....
An example of how this would work for an object created before the change
Let's say card 1 of a stack is currently 1002.
After the change:
the ID of card 1 is 1002 is true
the unique ID of card 1 is 00000000-0000-0000-0000-0000000003EA is true
because baseConvert(1002,10,16) = 3EA
Also..
set the ID of card 1 to 00000000-0000-0000-0000-0000000003EA
the ID of card 1 is 1002 is true
And...
set the ID of card 1 to 1002
the unique ID of card 1 is 00000000-0000-0000-0000-0000000003EA is true
Now the above example is obviously not a real UUID but it really doesn't matter as long as everything works does it. Over time these legacy IDs fade into history but if a developer really wanted to clean them out of their stacks they could do so quite easily.
For objects created after the change
The object is assigned a globally unique ID using one of the UUID schemes when it's created so no matter how many developers are working in parallel on the same stack there won't be an ID collision.