Really hard to judge for a user, since the “non-numeric key-value” feature is still undocumented in both the Reference Manual and online help.
As far as REPLACE is concerned, moving the top level item to the end of the top level list isn’t really a problem as long as items within the list are referenced by their 1st sub-items (= keys).
Still it seems odd that the relevant top level item is unnecessarily (from a functional point of view) moved within the top level list.
As for INSERT, I wonder if it should actually be a legal operation when referencing a top level item by its 1st sub-item as a key. I for one can’t think of any obvious meaning.
Again, it’s undocumented. And to me it seems odd.
I must admit, though, that in my example I misspelled “attribute 4”.
Much as the development team’s effort to implement dictionaries is to be appreciated, they are not a separate (primitive) type (yet?).
In my view this is becoming a bit of an issue once (pre-existing) primitive operations, when handling the informal sub-type, will behave fundamentally differently from the generic case.
The list type is very flexible, and lists may be interpreted as n-dimensional tables, sets, and many more. Constructing a practical sub-type approach now may facilitate the introduction of new subtypes in the future.
I think this is a point on which our pedagogic goals may conflict with the goals of a production programming language. In particular, we'd like to be able to teach an Algorithms and Data Structures (CS 2) course, in which students see how any data structure you want can be implemented in terms of a simple aggregate type. Indeed, I was dubious about implementing primitive nonnumeric indices altogether, rather than just having users implement association lists. (Our dictionaries are association lists, if you examine the structure, but with some syntax on top and with fast lookup.)
So I think that primitive hash tables, primitive binary search trees, primitive skip lists, primitive B-trees, primitive red-black trees, and so on, would be totally self-defeating. Those things belong in libraries, if anything, where users can read the Snap! code that implements them. (See scratch4cs.xml, the advertisement for BYOB3 that we sent the Scratch Team to try to convince them to add our stuff to Scratch.)
This is especially true with modern computers, for which cache geometry can matter more than asymptotic algorithm behavior. That makes the details of the code even more crucial.
Perhaps we’re not so far apart. I agree there’s nothing wrong with libraries, and not every possible data type or operation needs to be a primitive.
IMO - and here’s where I we may dissent - the standard for primitives ought to be universally high; if not, the programming language as a whole will be contaminated.
E.g. in the case of dictionaries, Snap! “doesn’t make any promises about order within the list”. This wouldn’t be an issue if “dictionary” were a regular data type, as all primitive functions would have been re-engineered to work with this characteristic, But as it is now, dictionaries are considered ordinary lists by most functions. One consequence of this is that the “=?” predicate will not always work correctly with dictionaries, as will any functions building on “=?”.
The Snap! development team have chosen not to define dictionary as a primitive type, but rather as a semantic layer on top of the list type. Then, by the same token as with sets, hash tables, binary search trees, and so on, instead of some (but not all relevant) primitive functions being bent to accommodate the informal sub-type, a set of specialized library functions ought to be created, I think.