From: budden
Subject: unload and "make clean" an asdf system?
Date: 
Message-ID: <29680cb3-1cbf-4f83-90ef-23a1d66bc35b@r36g2000prf.googlegroups.com>
Hi!
  Is there a way to do so? I'd like to have
- dependent systems unloaded/cleaned
- services stopped [maybe I should do (defmethod stop-op my-system)
for that]
- hooks cleaned [maybe I should defmethod smth for this]
- packages removed [maybe classes undefined?]
- fasls cleaned
- *features* cleaned [on sbcl]
- asdf forget about the system

From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <698ec12b-ff17-448f-9319-5c2ac3cabdec@z28g2000prd.googlegroups.com>
Brilliant silence...

(defun delete-fasls-on-system (system fasl-type)
  "Deletes all fasl files of system (w/o dependents)"
  (let ((dir (make-pathname :directory
               (butlast
                (pathname-directory (slot-value (asdf:find-
system :iolib) 'asdf::relative-pathname))) )))
   (cl-fad:walk-directory dir 'delete-file :directories t :test
(lambda (p) (string= (pathname-type p) fasl-type))))

(delete-fasls-on-system :cl-fad "fasl") ; seems to be working.
From: Pascal J. Bourguignon
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <874p1d54n0.fsf@informatimago.com>
budden <········@gmail.com> writes:

> Brilliant silence...

If loading your system can be inversed, then your system is not
so interesting.  Why would you want to load it in the first place?


> (delete-fasls-on-system :cl-fad "fasl") ; seems to be working.

"Seems" is the keyword.

-- 
__Pascal Bourguignon__
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <bdcaf21b-8c93-47cf-8011-1dd588cbc5e1@p2g2000prf.googlegroups.com>
> "Seems" is the keyword.
"Seems" is a disclaimer (very common for open-source software). I'm
new to asdf hacking and try to do some quickfix. I started this topic
to find collaborators. BTW, function is really not correct, I
shouldn't have used slot-value, there is an accessor.

I have read http://smuglispweeny.blogspot.com/2008/12/beginners-guide-to-asdf-ha.html
about asdf (thanks Kenny). I didn't know that it is so stupid with
respect to load sequence. But it seems very easy to fix, just to
define another "smart-load" operation. Why no-one done this already?

I'm going to create a small asdf-utils project. And I'd like to
include normal load function there. I find
(asdf:oos 'asdf:load-op :system-name) a grotesque style. Candidates
for name are:

i) (asdf:load! :system-name)
ii) (asdf:load-sys :system-name)
iii) (asdf:asdf-load :system-name)
iv) what'd you suggest

-------------
4$/hour lisp freelancer. Hire me!

Please vote
From: Alberto Riva
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <ghp60j$is76$1@usenet.osg.ufl.edu>
budden wrote on 12/10/2008 01:52 AM:
> 
> I'm going to create a small asdf-utils project. And I'd like to
> include normal load function there. I find
> (asdf:oos 'asdf:load-op :system-name) a grotesque style. Candidates
> for name are:
> 
> i) (asdf:load! :system-name)
> ii) (asdf:load-sys :system-name)
> iii) (asdf:asdf-load :system-name)
> iv) what'd you suggest

Define a reader macro on #\! so that you can just type

!l :system-name

or some other suitable abbreviation.

Alberto
From: Tobias C. Rittweiler
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <87skovke1b.fsf@freebits.de>
Alberto Riva <·····@nospam.ufl.edu> writes:

> budden wrote on 12/10/2008 01:52 AM:
>>
>> I'm going to create a small asdf-utils project. And I'd like to
>> include normal load function there. I find
>> (asdf:oos 'asdf:load-op :system-name) a grotesque style. Candidates
>> for name are:
>>
>> i) (asdf:load! :system-name)
>> ii) (asdf:load-sys :system-name)
>> iii) (asdf:asdf-load :system-name)
>> iv) what'd you suggest
>
> Define a reader macro on #\! so that you can just type
>
> !l :system-name
>
> or some other suitable abbreviation.
>
> Alberto

If you use SLIME, and the contrib `slime-asdf', you can use ,load at the
REPL. You're then prompted for the system's name, and you can, of
course, use TAB completion at the miniprompt.

  -T.
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <7c4f4a82-192e-4aed-8fbe-e66076c4d1e4@w24g2000prd.googlegroups.com>
Thanks, Tobias
  That's fine. I like completion and the way it puts command to REPL
history. There are commercial GUI lisp users too, though. Don't know
what to do to it.
From: Alex Mizrahi
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <4943d58b$0$90262$14726298@news.sunsite.dk>
 b>   Is there a way to do so?

no. it is not possible to do this in general, because Common Lisp
semantics is based on modifying global state that is shared between
many systems. some systems could provide unloading mechanisms,
but as there is no way to prove that unloading is done correctly, nobody
bothers.

in course of development typically it is enough to re-load systems, and
manually deal with leftover artefacts. if you want to make sure it is clean,
reload the whole thing, why not?

 b> - fasls cleaned

find path_to_system -name "*.fasl" | xargs rm

with zsh:
  rm path_to_system/**/*.fasl
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <d796e5fe-1f73-4579-a146-db2196aa64d0@n33g2000pri.googlegroups.com>
Hi!
> no. it is not possible to do this in general, because Common Lisp
> semantics is based on modifying global state that is shared between
> many systems.
#apt-get install modifies a global state of my debian, but I can apt-
get remove
#make modifies global state of filesystem, but there is make clean.
  Most asdf system are just libraries. To unload such, one need to:
unload all depenets and remove packages.
  Some systems run servers. Some protocol can be developed to allow
system maintainers to specify startup and shutdown actions performed
by asdf.

> find path_to_system -name "*.fasl" | xargs rm
My reply is:
(require :cl-fad)
(defun delete-fasls-on-system (system fasl-type)
  "Deletes all fasl files of system (w/o dependents)"
  (let ((dir (make-pathname :directory
               (butlast
                (pathname-directory (component-relative-pathname
(asdf:find-system system)))) )))
   (cl-fad:walk-directory dir 'print       :directories t :test
(lambda (p) (string= (pathname-type p) fasl-type)))
   (cl-fad:walk-directory dir 'delete-file :directories t :test
(lambda (p) (string= (pathname-type p) fasl-type)))))

I have even recursive variant of this, but I don't publish it now, as
it can't operate on dependant systems correctly.
And I'm not the first, who've done this, google revert-op.

Then, one can made asfd forget about a system with a code like this
(it is a mostly a stub only for now)
(in-package :asdf)
(require :iterate)
(defun undefsystem (name &key (feature t) (reload nil) (fasls "fasl")
packages dependents-too)
  "Removes just the system and (tries to remove) all of its fasl
files. Pass fasl file extension
as fasl type argument
Does _not_ undefine dependent systems (consider it a TODO). For real
cleanup
one need to undefine packages too, but asdf keeps no track of package/
system dependencies,and
this will fail if dependent packages exist. Currently I add packages
and dependents-too arguments, but
they're ignored"
  (break "This function is completely untested. It deletes files! It
is not too late to return")
  (assert (not packages) () ":packages not implemented")
  (assert (not dependents-too) () ":dependents-too not implemented")
  (assert (not (eq fasls 't)) () "undefsystem says: RTFM")
  (let ((system (find-system name)))
    (unless system
      (warn "system ~S not found" name)
      (return-from undefsystem nil))
    (let ((system-asdf-name (component-name system))
	  (system-kw (iterate::keywordize name))) ; keywordize source can be
found in :iterate
      #+ignore
      (dolist (p packages) (when (find-package p) (delete-package p))
      (when fasls (delete-fasls-on-system name fasls))
      (when feature (setf *features* (delete system-kw *features*)))
      (remhash system-asdf-name *defined-systems*)
      (when reload (oos 'load-op name))
      )))

> but as there is no way to prove that unloading is done correctly, nobody
> bothers.
Yes. It is a developers responsibility. But in many cases it is very
easy (default
way to unload would work well).
From: Alex Mizrahi
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <4944e46b$0$90268$14726298@news.sunsite.dk>
 ??>> no. it is not possible to do this in general, because Common Lisp
 ??>> semantics is based on modifying global state that is shared between
 ??>> many systems.
 b> #apt-get install modifies a global state of my debian, but I can apt-
 b> get remove
 b> #make modifies global state of filesystem, but there is make clean.

they work on file system, very simple structure that can be described
as a simple list of named entities (files and directories). Common Lisp
is not that simple. some information is not wipeable at all. for example, 
consider

(let ((registry (make-hash-table)))
  (defun register-thingie (key value)
      (setf (gethash key registry) value))
  (defun lookup-thingie (key)
      (gethash key registry)))

there is absolutely no way to remove thingie once it is registered.

 b>   Most asdf system are just libraries. To unload such, one need to:
 b> unload all depenets and remove packages.

wrong. libraries can define methods on generic functions it does not own.
for example, any library that creates metaclasses does something like this

(defmethod mop:validate-superclass ((class my-class-class) (super 
standard-class))
    t)

that is, it creates new method and attaches it to GF mop:validate-superclass
which it does not own. if won't be removed automatically -- you need to find 
it
and destroy.

 b>   Some systems run servers. Some protocol can be developed to allow
 b> system maintainers to specify startup and shutdown actions performed
 b> by asdf.

why do you think this is necessary, what is your use cases?

 ??>> find path_to_system -name "*.fasl" | xargs rm
 b> My reply is:
 b> (require :cl-fad)

what is the point of having 10x more verbose solution? just because you
can or what?

 ??>> but as there is no way to prove that unloading is done correctly,
 ??>> nobody bothers.
 b> Yes. It is a developers responsibility. But in many cases it is very
 b> easy (default
 b> way to unload would work well).

almost certainly developer will forget some small thingie. and barely 
anybody
needs half-assed cleanup. 
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <747539fc-8cb4-4681-a10a-2ac6152b8c1b@a12g2000pro.googlegroups.com>
Hi!
> they work on file system, very simple structure that can be described as a simple list of named entities (files and directories)
Wrong. Linux packages can also add/remove users, start/stop daemons,
create databases (mysql packages is a great example of such a
package). So they use many ways of introspection, not just `ls'.

> libraries can define methods on generic functions it does not own
This is just the case for which I'd like to get an automated
protection. I think MOP gurus can do that easily. If MOP do not allow
that, other way is to trace defgeneric calls in the scope of load
operation. Some (all?) implementations allow to run some code on
tracing. Third way is to redefine defgeneric itself. If all this
fails, we might add a special kind of declarations to asdf syntax,
e.g. (:modifies-method (:package-name :symbol-name)).

Anyway, it seems to be possible to keep track of metadata changes with
rather small effort and it would improve both the scalability and
reliability of CL.

----------
$5/hour cl freelancer
From: Alex Mizrahi
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <4947c039$0$90276$14726298@news.sunsite.dk>
 ??>> they work on file system, very simple structure that can be described
 ??>> as a simple list of named entities (files and directories)
 b> Wrong. Linux packages can also add/remove users, start/stop daemons,
 b> create databases (mysql packages is a great example of such a
 b> package). So they use many ways of introspection, not just `ls'.

right, there are such systems, but they are pretty fragile, so many
system administrators prefer more straight package systems that
deal only with files and do not have any "intellect" attached.

 ??>> libraries can define methods on generic functions it does not own
 b> This is just the case for which I'd like to get an automated
 b> protection.

what do you mean by "protection"? adding methods to GF is totally
legal, that's what GFs are made for -- for extensibility.

 b> Anyway, it seems to be possible to keep track of metadata changes with
 b> rather small effort and it would improve both the scalability and
 b> reliability of CL.

i've asked you for any real world use cases, do you have any? 
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <53688e83-7355-48c7-8ebf-020a3a1b4f7f@a29g2000pra.googlegroups.com>
Sorry, I've got no time for debates. What I really need is stated at
the start of the topic (and I can even give up some requirements).
Initially, you said that undoing all changes (e.g. defmethods) is hard
and made me think of it (indeed, it would be fine for general
"undefsystem" facility), then you made me think of how it can be done,
now you ask me if I really need it. No, I don't really need it. So we
return to the basics: what I need is to remove symbols and packages,
and it is extremely easy. Maybe I could even implement it in the same
amount of time I spent writing this post. Are you kidding? What are
you going to prove? Please be more constructive.
From: Alex Mizrahi
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <4949584a$0$90274$14726298@news.sunsite.dk>
 b> amount of time I spent writing this post. Are you kidding? What are
 b> you going to prove? Please be more constructive.

i am quite constructive -- i strongly recommend you solving this problem
in other way (reloading lisp instance), this will prevent wasting your time
on this non-issue, so you can do something really useful instead.
doing system cleanup is conceptually wrong.
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <6a66dee7-34b0-4fe1-882d-ca50ba56c5cf@i24g2000prf.googlegroups.com>
> i am quite constructive -- i strongly recommend you solving this problem
> in other way (reloading lisp instance), this will prevent wasting your time
> on this non-issue, so you can do something really useful instead.
> doing system cleanup is conceptually wrong.
Ok, thanks for care, but I prefer to keep being conceptually wrong :)
From: Pascal J. Bourguignon
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <7ck59xbzxv.fsf@pbourguignon.anevia.com>
budden <···········@mail.ru> writes:

>> i am quite constructive -- i strongly recommend you solving this problem
>> in other way (reloading lisp instance), this will prevent wasting your time
>> on this non-issue, so you can do something really useful instead.
>> doing system cleanup is conceptually wrong.
> Ok, thanks for care, but I prefer to keep being conceptually wrong :)

Let's take a simple example.

A system may deal heavily with circular structures, and to be 'user
friendly', will execute (setf *print-circle* t) when loading.

How do you recover the previous value?


Loading a system modifies global state, even shared global state.  You
would need a reversible computer (or virtual machine) to unload one.

-- 
__Pascal Bourguignon__
From: Ray Dillinger
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <4953b57c$0$95529$742ec2ed@news.sonic.net>
Alex Mizrahi wrote:

> i am quite constructive -- i strongly recommend you solving this problem
> in other way (reloading lisp instance), this will prevent wasting your
> time on this non-issue, so you can do something really useful instead.
> doing system cleanup is conceptually wrong.

No, it's not.  That's like the Windows solution to a borked configuration: 
"Just reboot."  Reboot, and all your running processes go away.  Reboot, 
and the server logs downtime.  Reboot, and lose state and configuration 
information you want as well as state and configuration information you 
don't.  "Just reboot" is NOT ACCEPTABLE in a critical application. 

An object system ought to keep track of what methods are added to a 
generic function by which packages, and it ought to respond to an
unload-package command by getting rid of those methods. 

                                Bear
From: Pascal Costanza
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <6rhv71F1r05bU1@mid.individual.net>
Ray Dillinger wrote:
> Alex Mizrahi wrote:
> 
>> i am quite constructive -- i strongly recommend you solving this problem
>> in other way (reloading lisp instance), this will prevent wasting your
>> time on this non-issue, so you can do something really useful instead.
>> doing system cleanup is conceptually wrong.
> 
> No, it's not.  That's like the Windows solution to a borked configuration: 
> "Just reboot."  Reboot, and all your running processes go away.  Reboot, 
> and the server logs downtime.  Reboot, and lose state and configuration 
> information you want as well as state and configuration information you 
> don't.  "Just reboot" is NOT ACCEPTABLE in a critical application. 
> 
> An object system ought to keep track of what methods are added to a 
> generic function by which packages, and it ought to respond to an
> unload-package command by getting rid of those methods. 

You can do something like that with ContextL. Just define your 
"packages" as layers, and define layered methods associated with such 
layers. Activating such layers globally can be done with 
'ensure-active-layer, and deactivating them can be done with 
'ensure-inactive-layer.

The problem with such an approach is that it may interfere with 
currently executing threads that may rely on the presence of a layer. 
For example, consider protocols for opening and closing resources, which 
are pairwise operations: If opening a resource is performed with the 
semantics of one layer, and the closing of the resource is performed 
with the semantics of another layer, there may be serious semantic 
mismatches. That's why it's better to use dynamically scoped constructs, 
and that's why ContextL places so much emphasis on dynamically scoped 
layer activation and deactivation.

However, if you build a good software architecture around dynamically 
scoped layer activation and deactivation, I think you can build a good 
approach for "hot patching." For example, in a server-based system, you 
can determine layers to be activated in the central poll loop, and thus 
have a chance for each new request to activate newly loaded layers with 
improved or changed functionality.


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: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <819d187f-e95c-48ff-a789-3ac0224cd2c1@q26g2000prq.googlegroups.com>
> You can do something like that with ContextL. Just define your
> "packages" as layers, and define layered methods associated with such
> layers. Activating such layers globally can be done with
> 'ensure-active-layer, and deactivating them can be done with
> 'ensure-inactive-layer.
I don't want to restrict myself to something less general than asdf.
I'd better allow my
undefsystem fail or err in some circumstances. In this case one can
just reload everything.
I don't want to make a "silver bullet" for 24x7 server systems, just a
quick-and-dirty thingie.
If it would feature a user-extension protocol, it _might_ be improved
to be rock-stable, but
primary purpose is just cover simplest cases.

> If opening a resource is performed with the
> semantics of one layer, and the closing of the resource is performed
> with the semantics of another layer, there may be serious semantic
> mismatches.
In this case layer vendor should care of checking that no resource is
busy, keeping
track of resources and defining method on undefsystem-op. Or user
would fail once and then
close resources manually.
From: Alex Mizrahi
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <4953c20c$0$90271$14726298@news.sunsite.dk>
 RD> No, it's not.  That's like the Windows solution to a borked 
configuration:
 RD> "Just reboot."  Reboot, and all your running processes go away.
 RD> Reboot, and the server logs downtime.  Reboot, and lose state and
 RD> configuration information you want as well as state and configuration
 RD> information you don't.  "Just reboot" is NOT ACCEPTABLE in a critical
 RD> application.

i just say you cannot do this automatic in CL. there is no general solution.
if you really need it, for a given system with a known constraints you can
create unloading/hot-patching mechanisms, but it will work only for that 
system.

 RD> An object system ought to keep track of what methods are added to a
 RD> generic function by which packages, and it ought to respond to an
 RD> unload-package command by getting rid of those methods.

you definitely speak not about Common Lisp, but about some hypothetic
language, as even your terminology differs from CL terminology (CL packages
 is namespace, and what you call packages is called "system". CL does not
define what system is, and is of no help in dealing with systems.)

yes, indeed, you can create a language that can deal with hot-patching
and unloading in effective way. but it will have very different semantics 
from CL and Scheme,
 most likely it will have to move from top-level semantics (when you just 
execute all
statements and they alter the global state) into a more structured way, 
where
you can track all features to their declarations. it will have to follow 
strict rules
like A B = B A (load order does not change system behaviour) and
 A B A^(-1) = B (system can be unloaded in a clean way), and you'll have to 
enforce
these rules.
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <8f851d2a-0ae4-45c5-bf45-bc815e36a9c0@z6g2000pre.googlegroups.com>
> it will have to follow
> strict rules
> like A B = B A (load order does not change system behaviour) and
>  A B A^(-1) = B (system can be unloaded in a clean way), and you'll have to
> enforce these rules.
I want just to unload all what depends on the system, clean up all the
traces of system precense and reload all back.
It is rather simple. It is what all make/package management tools do.

So, roughly, only A B B^(-1) = A is sufficient, which is rather weak
assumption. It is not absolutely general.  But it is sufficient for
many useful cases. I do not pretend to make general tool for all cases
which makes everything w/o user effort. I want just save my time
reloading everything just because of one library or one messed
package.
And, maybe, add a protocol for specifying cleanup actions for any
system.

I'm currently study asdf and clbuild as I get occasion for this (but
I'm short in time). I change nothing as task is not that easy. I need
to make minimal surgery to keep things easy and portable and this
requires taking many things into account. I see mostly '(asdf asdf-
install clbuild) triple contain everything user need, good practices
should be advertised and some minimal extensions could be useful. No
new tools are needed.

-----------------------------------------
(defmacro let1 (var val &body body) `(let ((,var ,val)) ,@body))
(require :iterate-keywords)
No more lisp freelances
From: Pascal J. Bourguignon
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <87y6y32302.fsf@informatimago.com>
budden <···········@mail.ru> writes:
> So, roughly, only A B B^(-1) = A is sufficient, which is rather weak
> assumption. 

If that's what you want, it's rather trivial to implement.

-- 
__Pascal Bourguignon__
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <dc39821d-5ad9-44da-837d-e0877210b595@b41g2000pra.googlegroups.com>
Hi!
In fact, it is impossible to implement in terms of clean asdf. I'd
like to extend asdf a bit to make it possible.
From: Pascal J. Bourguignon
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <87hc4lkzmz.fsf@informatimago.com>
budden <···········@mail.ru> writes:
> In fact, it is impossible to implement in terms of clean asdf. I'd
> like to extend asdf a bit to make it possible.

Since you didn't quote anything, I'll go on with my idea. I remember you
said you'd be happy with A B B^-1 = A, so here is a sketch of how
you can implement it:


(defvar *loaded-systems* '())

(defun make-snapshot-name (system)
  (merge-pathnames 
    (make-pathname :name (string system)
                   :type "SNAP"
                   :case :common
                   :directory '(:relative "SNAPSHOTS"))
    (user-homedir-pathname) nil))

(defun asdf-load (system)
   (push system *loaded-systems*)
   #+clisp (ext:saveinitmem (make-snapshot-name system))
   #-clisp (error "Please add image saving for ~A"
                  (lisp-implementation-type))
   (asdf:oos 'asdf:load-op system))

(defun asdf-unload (system)
   (unless (member system *loaded-systems* :test (function equal))
      (error "System ~A  has not been loaded yet." system))
   #+(and :clisp (#.(cl:if (cl:find-package "LINUX") :and :or)))
   (linux:execvp "clisp" (vector "-M" (namestring (make-snapshot-name system))))
   ;; More work needed here to pass the same arguments over.
   #-(and :clisp (#.(cl:if (cl:find-package "LINUX") :and :or)))
   (error "How do you execvp in ~A" (lisp-implementation-type)))


-- 
__Pascal Bourguignon__
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <0a7ece27-f2ca-405d-9295-8a66df2ce063@e1g2000pra.googlegroups.com>
Hi Pascal!

> Since you didn't quote anything, I'll go on with my idea. I remember you
> said you'd be happy with A B B^-1 = A, so here is a sketch of how
> you can implement it:

  It is fine that finally you have produced some code.
  Now I see that task is ambigious. I didn't mean restarting lisp and
reverting to
the previous state completely, I meant undoing only operations made by
that load-op. If you
consider apt-get uninstall (or remove, don't remember), it do not
revert disk to the state
prior to installing.
  And your way is not very efficient. SBCL has a minimal image size of
about 18Mb. If we load
100 systems, images will occupy 1800Mb on the disk and take a lot of
time on disk operations.
  I meant just undoing load-op's side effects. Mostly they are:
- fasls if system was compiled. Fasls can be deleted
- defpackage. Package can be deleted
- defun/defmacro/defvar in that package. This will be cleaned by
deletion of package
- altering asdf's metadata. This can be cleaned as metadata is
accessible.
- defining new methods on existing generic functions. If these methods
are specialized for classes defined
in the system's package, they can be ignored if we delete package and
make sure all created instances have become
a garbage. If not, we could try to keep the track of method
definitions (maybe it can be
done with trace). If system's author supply cleanup-op, it would help
too.
- altering global variables. This can not be undone unless system
author supply cleanup-op definition for
the system.
What did I miss?

So, at least we need to know system-package relation, and asdf do not
provide such an information.

If we have several systems, we need to unload dependent ones in an
proper order:

A B C C^-1 B^-1 = A
A B C B^-1 <> A C

Asdf keeps information on dependencies and this can be done easily.
From: Juanjo
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <6eaa9645-f0b7-4ba9-8925-3d67fa86ceb3@z6g2000pre.googlegroups.com>
On Dec 31, 10:15 am, budden <···········@mail.ru> wrote:
>   I meant just undoing load-op's side effects. Mostly they are:
> - fasls if system was compiled. Fasls can be deleted
> - defpackage. Package can be deleted
> - defun/defmacro/defvar in that package.
> - altering asdf's metadata.
> - defining new methods on existing generic functions. [...]
> - altering global variables.
> What did I miss?

ASDF does not keep information about loaded packages, function that
have been defined, variable assignments. What you are asking for
cannot be implemented without ASDF intrusively inspecting the loaded
code (very much implementation dependent) or adding some other
extensions to the system definition format.

Actually please note that what you are asking for is not the inverse
of ASDF load operation, but the inverse of Common Lisp's LOAD.

Juanjo
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <f4857c09-b021-47a3-955e-be7e591e918e@b41g2000pra.googlegroups.com>
> ASDF does not keep information about loaded packages, function that
> have been defined, variable assignments. What you are asking for
> cannot be implemented without ASDF intrusively inspecting the loaded
> code (very much implementation dependent) or adding some other
> extensions to the system definition format.
I think both methods can be combined. Extensions may be of the form
#+asdf+ (system-defines-package :system :package)
which are toplevel forms or clauses (we need to modify a system
parser).
asdf+ is a feature that present for extended asdf.
Some other information can be gathered by
> (trace defmethod defgeneric set-macro-char defvar defparameter ...)
though this might miss inlined calls.

> Actually please note that what you are asking for is not the inverse
> of ASDF load operation, but the inverse of Common Lisp's LOAD.
Load is too general, I'm not sure this is what I want. asdf adds some
declarations
about dependencies which we can't track otherwise.
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <d21b53cd-c2da-4f6a-9874-ed6d44ab96e4@s1g2000prg.googlegroups.com>
I think would it be nice to define new type of asdf component for a
package.
And maybe even include package definition in an asd system
definition.
This way, asdf will know about package-system relationships and will
be able to clear up packages
on clean-op. No code yet.
From: Pascal J. Bourguignon
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <7ceizosngo.fsf@pbourguignon.anevia.com>
budden <···········@mail.ru> writes:
> [...]
> - altering global variables. This can not be undone unless system
> author supply cleanup-op definition for
> the system.
> What did I miss?

That's the difficult part, loading an asdf system, like when
reading/loading any lisp code, may alter the global state.  Not only
global variables, but also things such as the readtable, the random
state, etc, or just interning symbols and keywords.

I'm not saying that well behaved systems will do all sort of
nastiness, but the possibility is there.

By my book, if an asdf system defines more than a same named package
it's already nasty!


> So, at least we need to know system-package relation, and asdf do not
> provide such an information.
>
> If we have several systems, we need to unload dependent ones in an
> proper order:
>
> A B C C^-1 B^-1 = A
> A B C B^-1 <> A C
>
> Asdf keeps information on dependencies and this can be done easily.

Why would you want to keep modifications made after loading the system
you want to unload?  I'd assume this use case:
    - load system S
    - use S to change the global state
    - unload system S
    - be happy ever after with the changed global state.

Well, if that's what you'd want, then a more general solution  may
give you much better results than some asdf hack.  It's named a tree
shaker.  Choose an implementation providing it.

-- 
__Pascal Bourguignon__
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <1b822193-f381-4b92-aca1-dd789d98e978@a29g2000pra.googlegroups.com>
Some use cases:

1) I'm installing new application with many dependencies. I have
loaded some library, but it was with wrong
version. I want to undo load and load other version with minimal
keystrokes.
2) I get a package dirty with some misprinted identifiers/renamed
functions and want to clean it up (tree
shaking won't help unless I delete a package).
3) I'm fighting with package system. I've changed exports/imports in a
library and I want to refresh only minimal set
of changes. Many projects are too expensive to rebuild and even reload
from the scratch.

The common problem of all the situations is that I'm unable to delete
a package cleanly when it gets used by other packages.
I have to unwind all dependency tree and it is what I should computer
do instead of me. Possible solution is not expected to be 100%
reliable, but it would make many things faster.
From: Pascal J. Bourguignon
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <7cabacs9uo.fsf@pbourguignon.anevia.com>
budden <···········@mail.ru> writes:

> Some use cases:
>
> 1) I'm installing new application with many dependencies. I have
> loaded some library, but it was with wrong
> version. I want to undo load and load other version with minimal
> keystrokes.

In general (ie. for well behavied systems), loading the other version
over the old (or new) one is all that is needed.


> 2) I get a package dirty with some misprinted identifiers/renamed
> functions and want to clean it up (tree
> shaking won't help unless I delete a package).

Why would you care?  Of course, you have to be careful not to use the
bad symbols for a while, but next time you reload from scratch you'll
have it clean.


> 3) I'm fighting with package system. I've changed exports/imports in a
> library and I want to refresh only minimal set
> of changes. 

You must distinguish this, from:

> Many projects are too expensive to rebuild and even reload
> from the scratch.

When you have big projects, with a stable set of base systems
installed, you should save an image, and then load this image to
further develop the project.  This way, if  you botch up some system
or package, you can easily and quickly reload from the saved image.

Basically, it's what I proposed in my previous post, but done
explicitely and purposely.  You wouldn't use up a lot of disk space
because you wouldn't save images between each system, but you'd only
distinguish a set of stable system, an "environment", from the set of
"in development" systems.  Ideally you have only your own applications
system "in development".


> The common problem of all the situations is that I'm unable to delete
> 00a package cleanly when it gets used by other packages.

Yes.  That's why you should try to set up your workflow to avoid having
to delete packages and systems.

> I have to unwind all dependency tree and it is what I should computer
> do instead of me. Possible solution is not expected to be 100%
> reliable, but it would make many things faster.

-- 
__Pascal Bourguignon__
From: Rob Warnock
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <qoSdnT4efrA-y8HUnZ2dnUVZ_gqdnZ2d@speakeasy.net>
budden <···········@mail.ru> wrote:
+---------------
| And your way is not very efficient. SBCL has a minimal image size of
| about 18Mb. If we load 100 systems, images will occupy 1800Mb on the disk
| and take a lot of time on disk operations.
+---------------

That depends very much one exactly *which* "100 systems" you load.
Remember, SBCL's base image includes the compiler and the full CL
runtime; most additional systems you might add are *much* smaller
that that. And the same will be true for other CLs as well.

E.g., under CMUCL, the Unix/Linux executable is ~250 KB, the base
image is ~25 MB, but adding the following packages only adds the
indicated amounts to the heap size[1]:

    CFFI               ~0.6 MB
    LTk-0.90           ~1.4 MB
    cl-ppcre-0.7.6     ~1.0 MB
    cl-typesetting-2.1 ~7.5 MB [includes cl-pdf, cl-iterate, xml-render]

And those are the *big* ones! Things like SPLIT-SEQUENCE or META
are less than 100 KB each. Besides, who loads "100" systems into
an image anyway?!?

IME you *greatly* exaggerate the heap size and/or disk image size
of even a *VERY* rich CL execution environment. It would be quite
rare to find one over 100 MB...


-Rob

[1] Measured by doing several (GC :FULL T) ops before and after
    the ASDF load of each [until "bytes retained" stabilizes],
    and taking the differences in the reported "GC completed
    with ${NNN} bytes retained" numbers. This will be close
    [though not identical] to the sizes added to a saved heap
    image on disk. For example, if I load all six packages
    mentioned above and then do a SAVE-LISP, the resulting
    image file on disk is only 9.8 MB larger than a one from
    a SAVE-LISP without loading those packages:

      $ ls -l *.image
      -rw-r--r--  1 rpw3  rpw3  25899008 Dec 31 21:16 initial.image
      -rw-r--r--  1 rpw3  rpw3  35692544 Dec 31 21:18 final.image
      $ 

    And you save an *enormous* amount of startup time by doing it that way:

       $ time cmucl -core final.image -quiet \
		    -eval '(progn (print :hello)(terpri)(quit))'

       :HELLO 
       0.017u 0.017s 0:00.04 50.0%     192+2670k 0+0io 0pf+0w
       $ 

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: budden
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <cd6caa40-b741-4e9f-a3af-01adaea7c688@v39g2000pro.googlegroups.com>
Hi!
  Happy new year and all the good wishes!
> +---------------
> | And your way is not very efficient. SBCL has a minimal image size of
> | about 18Mb. If we load 100 systems, images will occupy 1800Mb on the disk
> | and take a lot of time on disk operations.
> +---------------
This was meant for the case we would want to save intermediate image
after every load-op.

> That's why you should try to set up your workflow to avoid having
to delete packages and systems
In fact, it is not too hard to enable asdf to delete packages and
systems and this will allow for more flexible workflow :)
From: Stanisław Halik
Subject: Re: unload and "make clean" an asdf system?
Date: 
Message-ID: <gjisbl$1gcn$2@opal.icpnet.pl>
thus spoke Rob Warnock <····@rpw3.org>:

> E.g., under CMUCL, the Unix/Linux executable is ~250 KB, the base
> image is ~25 MB, but adding the following packages only adds the
> indicated amounts to the heap size[1]:
>    CFFI               ~0.6 MB
>    LTk-0.90           ~1.4 MB
>    cl-ppcre-0.7.6     ~1.0 MB
>    cl-typesetting-2.1 ~7.5 MB [includes cl-pdf, cl-iterate, xml-render]
> And those are the *big* ones! Things like SPLIT-SEQUENCE or META
> are less than 100 KB each. Besides, who loads "100" systems into
> an image anyway?!?

I dare not ask the size of an image including cl-perec. Loading it even
with all fasls present takes about a minute.

-- 
You only have power over people so long as you don’t take everything
away from them. But when you’ve robbed a man of everything he’s no longer
in your power — he’s free again. -- Aleksandr Isayevich Solzhenitsyn