[NEW OBJECT REQUEST] Since the beginning of Max, [send] was designed WRONG!
Hi,
Sorry for being that raw, I surely don't want to harm anybody. Max is an absolutely fantastic tool and i'm very happy that some great mind created, and continue to develop, this new kind of tool.
But since 11 years i'm using Max, I get every day more convinced that very important key objects have been though the wrong way from the beginning: [send] and [receive].
(And this also extend to some other objects using special symbols arguments to refer to different data, like [buffer] and [groove])
And it have consequences in the way we patch every day. I think about a more logical way those 2 objects should work. Max is about managing objects, and objects made of objects: Subpatchers and abstractions. So in this 'object (somehow) oriented' tool that Max is, [send] and [receive] (or some new [psend], [preceive] objects) should share data WITHIN A PATCHER HIERARCHY in exactly the same way that the [pv] object does. Let me explain.
Patching in max is about connecting patch cords. Great. More patch cords. And more. And more. So to clean our patch/ keep our patching style usable, we tend to do several things:
1 - Use segmented patch cords (but nicer is not necessarily more clear, specially when those patch cords are on the top of the others),
2 - use [send] and [receive] in many places...
3 - and there are others features that have been added with the time, like the great encapsulate/desencapsulate tool to help structure our patch quickly.
But then we have a big problem. Real time art, sound or video, is about doing many things at the same time… For example, i have a great sounding patch that is monophonic and now i want, not necessarily to put it in a poly~, but i want a second voice. So that subpatcher that i just encapsulated and that is doing a great process, we will copy it! We now want to have 2, 3 or 5 version of it running at the same time! Or i will launch another time the same big patcher in max, to have two of them opened!…. The very first time any new young maxer will do one of those things, it will be a big buggy mess of sends and receives sending stuff to everyone everywhere, like if a mad guy working at the old phone office would connect every lines together so that everyone would talk to everyone in a big cacophony…
So ok, let's look back at those [send] and [receive] everywhere now, oh man... We will have to change them: Either back to patch cords, making our patch messy again. Either into something like [send #0_mydata] so that now it's becoming local.** But in that last case i will not be able to continue patching with subpatcher, i will HAVE to create an abstraction. And also, guess what, that damned patch is still not working… Oh wait, i forgot a send/receive that was hidden there… let fix it… still not fully working… oh and i forgot another one! And another one. Damned [send] and [receive], you go to hell, i will never use you again!
But a fact is that there are also some other [send] and [receive] that i have to keep 'global': The one that are connecting data between the parent patcher and the subpatchers/abstractions!… So i also have to deal with all that annoying stuff while patching/debugging: "Was that [receive] local or global, i don't remember?"
And so, from the beginning, we couldn't even just put #0 all the time everywhere because that not always the way we want it to work!
As a consequence, I personally tend to AVOID TOTALLY the use of [send] and [receive], because this is the ONLY way i can be SURE that my patch will still work when i will incorporate it as a module structure in an other patch using several modules like that…
…But then, pouah, without [send] and [receive], sometimes it's a mess of patch cords, a mess of inlets and outlets everywhere… really not convenient.
NEW OBJECT REQUEST:
If we want to keep Max nicely structured in objects, while patching in an agreeable way, [send] and [receive] should only share data within a patch hierarchy in exactly the same way [pv] does. Or, new objects, something like [psend] and [preceive], should do that, and i think most people should start to use them in place of [send] and [receive]...
Here is the nice thing about how [pv] works, and why some new version of [send] and [receive] should work the same, there are two cases:
1 - As long as the parent patcher doesn't contain one [pv] with the same name than some [pv] in subpatchers/abstractions, that data in one subpatcher/abstraction will stay local, and several identical subpatchers/abstractions will not mess-up with each other!!
2 - When the parent patcher does contain one [pv] with the same name, because that's about a data that we need to share more globally in that case, then that data will be share, as expected in that case, with all theses subpatchers/abstractions!!
...So you wouldn't need to bother figuring out answers like: "hmm, i don't know if that one is - or will one day be - used locally or globally?" Because it's done automatically for you!
Also, many other objects using special symbols arguments to refer to different objects, like [buffer] and [groove], should have the same @sticktopatcherhierarchy feature.
Since the symbol argument based data in max probably rely on Hashmap in the Max C code, It might be a bit of work to program theses new features, but i think it would totally worth it!
Also, i think theses new [send] and [receive] could be some nice new UI objects, something like in the image attached bellow, so we could localise them much better in our patches, and we would have less text in our patch (avoiding the words 'send/receive').
Patching in max would become much more agreeable!
Much more tidy with the data sent only at the right places!
Without the fear of getting all of that messing-up when will launch several identical patches at the same time! or when we put it a modular structure, in a poly~, etc.
Also it would also look more smart than those numbers everywhere replacing #0. ([send 121358_mydata]…) (and again we can ONLY use #0 inside abstraction, when we don't have several levels of abstractions encapsulated, and with the annoying constant care about how global or local a given data is gonna be.)
Note about existing objects: We can't use [pv] directly to replace send/receive because the pv object needs to be banged to output the data. We can't use pattr because it would just be too painful to necessarily specify all the time the precise hierarchy where you want the stuff to be sent. Possible third part objects: No way we're gonna use third part object for so central common objects used everywhere in our patches.
Cheers,
Alexandre
Why don't you use [pvar] (not to mistake for [pv]) instead of send and receive then ? or value ? i agree that for a beginner there will be some headache figuring why what how send receive where ??!! but, i'd say, it's max learning...
as a side note, i have also problems with those objects, and nearly never use them for the sole purpose of tidying patchcords. But the "ideal" send/receive pair i'd want is different from yours... i rarely have the problem you speak of, but what i would very appreciate is if your could retrieve last value sent to receive with a bang.
pvar is quite good for what you want, though it won't go down patcher hierarchy (neither up obviously)
as someone who is verbose myself, i must say, "tl;dr." but i think i got the gist. i always recommend to people only to use send and receive in situations that are comparable to using a global variable. the namespace is global, so i think it's best to save the use of those objects for when you want to share a message globally with all patches (not just as a way of using fewer patch cords).
@Vichug:
pvar: it's patcher specific, while we need patcher hierarchic. (Plus we need to go to the inspector to specify a name each time, sort of painful)
value: needs to be banged like pv, and global like the actual send.
retrieve last value sent to receive with a bang: Just use [f ] after [receive] and bang it.
@Chritopher:
Precisely because I, like you, refuse myself to use send/receive, I then LOOSE A LOT OF TIME trying to keep my patches clear and tidy, by rearranging objects, segmenting patch cords, multiplicating inlets and outlets everytime a little subpatch need a data, etc. While using a very few send/receive would have clean that the best way in two second! That's the problem.
ye value is irrelevant in that context. Although wha tyou say about use [f] after receive doesn't help a lot, because
* i'm not always sending floats... sure i could use like a [zl reg] but then anyway,...
* there is another object needed. Sure i could have an abstraction, but then it's a dependency for a rather basic function, and i'd like to avoid that.