dict documentation is still disappointing
Max/MSP 6 and its new "dict" object has been out for 2.5 years now, and while the help and reference files for the dict family have improved they're still remarkably lacking in actually useful explanations of how to employ the new data structure. There are exactly zero tutorials, and the only mention I've found of nested dicts (as dict's hierarchical nature was one of the selling points for me) is a brief example in the dict.pack help file, which demonstrates that it is possible to nest dicts, but tells me very little about how to actually create a nested dict and nearly nothing about how to use one.
I'd like to use dict to create a library of sysex data - synth programs organized by parameter, program#, and bank - so that I can organize, compare, and eventually even edit them. This seems like the sort of thing dict is intended for (though I'm disturbed by the sense that C74 has mostly abandoned Max's sysex data management capabilities). I could do this with colls, but data hierarchy in colls requires some clumsy index-number jiggery and is thus far from ideal. Perhaps I am mistaken and dict is the wrong tool for this, as it is actually intended for some other arcane purpose which remains a mystery. Digging through the forum leaves me mainly with the impression that I'm hardly the only person baffled by what was supposedly a key feature of Max 6.
Is this whole data structure just an elaborate troll by Cycling74?
Hi !
im sorry if i misunderstood your call . The main thing is to register Dict in its main namespace before passing it to another dict . Then u can reference its instance whenever and where u wish .
Here we discovered what is possible and where are the caveats (it was surprising a bit) that force you to treat packing/nesting Dict's with special care .
https://cycling74.com/forums/how-you-build-your-dict-determines-how-you-can-access-it-why/
I denied use of dict with plain Max patching for many more reasons . i Do prefer Javascript and C for certain aspects when it comes to complex structuring and passing packages of datas . As with code its all very intuitive . but not everyone prefer this over that .
Thanks for the reply. I'm familiar with the need to name dicts (I've been using the same technique with coll for years), but I don't know how to apply that to nesting. And I read that thread and learned only two things:
1. I'm not the only person who finds the usage of dict frustratingly opaque.
2. Cycling74 doesn't seem to be very interested in addressing this.
I don't understand the reason for this. In the past Max has always been accompanied by excellent, comprehensive, clear documentation (it's one of the things that elevates it above similar tools like pd, IMO). And the dict feature was one of the biggest selling points in my decision to pay for an upgrade to Max/MSP 6. But if I can't figure out how to use it, then it's of no use to me.
Thanks for responding. The mention of a sysex library was just context (ie, why nesting is desirable); the problems I'm running into aren't specific to sysex.
What I want to do is create a nested dictionary, with three layers of hierarchy (bank, preset, parameter) for each value. I've only found two ways to do this, the dict.pack object and the replace message for the dict object.
dict.pack doesn't appear to do what I want, because you have to name all the keys explicitly and have a separate inlet for each. This doesn't scale well at all: I have 1024 parameters per preset and 99 presets per bank, so naming all of them manually isn't practical. There doesn't appear to be any way to dynamically change the keys in a dict.pack.
The replace message works if you have set keys ("replace bankA::preset01::param34 127"), but Max can't handle both changeable arguments and double colons in the same message box. What I would need is a message that looked like "replace $1::$2::$3 $4", but if you send that to dict, the message box only recognizes the first and last argument, and creates two keys named "$2" and "$3" (sic). Adding spaces between the colons and the $ just confuses Max even further.
If I use a combine object to create the replace message:
[combine A :: 1 :: 0 " " 0]
followed by
[prepend replace]
…then I can get the proper message ("replace A::1::34 127"), except that dict does not interpret the space between the parameter ("34") and the value ("127") correctly (because combine makes a single symbol rather than a list) and instead makes a key named "34 127" which has no value.
So the solution is to use combine to get the list of keys (A::1::34) and then use a couple prepend objects to attach the message "replace" and the key-list in front of the value being stored. This is a bit clumsy, but it works, and I haven't found any other way to do it. I've attached an example patcher below.
I've read all the helpfiles and the dictionary reference. The dictionary reference makes no mention of nesting, hierarchy, or the replace message, and the example of replace given in the dict.help patcher doesn't address the problem with changeable arguments. There's no tutorial for using dict objects, the whole concept of nesting barely gets a passing mention in the help files, and the examples given aren't useable for creating the kind of dynamic nesting I describe above. In other words, the documentation did not help me very much.
Note that there still appears to be some weird, confusing, potentially problematic conflict between the way dict.pack and replace address dictionaries, as described in this thread:
For which the solution appears to be to simply not use dict.pack at all.
Thanks for pointing out sprintf, I'd forgotten about that object (and it probably is a bit better for this purpose than combine). And thanks for the pattr example - the pattr objects are another thing I need to sit down and get my head around one of these days.
It's definitely possible to do some nesting without dict. There's an old trick where you can nest in coll by using something like:
index = (bank*10000000)+(preset*10000)+(parameter)
...but as you can see it gets unwieldy fast with any depth.
It's odd to me that the dict reference emphasizes the ability of dict to use named keys, as that's not something I've ever needed personally (it does make a dict easier to read, at least). When Max 6 was announced dict was explicitly mentioned as a replacement for coll, and for me the biggest apparent advantage of dict over coll so far is the ability to build hierarchical datasets. But I'd be willing to bet that most people doing that will be using dynamic keys (like in my example) rather than fixed or manually assigned keys, as in the helpfiles examples, so it would be useful to have that demonstrated.
Hopefully this discussion will be helpful for someone else at some point. If I come across more good examples of how to use dict I will post them.
Oh, and thanks as well for getting me to take another look at the Replace message. I'd written it off as a solution since it didn't do what I needed as demonstrated in the help.