From: Vladimir Prus (ghost_at_[hidden])
Date: 2003-05-13 10:18:29
David Abrahams wrote:
> > - creation of instances involves executing lots of code, with uncertain
> > performance.
> I don't understand your concern here. The time it takes to "execute"
> a rule definition should be negligible.
It should, but I'm not sure it is. BTW, rule definition often contains
"import" statements, which are probably not fast either.
> I think a bigger efficiency concern is probably that we have no way of
> "deleting" modules (instances) -- the way you generate vectors
> on-the-fly for printing purposes in generators.jam (many of which are
> never used), this could eat up lots of memory very quickly.
> > To create instance you just generate unique id for class and call
> > __init__ method --- which is much simpler than the current approach.
> So... the "data members" for _all_ instances of a class live inside
> the same module namespace, instead of giving each one a separate
> module? That would make implementing delete pretty difficult.
Another good point. So the question is really if initialization or memory
causes more performance problems.
> > The syntax for using classes stays the same --- provided a new
> > builtin facility is introduced --- bound rules, which have implicit
> > argument (self) automatically prepended on invocation.
> We already have bound rules ;-)
> All you need to do is use this notation:
> $(self.foo) bar baz ;
> instead of
> $(self).foo bar baz ;
> If you're willing to keep the one-module-per-instance arrangement,
> you just bind "self.foo" to "foo $(self)".
Oh... that's smart. But the need for binding arises only if we move to
> > I'm not sure this is precisely the way to go, but probably classes are
> > used extensively enough to have better core support?
> Probably, though I doubt we need to do anything so radical.
> >> - core ----------------------------------------------------------
> > Just a naming issue: "core" sounds like "the most important part"
> > for me.
> Probably correct.
> > In fact, it's just a set of utilities.
> I think they're more than just utilities: they're the substrate upon
> which the entire system is built -- they're practically at the
> language level.
Hmm... just a note: if we were to reimplement V2 in Python, most of those
modules will be uncessarary. The name "core", IMO, overly emphasizes their
> >> o Refactoring classes
> >> We propose that each class have its own file.
> > This sounds too radical for me. We'll end up with a big number of
> > modules, some of that are so small that just don't carry their own
> > weight. I'll see if I can come up with better argumentation...
> I mostly agree with that assessment, though I'd like to see us try
> one-class-per-file for a while and see how uncomfortable it really is.
OK, why not?
> >> - Eliminate the "abstract-target" base class and resulting
> >> heirarchy. The derived classes ("project-target", "main-target",
> >> "basic-target") are not really related and are never used
> >> polymorphically.
> > I'm not so sure. Imagine you have a command line like
> > bjam @project1 @project2/x
> > where project1 is... a project, and project2/x is a target in project2.
> > The build-system module would lookup both target id and get two abstract
> > targets, one of which is project-target and another is main-target. They
> > have polymorphic 'generate' method, which allows generate both of them.
> > Not sure that 'project.lookup' will return project target right now, but
> > the use case above is perfectly reasonable.
> I agree with that. There are other ways to handle this which avoid
> that polymorphism: the entity which is looked up as a @project1 does
> not *need* to be the same one that stores the structural information -
> it could just be another "target-spec", but I also don't see any
> advantage to doing that.
> >> - Rename "project-target" -> something like "project-spec" or
> >> simply "project". Possibly absorb all the functionality of
> >> existing modules "project" and "project-root" into this
> >> class...they are circularly dependent anyway!
> > I'm -1 on "project-spec". You can't say that "project-spec" contains main
> > target, or can be generated. OTOH, "project" can do both. I'm fine with
> > this name.
> That's the name I like.
> >> - Rename "main-target" -> something like "main-target-spec" ???
> >> It doesn't actually represent a "target"...it respresents a set
> >> of formulas, any one or more of which can be used to create
> >> variants of a target with this id. Anyway, it is a user-level
> >> concept and confusing with respect to internal notions of
> >> "target".
> > I'm -1 on *-spec for the same reason as above. '*-spec' is like a
> > textual specification, without any behaviour.
> That was exactly the design intention when we started out on this BBv2
> journey: reading a Jamfile was supposed to (usually) do almost nothing
> other than parsing the err... target specifications... written by the
> user. I claim that there *should* be little or no behavior
> associated with these things. It probably makes sense to install
> some kind of "target-generator" in them to handle what little
> behavior there is.
Reading a Jamfile is supposed to do almost nothing even now. I just don't get
the point of little behaviour. Say you rename 'main-target' to
'main-target-spec' and add a rule 'generate-main-target-from-spec'. What do
> > I also think 'main-target' is fine. This term is inherited from V1
> > and still makes sense to me.
> Here's the problem: we have too many blasted things called "target",
> which all have different meanings! We even have a target called
> "abstract-file-target" which is not an abstract-target, but a
> virtual-target!! I think you underestimate the difficulty this
> situation causes for even experienced guys like me and Rene.
OK, agreed, "abstract-file-target" is wierd beast.
> Entities in different categories should have different names. We want
> only entities in the current "virtual-target" category to be called
> "target" (except that possibly strings representing jam target names
> could be called "jam-target"; fortunately they are just strings so
> there's no class-naming problem).
That's good intention, but neither 'main-target-spec' or 'target-spec' sounds
right for me: they are not spec for single current virtual-target and future
'target'. They are really user-level entities.
> > I think it's natural for user to think that there are projects with
> > main targets in them.
> If neccessary, we can say anything we want in the documentation and
> use slightly different terminology in the code.
Although it's better to have common terms in both places.
> > And, unless we're going to coin a new user-level terminology, it's
> > better to leave "main-target" class name --- so that class has the
> > same name as user-level entity.
> But then you have to tell users that projects are also "abstract
> targets", though not "main" because they didn't specify them.
> Here's a radical notion: suppose virtual-targets and main targets
> are all the same thing? I claim it makes some sense, actually. In
> BBv1, you get a NOTFILE jam target for each "main-target". Why not
> create virtual targets right away for all "top-level" user-visible
> entities: main targets, projects, etc...
> That would be one way to eliminate the different types of "targets".
What 'generate' will do for current virtual targets?
And what 'actualize' will do for current abstract targets?
Although some though is needed --- e.g. 'generate' might return Jam targets
and 'actualize' can be eliminated, I see some appeal in this idea.
> >> - Eliminate or rename "typed-target". Pending David's review of the
> >> "generate" process.
> > I don't understand this one. Instances of 'typed-target' use generators,
> > and instances of other classes do not. What's the point?
> The point is that:
> 1. All (or nearly all) targets have types, so the name is
> misleading. This is part of the problem with having too many
> things called "target" (and too much overloading of the term
> "generate"): the right name would have been something like
> "basic-target-generated-by-generators", but that's too
> cumbersome, so we ended up with something that makes almost no
> sense unless you know exactly where it sits in its class
> hierarchy (and a bunch of other context as well).
> 2. The generator fulfills the same role of implementing point a of
> variation that the all of the basic-target classes do, by
> overriding construct. It makes more sense to us to make all of
> these into a single class and allow pluggable
> dependency-graph-builders to handle that job. What we
> currently call "generator" could be a particular kind of
The problem is that basic targets has more freedom in variation. Concrete
derived class can have different kinds of parameters to ctor, for example.
Not that it's impossible with generators, but not easy, I think. Also, there's
some behaviour that can't be tweaked in generators. For example,
'stage-target-class.check-for-unused-sources' supresses all checks for unsused
sources, because they make no sense for this kind of target. How will you get
this with generators?
> >> - Rename "virtual-target" -> "target". These are the real objects
> >> that are associated directly with targets.
> > Are they? If you create virtual-target with certain name it is just
> > hanging in the air, untill you decide you really want to generate it.
> I think I'm hearing a *new* (third, fourth?) meaning for "generate"
> here! As I've understood it thus far, "generate" has always meant the
> creation of virtual-targets ("targets") from abstract-targets
> ("target-specifications"). What can it mean to "generate" a virtual
> target which has already been created?
I meant "unless you decide you really what to actualize it". Apologies.
Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk