Hi,
Maybe I'm late, but I try to answer to the questions that have been raised about the list stuff, for two reasons: first, in case this is helpful to those who asked, and second, so that those who know more than I do can correct me where I'm wrong or show me if the whole thig can be stated in a different way.
This is my understanding of how lists and messages interact.
with a number atom, so
[1( is equivalent to [float 1(
[1 2 3( is equivalent to [list 1 2 3(
Another way of stating this (perhaps more correct??) may be that a message cannot start with a number atom, i.e. it always starts with a symbol atom which is its identifier, so if you type "1" into a message box (or a text file read by [textfile]) the message actually generated has an implicit (or automatically added) "float" or "list" identifier - Which of the two interpretations is more correct is, from my point of view, just an implementation matter.
the type of their only element, so
[list foo( is equivalent to [symbol foo(
[list 1( is equivalent to [float 1( - which is equivalent to [1(
exactly the same way. The fact that some signal objects such as
[*~]
will not accept "list <somenumber>" complaining they have no method for list, is in my opinion a BUG. Somebody just forgot to do the needed conversions at the inlets. I remember someone agreed with me on this.
Whether the conversions are made at outlets or inlets of objects is another implementation matter that I think should be transparent/irrelevant to the user.
[bang( is equivalent to [list(
A message with identifier "bang" _and_ arguments, such as
[bang 1 2 3( or [bang foo bar(
is equivalent to just "bang". At least, [list] objects and [route] treat it as such and ignore its arguments.
well documented, more pragmatical (maybe) than elegant, but pretty consistent, which seems to be:
a. If the arguments are all symbolic atoms, they match the message identifier
b. If the arguments are all numbers, they are interpreted as the first element of a list starting with a number; that is, any list starting with a float that matches an argument, will go out through the corresponding outlet (with the matching float stripped; i'll go into stripping later). Any non-list message will go unmatched.
c. You can use "symbol", "float", "bang" or "list" as arguments of [route]; consistently with what stated at point (a), a symbol (which is a message whose identifier is "symbol") will match the "symbol" argument, etc.
d. Since "symbol foo" and "list foo" are perfectly equivalent messages, it won't matter how you write them, they both mean the same to [route]. So this raises a potential ambiguity: What do you expect to happen with
[symbol foo( | [route symbol list]
? This is both a (one element) list and a symbol. Well, this will match the "symbol" argument (i.e. be output at the first outlet) The same would happen with [list foo(, since it is exactly the same.
Consistently, though surprisingly at first sight, this:
[list foo( | [route list]
will output the list to the "unmatched" (second) outlet, since the message is recognised as a symbol. For the same reason,
[list 1( | [route list]
will go unmatched, since the message is recognised as a float.
That is, "being a float" or "being a symbol" takes priority over "being a one-element list".
This is (i suppose) for the sake of being able to distinguish symbols from floats and from lists. Imagine it wouldn't be so. You couldn't expect [route] to distinguish "list 1" from "1" or "float 1" since this would break the equivalence rules; but then, it would match floats and symbols as lists and you couldn't even distinguish floats from symbols (they would all be one-element lists).
Well maybe it was more obvious than i've made it: the specific takes priority over the general, that's it.
e. If you mix numeric arguments with non-numeric arguments, then the symbolic arguments match a list starting with them as symbol, i.e.
[list foo bar( | [route 1 2 foo]
will match foo, and output "bar" at the third outlet, while
[foo bar( | [route 1 2 foo]
will go unmatched.
I don't think this is documented anywhere and it is rather questionable whether one can expect it... however it is kind of consistent to what it does with floats.
f. This was about matching. Now about the "stripping" behaviour of [route]. Here I do think it has some arbitrary aspects, that is it could behave differently than it does and still be consistent (or even more consistent?), or maybe it's me who don't see the reasoning that make its behaviour the "only consistent possible one" (not that it needs be). Well, here it is:
"symbol", "bang", is matched, it is stripped. For example:
"foo bar 1 2 3" ->[route foo]-> "bar 1 2 3"
-- an empty message will be converted to a bang -- a message starting with a number will become a list (or you may say it already implicitly is)
For example:
"foo" ->[route foo]-> "bang"
"foo 1 2 3" ->[route foo]-> "list 1 2 3" (or "1 2 3" which would be
the same)
"bang" ->[route bang]-> "bang"
since "float 1" becomes "1" which is identical to "float 1")
Here comes the (imho) questionable part:
That is:
"list foo bar" ->[route list]-> "foo bar"
"symbol foo" ->[route symbol]-> "symbol foo"
I personally think that either both or none should be stripped. My personal experience kind of suggests to me that NOT stripping the symbol identifier is probably more desirable (dunnow if it can be "proven" to be so), so I think not stripping the list identifier would be more consistent. Then a simple and general rule could be stated: "All the special identifiers (list, symbol, float, bang) are stripped, while all other identifiers are not"; now you have to exclude list.
I may guess that at some point of history the [list trim] object didn't exist, so [route list] was the only way of stripping a list identifier and converting a list to a non-list?
number is matched, e.g. [1 2 3(->[route 1], both the "list" identifier _and_ the matched first element are stripped, that is:
"list 1 foo bar"->[route 1]->"foo bar", not "list foo bar"
Obviously when the second element is also a float, the list identifier cannot be stripped (or you may say, stripping it is irrelevant). The result is still a list.
performing with it the operations they have to perform. This includes [list length] which indeed once upon a time didn't. That is, [foo 2 3 4(--[list length] gave 3. Now it gives 4, consistently with the rule that the message is converted to a list prior to anything, as with all other list objects. This was a break of backward compatibility (in the case of patches relying on [list length] to count the number of arguments of a non-list message) for the sake of consistency.
I'm not sure exactly where all this information comes from. I think the most part is stated in the "all about data types" patch, or can be somewhat deduced from there; the rest I guess I inferred from tests. I never found any behaviour of Pd that does not match this model, except the abovementioned fact that signal objects (which are supposed to accept floats in their signal inlets), don't accept one-float lists (which are supposed to be equivalent to floats according to this model), and I am not the only one to think this is a bug (note they do accept the one-element list in an inlet if the presence of a float argument converts that inlet to a non-signal inlet)
This whole discussion totally ignores POINTERS (thery are yet another type of atom, aren't they?) because I don't know anything about them. If anybody can fill this gap that would be appreciated (by me at least lol).
Hope this message is of some use.
cheers m.
--- On Fri, 2/5/10, Matteo Sisti Sette matteosistisette@gmail.com wrote:
From: Matteo Sisti Sette matteosistisette@gmail.com Subject: Re: [PD] [list] output To: "PD list" pd-list@iem.at Date: Friday, February 5, 2010, 7:56 PM Hi,
Maybe I'm late, but I try to answer to the questions that have been raised about the list stuff, for two reasons: first, in case this is helpful to those who asked, and second, so that those who know more than I do can correct me where I'm wrong or show me if the whole thig can be stated in a different way.
This is my understanding of how lists and messages interact.
- The "float" or "list" identifiers are implicit when a
message starts with a number atom, so
[1( is equivalent to [float 1(
[1 2 3( is equivalent to [list 1 2 3(
Another way of stating this (perhaps more correct??) may be that a message cannot start with a number atom, i.e. it always starts with a symbol atom which is its identifier, so if you type "1" into a message box (or a text file read by [textfile]) the message actually generated has an implicit (or automatically added) "float" or "list" identifier - Which of the two interpretations is more correct is, from my point of view, just an implementation matter.
- One-element lists are equivalent to symbols or numbers,
depending on the type of their only element, so
[list foo( is equivalent to [symbol foo(
[list 1( is equivalent to [float 1( - which is equivalent to [1(
- Equivalent means that ALL objects in Pd will treat such
messages exactly the same way. The fact that some signal objects such as
[*~]
will not accept "list <somenumber>" complaining they have no method for list, is in my opinion a BUG. Somebody just forgot to do the needed conversions at the inlets. I remember someone agreed with me on this.
Whether the conversions are made at outlets or inlets of objects is another implementation matter that I think should be transparent/irrelevant to the user.
It is a bug.
I'm concerned mainly with documentation, and for an object like [list], I think it's best to say that it always outputs messages with the "list" selector, but also say how the message "list" and one-element lists are handled by objects in Pd. (The paragraph in [pd list trim] in list-help.pd already goes in this direction, it just needs to be expanded.)
-Jonathan
Jonathan Wilkes escribió:
I'm concerned mainly with documentation, and for an object like [list], I think it's best to say that it always outputs messages with the "list" selector,
Except [list trim], of course
Matteo Sisti Sette wrote:
Jonathan Wilkes escribió:
I'm concerned mainly with documentation, and for an object like [list]
actually, there is no objectclass "list". what you get with [list] is an instance of the objectclass "list append" (and yes, this is an objectclass name with a space in it)
, I think it's best to say that it always outputs messages with
the "list" selector,
Except [list trim], of course
almost.
[bang( | [list append] | [list trim] | ??
gmadsr IOhannes
IOhannes zmölnig escribió:
Matteo Sisti Sette wrote:
Jonathan Wilkes escribió:
, I think it's best to say that it always outputs messages with the "list" selector,
Except [list trim], of course
almost.
[bang( | [list append] | [list trim] | ??
The answer is "bang". Or "list", that is the same.
The question shouldn't be whether a message has or doesn't have the list identifier: the question should be what the message is. "list foo" and "symbol foo" are the same message; whether they are represented in one or the other way is (or should be) a matter of internal representation, irrelevant to the user. "list foo" _is_ a symbol (and it _is_ a list). "symbol foo" _is_ a list (and it _is_ a symbol). The same holds for "list" and "bang", which both represent the empty list, or the bang which is the very same thing.
So, [bang(->[list append] appends the empty list to the empty list, producing an empty list, or a bang, that is the same. Then "list"->[list trim], or "bang"->[list trim] that is the same, tries to strip the list identifier from the empty list, obtaining an empty message, which again is equivalent to a bang (a completely empty message does not exist), so the output of your example is "bang", or "list", which is the same. Indeed if you feed it to a [print] it will print "bang". Is it 'written' as "list" or as "bang"? Who cares? It won't ever do any difference in any patch, and if it does, it is because of some bug.
--- On Sat, 2/6/10, IOhannes zmölnig zmoelnig@iem.at wrote:
From: IOhannes zmölnig zmoelnig@iem.at Subject: Re: [PD] [list] output To: "Matteo Sisti Sette" matteosistisette@gmail.com Cc: "Jonathan Wilkes" jancsika@yahoo.com, "PD list" pd-list@iem.at Date: Saturday, February 6, 2010, 1:49 PM Matteo Sisti Sette wrote:
Jonathan Wilkes escribió:
I'm concerned mainly with documentation, and for
an object like
[list]
actually, there is no objectclass "list". what you get with [list] is an instance of the objectclass "list append" (and yes, this is an objectclass name with a space in it)
I should have said [list append] since I'm talking about documentation. I'm not changing the docs in any way to make it look like there is a sixth object class (actually list-help.pd currently says there are four, which is wrong).
I think it's best to show the relationship among the list objects as the fact that they can all be called by starting with the "list" selector in an object box, and the first argument determines which object class gets instantiated. (Shortcuts being [list] with no args or with the first arg being a float -> [list append], as well as the implicit list [1 2 3] -> [list append]).
Then one subpatch for each object class (just as the current help for list).
-Jonathan
--- On Fri, 2/5/10, Matteo Sisti Sette matteosistisette@gmail.com wrote:
From: Matteo Sisti Sette matteosistisette@gmail.com Subject: Re: [PD] [list] output To: "PD list" pd-list@iem.at Date: Friday, February 5, 2010, 7:56 PM Hi,
[...]
This whole discussion totally ignores POINTERS (thery are yet another type of atom, aren't they?) because I don't know anything about them. If anybody can fill this gap that would be appreciated (by me at least lol).
[route] will always send a pointer to the rejection outlet.
A list with one pointer element will trick [route]:
[traverse some-canvas, bang( | [pointer] | [list append] | [route symbol]
In the patch above it will match the symbol outlet. Now try hooking that symbol outlet up to some object like [print], or a symbol box, save all your important patches, and click the message box...
-Jonathan
Jonathan Wilkes escribió:
Now try hooking that symbol outlet up to some object like [print], or a symbol box, save all your important patches, and click the message box...
I kind of guess what's gonna happen :)
Hallo, Jonathan Wilkes hat gesagt: // Jonathan Wilkes wrote:
A list with one pointer element will trick [route]:
[traverse some-canvas, bang( | [pointer] | [list append] | [route symbol]
Is this crasher bug already reported on Sourceforge? You can crash Pd without the [list append] here, btw. and also by replaceing the [print] with a [set $1(--->[ ( message box construction.
Anyway to "route" pointers one usually uses the [pointer] object. For pointers it's useful to know what type of [struct] they belong to, so something like [pointer event time score] will dispatch your event, time and score pointers accordingly through their respective inlets.
Frank
--- On Sun, 2/7/10, Frank Barknecht fbar@footils.org wrote:
From: Frank Barknecht fbar@footils.org Subject: Re: [PD] [list] output To: pd-list@iem.at Date: Sunday, February 7, 2010, 12:48 PM Hallo, Jonathan Wilkes hat gesagt: // Jonathan Wilkes wrote:
A list with one pointer element will trick [route]:
[traverse some-canvas, bang( | [pointer] | [list append] | [route symbol]
Is this crasher bug already reported on Sourceforge? You can crash Pd without the [list append] here, btw. and also by replaceing the [print] with a [set $1(--->[ ( message box construction.
Anyway to "route" pointers one usually uses the [pointer] object. For pointers it's useful to know what type of [struct] they belong to, so something like [pointer event time score] will dispatch your event, time and score pointers accordingly through their respective inlets.
I've never actually used [route] with a pointer in practice. It could be useful in teaching, however, to show how the standard messages are routed according to their selector (as far as I can tell, pointer messages have the selector "pointer", right?).
In Chapter 2.9.1, the Pd manual states: 'The pointer data type is also integrated into pipe-fitting objects such as "pack", "unpack", and "route".'
So it seems like [route] should handle pointers just as it does other the
other "standard" message types.
-Jonathan
Hallo, Jonathan Wilkes hat gesagt: // Jonathan Wilkes wrote:
In Chapter 2.9.1, the Pd manual states: 'The pointer data type is also integrated into pipe-fitting objects such as "pack", "unpack", and "route".'
So it seems like [route] should handle pointers just as it does other the
other "standard" message types.
Yeah, generally it does, but obviously there is a serious bug. All crashes are serious bugs. Anyway all [route] would be able do with pointers is route them according to selector. But as all pointers share the same selector, this isn't actually very useful. Here the [pointer] based routing comes into play.
Frank
--- On Mon, 2/8/10, Frank Barknecht fbar@footils.org wrote:
From: Frank Barknecht fbar@footils.org Subject: Re: [PD] [list] output To: pd-list@iem.at Date: Monday, February 8, 2010, 9:32 AM Hallo, Jonathan Wilkes hat gesagt: // Jonathan Wilkes wrote:
In Chapter 2.9.1, the Pd manual states: 'The pointer data type is also integrated into
pipe-fitting objects such as "pack", "unpack", and "route".'
So it seems like [route] should handle pointers just
as it does other the
other "standard" message types.
Yeah, generally it does, but obviously there is a serious bug.
It generally does what?
-Jonathan