A few days ago I added class_addmethod2 to m_class.c and m_pd.h.
Its advantages over class_addmethod are:
1. it doesn't use varargs and you don't need to remember to use A_NULL 2. the syntax is shorter so declarations can fit in one line 3. it's closer to how binbuf_addv works
basically, atom types are given letters:
f=A_FLOAT F=A_DEFFLOAT s=A_SYMBOL S=A_DEFSYMBOL p=A_POINTER *=A_GIMME !=A_CANT (e.g. for dsp messages)
so instead of writing:
class_addmethod(myclass, (t_method)myclass_mymethod, gensym("mymethod"), A_POINTER, A_FLOAT, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYMBOL, A_NULL);
you can write:
class_addmethod2(myclass, (t_method)myclass_mymethod, gensym("mymethod"), "pffsFFS");
and class_addmethod3 is a macro in desire.c which further abbreviates it:
class_addmethod3(myclass, myclass_mymethod, "mymethod", "pffsFFS");
____________________________________________________________________ Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju Freelance Digital Arts Engineer, Montréal QC Canada
How about calling this "class_addv" or, possibly, "class_vmess"? I think it's a much better design than class_addmethod and I should add it, once we figure out the best name, to the "main" API.
cheers Miller
On Sun, Nov 20, 2005 at 01:57:24PM -0500, Mathieu Bouchard wrote:
A few days ago I added class_addmethod2 to m_class.c and m_pd.h.
Its advantages over class_addmethod are:
- it doesn't use varargs and you don't need to remember to use A_NULL
- the syntax is shorter so declarations can fit in one line
- it's closer to how binbuf_addv works
basically, atom types are given letters:
f=A_FLOAT F=A_DEFFLOAT s=A_SYMBOL S=A_DEFSYMBOL p=A_POINTER *=A_GIMME !=A_CANT (e.g. for dsp messages)
so instead of writing:
class_addmethod(myclass, (t_method)myclass_mymethod, gensym("mymethod"), A_POINTER, A_FLOAT, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYMBOL, A_NULL);
you can write:
class_addmethod2(myclass, (t_method)myclass_mymethod, gensym("mymethod"), "pffsFFS");
and class_addmethod3 is a macro in desire.c which further abbreviates it:
class_addmethod3(myclass, myclass_mymethod, "mymethod", "pffsFFS");
Mathieu Bouchard - t?l:+1.514.383.3801 - http://artengine.ca/matju Freelance Digital Arts Engineer, Montr?al QC Canada
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
I have to say that I like the A_FLOAT, etc names better (you can probably guess why). Code should document itself. "pffsFFS" is easy to skim over while "A_POINTER, A_FLOAT, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYMBOL" is very clear. I won't miss the A_NULL though.
This function is only used once per object, and it defines the structure of the object, so it should be as clear as possible. The A_FLOAT style of function is very commonly used throughout C libraries, so it makes sense.
.hc
On Dec 15, 2005, at 12:49 PM, Miller Puckette wrote:
How about calling this "class_addv" or, possibly, "class_vmess"? I think it's a much better design than class_addmethod and I should add it, once we figure out the best name, to the "main" API.
cheers Miller
On Sun, Nov 20, 2005 at 01:57:24PM -0500, Mathieu Bouchard wrote:
A few days ago I added class_addmethod2 to m_class.c and m_pd.h.
Its advantages over class_addmethod are:
- it doesn't use varargs and you don't need to remember to use
A_NULL 2. the syntax is shorter so declarations can fit in one line 3. it's closer to how binbuf_addv works
basically, atom types are given letters:
f=A_FLOAT F=A_DEFFLOAT s=A_SYMBOL S=A_DEFSYMBOL p=A_POINTER *=A_GIMME !=A_CANT (e.g. for dsp messages)
so instead of writing:
class_addmethod(myclass, (t_method)myclass_mymethod, gensym("mymethod"), A_POINTER, A_FLOAT, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYMBOL, A_NULL);
you can write:
class_addmethod2(myclass, (t_method)myclass_mymethod, gensym("mymethod"), "pffsFFS");
and class_addmethod3 is a macro in desire.c which further abbreviates it:
class_addmethod3(myclass, myclass_mymethod, "mymethod", "pffsFFS");
Mathieu Bouchard - t?l:+1.514.383.3801 - http://artengine.ca/matju Freelance Digital Arts Engineer, Montr?al QC Canada
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
________________________________________________________________________ ____
"I have the audacity to believe that peoples everywhere can have three meals a day for their bodies, education and culture for their minds, and dignity, equality and freedom for their spirits." - Martin Luther King, Jr.
Hallo, Hans-Christoph Steiner hat gesagt: // Hans-Christoph Steiner wrote:
I have to say that I like the A_FLOAT, etc names better (you can probably guess why). Code should document itself. "pffsFFS" is easy to skim over while "A_POINTER, A_FLOAT, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYMBOL" is very clear. I won't miss the A_NULL though.
Maybe a "best of both worlds" approach could be used, that allows both long names and short aliases for methods, that accept veryveryverymany arguments and thus aren't readable with A_POINTER,... anyways.
I could think of using a field delimiter like ":" in the argument type string: "p:f:f:s" or "A_POINTER:A_FLOAT:A_FLOAT:A_SYMBOL" then could be allowed. And we would get rid of A_NULL in both cases.
Ciao
On Dec 16, 2005, at 3:48 AM, Frank Barknecht wrote:
Hallo, Hans-Christoph Steiner hat gesagt: // Hans-Christoph Steiner wrote:
I have to say that I like the A_FLOAT, etc names better (you can probably guess why). Code should document itself. "pffsFFS" is easy to skim over while "A_POINTER, A_FLOAT, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYMBOL" is very clear. I won't miss the A_NULL though.
Maybe a "best of both worlds" approach could be used, that allows both long names and short aliases for methods, that accept veryveryverymany arguments and thus aren't readable with A_POINTER,... anyways.
I could think of using a field delimiter like ":" in the argument type string: "p:f:f:s" or "A_POINTER:A_FLOAT:A_FLOAT:A_SYMBOL" then could be allowed. And we would get rid of A_NULL in both cases.
I think that this is readable:
class_addmethod(test_class, (t_method) test_start, gensym("start"), A_DEFSYMBOL, A_POINTER, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL);
You can't get longer than that since then an A_GIMME needs to be used.
.hc
________________________________________________________________________ ____
"Information wants to be free." -Stewart Brand
On Fri, 16 Dec 2005, Frank Barknecht wrote:
Maybe a "best of both worlds" approach could be used, that allows both long names and short aliases for methods, that accept veryveryverymany arguments and thus aren't readable with A_POINTER,... anyways.
I'm not very much concerned with methods that accept veryveryverymany arguments (except in the case of undifferentiated A_GIMME args, a la [list append] and such). The readability aspect I had in mind is that the declaration of methods should be formattable as a nice table that lists you all the methods of a class in a way that does fit on a page. You *could* use tools that would generate the big picture from a more verbosely written code, but it's easier to get the big picture for free as you're writing the code (or reading it).
I could think of using a field delimiter like ":" in the argument type string: "p:f:f:s" or "A_POINTER:A_FLOAT:A_FLOAT:A_SYMBOL" then could be allowed. And we would get rid of A_NULL in both cases.
I think that atomtypes are very few and will most likely stay rather few, so it's easy to remember the abbreviations of them all, and we'll never come close to run out of letters of the alphabet, unless we change the typing paradigm completely, but that would require a completely new API anyway.
Note: I don't even know whether it will be possible to add A_STRING and A_LISTPTR, because reference-counting would require that t_atom gets a constructor and a destructor, which would be a change to Pd's external API which wouldn't be backwards-compatible.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
On Thu, 15 Dec 2005, Hans-Christoph Steiner wrote:
I have to say that I like the A_FLOAT, etc names better (you can probably guess why). Code should document itself.
A_FLOAT doesn't really tell you that it's an atom. "A" is an ambiguous abbreviation of "ATOM". ATOM_FLOAT is better, but it's misleading because it isn't a t_atom, it's a t_atomtype, so it should be called ATOMTYPE_FLOAT instead. But then it doesn't tell you it's from Pd. PD_ATOMTYPE_FLOAT could be confused with something else called Pd, possibly another program's name or something else called "PD" inside of another program. PURE_DATA_ATOMTYPE_FLOAT doesn't explain to you what a FLOAT is, and anyway, FLOAT is jargon of the nerds; so PURE_DATA_ATOMTYPE_32_BIT_FLOATING_POINT_NUMBER is already better, but then not everybody knows what a floating-point-number is, so it should be PURE_DATA_ATOMTYPE_32_BIT_RELATIVE_PRECISION_NUMBER.
class_addmethod(myclass, (t_method)myclass_mymethod, gensym("mymethod"), A_POINTER, A_FLOAT, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYMBOL, A_NULL);
It's far better to write this as:
object_class_add_method_declaration( my_pointer_to_object_class, (t_method_pointer)my_object_class_mymethod, generate_singleton_character_string_pointer("mymethod"), PURE_DATA_ATOMTYPE_32_BIT_RELATIVE_PRECISION_NUMBER, PURE_DATA_ATOMTYPE_32_BIT_RELATIVE_PRECISION_NUMBER, PURE_DATA_ATOMTYPE_SINGLETON_CHARACTER_STRING_POINTER, PURE_DATA_ATOMTYPE_32_BIT_RELATIVE_PRECISION_NUMBER_DEFAULTING_TO_ZERO, PURE_DATA_ATOMTYPE_32_BIT_RELATIVE_PRECISION_NUMBER_DEFAULTING_TO_ZERO, PURE_DATA_ATOMTYPE_SINGLETON_CHARACTER_STRING_POINTER_DEFAULTING_TO_EMPTY_STRING, PURE_DATA_ATOMTYPE_TERMINATOR_TO_ENSURE_THAT_WE_DO_NOT_BLUESCREEN_INTO_OBLIVION);
which is obviously a lot clearer, we all should agree.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada
On Thu, 15 Dec 2005, Miller Puckette wrote:
How about calling this "class_addv" or, possibly, "class_vmess"?
Why would it be called by either of those names? it doesn't do "addv", it only reminds of addv's syntax, but then so do my functions pd_scanargs, pd_saveargs, sys_mgui, and some future ones too (pd_setargs).
I think it's a much better design than class_addmethod and I should add it, once we figure out the best name, to the "main" API.
I think it should be more polished before being added to any API. Here are the changes that I propose:
f=A_FLOAT F=A_DEFFLOAT s=A_SYMBOL S=A_DEFSYMBOL p=A_POINTER
add "=" meaning DEFAULT (the equal sign is the default-value sign in C++, Python, Ruby) such that all subsequent A_FLOAT and A_SYMBOL and A_POINTER are treated as default. That would introduce a default-pointer feature and would deprecate A_DEFFLOAT, A_DEFSYM, A_DEFSYMBOL.
(there's a default-value feature called ";" in pd_scanargs but it works differently and it mentally conflicts with binbuf's idea of ";". I don't recall why I picked ";" in the first place, but I was inspired by an equivalent mechanism in Ruby)
the problem with that "=" (and A_DEFFLOAT etc) is that it doesn't allow to specify default atom values other than zero and null-symbol, contrary to how the "=" works in C++/Python/Ruby.
*=A_GIMME
A_GIMME would come to work with other specifiers, as long as it is supplied last, so "fs*" would result in args like (t_pd *, t_float, t_symbol*, int argc, t_atom *argv) where argc,argv would only represent the _rest_ of the args. The "=" specifier can be combined so that there can be mandatory-args, optional-args and rest-args in the same message.
That usage of "*" would be consistent with the splat-operator (unary *) in Python and Ruby, and equivalent concepts in other languages: the "&rest" macro in CommonLISP; the "args" keyword in Tcl.
!=A_CANT (e.g. for dsp messages)
I'd like to have more doc on how A_CANT is _meant_ to be used.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju | Freelance Digital Arts Engineer, Montréal QC Canada