Re: Package dependencies

*To*: mathgroup at smc.vnet.net*Subject*: [mg45781] Re: Package dependencies*From*: Maxim <dontsendhere@.>*Date*: Sat, 24 Jan 2004 00:36:44 -0500 (EST)*References*: <buqmm4$rbu$1@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

This is a very ingenious hack indeed; it's worth commenting line by line. Let's replace the package c.m with c2.m: (*--------c.m---------*) DeclarePackage["b`","f"] (*--------------------*) (*--------c2.m--------*) BeginPackage["a`"] f := ( Clear[f]; Get["a`"]; Needs["b`"]; f ) EndPackage[] (*--------------------*) How does c2.m work? BeginPackage["a`"]: makes sure that f is placed in the correct context and adds this context to $ContextPath (basically duplicating the work of a.m); otherwise we wouldn't be able to access a`f simply as f; Clear[f]: without it we'd get infinite recursion when f on the right-hand side is evaluated; Get["a`"]: not Needs["a`"] because BeginPackage["a`"] modifies $Packages, so Needs would decide that a.m was already loaded. For the same reason Get["a`"] cannot be omitted, since BeginPackage["b`","a`"] in b.m also uses Needs! But a hack is still a hack and it is easy to build a 'counter-example' when it won't work. The stub definition for f in c2.m will be used when f is evaluated, while the phrase "when f is first used" means something like "when symbol f is first encountered by the parser". So if we have a definition f /: Hold[f[1]]=1 in b.m then evaluating Hold[f[1]] will not load b.m, and therefore c2.m does not accurately emulate the behaviour of DeclarePackage: In[1]:= <<c` Hold[f[1]] Out[2]= 1 In[1]:= <<c2` Hold[f[1]] Out[2]= Hold[f[1]] Not to mention several smaller nuisances: if b.m depends on several base packages then you'll have to manually find the one in which f is defined; if several packages depend on a.m then Get["a`"] will load a.m several times. Maxim Rytin m.r at prontomail.com Omega Consulting wrote: > On a modern computer, package loading is quick. Unless the package is very > large (or part of a large set of interdependent packages), DeclarePackage > is not really necessary. Just use Get or Needs in c.m. > > However, if you must load the packages when f is first used, you can create > a "stub" function. Something like: > > BeginPackage["a`"] > f := ( > Clear[f]; > Get["a`"]; > Needs["b`"]; > f > ) > EndPackage[] > > In[1]:= << c` > > In[2]:= > ?f > a`f > f := (Clear[f]; << a`; Needs[b`]; f) > > So f is defined to load a` and b`, which re-defines f. > > In[3]:= f[1] > Out[3]= 1 > > In[4]:= > ?f > a`f > f[0] = 0 > f[1] = 1 > > At 04:07 AM 1/20/2004, Maxim wrote: > >Suppose we have a package a.m defining function f: > > > >BeginPackage["a`"] > >f[0] = 0 > >EndPackage[] > > > >Then we create package b.m which introduces additional definitions for > >f: > > > >BeginPackage["b`","a`"] > >f[1] = f[0] + 1 > >EndPackage[] > > > >Now after loading b.m we'll have f[0]=0 and f[1]=1. Finally, we want to > >create a package c.m that determines when b.m should be autoloaded. We > >add the following line to c.m: > > > >DeclarePackage["b`","f"] > > > >Unfortunately, it doesn't work that way: > > > >In[1]:= > ><<c` > >f[1] > > > >Out[2]= > >1+f[0] > > > >(standalone kernel will also give f::shdw warning). The reason is that > >DeclarePackage creates symbol f (with attribute Stub) in the b` context. > >This implementation decision seems rather questionable: the idea of > >DeclarePackage is to load b.m when f is first used, which is exactly > >what we want here -- but nobody said the symbol f was needed in context > >b`! > > > >Probably this difficulty can be avoided by some creative usage of Remove > >and $NewSymbol, but simply adding Remove["b`f"] to b.m won't solve the > >problem completely. > > > >This is exactly the situation with Geometry\Polytopes.m, > >Graphics\Polyhedra.m and Graphics\Kernel\init.m -- you can use > ><<graphics` to declare most of the symbols in all the Graphics\* > >packages, but not Tetrahedron, Cube and others because there are > >definitions for them both in Polytopes.m and Polyhedra.m. > > > >Maxim Rytin > >m.r at prontomail.com > > -------------------------------------------------------------- > Omega Consulting > "The final answer to your Mathematica needs" > http://omegaconsultinggroup.com

**Re: typesetting fractions**

**Any way to display vars internal to a function on interrupt?**

**Re: Package dependencies**

**Re: Package dependencies**