@FFW I sort of thought you meant something like that but wasn't sure. I don't think message rate stuff is flattened and can't find anything in the source but I don't really know, I just don't see much advantage in doing it with how slow and simple message rate is. Thanks for the clarification.
-
"Return to caller" (followup from "symbols explicit")
-
@oid said:
@ddw_music In pd there is no instruction pointer so never any need to return or backtrack or goto.
You absolutely must backtrack in the case of any object that has multiple outputs. Backtracking is most straightforwardly done with a stack.
A stack is only a data structure that defines two operations: add something new at the end (push) and take the last item off of the end (pop) -- last in, first out. "Stack" doesn't define what it should be used for. It may be data, as in FORTH; it may be execution frames; can be anything.
If necessary, I could find it in the source code later, but let's assume that Miller Puckette is no fool, and he knows that tree traversal is best done with a stack, and that he isn't going to waste time trying to implement some alternative to a stack because of a preconception that stacks are for x or y but never z (and further, that he wouldn't post "stack overflow" errors to the console if that was misleading).
I am not quite sure how it deals with reaching the end of the branch...
I'm also not sure of the implementation details in C (don't really need to be), but if each object gets pushed onto a message-passing stack, then it's easy: when this object is done, pop an object off the stack and see if it has outputs that haven't been issued yet; then issue them, or if there are none, pop again and repeat until the stack is empty. Because a stack is LIFO, this is always (literally!) backtracking.
If you've ever used Max's graphical debug mode: it literally shows you the message-passing stack in a window. I'll admit that I don't have the line-number evidence to show exactly how pd does it in C, but I'm not making this up...
Trigger is unused at run time, it's only used at "flatten" time... However audio tree is flatten to create a DSP chain but maybe the control tree is not…
I'm quite sure there's no flattening for control objects. (See Max's debugger, or I bet pd's trace mode will show the same.)
Edit:
trace: bang trigger: bang -- not flattened message: One print: One trigger: bang -- and, after doing "One," it backtracked to here message: Two print: Two backtrace: -- what happened before the [trace] object? bng: bang
Note that you don't know "what happened before the [trace] object" without a stack
Again, if I'm really saying anything controversial, when time permits I can go diving into pd's sources and find the evidence. But IMO the [trace] output is enough.
hjh
-
@ddw_music I never said pd did not have a stack, I said that I did not think it had a RETURN stack. I don't think I can reasonably respond to your post without risking more confusion.
-
@oid Perhaps I owe an apology for an excessively critical post -- I can see that I was a bit too heated.
Perhaps part of the problem in this thread is trying to find terminology without agreeing on terminology -- I'm using some terms in a way that you disagree with, or might be misunderstanding to some extent, and vice versa.
I think some of the things that have been said in this thread are misleading in some ways. Message-passing along patch cables isn't a goto -- it just isn't. Gotos have been discouraged for a long time because they're messy. Overuse produces spaghetti code, and goto-heavy code is hard to debug because gotos are history-less -- there's no backtrace to see how you got into a bad place. Pd message passing keeps all the history until you reach the end of the chain. Stack traces are a characteristic of procedure/function calls -- not a characteristic of gotos.
I do see that Pd doesn't use a stack for returning data to a caller. But there have been some statements that seem to go beyond that, for instance, "without a return stack we can't actually return" -- that's true, we can't return data but execution can and does return back to an object that was previously touched.
Again, probably a lot of this is about terminology -- for example, when I used the term "procedure call," that isn't the normal way that Pd users talk about message passing, so there's a bit of "well that doesn't make sense"... but I think the behavior of Pd control objects lines up very closely with the behavior of procedure calls, and I think some of the resistance to this idea has been overstated to some extent or another. (Likewise, to suggest that you totally rejected the idea of a stack is a considerable overstatement -- which I certainly have to retract.)
So I am sorry about getting a bit punchy there -- at the same time, I'm a bit bewildered why so many things I've tried to say in this thread seem to have gotten a "well, no, that's not it" where I guess I hoped for a "hmm, that's interesting, have you considered?"
hjh
-
@ddw_music said:
Gotos have been discouraged for a long time because they're messy.
Hmm, that's interesting, have you considered Java's use of gotos?
They're structured, provide a convenient way for exiting deeply nested loops, and feel similar to Java's exception framework.
Never mind, I just couldn't resist. Carry on.
-
@jameslo said:
Hmm, that's interesting, have you considered Java's use of gotos?
Nice one
well, there's a time and place for everything. There are gotos in SuperCollider's C++ codebase, iirc mainly in the long
switch
blocks in the bytecode interpreter. I guess... it's like second inversion triads. In conventional harmony, there are a few legit ways to use them, but otherwise, don't; same for gotos.hjh