[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