[L2Ork-dev] Patch private abstractions

Jonathan Wilkes jon.w.wilkes at gmail.com
Wed Aug 5 13:58:35 EDT 2020


I'd like to invoke the realtime performance analogy for development
software that's somewhere on the Purr Data GSoC page. That is: remove
everything that isn't strictly needed in the hot path of development,
and then see if the result is enough to fit the common use cases.

Global default scope would at first glance appear to fit that process
because that's what Pd normally does.But it forces
$0 for the common case of local scope and also creates unsolvable
syncing/caching problems for even modestly
complex data:

1. On Monday, a user creates [struct foo] in one patch and creates a
data structure in a 2nd patch.
2. On Tuesday, a user only opens the first patch and changes the
definition of [struct foo], then saves and closes it.
3. On Wednesday, a user only opens the 2nd patch.
3. On Thursday, a user opens the first patch, then opens the second patch.

The problem is similar for global scope among glists. Unless I'm
missing an obvious solution, I think solving that problem for
all cases will eat your development time. Worse, we have no common use
case where that level of complexity is needed.

Perhaps a good starting point is this: what's the most efficacious way
to get from this feature to using [clone] to create
many versions of the abstraction? Say, for the purpose of creating
massive polyphony. That will be a common use case.

>From there I think the best place to go is to just implement it (like
what you had in your presentation yesterday) and
make a merge request so we can begin playing around with it and
testing out some of the common use cases.

One thought-- [ab <name>] makes it tricky to later add subcommands to
[ab]. A user may have already used
that name for their abstraction. But again, we know [ab <name>] is
ergonomic for users and you implemented it already.
So let's see how far that takes us...

-Jonathan

On Wed, Aug 5, 2020 at 1:09 PM Matt Barber <brbrofsvl at gmail.com> wrote:
>
> I see three basic approaches to scope:
>
> 1. [ab <name>] abstractions are treated as every bit as local as [pd <name>] subpatches, except for each instance has a private $0. [ab <name>] definitions do not cross file boundaries, either up to parent or down to file abstractions, but the can cross [ab <name>] boundaries, so that [ab lob] first defined as root->[pd foo]->[ab bar]->[ab lob] can be instantiated anywhere else in root except in another [ab lob] or descendant, or across a file boundary. This is probably the most Pd-like, and what I'd likely go with by default, as it fits best with the pd/ab object analogy.
>
> 2. [ab <name>] abstractions are treated as strictly private as file abstractions, so definitions inside cannot pass out to parent or down to other [ab <name>] descendents]. In other words you treat [ab <name>] as though it were a file boundary. This is also pretty Pd-like, and I would likely go with it if we were going with a model where you could [ab define jinx] and then use [jinx] on its own without needing to call the [ab] object.
>
> 3. [ab <name>] abstractions are treated as a kind of hybrid. [ab lob] defined as [ab bar]->[ab lob] can be used in any instance of [ab bar] and descendents (including [ab <name>] descendents) but not in parent or root. If root already has an [ab lob] defined, it will be replaced by the new definition in [ab bar] instances. This is normal programming local scope, is elegant, and is therefore least Pd-like.
>
> Other considerations:
>
> You could send messages to ab-<name> and access every instance.
>
> Name clash. Should the [ab] names be their own separate thing, so that [ab counter] and a file abstraction called by [counter] are different? Is that even possible? Likewise should [ab float] be possible without conflicting with builtin, or [ab z~] without conflicting with an external? This could preclude use with [clone], except it could still be done with [clone ab-counter] to distinguish from the file-defined [clone counter].
>
> I don't have strong opinions about that yet.
>
> What happens if one deletes all instances of [ab foo]? I think the patch should somehow remember the definition so that it can be instantiated again. That probably means it should be hoisted to root and not associated with any instances at all.
>
> Will [savestate] work? It doesn't work with [clone]. What does [initbang] do if you are trying to use it to dynamically patch inside instances (I think it should behave about like it does in file abstractions, but there could be problems I haven't thought of yet).
>
> Matt
>
> On Wed, Aug 5, 2020 at 7:08 AM Guillem Bartrina <guillembartrina at gmail.com> wrote:
>>
>> Hi,
>>
>> In the last meeting we (more or less) conclude that the most ergonomic approach is the one that simply uses [ab <name>], with implicit creation and deletion for the shared abstraction definition and an implicit flat scope (instantiable by the whole subpatch/abstractions tree, even if first definition was in an other branch or a deeper level or inside an abstraction).
>>
>> Local scope for these kind of abstractions will be achieved using [ab $0-<name>].
>>
>> * This 'local scope' won't be, in fact, a real local scope but the string '$0-name' is much harder to reproduce by the user because he must know the '$0' ID of the patch where the local abstraction has been created.
>>
>> If a real local scope is wanted then we will have to deal with conditional behaviour that may make the feature even harder to implement.
>>
>>
>> The flat scope mentioned above scares me a little because it might be the source of a lot of problems. To start with, a clean and strong storing and lookup system for the shared abstraction definitions must be designed and tested.
>>
>> Possible problems:
>>
>> - We have to prevent instantiating abstractions within themselves (or one of their descendants).
>>
>> - Possible name clash with other private abstractions when instantiating file-based abstractions.
>>
>> - Where should the abstraction definitions be stored within the pd file, to prevent code repetition like the subpatches? Maybe hoisted inside the root patch definition, as is currently implemented.
>>
>> ----------------------------
>>
>> The first approach I showed you yesterday was based on Jonathan's approach:
>>
>> > 1. Implicit as you describe above. Rule: the names go from the root>
>> > down to the subpatches without
>> > affecting file-based abstractions in the root or the subpatches. If
>> > the [ab name] exists inside a file-based abstraction, it doesn't
>> > affect the parent on which the abstraction was created.
>>
>> If I understood correctly, the goal now is the same but the scope now crosses file boundaries.
>>
>> Best,
>>
>>
>>
>>
>>
>> _______________________________________________
>> L2Ork-dev mailing list
>> L2Ork-dev at disis.music.vt.edu
>> https://disis.music.vt.edu/listinfo/l2ork-dev
>
> _______________________________________________
> L2Ork-dev mailing list
> L2Ork-dev at disis.music.vt.edu
> https://disis.music.vt.edu/listinfo/l2ork-dev


More information about the L2Ork-dev mailing list