[This is getting pretty OT for pd-list, let's take further discussion to private email or linux-audio-dev]
Thanks for the Nova link, that thesis looks very interesting. I hadn't heard of Nova before. Is it still active? Looks like at least parts of it merged into SuperCollider but I can't see that the main project is still going.
I am definitely still designing as I iterate... get a bit of functionality working, try to use it to do something different than it could do before, see what irritates me, repeat. Both you and HC have made good points that make me think I still have some work to do on scoping and on layers/subpatches/abstractions.
Your comments about dotted namespaces stump me a bit. I see what you mean about DNS address resolution, but very many programming languages share a common notation and meaning for dotted access to objects/subobjects. I'm trying to make things look as much like "visual python" as I can, so I would tend to use a similar syntax, but then again accessing scopes is not exactly like accessing object attributes. I will have to chew on it a while.
Thanks, Bill Gribble
On Sat, 2013-01-26 at 15:55 -0800, Jonathan Wilkes wrote:
----- Original Message -----
From: Bill Gribble grib@billgribble.com To: Jonathan Wilkes jancsika@yahoo.com Cc: Lorenzo Sutton lorenzofsutton@gmail.com; "pd-list@iem.at" pd-list@iem.at Sent: Saturday, January 26, 2013 11:01 AM Subject: Re: [PD] GUI toolkits and custom GUIs WAS: Integra Live 1.5 released
On Fri, 2013-01-25 at 19:30 -0800, Jonathan Wilkes wrote:
So inside [blah] let's say I have this:
[r foo] | [print I_don_t_want_bob_to_trigger_this]
I share my [blah] abstraction with Bob, who creates a [blah] instance in
the same
patch where he has
[Click here to start my thing( | [s foo]
I suppose I don't know what "lexical hygiene" means. But I
think you have to have
a way to explicitly state that "binding symbol foo applies to this< canvas and all of its children, but not to any parents". Do you have a way to do
that without using
the $0 kludge?
PD's behavior and the $0 kludge falls out of the design where there is a single namespace for s/r targets. It's a programming language where there are only global variables. This makes some things easy (communicating with other patches) and some things hard (keeping things private, duplicating code blocks without copies stomping on each other).
The best solution I've seen is Tim Blechmann's use of [declare] in Nova (though one could use a different class rather than overloading a current one):
http://tim.klingt.org/publications/tim_blechmann_nova.pdf
I can't remember what his default behavior was when the binding-symbol isn't [declare]'d, but if it defaulted to global in that case then the system would be backwards compatible with Pd. It's also trivial to learn, as the declaration is basically a stamp on a canvas that says "this name doesn't communicate with my parents, but it can communicate with all my children-- unless of course they declare the name for themselves." He also has a mechanism to explicitly declare something global.
The benefit is that when a name is declared on a canvas, the meaning is trivial to understand: IF stamped THEN local to me and my unstamped children. The drawback is that on a canvas that doesn't have a declaration on it, the user doesn't immediately know how far up the tree the scope goes simply by looking at the patch (though a mechanism could easily be added to reveal that).
Your system has the benefit of sane defaults-- if I understand correctly, names in your system will default to the behavior one currently gets in Pd by prepending a $0 to the name. That probably covers most of the common patching cases. The drawback is that for uncommon cases your namespace notation is non-trivial to learn, even though it makes the scope of uncommon cases explicit.
(To get a sense of how difficult it is for a user to _truly_ grasp scope levels using the "." separator, look at the history of scams based on shuffling the levels of domain names, changing the tld, and even putting the company name as a subdirectory of some nondescript domain name like acctmngr.com/microsoft.)
Anyway, I suppose that's enough commentary until I can actually play around with your system and see how it works. (The png showing the IDE-style interface looks nice, though.)
My design started from the presumption that all variables (names) are local to a scope. Each patch has its own "global" scope (which is the default for new names), and can have named scopes within it. This sort-of follows a model of "lexical scoping" that you see in languages like Lisp and Scheme where you can explicitly wrap a block of code in an environment where variables just local to that scope are declared. In MFP, a layer (subpatch) or group of layers can share a scope just among themselves, or can use the patch's global scope.
Again, this makes some things easy (cut and paste of subpatches without stepping on each other, management of names without $0-prefixes, knowing that your abstraction won't interfere with someone else's) and some things hard (broadcasting to every instance of a patch/abstraction, listening in on message traffic internal to somebody else's abstraction).
Back to your example: it wouldn't work as-is in MFP. The [s] would have to qualify the "foo" name, since it doesn't exist in the scope of the [s]. Let's say I make a [blah] in the patch with the [s] and I name it "blah_1". The [s foo] would need to be [s blah_1.foo] for it to get where you intend it to go. If you made 2 [blah] instances, "blah_1" and "blah_2", you would have to send to the one that you wanted the message to go to.
There are also use cases for "binding symbol foo applies to all
instances of
this< abstraction", and possibly "all instances of
abstractions from >this<
libdir" (though the latter may be overkill).
Yes, these are real use cases. I'm still trying to work out which ones are highest-value; you can't do either of these things in MFP right now.
The libdir scope isn't so important unless it is accompanied by another feature, which is a libdir setup file that is analogous to classname_setup in a c external, except that it's a Pd patch instead of a c file.
There are a few ways it could be implemented, but basically it should be possible for a libdir author to make a "setup" patch that gets loaded (in a way similar to the pd-_float template for arrays) whenever the libdir is loaded. One way to do this would be to load libdirname-meta.pd when libdirname is loaded. (Right now in Pd-ext libdirname-meta.pd just has comments describing the libdir itself.) That way the author could put stuff that is commonly used by all the libdir abstractions in libdirname-meta.pd (like a shared [table], for example), and it will be loaded and available to access. But of course for it to work there must be a libdir scope so that messages can pass back and forth between the setup patch and the libdir abstractions with impunity.
-Jonathan
Thanks, Bill Gribble
-Jonathan
At the same time, references to names that can't be resolved in
the local
scope do bubble up, so you can have more global names if you need
them.
Thanks, Bill Gribble
On Jan 25, 2013, at 21:27, Jonathan Wilkes jancsika@yahoo.com
wrote:
----- Original Message -----
From: Bill Gribble grib@billgribble.com To: Jonathan Wilkes jancsika@yahoo.com Cc: Lorenzo Sutton lorenzofsutton@gmail.com;
"pd-list@iem.at" pd-list@iem.at
Sent: Friday, January 25, 2013 7:55 PM Subject: Re: [PD] GUI toolkits and custom GUIs WAS: Integra
Live 1.5
released
On Fri, 2013-01-25 at 15:21 -0800, Jonathan Wilkes wrote: >> From: Bill Gribble grib@billgribble.com >> I am working on a pd-clone intended to explore a lot
of the
topics in
this >> thread. It's not fully baked yet -- the biggest
working
patch is
a biquad >> filter designer with pole-zero and freq response
plotting --
but
I'm >> particularly excited about the approach to
namespacing and
scope
management, >> which works a lot like hc describes. Patches have a
set of
scopes
which can be >> mapped onto subpatches (represented as layers, not
separate
windows).
Name >> resolution in send/receive elements works like you
would want
it to.
> > How does scope work for abstractions?
Well, every object in a patch has a name. To find that
object, the
tree
of patches and scopes is crawled upward from the site of the
lookup.
For
example, the (equivalent of) [s "foo"] first looks
in the
scope of the
[s], then the patch-global scope of the containing patch,
then in the
application global scope for the name "foo".
Dotted notation can drill down, so [s "foo.bar"]
would try to
find an
object named "foo", then find "bar" in
its
patch-global
scope (or an object named "bar" within a scope named
"foo" in
the current
patch).
Does that make sense?
I don't think I understand it.
Let's say I have abstraction [blah]. I want [s foo] and [r
foo] inside
[blah] and
all of [blah]'s children to talk to each other. Then I want
to share
my abstraction
with Bob who needn't worry about the send/receive names I
used inside
[blah]
because they are guaranteed not to conflict with anything he does
outside
the
scope of the [blah] abstraction (e.g., creating a [s foo] on the
same
canvas where
a [blah] object sits).
Can I specify the scope of the s/r symbol in this way?
Jonathan
Thanks, Bill Gribble