How to handle large prgrams in LISP

Discussion of Common Lisp
Post Reply
black_hat
Posts: 5
Joined: Sun Sep 05, 2010 9:53 am

How to handle large prgrams in LISP

Post by black_hat » Fri Oct 08, 2010 4:37 am

Hello,

As I am still new to LISP, I am trying to develop a good understanding of LISP programming style. My question is if I have a program with multiple class definitions as well as method definitions, is it typical to place everything in one file or does the code get 'modularized' if you will. I have a current project which is rather large and to make the code more manageable I put the definitions for class1 and it's methods in file1, definitions for class2 and it's methods in file2,...,definitions for class1 and it's methods in file_n. Then in my main program I simply add the lines:

Code: Select all

(load "file1")
...
(load file_n")
...
(remainder of code)
Is this acceptable LISP practice or is there a better way? Thanks

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: How to handle large prgrams in LISP

Post by ramarren » Fri Oct 08, 2010 5:30 am

black_hat wrote:LISP
First thing about style, the family of languages is usually called "Lisp", and Common Lisp, which is only one of quite many languages belonging to this family, is most certainly spelled without capitalizing every letter. The "LISP" form is usually considered archaic.

Projects in CL are usually handled with a system definition facility, this days most often ASDF. It is included in most CL implementations. There is a small introduction to creating projects here. You can read ASDF manual for more details, although note that some CL implementations might not yet include the new ASDF 2.0 version.

Also, almost all CL implementation have a native-code compiler, and all have at least some compilation capability, since the standard requires it, which means that usually you would want to compile the files before loading them. ASDF deals with that and recompiling only things that changed automatically.

Paul Donnelly
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: How to handle large prgrams in LISP

Post by Paul Donnelly » Fri Oct 08, 2010 4:25 pm

black_hat wrote:I have a current project which is rather large and to make the code more manageable I put the definitions for class1 and it's methods in file1, definitions for class2 and it's methods in file2,...,definitions for class1 and it's methods in file_n.
It seems a little nutty to break it down that far. I wouldn't have a file for every class.

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: How to handle large prgrams in LISP

Post by nuntius » Sat Oct 09, 2010 9:12 am

One file per class is the norm in Java. However, the java compiler also uses that information to locate the source and object files. CL has no such tool; thus there is little benefit to this convention (and it rather defeats the purpose of generic functions).

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: How to handle large prgrams in LISP

Post by gugamilare » Sat Oct 09, 2010 12:09 pm

nuntius wrote:One file per class is the norm in Java. However, the java compiler also uses that information to locate the source and object files. CL has no such tool; thus there is little benefit to this convention (and it rather defeats the purpose of generic functions).
In Emacs you can find functions, classes and any other kind definitions using [M-.], but that, of course, does not depend on defining an object per file.

Warren Wilkinson
Posts: 117
Joined: Tue Aug 10, 2010 11:24 pm
Location: Calgary, Alberta
Contact:

Re: How to handle large prgrams in LISP

Post by Warren Wilkinson » Sat Oct 09, 2010 2:44 pm

My code is grouped by 'operational unit' rather than class. I do not use ASDF for my own code (but I might've if my code were intended to be a library).

In my large program I tried to have very little 'project defining code' overhead. I got the idea from Forth which (in some versions) don't even have files insead only having 1024 character 'screens'. What Forth users do is have the first screen (screen 0) work like a table of contents and load other blocks where real program code is. So my first lisp file is called 'load.lisp', it loads all the SBCL extensions (using :require) then loads asdf libraries and then my files.

Most of my code is in source subdirectories. I have 1 package per file, and I name them as :subdir.file. 'Util' is my first subdirectory which contains util.lisp (generic utilities), tree.lisp (a really simple tree built from lists), and encrypt.lisp (my interface to some encryption/md5 libraries) etc. These files define packages util.util, util.tree and util.encrypt. My other source subdirectories are database, forth, view, http, and web. I do not have second level load.lisps in subdirectorys, the toplevel load.lisp loads every file.

Since package-names = directory paths I created a perl script to compute lisp file dependencies which I used in a makefile. Later on, I adopted another Forth principle: Source Code = Object code. In color forth there is no intermediate stage called object code (in fact, you directly edit object code with what is almost a decompiler). In Lisp there is a destinction between source and object code, but I ignore it. My build is SBCL --load "load.lisp" --eval "(build-image)", where (build-image) is a routine defined at the end of load.lisp that calls 'save-image-and-die'. In my makefile I named this target server.core.

To deploy I invoke a makefile target called deploy which tar.gzs the makefile and source directory. I then secure copy (using scp from the ssh tools) and untar it on the server, build and install it. Then I delete the source code off the server. To make installation simple, I compile a lot of external files right into my lisp core image. For example, most of the images my server uses and the CSS files are compiled into the program using compile-time-value. These data files I store in the source directory as well, under a subdirectory called 'static'.

Code: Select all

(define compile-time-value (expr) (eval expr))
Need an online wiki database? My Lisp startup http://www.formlis.com combines a wiki with forms and reports.

JamesF
Posts: 98
Joined: Thu Jul 10, 2008 7:14 pm

Re: How to handle large prgrams in LISP

Post by JamesF » Mon Oct 11, 2010 6:46 pm

There's not really a canonical way of doing it.

Personally, I tend to start with a single file, then ASDF-ify it when it starts looking like a real application. Once things get to the point where a single file is unwieldy, I split it into two or more files along whatever lines appear most logical at the time. Those split-lines can change over time, with growth and refactoring. Sometimes it makes most sense to put an object and its methods in the same file; other times, you may want the file and its generic functions in one place, and the method declarations elsewhere. I've used this latter trick in order to be able to transparently swap out things like different markup parsers and backend handlers (text-files vs database) for a wiki that I've been chipping away at.

If you're most comfortable with keeping each object and its methods in their own files, I'd suggest carrying on with that for now, to avoid adding yet another learning curve to the collection. Sooner or later you'll get sick of adding more file declarations and start agglomerating the smaller ones into single files :)
If you go that way, you may well want to put your functions in yet another file... except maybe for helper-functions that are specific to a given method, which probably want to be wherever the method in question has gone.

Post Reply