From: Waldo
Subject: Packages Best Practices
Date: 
Message-ID: <1194973663.556205.203400@i38g2000prf.googlegroups.com>
Hi,

I'm fairly new to Lisp and have been reading a lot to get up to speed.
My goal is to be able to develop similar type of applications we use
in other languages. However, the other languages we use don't
necessarily support packages.

I've read several books on LISP and I understand the concepts behind
packages (how they are defined and used). However, I'm having some
difficulty deciding how to properly use packages in an real-world
application.

For example, assume I want to develop a simple CRM application (note
this description is only for illustration purposes and may not
necessarily be the best way to develop such application). I'll just
touch upon a couple of models instead of the entire application, but
if you picture the entire application, you would be able to understand
my dilemma.

So, I would create some set of classes that would abstract my access
to the database. Maybe they're just an interface to MySQL (maybe
something a la ActiveRecord).

I would then create, for example, a model for an Party (whether it is
a person, company, etc) which may subclass some of the abstractions
created above to access the database. Then, I would create another
model for the Contact mechanism (e.g. telephones, emails, IMs,
address, etc) which may also subclass some of the abstractions created
above to access the database.

As you go on defining the application, you would create many more
models (e.g. interested products, call or interaction history, etc).
Each model will have a visual representation (e.g. web page) to allow
a user to maintain the data.

So, leaving it up to this point, I would think I have different
approaches on developing something like this. But properly defining
the right package structure is still a bit hard to abstract (for me).

I would think that I could create a package for all the generic
database abstraction, which would export some functionality that I
would import into the models (e.g. crm.database). Then, I could
probably create a package for the models, where I would store the
Party and Contact models (e.g. crm.models). Following this approach, I
could have some other packages for presentations (e.g.
crm.views.models or crm.views.party and/or crm.views.contact, etc)
that would store all the code to interact with the end-user via the
web. I could also have some generic packages for business rules (e.g.
crm.business.party or crm.busienss.contact, etc).

So, the approach above may work and seems to "fragment" the code too
much. Another approach could be to just have something like
crm.database for all the database abstractions, then have something
like crm.party and crm.contact where each of these packages would have
all the relevant code for each model (e.g. the database model
definition, business rules, and presentation interface).

These are just a couple of approaches I can quickly think of, and I'm
sure that if anyone really sat down to think about more approaches,
many more approaches can be thought of.

So, the question goes back to, what are some of the best practices to
follow when structuring a large application with packages?

Thanks for your help

From: Ken
Subject: Re: Packages Best Practices
Date: 
Message-ID: <Afn_i.1937$xt4.864@newsfe10.lga>
Waldo wrote:
> So, the question goes back to, what are some of the best practices to
> follow when structuring a large application with packages?

Just look for any however recognizable a chunk you think you might want 
to use elsewhere in a different application and make that a package so 
when you get to that point you will have some confidence you can just 
take the corresponding directory of code and load just that.

Some people agonize over exposing internals and enforcing that by using 
packages and just exporting certain things and not others but I think in 
practice people do not accidentally use unsupported internals of a 
package and code is easy to change anyway, but if you are into that game 
again look for chunks hairy enough that it will be valuable to say oh 
look I only exported these symbols.

In my current megahugehairy application I punted on packages, they were 
just a nuisance. Other times I found it useful to divide things up after 
quite a bit of code had been written and the process did help me tighten 
up the interfaces. Not sure what that was worth, tho later on there were 
spinoff utilities that just used this package and that and they built 
smoothly.

btw, i am not sure this is a lot different than dividing a big C project 
up into sublibraries and deciding what gets made external.

kt
From: Thomas A. Russ
Subject: Re: Packages Best Practices
Date: 
Message-ID: <ymisl39vc1i.fsf@blackcat.isi.edu>
Waldo <·····@infoway.net> writes:

...
> I would think that I could create a package for all the generic
> database abstraction, which would export some functionality that I
> would import into the models (e.g. crm.database). Then, I could
> probably create a package for the models, where I would store the
> Party and Contact models (e.g. crm.models). Following this approach, I
> could have some other packages for presentations (e.g.
> crm.views.models or crm.views.party and/or crm.views.contact, etc)
> that would store all the code to interact with the end-user via the
> web. I could also have some generic packages for business rules (e.g.
> crm.business.party or crm.busienss.contact, etc).
> 
> So, the approach above may work and seems to "fragment" the code too
> much. Another approach could be to just have something like
> crm.database for all the database abstractions, then have something
> like crm.party and crm.contact where each of these packages would have
> all the relevant code for each model (e.g. the database model
> definition, business rules, and presentation interface).

Well, there is a bit of art to this part of the design.

Part of this also depends on the number of different programmers or
groups that would be working on the project.

The basic idea is that you want to use packages to avoid (especially
inadvertent) naming collisions between bodies of code that serve
different purposes and that might logically be developed independently
of each other.

So, the idea of having your DB compatibility interface layer be in its
own package is a good one.  Whether your main application needs to be
split depends a bit on its size and the degree to which the different
pieces interact.  The more interaction, the less you are likely to need
(or want) to use different packages, since they will either get in the
way (via the need to qualify references) or else you will be tempted to
just :USE the packages together somewhere (in which case you have to
worry about name conflicts between them anyway -- thus losing one of the
benefits of a separate package).

Pascal's advice about considering what sorts of utility "chunks" might
be reusable elsewhere makes a lot of sense, since that is where you have
an independent body of code.

In your example, I would tend to have the database connectivity in a
separate package.  I would have any other interface code (GUI, web
service, etc.) in its own package, and I would have the application
itself, unless very large, be in its own package.

Generally, I would expect that you would use fewer Lisp packages than
say Java packages for the same design, so the Lisp packages would
encompass a larger span of the application itself.

One final thought.  If you find yourself contemplating internal naming
conventions such as FOO-... and BAR-... and BAZ-... to keep things
separate, that is a sign that those parts of the code should perhaps
have their own packages.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Costanza
Subject: Re: Packages Best Practices
Date: 
Message-ID: <5pulgtFsobs7U1@mid.individual.net>
Waldo wrote:

> 
> So, the question goes back to, what are some of the best practices to
> follow when structuring a large application with packages?
> 

See https://lists.csail.mit.edu/pipermail/ll-discuss/2005-August/000837.html

I don't agree with Joe's assessment of the package system, but his 
advice is very good.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Alan Crowe
Subject: Re: Packages Best Practices
Date: 
Message-ID: <86y7d0ya9m.fsf@cawtech.freeserve.co.uk>
Pascal Costanza <··@p-cos.net> writes:

> Waldo wrote:
> 
> > 
> > So, the question goes back to, what are some of the best practices to
> > follow when structuring a large application with packages?
> > 
> 
> See https://lists.csail.mit.edu/pipermail/ll-discuss/2005-August/000837.html
> 
> I don't agree with Joe's assessment of the package system, but his 
> advice is very good.
> 

I've been trying to write a tutorial on the package system,
based on the reverse engineering of the system that I've
done in order to understand it.

http://www.cawtech.demon.co.uk/lisp/symbols-and-packages.html

but have got cold feet about halfway through because I lack
the experience to be handing out advice on Lisp programming
in the large.

I'm encouraged that I've reached the same conclusion as Joe
Marshall, though I express it very differently. One
conclusion of my attempt to reverse engineer the design
goals was:

    Non-goal: Coherent mutability

    One could attempt to compute with the package system by
    changing it as the computation proceeds. This would
    involve tracking internal dependencies in order to
    maintain coherence in the face of mutation. This is
    explicitly rejected. You build the package system. You
    use it, taking advantage of the fact that it is fast and
    memory efficient. Finally you exit the Lisp image,
    discarding it. It only supports sufficient mutability
    for construction and debugging.

Alan Crowe
Edinburgh
Scotland
From: Raffael Cavallaro
Subject: Re: Packages Best Practices
Date: 
Message-ID: <2007111323101816807-raffaelcavallaro@pasdespamsilvousplaitmaccom>
On 2007-11-13 12:23:28 -0500, Waldo <·····@infoway.net> said:

> So, the question goes back to, what are some of the best practices to
> follow when structuring a large application with packages?


Aim for the ability to simply use-package your package without 
conflicts. Don't export symbols with common obvious names, don't export 
more symbols than necessary - both lead to unecessary complexity.

Use common names if you like for the internals of your package, since 
these won't be exported. Export only distinctively named symbols.

Just my personal taste mind you, largely because it simplifies things, 
fwiw, my $.02, etc.
From: Waldo
Subject: Re: Packages Best Practices
Date: 
Message-ID: <1195059859.599802.240480@e9g2000prf.googlegroups.com>
Thanks everyone for their comments.

Although some of you share similar ideas, it is evident that there is
no formal Best Practices to follow, which conforms to the Common Lisp
way of things :)

Nonetheless, the aggregate of your comments has given me sufficient
information for me to formulate my own (separate and probably
different) set of Best Practices to follow.

Thanks again
From: Pascal Costanza
Subject: Re: Packages Best Practices
Date: 
Message-ID: <5q0o8lFtipf8U1@mid.individual.net>
Waldo wrote:
> Thanks everyone for their comments.
> 
> Although some of you share similar ideas, it is evident that there is
> no formal Best Practices to follow, which conforms to the Common Lisp
> way of things :)
> 
> Nonetheless, the aggregate of your comments has given me sufficient
> information for me to formulate my own (separate and probably
> different) set of Best Practices to follow.

That's the spirit. :)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/