[PD] Good programming practice


------------------------------------------------------------------------
rodney  rodney at atr.jp 

HI all,=20

After a quick search through the archives, this is the link provided =
from an
earlier discussion with the above subject.

http://www.earcatching.com/pdconv/

Pd allows a lot of different 'styles' of programming, some better for =
some
things than others. All I know is that my style has left me strangled in
invisible spagetti and hope to improve it by looking at how everyone =
else
does it.

Rod.
------------------------------------------------------------------------

Tom Schouten  doelie at zzz.kotnet.org 


spaghetti isn't that bad. life comes from chaos and turbulence :)

anyway. the thing to do i think is simple. every time you see a
collection of things that looks like something you can give a name
as a whole, you put it in a subpatch or an abstraction.

if you got wires going everywhere, the essence of your patch is most
likely the network of wires, not the objects connecting them. this is 
very hard to chop up.

i usually leave it as it is, or i define some 'busses' using send/receive
or catch/throw that take the edge off a bit.

the whole idea is, that most systems made by man can be factored.
at least if the maker was thinking and not just acting incrementally 
intuitive. in this light, thinking is pruning: cutting wires.

this means the structure looks like:
(1) very closely connected modules (spaghetti)
(2) reasonably interconnect between the modules

this is how OO works for example. information hiding is actually
spaghetti hiding in practice.

in fact most computer programs have this structure.
the second step is absolutely necessary if you want to understand
what you've been doing. if you can't add that level of organization,
what you are doing might be incomprehensible voodoo anyway. and
this is not necessarily a bad thing. pd sort of promotes this i think.

in fact, this 2 part structure, or a recursion thereof, can be
found in most structures that are built by any evolutionary
(incremental mutate + test) process. i.e. math, the unix kernel, 
the human brain, the rest of the human body, etc..
------------------------------------------------------------------------

Frank Barknecht  fbar at footils.org 

Hallo,
Tom Schouten hat gesagt: // Tom Schouten wrote:

> this means the structure looks like:
> (1) very closely connected modules (spaghetti)
> (2) reasonably interconnect between the modules

Interestingly Memento in RRADical is exactly this: If you look into
the central patch of it, originator.pd, it's pure spaghetti. Possible
to understand, but really harder to understand than necessary. However
the only thing that is interesting with originator is outside of it,
it's its "interface". This is very clear (I hope) and easy to
understand. 

BTW.: Inspired by this discussion I finally wrote a help file for all
Memento patches, which is in CVS.

ciao
-- 
 Frank Barknecht  

------------------------------------------------------------------------
Tom Schouten  doelie at zzz.kotnet.org 

another example: a C or C++ program

somewhere up the abstraction ladder there is a point where you no longer 
have circular dependencies between objects or structures, and your program
moves from a network-like structure to a tree-like one. that's where 
you 'got organized' :)

in forth, the spaghetti is the kernel: the way the threaded interpreter 
works (the executor: it works basicly with closures), and to some extent 
the outer interpreter (which translates symbolic code to threaded code).
the rest is fairly linear.

in fact, you have the same in mathematics:
axioms + logic

the axioms come from pretty much circular non-logic human thought,
and the rest of the structure is built on top of that in a clear
logic straightforward way.


------------------------------------------------------------------------

Peter Todd  Peter Todd" <peter_todd82 at yahoo.co.uk 

 had meant to mention this earlier, and even got as far as typing, but 
didn't for some unknown reason.  Maybe the feeling that all this might 
change if I had OSC working.  OSCroute sounds pretty useful.  Anyway, the 
new talk of GripD and $0 has incited me again.

Personally, I use $1 for a kind of address space for abstractions, rather 
than making things private.  For example, a patch with two similar synths , 
which uses two similar envelopes, would be structured so that each synth and 
envelope was given a friendly name (maybe 'lead' or 'bass' or whatever) as 
the first argument.  Synth-wide parameters use $1.parameterName, while the 
envelopes have names $1.ampEnv and $1.filterEnv.  Similarly, within the 
envelope abstraction, $1.parameterName is used for sends and recieves.  So, 
the sends and recieves for the attack [$1.A] of the lead synth's filter 
envelope become [lead.filterEnv.A], and so on.  If access to the parameters 
is desired from anywhere else, there are no particular dirty tricks 
involved, and nothing changes when you reopen the patch.  Of course, you can 
still use $0 as part of the name if you want to make it private at a high 
level.  There isn't too much risk of accidentally conflicting send, receive, 
values or whatever, but names could get a bit long - so I try to keep them 
short.

In order to make GOP patches work with polyphony, I've decided to use 
separate abstractions for the interface and the actual processing, and 
anything which is made polyphonic is given another argument for voice 
number.  Then messages destined for a particular voice are prepended with 
the voice number, and [route $2] is used to filter out the appropriate 
messages.  [throw~ $1.channel] is used at the 'instrument level'.  This 
allows voices and patches to be built dynamically quite easily.

Nothing terribly revolutionary, but perhaps it could be RRADical, none the 
less (did I mention OSC isn't working for me).  I'm sure there are some 
related points that aren't ocurring to me now, and things outside the 
midi-polysynth box.  I'll stop now before I ramble too much.

Hope this is useful,

Peter 


------------------------------------------------------------------------


Frank Barknecht  fbar at footils.org 

This is not too different from the way, rradical does it, except this:
rradical does keep all things local, while still allowing access
through $1-named addresses. I intentionally did not use send/receive
pairs for this. Although clashes are unlikely with consistently named
sends, they still are possible and require a user to take care of
this. Also sends require a user to remember all these names and write
a lot of [s something] objects. This is fine, if you're the only user,
but as soon as others try to use an abstraction library, things get
too complicated IMO.

Instead all this is solved in rradical through the OSC x-let, which
actually currently doesn't need to use OSC, plain [route] would work
as well, but OSC made it much easier and has several other advantages
(foremost that's pattern matching)

In rradical, no send names have to be remembered at all, because there
are none! This is important. Everything is done through the OSC
inlets, which basically are connected to [OSCroute $1]. This could be
[route $1] as well. Then every parameter, that should be controlled,
has another [OSCroute /paramname] which could be [route paramname] as
well, if you want to avoid OSC.

Now if every OSC inlet is fed by [r OSC] receivers, a user of rradical
has remote control of all parameters through one single global sender,
if (s)he likes to do so, just by sending correctly formatted messages
to it: "; OSC /synth/paramname 20" (OSC) or "; OSC synth paramname 20"
(route, not implemented in rradical). No global sends at all, except
one not named by me, but by the user.

I called this the "strict borders, single crossing" principle in
RRADical.

Ciao
-- 

------------------------------------------------------------------------

Peter Todd  Peter Todd" <peter_todd82 at yahoo.co.uk 

This is more in response to Frank than any new contribution to the 
discussion - feel free to ignore it, I doubt there is much new to learn.

> Hallo,
>
> This is not too different from the way, rradical does it, except this:
> rradical does keep all things local, while still allowing access
> through $1-named addresses. I intentionally did not use send/receive
> pairs for this. Although clashes are unlikely with consistently named
> sends, they still are possible and require a user to take care of
> this. Also sends require a user to remember all these names and write
> a lot of [s something] objects. This is fine, if you're the only user,
> but as soon as others try to use an abstraction library, things get
> too complicated IMO.

That sounds reasonable.  Nonetheless, the only time a user is required to 
write the [s something]s, is when they explicitly want to control things in 
a different way (and they can 'send' with messages, rather than [s]) - 
again, not so different from rradical?  I still prefer your method, though, 
I think (and it's better that there is a consensus / standard, so people 
don't keep reinventing the wheel).

>
> Instead all this is solved in rradical through the OSC x-let, which
> actually currently doesn't need to use OSC, plain [route] would work
> as well, but OSC made it much easier and has several other advantages
> (foremost that's pattern matching)

I've been anticipating taking advantage of some OSC features.

>
> In rradical, no send names have to be remembered at all, because there
> are none! This is important. Everything is done through the OSC
> inlets, which basically are connected to [OSCroute $1]. This could be
> [route $1] as well. Then every parameter, that should be controlled,
> has another [OSCroute /paramname] which could be [route paramname] as
> well, if you want to avoid OSC.

By this, I presume you mean that there is an OSCroute created outside each 
actual rradical abstraction subsequently connected to the OSC inlet?  That 
seems to make most sense.

>
> Now if every OSC inlet is fed by [r OSC] receivers, a user of rradical
> has remote control of all parameters through one single global sender,
> if (s)he likes to do so, just by sending correctly formatted messages
> to it: "; OSC /synth/paramname 20" (OSC) or "; OSC synth paramname 20"
> (route, not implemented in rradical). No global sends at all, except
> one not named by me, but by the user.
>
> I called this the "strict borders, single crossing" principle in
> RRADical.
>

Of course being greeted with lots of 'couldn't create' errors had 
discouraged me up until this point from actually studying how rradical is 
working (I don't know why I didn't ask for help in finding OSC sooner, for 
that and other reasons).  You've laid out many things very clearly and I 
find nothing to disagree with.  I still need to read the documentation and 
experiment with this, but it seems that most things are under control.

Regards,

Peter


> Ciao
> -- 
> Frank Barknecht                               _ ______footils.org__
>



    * Previous message: [PD] Good programming practice


-----------------------------------------------------------------------------
Frank Barknecht  fbar at footils.org
Sat, 23 Oct 2004 23:39:23 +0200



Hallo,
Peter Todd hat gesagt: // Peter Todd wrote:

> That sounds reasonable.  Nonetheless, the only time a user is required to 
> write the [s something]s, is when they explicitly want to control things in 
> a different way (and they can 'send' with messages, rather than [s]) - 
> again, not so different from rradical?  

You're right, this is actually quite similar. 

> By this, I presume you mean that there is an OSCroute created outside each 
> actual rradical abstraction subsequently connected to the OSC inlet?  That 
> seems to make most sense.

Actually there are OSCroute's *inside* each rrad-abstraction. Think: 

  [inlet]
  |
  [route $1]
  |
  [route /freq /vol /pan ...]
  |
  [s $0-freq] ...

Actually this is hidden inside auxiliary abstractions: "originator"
and "commun".

Ciao
-- 
 Frank Barknecht                               _ ______footils.org__


-------------------------------------------------------------------------------
guenter geiger  geiger at xdv.org
Wed, 20 Oct 2004 12:06:24 +0200 (CEST)

    * Previous message: [PD] Good programming practice
    * Next message: [PD] Gem: Bug with color and separator?
    * Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

On Wed, 20 Oct 2004, Tom Schouten wrote:
> the whole idea is, that most systems made by man can be factored.
> at least if the maker was thinking and not just acting incrementally
> intuitive. in this light, thinking is pruning: cutting wires.

I recently was working with an algorithm that was exactly doing that.
Finding communities in complex networks. We could imlement it in Pd and
add a button "Clean up", which would take over the tedious thinking part
:)

Guenter

>
> this means the structure looks like:
> (1) very closely connected modules (spaghetti)
> (2) reasonably interconnect between the modules
>
> this is how OO works for example. information hiding is actually
> spaghetti hiding in practice.
>
> in fact most computer programs have this structure.
> the second step is absolutely necessary if you want to understand
> what you've been doing. if you can't add that level of organization,
> what you are doing might be incomprehensible voodoo anyway. and
> this is not necessarily a bad thing. pd sort of promotes this i think.
>
> in fact, this 2 part structure, or a recursion thereof, can be
> found in most structures that are built by any evolutionary
> (incremental mutate + test) process. i.e. math, the unix kernel,
> the human brain, the rest of the human body, etc..
>
>
> _______________________________________________
> PD-list@iem.at mailing list
> UNSUBSCRIBE and account-management -> http://iem.at/cgi-bin/mailman/listinfo/pd-list
>