outlet_anything() or outlet_list()

MIB's icon

As far as I understand outlet_list(), the t_atom that is send through the outlet MUST to begin with an int or float. In my case I have a t_symbol, so I used outlet_anything() where I do something like this:

outlet_anything(x->anythingOut, gensym("hello"), 6, data);

where data is a t_atom with 6 elements (ints and floats).

When I compile and put it into Max and have a "route hello", everything works fine.

I then decided that I needed another layer for routing in Max so I pushed the gensym("hello") into my t_atom data structure and wrote my outlet like this:

outlet_anything(x->anythingOut, gensym("here"), 7, data);

This is where things break in Max and I don't know why. I am trying to route things like so:

[route here]
|
|
[route hello]

However, the routing fails although I see that the correct message is output when I print it to the window, or put it in a message box… odd thing is, once I select the text in the message box and then unselect, the routing of the contents of said message box works fine… this leads me to belief that something is formatted wrongly somewhere. I just can't figure out what or where…

Thanks for any pointers (and I hope I made at least a bit of sense here).

Timothy Place's icon

A legal list should begin with a number (int or float) and then arguments of any type.

It is possible to coerce Max into believing that an array of atoms is a list when it begins with a symbol, but the behavior of Max as a result of sending these illegitimate lists around is undefined (bad things may happen).

Luigi Castelli's icon

@MIB: AFAICT your understanding of the difference between outlet_anything() and outlet_list() is correct. If you are expecting different results maybe posting some code could help see what is really going on.

- Luigi

Peter Castine's icon

Just to add to Timothy's point: it's a bit boring that lists have to begin with a numeric value (and seems like a really weird rule when coming from a LISP-related language). And the fact is that there is no problem at all in using outlet_list() with a string of atoms of which the first is a symbol. At least as far as that goes.

The surprising stuff starts to happen when you pass things around different objects. A lot of objects will sniff the string of atoms coming in (or just before they're going to be sent out) and massage them to follow "proper" (if somewhat jejune) Max conventions.

It can be even more surprising when objects like [scramble], [zl scramble], or [lp.crabelms] treat real "lists" and real "messages with arguments" identically. But they do (and this is convenient, and the documentation of two of these objects treats the two different structures synonymously).

So the long and short of it (and I have learned this the hard way)-: is that you ignore the Max distinction between "real" lists and "fake" lists at your own peril. The distinction is ingrained into so many Max objects that life makes more sense when you follow suit.

This idiosyncrasy is the one aspect of Max for which I've never found a really satisfactory explanation. Pretty much every other peculiarity in Max (right-to-left, hot and cold inlets, etc., yadayada) actually makes a lot of sense once you grok the logic. The list-must-start-with-number rule seems just plain arbitrary.

I daresay it seemed like a good idea at the time.

MIB's icon

Ok, so I'm at least understanding the SDK ;)

@Tim and Peter: thanks for clarifying. although I am really curious now as to why that design choice was made in the first place...

I will try and replicate the issue in a scaled down example and post again. Thanks so far for the input!!

MIB's icon

My issue is resolved and it had nothing to do with outlets/outlet-types and everything to do with me messing up my pointers…
I was storing the t_symbol for my outlet_anything() as a global variable and missed to declare it as a pointer like so t_symbol * mySymbol… I need more testing, but this seems to have been the culprit!

Thanks for the help and info, as always I learned a lot!