[Csnd-dev] Named Arguments
Steven Yi <[email protected]>
| Newsgroups | gmane.comp.audio.csound.devel |
|---|---|
| Message-ID | <CANtcCs7mvKZNdqd53Xrhwf9953UAjj7hUWyp0Y=bUV-zqYAZrQ@mail.gmail.com> |
Hi All,
Looking at https://github.com/csound/csound/issues/745 and trying to
evaluate for milestone scheduling. Rather than look at it from the view of
liking the feature or not, as I think there's plenty of supporters for
languages with named arguments, I'm interested to discuss the technical
requirements. In particular, it seems like something that will require
internal changes and therefore has API stability implications.
Language-wise, we'd have to figure out the rules for named arguments vs.
positional arguments, i.e., sorting out what to do if someone writes:
some_opcode(value: 1, 3, 4)
Internally, opcode would need a map of argument names to positions. For
both old-style and new-style UDOs we have information we can parse from
either the xin/xout statements or the opcode signature (in new-style UDOs).
For native opcodes, we do not have any information for arguments besides
position and type.
One thing that might be interesting internally is to redefine OENTRY
to move away from the input and output types as strings and instead use
data structures. It would be some tedious work but offers some interesting
benefits and drawbacks. Benefits would include:
* having all of the type data pre-parsed at compile-time (saving runtime
work)
* better error reporting for opcode used errors
* potential for further arg type enhancements (optional, default values,
etc.)
Drawbacks I can think of:
* Likely to take up more memory to add arg names
* Once an arg is named, we'd have to be very careful to check the arg names
or new projects might break if the arg name changes
I did a mockup of what the code might look like for static initialization
of arguments with names and types:
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
typedef struct {
char* name;
int type;
} OPCODE_ARG;
typedef struct {
char* name;
int outcount;
int incount;
OPCODE_ARG args[];
} OENTRY;
OENTRY a = {
.name = "my_test_opcode",
.outcount = 1,
.incount = 2,
.args = {{ "out", 0}, { "inarg1", 0}, { "inarg2", 1}},
};
int main(int argc, char** argv) {
printf("Opcode name: %s\n", a.name);
printf("Opcode out args\n");
for (int i = 0; i < a.outcount; i++) {
OPCODE_ARG* out_type = &a.args[i];
printf(" %s: %d\n", out_type->name, out_type->type);
}
printf("Opcode in args\n");
for (int i = a.outcount; i < a.incount + a.outcount; i++) {
OPCODE_ARG* in_type = &a.args[i];
printf(" %s: %d\n", in_type->name, in_type->type);
}
}
(In our code, the OPCODE_ARG would have a CS_VAR_TYPE instead of int type;
this is just mockup code.)
One can imagine the OPCODE_ARG having other fields like "void*
defaultValue", that the compiler could then treat the arg as optional.
Regardless, we need to figure out sooner rather than later what we want to
do for Issue 745 as I think it would require a change to OENTRY and would
have to either go into CS7 or delayed until CS8.
Steven