Hello everyone,
We’re getting pretty close to finished with our implementation of dictionaries for App Inventor. With this new datatype though we have some opportunities to revisit some design decisions and think about how to make use of this new datatype in App Inventor. Mainly, I am thinking about the Web component’s JsonDecode and XMLDecode blocks. At present, these blocks return an associative list (alist) when they encounter a dictionary-like object. Of course, we could make it so that these methods instead return Dictionary objects rather than Lists. This has the benefit of improved app performance (dictionaries are amortized constant speed lookup versus worst case linear time in alists), and since dictionaries render as JSON they make interoperating with JSON services easier. The dictionary blocks also include some advanced blocks in the form of the get/set using a key path. Dictionaries and alists are also interchangable at the block level. For example, the lookup in pairs (list) block will accept either lists or dictionaries, and similarly the get blocks in the dictionaries drawer will work with alists.
Here are the possible options I’ve thought about, and I encourage any additions or suggestions:
Option 1.
Make the JsonDecode/XMLDecode blocks return dictionaries instead of alists.
This would be the easiest change since it wouldn’t require any new blocks added to the language and we wouldn’t need to bump the Web component’s version number. These methods already return Object, so no API level change is required.
Option 2.
Rename the existing functions to ...AsLists
and introduce new methods by the same name that return dictionaries.
This option would have the existing versions of the methods renamed to indicate that they will return lists. We would introduce new methods under the same name guaranteed to return dictionaries like in option 1. This allows people who would prefer the alist behavior to use the original functionality whereas most people will probably benefit from the new method (same as option 1).
Option 3.
Add a parameter to the methods to control whether dictionaries or alists are returned.
This allows us to not introduce new blocks, but still requires an API change and is not backward compatible with older companions that will have the old method signature.
Option 4.
Add a property on the Web component that controls the type.
This allows us to not change any of the method signatures (like option 1), but does require a bump in version due to the addition of a new property. One possible downside of decoupling the control over the behavior from the method is people might not realize that this option is available or what it’s for. It’s also set for every decode call by the web component, which may or may not be desired (unlike option 2 where it’s on a per-invocation basis). The benefit is that it allows the user to choose the parsing behavior similar to option 2.
Personally, I am for option 1 or 2, with a slight lean toward option 2 for people who might really need backward compatibility. This is also motivated by a desire to redesign the structure returned by XMLDecode, which will be a breaking change (and therefore why option 2 is preferable).
Regards,
Evan