[PEAK] Package organization

Phillip J. Eby pje at telecommunity.com
Wed Dec 3 13:30:03 EST 2003


Just some random thoughts re: documenting the overall structure of PEAK...

-------------
Primitives: protocols, adapt, NOT_FOUND, NOT_GIVEN, Items

Core: binding, config, naming, model (plus PropertyName, and perhaps some 
sort of "streams" API that would collect the scattered stream-like things 
we have floating around.  'config' and 'naming' both need to deal with 
streams better.)

Framework: running, logs, query, storage, security, web, net

Other: metamodels, tools, util
-------------

The idea here is that "primitives" need to be understood first.  "Core" 
packages are critical parts of PEAK, upon which most other things depend to 
one degree or another.  The "core" can be used as a "meta-framework" for 
developing other frameworks, and should be understood before delving into 
specific frameworks.

"Framework" packages support a particular area of application 
functionality.  They are the "blessed" way of supporting that area of 
functionality within PEAK, but there is no obligation for you to use 
them.  (In the sense that the core does not depend on them.  They may, 
however, depend on one another.)

The final category, "other", covers two different kinds of things:

* Tools that may use any other part of the system, but the rest of the 
system doesn't depend on them (tools, metamodels)

* Utilities that are largely independent of the rest of PEAK (util), and 
don't depend on anything but the "primitives".

So, if we viewed it like an inheritance diagram, it might look like:

                    Primitives
                     /      \
                  Core    Utilities
                   /
              Frameworks
                  /
               Tools

Except that technically, the Core also uses Utilities, so maybe it should 
be just:

     Primitives, Utilities, Core, Frameworks, Tools

Except that it might imply that you need to know about the utilities in 
order to use the core, which isn't true.

Also, a discussion came up on IRC lately about 'from peak.api import *' and 
what it returns.  Some folks argued (in effect) that it should only import 
core APIs and primitives, not framework APIs.  I'm not sure I agree with 
this, and would like to see more discussion on it here.

Personally, I like peak.api exporting framework APIs, core APIs, and 
primitives.  Since most of the code I write either *is* PEAK, or uses PEAK, 
these are the API's I'm going to be using.  Thus, to me, having to write, e.g.:

from peak.api import *  # get the core
from peak.api import logs, storage, query

when I'm creating a DM module, seems like overkill.  Indeed, I'm pretty 
positive that if I did this, I'd have obscure runtime breakage if for 
example I used self.log.log(logs.TRACE) somewhere after forgetting to 
import 'logs'.

To me, the "namespace pollution" argument doesn't make a lot of sense, 
because if I need local meaning for one of those names, I can still have 
it.  But I always put 'from peak.api import *' at the very top of the 
module, so anything after that is going to override it.  (Not that I can 
think of any reason I'd have a module global with one of those names.)

However, what I *could* do, is add a 'core' module that exports only the 
core APIs from 'api'.  Thus, if one wishes to use the whole API 
(frameworks, core, and primitives), one would 'from peak.api import *', but 
if one wishes to use only the core API, one could use 'from peak.core 
import *'.

Anyway, I'd like to see some comments on all of this (organization concepts 
in general) before deciding on a specific solution for the core vs. 
non-core import question.




More information about the PEAK mailing list