When working on a larger lisp code base, one with 10+ files in one package, I begin to get nervous about accidental name conflicts, and was wondering how other people deal with this.
Here's the scenario I'm worried about:
* dsl.lisp, written by a coworker two years ago, has a number of small functions that are helpers for the main #'WRITE-DSL-REPORT function; one of these helpers is #'GET-WAN-IPS * nagios-config.lisp, written by me today, has a number of small functions that are helpers for the main #'WRITE-NAGIOS-CONFIG function; one of these helpers is #'GET-WAN-IPS * I miss the compiler warning about redefining #'GET-WAN-IPS * I test my code, it works in my REPL so I commit and call it a day * Code eventually gets pushed to production and #'WRITE-DSL-REPORT is broken
It doesn't happen very often (and testing procedures usually catch stuff before it goes to production), but it seems like there should be a nicer way to deal with helper functions that you want to develop/test from the REPL, but don't need to be used outside the current file.
I had a few ideas to solve it, none of which I really like. I could add a top-level FLET for the file, but the extra indentation will be annoying and it'll be harder to test/maintain those helper functions. I could define a helper package, per-file, and put my helper functions in that package (e.g. (defun nagios-config-helpers::get-wan-ips ...)), but that feels funny and awkward, which usually means it's a bad idea. I could break up my code into many smaller packages, each exporting and importing the functions needed elsewhere in the system, but that seems like recipe for dependency headaches and a lot of unneeded paperwork.
Do other people have this anxiety? Are there elegant ways to deal with it? (besides medication and more unit testing)
Thanks,
For your specific example, I would do some combination of
- Figure out why there are 2 GET-WAN-IPS helpers, how they differ, and factor to a single function. - Change GET-WAN-IP to a generic function and factor. - Create another package and factor.
The entire point of packages is to avoid name conflicts. So, if you are experiencing a name conflict in a single package, it's time to factor the code.
Search the archives for a recent discussion on conflicts between packages, maybe that has some insight that is applicable to your issue.
Good luck,
Tom ---------------------------------------------------------------- Thomas M. Hermann Odonata Research LLC http://www.odonata-research.com/ http://www.linkedin.com/in/thomasmhermann
On Wed, Apr 13, 2011 at 1:35 PM, Ryan Davis ryan@acceleration.net wrote:
When working on a larger lisp code base, one with 10+ files in one package, I begin to get nervous about accidental name conflicts, and was wondering how other people deal with this.
Here's the scenario I'm worried about:
- dsl.lisp, written by a coworker two years ago, has a number of small
functions that are helpers for the main #'WRITE-DSL-REPORT function; one of these helpers is #'GET-WAN-IPS - nagios-config.lisp, written by me today, has a number of small functions that are helpers for the main #'WRITE-NAGIOS-CONFIG function; one of these helpers is #'GET-WAN-IPS
- I miss the compiler warning about redefining #'GET-WAN-IPS
- I test my code, it works in my REPL so I commit and call it a day
- Code eventually gets pushed to production and #'WRITE-DSL-REPORT is
broken
It doesn't happen very often (and testing procedures usually catch stuff before it goes to production), but it seems like there should be a nicer way to deal with helper functions that you want to develop/test from the REPL, but don't need to be used outside the current file.
I had a few ideas to solve it, none of which I really like. I could add a top-level FLET for the file, but the extra indentation will be annoying and it'll be harder to test/maintain those helper functions. I could define a helper package, per-file, and put my helper functions in that package (e.g. (defun nagios-config-helpers::get-wan-ips ...)), but that feels funny and awkward, which usually means it's a bad idea. I could break up my code into many smaller packages, each exporting and importing the functions needed elsewhere in the system, but that seems like recipe for dependency headaches and a lot of unneeded paperwork.
Do other people have this anxiety? Are there elegant ways to deal with it? (besides medication and more unit testing)
Thanks,
-- Ryan Davis Acceleration.net Director of Programming Services 2831 NW 41st street, suite B Gainesville, FL 32606
Office: 352-335-6500 x 124 Fax: 352-335-6506
pro mailing list pro@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/pro
On Wed, Apr 13, 2011 at 11:35 AM, Ryan Davis ryan@acceleration.net wrote:
When working on a larger lisp code base, one with 10+ files in one package, I begin to get nervous about accidental name conflicts, and was wondering how other people deal with this.
I used to work on some large Lisp systems in a place where standard practice was often to let packages grow very large -- much larger than 10 source files -- and as I recall, name collisions occurred remarkably rarely. And often when they did happen, the two functions actually had the same or very similar contracts.
I think part of the reason for this was good naming practices. As a general matter, the more specific the purpose of a routine, the longer its name should be. If it's used only in one file, there should be at least one word in its name that identifies it as related to the other code in the file, such that that word is unlikely to appear in unrelated code.
If that doesn't satisfy you, you're welcome to try my lexical contexts package:
http://common-lisp.net/cgi-bin/viewcvs.cgi/devel/src/contexts.text?rev=1.1&a... http://common-lisp.net/cgi-bin/viewcvs.cgi/devel/src/contexts.lisp?rev=1.1&a...
I've found it handy on occasion, though I don't use it for everything by any means.
-- Scott
On 4/13/2011 2:35 PM, Ryan Davis wrote:
When working on a larger lisp code base, one with 10+ files in one package, I begin to get nervous about accidental name conflicts, and was wondering how other people deal with this.
Here's the scenario I'm worried about:
* dsl.lisp, written by a coworker two years ago, has a number of small functions that are helpers for the main #'WRITE-DSL-REPORT function; one of these helpers is #'GET-WAN-IPS * nagios-config.lisp, written by me today, has a number of small functions that are helpers for the main #'WRITE-NAGIOS-CONFIG function; one of these helpers is #'GET-WAN-IPS * I miss the compiler warning about redefining #'GET-WAN-IPS * I test my code, it works in my REPL so I commit and call it a day * Code eventually gets pushed to production and #'WRITE-DSL-REPORT is broken
It doesn't happen very often (and testing procedures usually catch stuff before it goes to production), but it seems like there should be a nicer way to deal with helper functions that you want to develop/test from the REPL, but don't need to be used outside the current file.
The compiler warning should not have been missed. We have a "no warnings" policy so warnings stand out, and I use the option in the AllegroCL IDE that has it pop up a dialog on warnings (so I /really/ cannot miss them).
I suspect also that there may be a problem with the conclusion that the code has been tested and works because it works in a REPL.
Absent those two issues, there is no longer a problem. :)
kt