accessing and processing arrays
hi, sorry for the noob question, but i'm wondering how are people using array objects?
i'm a bit befuddled by them in a visual patching environ... in coding languages for example we don't need a separate library/function for things like 'array.at()' we just remember the name we defined the array with originally... and if 'array.at' can't access an array remotely by name, then why is it any different from zl.mth?
but in Max, i notice that arrays do have a unique ID/name:

is there a way to access this remotely? (the same way we can with 'dict' and 'jitter matrix' names that all follow this same naming format?) is the only way to discretely name an array, to use it within 'dict'? but then why if it's named within 'dict', can't other array objects have access to that name?
i may also be coming from an extreme place of ignorance as i'm one of the few people who doesn't tend to use javascript in Max(i DO like js, i just don't come to the Max environ with the intent to 'code' so much within it), is the main benefit of the new 'array' object in javascript? (can you access array names more discretely there?)
perhaps even if some experts who use 'dict' and javascript could help me understand how the new objects dealing with arrays can be used most effectively with a general discussion here, it'd also help me wrap my head around it. i AM excited about arrays, because i've been using a buffer~ object for decades now 😆... i just feel very confused about how they can be used effectively in a visual environ...
here's some more explanation of my confusion... i envisioned that i could process similar information into different dicts remotely by the new array objects... but it seems like i still need to do alot of work to parse all the information out of one dict into another(which brings me back to the question, why wouldn't i just use all the 'zl' objects to process them and then 'dict' to store... if there isn't a generalized memory space for arrays?)

(^and separately, the usage of 'array.map' as described in its helpfile really trips me up... you can see in the pic above, i just guess at what it's doing internally... i realize it saves me from creating those objects, but it feels like a strange object-design to connect an object's outlet back into one of its own inlets(let alone, into a cold-inlet, and yet it will always respond in that context of usage as if sent through a hot-inlet anyways) 😅)
please let me know any tricks and tips you have on using arrays, and even just processing arrays within dict in different ways(also, if these tips involve javascript, that's great too... i'm probably missing a whole world of ease there)
maybe this will shed some light:
Thank you, Rob(tho the video still makes me feel like visual-paradigm is getting more awkward for stuff like this, and i should get more heavily into javascript, it helps to see how it might be done)this does indeed shed light, much appreciated 🙏
I also find working in Javascript much simpler for these sorts of data structures. However, there are lots of people for whom "just use Javascript" represents a conceptual hurdle which they don't have the time or energy to overcome. Or you might have timer-thread needs for arrays and strings which can't be satisfied by JS. Or you need a solution which doesn't involve external files. Or...
In any case, we hope that these objects, and some of the under-the-hood changes we made to support them, will simplify some tasks in Max, and make certain complicated tasks more realizable. Good luck, and we're happy to answer questions as they come up.
FWIW, for timer thread access to arrays and strings in code, I will definitely be adding them to Scheme for Max (which can run code in the timer thread), but I don't think there are any SDK examples yet. Jeremy and Rob, do you have any sense of when these will be available in the C SDK?
thanks!
I can cook up some example code sometime soon, like early next week. There's nothing particularly new or exotic if you are familiar with how dictionaries are used. The underlying classes t_atomarray and t_string have been around for many, many years, and the usage is similar to sending t_dictionary objects out into the world. But there are a few things to keep in mind, so keep an eye out!
That said, we have some nice syntactical sugar for quickly rolling up new array. and string. objects, and that's not available to 3rd party devs quite yet.
Iain wrote:
Jeremy and Rob, do you have any sense of when these will be available in the C SDK?
I too would love to see c-api access to Max Strings and Arrays, especially considering that these types map well to corresponding types in wrapper languages.
Here's a little kit to get started with strings and arrays. You'll need to hack your max-sdk a little bit to make it work, but it's a beginning until we've had a chance to do a proper 8.6 SDK release.
Replace the max-linker-flags.txt in your max-sdk-base/script
folder with the provided file, and then you should be able to build these using your standard cmake process. They don't do anything impressive, but they should demonstrate the basics.
This has been a useful exercise to see what is already being exported for third party use and what isn't. When we get a new SDK out, we'll update the exports and headers to make some of this a little less awkward, so consider this stuff pre-release and subject to change.
This sample code is not thread-safe. If you want your objects to be threadsafe, for now you'll need to add your own mutex-y stuff around access to your internally maintained objects (and don't forget to unlock before using outlet functions) -- you don't want your internal array to be modified on both the UI and timer threads simultaneously, for instance.
At some point we will release our support API for strings and arrays. It handles a lot of what's being done manually in these samples -- conversion of basic types to arrays/strings & output, as well as inlet creation and some other handy stuff -- while ensuring thread safety. All of our internal objects are built using that framework, but it's not ready for external use yet.
Here's a little helpfile:
Thanks for your interest, and we'll keep you posted as new materials are made available.
Awesome, thanks Jeremy. A quick question about the thread safety issue: In Scheme for Max I handles this by forcing the object to only run in one thread. All incoming messages are promoted/deferred before processing (depending on the thread chosen) I am thinking from what you are describing that this should mean I am fine without thread protection on array access - or do you mean one needs thread protection in case some other object is accessing the array in an another thread? (And would that not potentially result in a block?)
thanks
a little kit to get started with strings and arrays... consider this stuff pre-release and subject to change.
Thank You!
Awesome, thanks Jeremy. A quick question about the thread safety issue: In Scheme for Max I handles this by forcing the object to only run in one thread. All incoming messages are promoted/deferred before processing (depending on the thread chosen) I am thinking from what you are describing that this should mean I am fine without thread protection on array access - or do you mean one needs thread protection in case some other object is accessing the array in an another thread? (And would that not potentially result in a block?)
arrays have names, so some user could determine your array's name and do stuff to it at any thread level, in theory.
If you don't care about that (ab)use case, then your deferral of incoming messages should take care of any threading issues. Good citizens in the array/string world need to clone incoming objects before doing anything to them (it's like the rule that you may not modify the atoms in an incoming argc/argv A_GIMME method), so if everyone is playing by the rules, you should be in good shape (apart from the exception mentioned above).
By the way, I would recommend cloning incoming arrays before you defer them. Imagine the situation of a timer-thread input to your object, which input is freed immediately after the outlet call. If you simply defer the array name and try to resolve it on the main thread, it won't resolve. Another option would be to resolve it when it arrives and call object_retain()
(or use that arrayobj_findregistered_retain()
in the sample code) to prevent it being freed until you've had a chance to clone it on the main thead (and don't forget to call object_release()
or that object will never go away).
Here's a little kit to get started with strings and arrays. You'll need to hack your max-sdk a little bit to make it work, but it's a beginning until we've had a chance to do a proper 8.6 SDK release.
Thanks very much!