Thread: [tuxdroid-user] Naming functions
Status: Beta
Brought to you by:
ks156
From: neimad <ror...@gm...> - 2007-06-24 15:21:05
|
Hello, The naming of functions is currently very inconsistent: some are verbs (orders), some are nouns; some have a prefix, some have a suffix -- some have both, and some have neither. For example: tux_connection() is a noun but connect_to_tux() is an order, id_request() is prefixed while wakeup_tux() is suffixed. These last two functions both take an id but one has "id" in its name and the other has "tux"... Imo, all functions should be _verbs_ in the imperative form: functions are *orders* given to the machine. It's the usual naming scheme for english code. I think a good convention is also to prefix functions with the type of object they act upon. Say I have a type dongle_t; then, connecting to a dongle would be done with dongle_connect(). What about send_usb_tux_cmd() ? Does it "send a 'usb tux' command" ? If so, what does that mean ? I have a really hard time trying to figure out what functions do from their name. We really need to define some consistent naming conventions for types, variables and functions... Damien |
From: David B. <da...@ja...> - 2007-06-25 10:35:42
|
On Sun, 24 Jun 2007 17:23:52 +0200, neimad <ror...@gm...> wrote: > Hello, > > The naming of functions is currently very inconsistent: some are verbs > (orders), some are nouns; some have a prefix, some have a suffix -- > some have both, and some have neither. > > For example: tux_connection() is a noun but connect_to_tux() is an > order, id_request() is prefixed while wakeup_tux() is suffixed. These > last two functions both take an id but one has "id" in its name and > the other has "tux"... > > Imo, all functions should be _verbs_ in the imperative form: functions > are *orders* given to the machine. It's the usual naming scheme for > english code. > > I think a good convention is also to prefix functions with the type of > object they act upon. Say I have a type dongle_t; then, connecting to > a dongle would be done with dongle_connect(). > > What about send_usb_tux_cmd() ? Does it "send a 'usb tux' command" ? > If so, what does that mean ? I have a really hard time trying to > figure out what functions do from their name. > > We really need to define some consistent naming conventions for types, > variables and functions... > I completely agree with you here but I have really no experience with naming practices. So just give me the name of a couple of functions you're not sure about, I'll try to describe them correcty so you can show us some good names. Here are the connection functions I wrote and some description of them: - disconnect_from_tux() Disconnect from a tux (only one is connected so we don't need to pass any parameter) - connect_to_tux(id) Connect to a tux which has the id given as parameter - random_tux_connection() Connect to the first tux found around, that's the same behavior as the connection we have now in the daemon, we can't choose which tux we want to connect to, so this is random. - id_request(*id) Returns the id (as pointer) of the tux you're connected to. (That may sound stupid as you had to give the id to connect, but another application running on the same daemon/tux will not know it. And if your application is restarted, the connection will stay but you may loose the id.) - id_lookup(*id) Returns the id (pointer) of the first tux found around - change_id(id) Chenge the id of a disconnected tux to the id given as parameter - wakeup_tux(id) Wake-up the tux with the id given as parameter - avoid_wifi_channel(wifi_channel) Avoid the frequencies of a wifi_channel, tux will use all the other frequencies except those used by the given wifi_channel. A few extra questions and points: - should all these functions return an int that indicates if there's an error or not? - if so, should we do it also for functions that can't catch an error right now, just to ease the future in case we can add an error check later. I guess that makes sense only if we know it's possible to add such a check later; - you can also give some recommendations for the name of parameters (like wifi_channel) and variables while we're at it. What about wakeup or wake_up or wake-up? - is "int id_lookup(*id)" a good way to return both the id and if the command succeeded or not? That's something I copied from some unix functions; - should we return 0 if successful, -1 otherwise in all functions? Some of them return 0 if failure and 1 if success, ... I guess we should be consistent here too - thanks again for taking care of the sanity of the code ;-) David |
From: neimad <ror...@gm...> - 2007-06-25 20:23:31
|
"David Bourgeois" <da...@ja...> writes: [...] > - disconnect_from_tux() > - connect_to_tux(id) > - random_tux_connection() > - id_request(*id) > - id_lookup(*id) > - change_id(id) > - wakeup_tux(id) > - avoid_wifi_channel(wifi_channel) The naming of these particular functions isn't bad per se, but if we want to be consistent throughout the code, we should pick a naming convention. Taking the above functions as examples, I think I'd name them: tux_disconnect() tux_connect() tux_connect_random() tux_id() tux_lookup() tux_change_id() tux_avoid_wifi_channel() or dongle_avoid_wifi_channel() [depending on *what* exactly will avoid using the channel: is it the dongle or tux ?] All these functions work on a "tux" object (albeit abstract, as we don't currently have any data structure representing a tux), hence their tux_ prefix. tux_connect() could be connect_to_tux(), as it doesn't have yet a "tux object" to act upon and instead it does return/find such an object. If I take an example using files: file_t *open_file(const char *filename) This function doesn't act on a file_t object but returns one and thus doesn't have the file_ prefix, but int file_write(file_t *file, void *data, size_t size) acts on a file_t object and thus is prefixed with file_. Or we may just decide that open_file() would be better named file_open(), since it's in a "file" module (my preference). And so on... (Notice too that the file_t parameter is always first.) We can have very strict naming conventions, or we can give some slack, but currently the naming is almost random ;-) I prefer very strict naming conventions, because then you don't even have to ask yourself "what was the name of that function again ?": if you have a file, of type file_t, then you now all ops on it start with file_. Same goes for variables and constants (say, FILE_MODE_RO, FILE_MODE_RW...). Btw, if I have an enum about the file access modes, I'd name it as follows (file_mode prefix for the type and its values): typedef enum { FILE_MODE_RO, FILE_MODE_RW } file_mode_t; > - should all these functions return an int that indicates if there's > an error or not? Not necessarily. Sometimes it's just more convenient to have special values meaning error (for example, >= 0 might be the number of bytes while < 0 is an error). But this is not always possible nor desirable. I don't really have rules here, I just pick what I think is best... > - if so, should we do it also for functions that can't catch an error > right now, just to ease the future in case we can add an error check > later. I guess that makes sense only if we know it's possible to add > such a check later; No, that's "overdesign", kinda. And all your code will have to manage non-existent errors everywhere you call these functions, all for nothing. > - you can also give some recommendations for the name of parameters > (like wifi_channel) and variables while we're at it. What about > wakeup or wake_up or wake-up? I don't have any recommendation for the naming of parameters, except that they should make as obvious as possible what they are, of course. > - is "int id_lookup(*id)" a good way to return both the id and if the > command succeeded or not? That's something I copied from some unix > functions; Yes, it's alright. Going back to your first question: this is a case were it may be possible to return a special value for errors, depending on the actual type of id: if it's signed, the usual convention "< 0 means error" could be used, but if it's unsigned and zero is a valid id value, then you can't and you must write the function as you did. Having special values may also simplify the code a lot: if we can have a special value ID_NONE to mean "no id", then there's no need to have both an id value and a boolean telling whether the id is actually set. > - should we return 0 if successful, -1 otherwise in all functions? > Some of them return 0 if failure and 1 if success, ... I guess we > should be consistent here too Well, those functions that return 1 on success and 0 on failure should really return true and false, respectively. Here too, it all depends on how much consistent we want to be. Imho, a module (say, USBDaemon_log.c) should use the same convention for all its functions as much as possible. Different conventions for different modules might be perfectly legit, though. Damien |
From: David B. <da...@ja...> - 2007-06-25 21:16:11
|
As usual, I'm delighted to read your posts. Thanks for all the details, I've now a much better idea on how to handle that. You're right on the point when saying "naming is almost random", where almost means that sometimes we really think about it but without common guidelines that doesn't make anything better. I'll certainly bug you again when I'll be stuck on some choices. For now I'll go for your suggestions :-) Cheers, David |