# Hi everybody, # This morning two ideas about macros which could make our lives easier has come to my mind. # 1) There are these objects, every time we create them, we add some messageboxes to control them. For example, [writesf¨~] with [open(, [save( and [stop messages( or [netsend] with [connect(, [disconnect(, [send( messages etc. # What if, these absolutely necessary messagebox's are created when we created these objects, so we do not have to look to their help patches every time. Or there could be a new type of abstractions, which includes these message boxes information, at the same level with them.
# 2) For example, I have a patch witch uses a lot of abstractions. And every time a send it to my friend, I forget to attach some of these abstractions, and it did'nt work on his/her computer. So, what if, there were a button, which changes every abstraction in the patch with a sub-window. e.g, one of my abstractions (partial.pd) [partial] would changed with [pd partial]. # hmm... I looked and saw that sub-windows does not take creation arguments, so these could be a problem... # Aha! Creation arguments could be hard coded in the sub-window. e.g: [partial 2 cos] => [partial] in which
[r fundFreq] | [* $1]
=>
[r fundFreq] | [* 2]
# How could these ideas be implemented? Do you have suggestions? # Thank you very much for your elegant, educative and funny conversations... -ugur guney-
ugur guney wrote:
# Hi everybody, # This morning two ideas about macros which could make our lives easier has come to my mind. # 1) There are these objects, every time we create them, we add some messageboxes to control them. For example, [writesf¨~] with [open(, [save( and [stop messages( or [netsend] with [connect(, [disconnect(, [send( messages etc. # What if, these absolutely necessary messagebox's are created when we created these objects, so we do not have to look to their help patches every time.
well, after some time, you don't need to look at the help-patch to remember the [connect( message for [netsend]....
any you could always make an abstraction (gop) that does all this.
nevertheless it sounds like an interesting idea, though i don't see any way to solve the "absolutely necessary messages" problem: what is "absolutely necessary" (from the object developer's point of view, not from the user's)? either all messages an object accepts are considered "necessary" (like [bang( [float $1( [stop( for [metro], or somebody has to sit down and declare a subset of the messages to be necessary.
i guess the simplest (and most flexible) way would be to have several paste-buffers with user-definable shortkeys (so that e.g. Ctrl-Shift-m could be tought to produce a [tgl] connected with a [metro])
Or there could be a new type of abstractions, which includes these message boxes information, at the same level with them.
# 2) For example, I have a patch witch uses a lot of abstractions. And every time a send it to my friend, I forget to attach some of these abstractions, and it did'nt work on his/her computer. So, what if, there were a button, which changes every abstraction in the patch with a sub-window.
miller had plans to implement a "embed abstractions into patch" feature a while ago. i don't know how far this has grown
mfg.asdr. IOhannes
That's a smashing idea. Maybe not keys (hard to remember), but a dropdown list containing a pool of user-definable pre-built circuits.
On Tue, 03 Oct 2006 11:52:23 +0200 IOhannes m zmoelnig zmoelnig@iem.at wrote:
i guess the simplest (and most flexible) way would be to have several paste-buffers with user-definable shortkeys (so that e.g. Ctrl-Shift-m could be tought to produce a [tgl] connected with a [metro])
On Tue, 3 Oct 2006, ugur guney wrote:
# 1) There are these objects, every time we create them, we add some messageboxes to control them. For example, [writesf¨~] with [open(, [save( and [stop messages( or [netsend] with [connect(, [disconnect(, [send( messages etc.
You may keep a patch open, whose only purpose is to be copy+pasted from.
Else, in DesireData only, you can do this: write the following in a text editor, copy them with Ctrl+C, and then paste them in a patch with Ctrl+V. They will appear as objects in the patch, and they will connected if you're copying all 5 lines at once:
#X obj 0 50 netsend 1234; #X msg 25 25 connect; #X msg 25 25 disconnect; #X connect 1 0 0 0; #X connect 2 0 0 0;
Similarly you can take patch portions and copy them in a text editor (with DesireData only).
Also with DesireData only, you may add a def in bin/desire:
def Canvas readymade_netsend {} { global clipboard $clipboard value= { #X obj 0 50 netsend 1234; #X msg 25 25 connect; #X msg 25 25 disconnect; #X connect 1 0 0 0; #X connect 2 0 0 0; } $self paste }
and then edit ~/.ddrc to add a keyboard shortcut for it, e.g.:
key { Canvas { readymade_netsend Ctrl+Alt+n } }
there's a trick to prevent clobbering the clipboard too, which the "duplicate" function of Ctrl+D is using already.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
On Tue, 3 Oct 2006, Mathieu Bouchard wrote:
#X obj 0 50 netsend 1234; #X msg 25 25 connect; #X msg 25 25 disconnect; #X connect 1 0 0 0; #X connect 2 0 0 0;
Typo. I handwrote this patch, so by mistake the two object boxes are on top of each other. I wanted to write the 2nd line like:
#X msg 25 0 connect;
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
On Tue, 3 Oct 2006, Mathieu Bouchard wrote:
On Tue, 3 Oct 2006, Mathieu Bouchard wrote: Typo. I handwrote this patch, so by mistake the two object boxes are on top of each other. I wanted to write the 2nd line like: #X msg 25 0 connect;
This is so dumb: making typos while correcting typos. I meant messageboxes of course. I never make those mistakes normally, and I'm always the one insisting on precise words and now boom.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
Karma?
;-)
~Kyle
On 10/3/06, Mathieu Bouchard matju@artengine.ca wrote:
On Tue, 3 Oct 2006, Mathieu Bouchard wrote:
On Tue, 3 Oct 2006, Mathieu Bouchard wrote: Typo. I handwrote this patch, so by mistake the two object boxes are on top of each other. I wanted to write the 2nd line like: #X msg 25 0 connect;
This is so dumb: making typos while correcting typos. I meant messageboxes of course. I never make those mistakes normally, and I'm always the one insisting on precise words and now boom.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
I think you have answered your own question with point 1. Those creation arguments are in essence abstraction parameters.
But point 2 has some merit and it's been raised before. The necessity for abstractions to be separate files is imho one of Pds most significant flaws. I avoid using abstractions entirely because even with the most careful management they are more trouble than they are worth.
A "convert abstractions to subpatches" or "embed abstractions" utility would be of great practical benefit. You have spotted one of the difficulties in doing this, substituting parameters in each instance, and you are correct it's nothing more than a substitution problem. But which "version" do you use if there is an identically named abstraction inside and outside your patch with different functionality? I don't know that there is a sensible order of precedence yet, like abstractions in the path > abstractions in the same directory as the patch > abstractions inside the patch (aliases).
Besides, converting abstractions to sub-patches would be a one way street which prevented you from editing one piece of code and having it update in many places... that's the real reason for abstractions in the first place. But those that really *use* Pd a lot probably agree with me that another reason for abstractions is to test/edit a piece of code in many places, and once you've got it right cast it in stone as a subpatch.
That is why I suggested the concept of "aliases" as a halfway marker between abstractions and subpatches.
I think there is groundwork to be done before this can move forward. Namespaces and scope are two ugly aspects of Pd right now that are being worked on. Once this is sorted out we could move towards
The ability to move "downwards" from abstractions to aliases to subpatches would be easy, but the reverse would require some more work, for example mapping each $n argument onto an inlet and each inlet back to a $n argument. I think the smart coders know it would be premature to make this switch at present and it would probably get broken. In my opinion this is worth getting right even if it means sacrificing backwards compatability, and it's not too late in the day to do it.
On Tue, 3 Oct 2006 10:46:09 +0300 "ugur guney" ugurguney@gmail.com wrote:
# Hi everybody, # This morning two ideas about macros which could make our lives easier has come to my mind. # 1) There are these objects, every time we create them, we add some messageboxes to control them. For example, [writesf¨~] with [open(, [save( and [stop messages( or [netsend] with [connect(, [disconnect(, [send( messages etc. # What if, these absolutely necessary messagebox's are created when we created these objects, so we do not have to look to their help patches every time. Or there could be a new type of abstractions, which includes these message boxes information, at the same level with them.
# 2) For example, I have a patch witch uses a lot of abstractions. And every time a send it to my friend, I forget to attach some of these abstractions, and it did'nt work on his/her computer. So, what if, there were a button, which changes every abstraction in the patch with a sub-window. e.g, one of my abstractions (partial.pd) [partial] would changed with [pd partial]. # hmm... I looked and saw that sub-windows does not take creation arguments, so these could be a problem... # Aha! Creation arguments could be hard coded in the sub-window. e.g: [partial 2 cos] => [partial] in which
[r fundFreq] | [* $1]
=>
[r fundFreq] | [* 2]
# How could these ideas be implemented? Do you have suggestions? # Thank you very much for your elegant, educative and funny conversations... -ugur guney-
Hallo, padawan12 hat gesagt: // padawan12 wrote:
But those that really *use* Pd a lot probably agree with me that another reason for abstractions is to test/edit a piece of code in many places, and once you've got it right cast it in stone as a subpatch.
Well, I don't agree at all. ;) People should learn the many possibilities and advantages of abstractions instead.
I think, I've written about my view here several times, so I will only repeat my main point: subpatches and abstractions are something completely different!
To those who program with text based languages: subpatches are code blocks, they are the "{...}" in Perl or C or the indented blocks in Python. Abstractions however are functions. They are the "func" in the "int func(arg){}" of C or in the "def func(arg):..." of Python. The two important differences are the "arg" that is possible to pass and the fact, that a function is defined in exactly one place and then, when it gets called, you can be sure, that it always show the same behaviour. Subpatches however may all behave in a different way and they don't accept arguments.
IMO one should not try to dumb down a "func(arg)" into a "{}" at all.
What's missing in Pd may be a way to embed "func(arg)" in the same file, but this is something different from converting it to a subpatch.
We would probably need to create a way to declare and define an embedded abstraction in one place of the patch, maybe using a subpatch-like object [def myEmbeddedAbstraction args] which would have its own canvas to edit it like a subpatch, and then one could use [myEmbeddedAbstraction args] inside just this patch. But I guess that this is as tricky to implement as the [import] object that was discussed recently on pd-dev. But maybe it isn't.
Frank Barknecht _ ______footils.org_ __goto10.org__
On Tue, 3 Oct 2006, Frank Barknecht wrote:
To those who program with text based languages: subpatches are code blocks, they are the "{...}" in Perl or C or the indented blocks in Python.
Yes; however, not all code blocks map to subpatches: most just map to patterns of wires.
Abstractions however are functions. They are the "func" in the "int func(arg){}" of C or in the "def func(arg):..." of Python.
They're more like objects, because they have state that survive the handling of a message; and because they have instances. (Some functions called "closures" have both of those characteristics, but they don't exist in C/C++ nor Python)
IMO one should not try to dumb down a "func(arg)" into a "{}" at all.
BTW, in several popular languages, the "{}" do introduce closures: in Perl (only when preceded by "sub"), and in Ruby (in all cases). I'm not sure about SuperCollider but I'd assume that it's mostly as in Ruby.
We would probably need to create a way to declare and define an embedded abstraction in one place of the patch, maybe using a subpatch-like object [def myEmbeddedAbstraction args]
I suggested [class myEmbeddedAbstraction] in the previous mail. The "args" part is unneeded for the reason that all normal info about args is already inside of that abstraction.
But I guess that this is as tricky to implement as the [import] object that was discussed recently on pd-dev. But maybe it isn't.
two words: multiple objectmakers. This simplifies both problems into just one problem by inserting an intermediate between the imports and the "physical representation" of the involved patches. Ok, it doesn't make it "just one problem" (depending on the way you look at it), but it's still simpler overall.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
On Tue, 3 Oct 2006 12:41:12 +0200 Frank Barknecht fbar@footils.org wrote:
Hallo, padawan12 hat gesagt: // padawan12 wrote:
But those that really *use* Pd a lot probably agree with me that another reason for abstractions is to test/edit a piece of code in many places, and once you've got it right cast it in stone as a subpatch.
Well, I don't agree at all. ;) People should learn the many possibilities and advantages of abstractions instead.
I think, I've written about my view here several times, so I will only repeat my main point: subpatches and abstractions are something completely different!
To those who program with text based languages: subpatches are code blocks, they are the "{...}" in Perl or C or the indented blocks in Python. Abstractions however are functions. They are the "func" in the "int func(arg){}" of C or in the "def func(arg):..." of Python. The two important differences are the "arg" that is possible to pass and the fact, that a function is defined in exactly one place and then, when it gets called, you can be sure, that it always show the same behaviour. Subpatches however may all behave in a different way and they don't accept arguments.
IMO one should not try to dumb down a "func(arg)" into a "{}" at all.
Yes, I totally understand, you explained it very well, here and before and it makes perfect sense. Nobody is suggeting replacing abstractions, or dumbing them down. My personal gripe is that they must currently be in separate files and there is no continuum/route between abstractions and subpatches except by manually copying, pasting and changing the code.
The ability to "recast" an abstraction/function as a fixed code block (or a swift mechanism to promote subpatches) in no way diminishes the value of abstractions, but it is very useful.
Suppose you have created a patch using an abstraction. As it happens the abstraction is an old familiar you've used in many patches, but on this occasion you need some slightly different behaviour. So you edit the abstraction thinking that you're doing so safely and taking into account all previous uses. You don't even discover that you just broke a whole load of your patches until days or weeks later when you try and load them. Of course you could just say copy the abstraction and work on that, but you end up with an ugly mess of special cases
What's missing in Pd may be a way to embed "func(arg)" in the same file, but this is something different from converting it to a subpatch.
Is it so different? In both cases you created a new local copy replacing $ (initialise time arguments) with inlets instead. Granted, you cannot now say [pd MySubpatch arg1 arg2..] and must explicitly set the parameters through the inlets, but that's what you wanted.
I didn't fully understand the power of abstractions until you showed me the [nqpoly] object invisibly creating multiple copies of the same thing, that is way cool, and very desirable! Which is why the idea of an "alias" isn't quite the same thing as an "embeded abstraction". I guess a better way of explaining what I mean is that an alias is a subpatch with local scope, so you can define $0- type things inside it like tables and then copy it with impunity, but if you edit the "master" copy the others all follow suit.
I think the missing ingredient in all this are "local variables" for subpatches.
We would probably need to create a way to declare and define an embedded abstraction in one place of the patch, maybe using a subpatch-like object [def myEmbeddedAbstraction args] which would have its own canvas to edit it like a subpatch, and then one could use [myEmbeddedAbstraction args] inside just this patch. But I guess that this is as tricky to implement as the [import] object that was discussed recently on pd-dev. But maybe it isn't.
That sounds nice. It gets around having to remember which was your "master alias", but then again perhaps a more elegant method is that (they are true aliases) editing *any* copy is equivilent.
What are the issues making this difficult? - remember I still have a very limited appreciation of the Pd kernel code.
Cheers,
a.
Ciao
Frank Barknecht _ ______footils.org_ __goto10.org__
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Hallo, padawan12 hat gesagt: // padawan12 wrote:
Yes, I totally understand, you explained it very well, here and before and it makes perfect sense. Nobody is suggeting replacing abstractions, or dumbing them down. My personal gripe is that they must currently be in separate files and there is no continuum/route between abstractions and subpatches except by manually copying, pasting and changing the code.
Yes, but in my view, subpatches and abstractions serve different purposes (like blocks and functions), so a direct route to convert between them is not necessary. Or at least a way to convert an abstraction to a subpatch is not necessary. The other way around may be nice sometimes, however just typing Ctrl-N and copying over the subpatch's contents is close to convenient.
The ability to "recast" an abstraction/function as a fixed code block (or a swift mechanism to promote subpatches) in no way diminishes the value of abstractions, but it is very useful.
I would agree that embedding abstractions can be useful, but where is making a subpatch out of an abstraction useful, when you loose access to abstraction features like arguments or edit-once-use-everwhere? OTOH adding these features to subpatches would in the end make subpatches be abstractions, and you would actually loose what subpatches were useful for: code organization usign code blocks (see below for more detail).
Suppose you have created a patch using an abstraction. As it happens the abstraction is an old familiar you've used in many patches, but on this occasion you need some slightly different behaviour. So you edit the abstraction thinking that you're doing so safely and taking into account all previous uses. You don't even discover that you just broke a whole load of your patches until days or weeks later when you try and load them. Of course you could just say copy the abstraction and work on that, but you end up with an ugly mess of special cases
I would say that this is just a matter of organizing things and keeping the environment clean. if the behaviour of an abstraction changes significantly it probably would have been better to save it under a different name. Or save it locally next to the main patch, and not in a global abstraction-directory. Another thing I often do is make "wrapper abstractions": I don't change the abstraction itself, but put it inside another abstraction which adds some functionality:
[myabs]
then will become:
[inlet] | [pd do_something] | [myabs] | [pd do_something_more] | [outlet]
I didn't fully understand the power of abstractions until you showed me the [nqpoly] object invisibly creating multiple copies of the same thing, that is way cool, and very desirable! Which is why the idea of an "alias" isn't quite the same thing as an "embeded abstraction". I guess a better way of explaining what I mean is that an alias is a subpatch with local scope, so you can define $0- type things inside it like tables and then copy it with impunity, but if you edit the "master" copy the others all follow suit.
I think the missing ingredient in all this are "local variables" for subpatches.
But I *want* my subpatches to share the scope of the surrounding patch! ;)
I like to compare subpatches to curtains: I use subpatches to put things I'm done with behind a curtain so I don't see them anymore. The stuff hidden by that curtain is still in the same room, I can still talk to a person behind it, I know what's behind that curtain, it's good to have it there, I can take a look behind the curtain quickly if I want to. Being able to talk to a person behind a curtain is equivalent to subpatches sharing $0 with the surrounding patch.
Abstractions however are more like people that live in another flat, people I call over the telephone line: If I want to go out for a beer, I call my friends. I can call them from everywhere I am, because they always have the same phone number(s) everywhere I am. If I need to order a pizza, I call the pizza service. But I don't want to have the pizza service behind a curtain in my living room. It may be nice to have a pizza service in the same house you live, though, as an embedded pizza service abstraction.
We would probably need to create a way to declare and define an embedded abstraction in one place of the patch, maybe using a subpatch-like object [def myEmbeddedAbstraction args] which would have its own canvas to edit it like a subpatch, and then one could use [myEmbeddedAbstraction args] inside just this patch. But I guess that this is as tricky to implement as the [import] object that was discussed recently on pd-dev. But maybe it isn't.
That sounds nice. It gets around having to remember which was your "master alias", but then again perhaps a more elegant method is that (they are true aliases) editing *any* copy is equivilent.
Hm, yes, that would probably make more sense.
Frank Barknecht _ ______footils.org_ __goto10.org__
On Tue, 3 Oct 2006 14:55:55 +0200 Frank Barknecht fbar@footils.org wrote:
I would agree that embedding abstractions can be useful, but where is making a subpatch out of an abstraction useful,
Just in the particular case where you want to consolidate everything into a single easy to share file.
make "wrapper abstractions": I don't change the abstraction itself, but put it inside another abstraction which adds some functionality:
[myabs]
then will become:
[inlet] | [pd do_something] | [myabs] | [pd do_something_more] | [outlet]
Great if your abstraction already exposes everything you might want to access.
But I *want* my subpatches to share the scope of the surrounding patch! ;)
Me too. Mostly. But sometimes I don't. :)
I love the analogy btw, so it's rather like I enjoy Pizza, but sometimes I like Kebab, Indian, or Chinese but I only have one phone number for Tony, Stavros, Sanjay and Chen labelled "food".
Let's see what we agree on....
Embedded abstractions inside a patch file.
Some kind of local (my $n) scoping for subpatches.
You know, on reflection this whole debate is best described as "encapsulation" and I've been looking at OSC/RRAD lately and thinking what a great system this is and should be more in the basic core of Pd. Perhaps a way to address a variable behind many layers of curtains as /foo/bar/$n or something?
best, a.
On Wed, Oct 04, 2006 at 04:03:38AM +0100, padawan12 wrote:
On Tue, 3 Oct 2006 14:55:55 +0200 Frank Barknecht fbar@footils.org wrote:
I would agree that embedding abstractions can be useful, but where is making a subpatch out of an abstraction useful,
make "wrapper abstractions": I don't change the abstraction itself, but put it inside another abstraction which adds some functionality:
You know, on reflection this whole debate is best described as "encapsulation"
To me it actually sounds like what you guys want is the Pd equivalent of inheritance and the overriding of methods. You want an abstraction which has some basic behaviour, but you also want the ability to keep that same abstraction and 'override' certain behaviours. Unfortunately there probably isn't a way to do that in a patching environment where the program is a 2d netlist. Seems like a similar problem to that of version control (merging, etc.) of patches.
Actually I'm going to contradict myself straight away. One way to do this is to pass in the names of your 'method' patches as arguments to some master patch. So you treat one patch as a "class" and it's arguments as the names of patches which are it's "methods". Let me give an example:
You have a "class" patch called envelope~ which takes one argument. When you send an integer to the inlet of envelope~ it makes a line~ of that length, and passes it through an abstraction called [$1] and sends it to the output. So you use it like this:
[2000( | [envelope~ mylog] | [some other stuff~]
"mylog" is the name of a subpatch which itself takes a signal that goes from 0 to 1 and outputs a nice log envelope. You also have another subpatch called "pants" which takes a signal that goes from 0 to 1 and outputs a signal shaped like some pants. Hence you can also call envelope~ like this:
[2000( | [envelope~ pants] | [some other stuff~]
In the first case it will create a 2000 millisecond long signal in the shape of a log envelope. The second will create a 2000 millisecond long signal in the shape of some pants. Both use the same [envelope~] patch, which you can keep the same and just change the patches you pass into it.
Best,
Chris.
chris@mccormick.cx http://mccormick.cx
On Tue, 3 Oct 2006, Chris McCormick wrote:
On Wed, Oct 04, 2006 at 04:03:38AM +0100, padawan12 wrote:
Frank Barknecht fbar@footils.org wrote:
make "wrapper abstractions": I don't change the abstraction itself, but put it inside another abstraction which adds some functionality:
You know, on reflection this whole debate is best described as "encapsulation"
To me it actually sounds like what you guys want is the Pd equivalent of inheritance and the overriding of methods. You want an abstraction which has some basic behaviour, but you also want the ability to keep version control (merging, etc.) of patches.
What I thought that inheritance would mean in Pd, is simply some kind of nesting of one objectbox which would share the same $0 as the parent; and some kind of inheritance hierarchy, preferably something in the style of CLOS and Ruby (linearized multiple inheritance).
The overriding of specific methods would be done only through the use of [route]. For this kind of thing, though, GridFlow's [route2] could be helping a bit, else one may have to do [list prepend] and [list trim] a lot in order to undo what [route] does to messages. ([route2] does the same routing but without changing the messaages)
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
On Wed, 4 Oct 2006, padawan12 wrote:
Which is why the idea of an "alias" isn't quite the same thing as an "embeded abstraction". I guess a better way of explaining what I mean is that an alias is a subpatch with local scope, so you can define $0- type things inside it like tables and then copy it with impunity, but if you edit the "master" copy the others all follow suit.
Really? Then what do you mean by "embedded abstraction" now?
I think the missing ingredient in all this are "local variables" for subpatches.
This is complicated by the fact that many subpatches use $-variables to access what belongs to their parent.
[myEmbeddedAbstraction args] inside just this patch. But I guess that this is as tricky to implement as the [import] object that was discussed recently on pd-dev. But maybe it isn't.
Ah, in the last mail I forgot to think about the evaluation order of object constructors in a patch. That's going to be a big problem, or at least an "ugly" one; sort of like the kind of reason that pushed the authors of C to require declarations to be above the uses of functions (so that the compiler doesn't have to parse things twice...)
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
On Tue, 3 Oct 2006 19:51:57 -0400 (EDT) Mathieu Bouchard matju@artengine.ca wrote:
On Wed, 4 Oct 2006, padawan12 wrote:
Which is why the idea of an "alias" isn't quite the same thing as an "embeded abstraction". I guess a better way of explaining what I mean is that an alias is a subpatch with local scope, so you can define $0- type things inside it like tables and then copy it with impunity, but if you edit the "master" copy the others all follow suit.
Really? Then what do you mean by "embedded abstraction" now?
[user-rant]
Really. The same as I meant by it before. I mean it literally, an abstraction that has been embedded. I'm not being flippant, I'm talking about the process/action of doing just that from a users POV without caring about how it's implemented. That's a really useful point of view if you care to take heed of it.
When I did HCI studies in the past the most valued subjects were the "semi-naive" users, the ones who didn't have assumptions or a priori ideas about how things were implemented but were able to articulate their problems and needs from an "outside" perspective. The problem with being amongst the trees of development is you stop seeing the wood, which is not a fault, it's just the way our minds work. I hope the OP will chip in with some elaboration on his/her initial suggestions, but from my own position I've definitely reached that annoying (to everybody else) point where I've now used Pd enough to know about its limitations and things I'd like to improve but not enough of the workings to change them. Nomenclature is already pretty poor in Pd so it's foolish to get into semantic tangles about what words "mean" when they speak for themselves.
Let's nail the discussion back down to Earth and address the points of the OP. The best way to tackle this imho is to stop stroking our beards over coding theory and examine some actual problem examples so we are clear about the reasons.
Here is one...
"I wish to construct a piano instrument that contains a couple of arrays and delays, and I want to be able to make copies of that instrument inside my patch, as easily as CTL-C/CTL-V, without having to rename tables and delays, and without having to create abstractions in a separate file. Now, being a dumb user I just realised I made a mistake in my instrument so I want to make one edit and have all the copies change"
Neither abstractions nor subpatches alone satisfy this.
Here's another....
"I just finished my grand oeuvre symphonie de puredata containing 50 abstractions strewn across my filesystem. I wish to place it on my website as a simple, single file, without having to track down each abstraction and put it into a zip file. I want to simply load the patch, press "convert abstractions to fixed" (or something) and save out my new "embedded" file."
The only way to do this afaik is to tediously copy and paste each abstraction into a subpatch and fix its $ values by hand.
and finally...
"I'm still waiting for my pony."
These are a typical beginners problems to be taken on face value. One mustn't deconstruct the request (however stupid or impossible it may seem as a developer) and ask "Why would you want to do that?", I just do... that's the way *users* think. Nor must you provide an alternative method involving some obscure or advanced facet of the language and none of the elements of the original problem, or say "No, what you really meant was...", that's sidestepping and potentially insulting to a user who may be an expert in their field. That's the "listening discipline" that sets software developers apart from mere gifted programmers. To quote the cliche - A PhD in thermodynamics of the internal combustion engine doesn't mean you know where I want to drive to, or even that you could drive there yourself.
[/user-rant]
:)
respectfully,
a.
Hallo, padawan12 hat gesagt: // padawan12 wrote:
"I wish to construct a piano instrument that contains a couple of arrays and delays, and I want to be able to make copies of that instrument inside my patch, as easily as CTL-C/CTL-V, without having to rename tables and delays, and without having to create abstractions in a separate file. Now, being a dumb user I just realised I made a mistake in my instrument so I want to make one edit and have all the copies change"
If this "dumb user" wasn't so dumb to reject having to create abstractions in a seperate file, he would be a lucky user because he would be able to do everything he wanted to using abstractions in seperate files.
Here's another....
"I just finished my grand oeuvre symphonie de puredata containing 50 abstractions strewn across my filesystem. I wish to place it on my website as a simple, single file, without having to track down each abstraction and put it into a zip file. I want to simply load the patch, press "convert abstractions to fixed" (or something) and save out my new "embedded" file."
The only way to do this afaik is to tediously copy and paste each abstraction into a subpatch and fix its $ values by hand.
I've said it before and I say it again: There's more than one file in life. ;)
A patch with 50 subpatches should be rewritten and modularized into a patch using 5(!) abstractions, not the other way around.
Still I agree: An easier way to find and possible save together the abstractions used in a patch would be very handy.
These are a typical beginners problems to be taken on face value. One mustn't deconstruct the request (however stupid or impossible it may seem as a developer) and ask "Why would you want to do that?", I just do... that's the way *users* think. Nor must you provide an alternative method involving some obscure or advanced facet of the language and none of the elements of the original problem, or say "No, what you really meant was...", that's sidestepping and potentially insulting to a user who may be an expert in their field.
That's surely very true, however in regard to the problem of subpatches vs. abstractions (leaving embedded abstractions aside for now) an additional problem is education of the user. It took me a long time to understand the difference between subpatches and abstractions, time like in two years or so. Some of my very old patches try to use arguments in subpatches etc.
The difference is a tricky thing, but it's so very important to understand, that I'm always getting a bit nervous if the two are brought too close together, like in "converting abstractions to subpatches".
Unless different uses for subpatches and abstractions aren't fully recognized by the user, the question of saving them externally or internally or both is secondary. (Maybe it's even better to keep abstractions in seperate files just to let them be "different enough" from subpatches but I admit that's an arrogant view.)
Frank Barknecht _ ______footils.org_ __goto10.org__
Hallo, Frank Barknecht hat gesagt: // Frank Barknecht wrote:
If this "dumb user" wasn't so dumb to reject having to create abstractions in a seperate file, he would be a lucky user because he would be able to do everything he wanted to using abstractions in seperate files.
It just occured to me that this could be read as if I'd think that users, who don't like seperate files, were dumb, but that's not what I meant to express. I think they are wrong, but I don't consider them dumb at all.
Frank Barknecht _ ______footils.org_ __goto10.org__
On Wed, 4 Oct 2006 01:54:49 +0100 padawan12 padawan12@obiwannabe.co.uk wrote:
In both cases you created a new local copy replacing $ (initialise time arguments) with inlets instead. Granted, you cannot now say [pd MySubpatch arg1 arg2..] and must explicitly set the parameters through the inlets, but that's what you wanted.
Sorry, that's nonsense. Obviously they *are* different cases. I'm getting ahead of myself imagining aliases derived from true abstractions where each $arg in the abstraction is replaced by an inlet which implicity broadcasts to a local variable $n
a.
hola a totes,
im developing a 4 sample trigger with effects patx in pd.
Im using the ydegoyon's playlist as a sample selector, but im wondering if there is any object/external that bangs different signals only with the movement of the mouse (without any click)...
any suggestions for a mouseover trigger interface?
salut x!
:::::::::::::::::::::::::::::::::
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
You could use MouseState in the Cyclone library. Send it bangs through a metro at your required sampling period, and then use a select object or moses to filter the data.
~Kyle
On 10/3/06, x4v1 freequencies@straddle3.net wrote:
hola a totes,
im developing a 4 sample trigger with effects patx in pd.
Im using the ydegoyon's playlist as a sample selector, but im wondering if there is any object/external that bangs different signals only with the movement of the mouse (without any click)...
any suggestions for a mouseover trigger interface?
salut x!
:::::::::::::::::::::::::::::::::
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Kyle Klipowicz a écrit :
You could use MouseState in the Cyclone library. Send it bangs through a metro at your required sampling period, and then use a select object or moses to filter the data.
~Kyle
On 10/3/06, x4v1 freequencies@straddle3.net wrote:
hola a totes,
im developing a 4 sample trigger with effects patx in pd.
Im using the ydegoyon's playlist as a sample selector, but im wondering if there is any object/external that bangs different signals only with the movement of the mouse (without any click)...
toxy/tot can capture messages sent to a patch, mouse motions, mouse clicks, menu closing ect...
___________________________________________________________________________ Découvrez un nouveau moyen de poser toutes vos questions quel que soit le sujet ! Yahoo! Questions/Réponses pour partager vos connaissances, vos opinions et vos expériences. http://fr.answers.yahoo.com
x4v1 wrote:
any suggestions for a mouseover trigger interface?
If GridFlow is an option for you, you can get detailed mouse (and keyboard, too) events from GridFlow's [#out window] and parse them with [#mouse]. [#out window]--[#mouse] outputs movement events, not only clicks.
Claude Heiland-Allen wrote:
x4v1 wrote:
any suggestions for a mouseover trigger interface?
If GridFlow is an option for you, you can get detailed mouse (and keyboard, too) events from GridFlow's [#out window] and parse them with [#mouse]. [#out window]--[#mouse] outputs movement events, not only clicks.
Claude
pdp can do what you describe there too, but i think xavi wants an object to select files, not to get mouse coordinates.
that's a mode that could be added to playlist, but not the default one, as it could be very confusing ( i don't like touchpads that click by themselves neither )
ciao, sevy
On Wed, 4 Oct 2006, padawan12 wrote:
The necessity for abstractions to be separate files is imho one of Pds most significant flaws. I avoid using abstractions entirely because even with the most careful management they are more trouble than they are worth.
Let me propose a syntax addition: an abstraction file would be embeddable in another pd file (any other pd file) just by inserting that file anywhere where an #X obj can be put, then add the following line:
#X class myfilename;
Where "myfilename" is the classname (the filename of the abstraction minus the .pd suffix)
This proposal makes a bit more sense in combination with multiple objectmakers as I proposed recently.
A "convert abstractions to subpatches"
no. an abstraction and a subpatch are quite different, especially for the handling of $0, $1, $2, ... where every abstraction instance (and every messagebox) brings a new context for the $-variables. It would still be possible to do the conversion by replacing all dollar-signs by their corresponding values, but that's almost never what I'd want to do.
But those that really *use* Pd a lot probably agree with me that another reason for abstractions is to test/edit a piece of code in many places, and once you've got it right cast it in stone as a subpatch.
I don't know why I'd like to cast anything in stone like that. For casting in stone, it's sufficient to just stop editing it. That way, whenever you want to uncast it, you just resume editing it.
- Subpatches - single fixed code blocks
- Aliases - reusable code blocks within the main file
- Abstractions - reusable code blocks in separate files
I don't think that it should be called Aliases. That name should be reserved for something else whose purpose is more one of aliasing: e.g. multiple creator names for one class...
I believe that (2) should still be called Abstractions, unless we get another name for both (2) and (3) which is less vague and/or less long than Abstractions.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
Hallo, Mathieu Bouchard hat gesagt: // Mathieu Bouchard wrote:
- Subpatches - single fixed code blocks
- Aliases - reusable code blocks within the main file
- Abstractions - reusable code blocks in separate files
I believe that (2) should still be called Abstractions, unless we get another name for both (2) and (3) which is less vague and/or less long than Abstractions.
It occured to me, that "1) Subpatches" already have a different name which IMO is a much better name for the concept realized: "page". Maybe I'll use [page whatever] from now on in my patches. It's a better name because subpatches aren't patches themselves, but parts of a patch much like objects. Like pages in a book, sub"pages" are used to collect and organize content, that doesn't fit on one page alone.
(Embedded abstractions may be called subpatches then, but it's too late for that.)
Frank Barknecht _ ______footils.org_ __goto10.org__
On Thu, 5 Oct 2006, Frank Barknecht wrote:
It occured to me, that "1) Subpatches" already have a different name which IMO is a much better name for the concept realized: "page".
I would have used [page] instead of [pd], long ago; however, in 2002 or 2003, I found a bug that only applies to [page] and not [pd], and reported it on pd-list, but it never got fixed. This is because subpatches need a special hack in order to not lose their contents while being deleted. This is because pd doesn't have the reinitialization feature of jMax, so something had to be hardcoded, and it got hardcoded for [pd] but not for [page]. This is a two-line fix that I could provide if you want it.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
Hallo, Mathieu Bouchard hat gesagt: // Mathieu Bouchard wrote:
This is because pd doesn't have the reinitialization feature of jMax, so something had to be hardcoded, and it got hardcoded for [pd] but not for [page]. This is a two-line fix that I could provide if you want it.
That would be great.
(You or I could put it in the patch tracker then. It wouldn't be much use if only us would be able to use [page] correctly in our patched Pds.)
Frank Barknecht _ ______footils.org_ __goto10.org__
On Wed, 4 Oct 2006 00:12:21 +0100 padawan12 padawan12@obiwannabe.co.uk wrote:
I don't know that there is a sensible order of precedence yet, like abstractions in the path > abstractions in the same directory as the patch > abstractions inside the patch (aliases).
oops, reverse those inequalities :)
a.
Hallo, padawan12 hat gesagt: // padawan12 wrote:
On Wed, 4 Oct 2006 00:12:21 +0100 padawan12 padawan12@obiwannabe.co.uk wrote:
I don't know that there is a sensible order of precedence yet, like abstractions in the path > abstractions in the same directory as the patch > abstractions inside the patch (aliases).
oops, reverse those inequalities :)
Abstraction next to a patch overwrite abstractions somewhere in your path for that patch.
Frank Barknecht _ ______footils.org_ __goto10.org__