Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to undo a `declaration` proclamation?

Tags:

common-lisp

It appears that most (if not all) global declarations cannot be reverted in an ANSI CL standard way.

E.g., once you evaluate (either directly or by loading a file) a form like (proclaim '(declaration my-decl)) or (declaim (special *my-var*)) there is no portable way to make (declare (my-decl ...)) illegal or *my-var* lexical.

Various implementation offer non-portable way to revert the special declaration, usually via (proclaim '(notspecial *my-var*)) or some other trick.

How about the declaration proclamation?

How do various implementations undo it? How would you implement it? Do you think (proclaim '(notdeclaration my-decl)) is a good idea?

Motivation: in a test suite, it would be nice to be modular - to be able to revert all effects of a test statements to avoid any possible interference with test suite parts. I know it's a week motivation because The Right Way is to use packages.

like image 853
sds Avatar asked Aug 03 '17 14:08

sds


1 Answers

One possible way is to provide a transaction mechanism (rollback/commit). This is taken from Xach's Naggum's archive:

I miss a transaction facility where I can make a number of changes
to the system that are only visible to my thread of a multi-threaded
execution environment and then discard them or commit them all at
once. E.g., loading a file could be such a transcation. Signaling
an error during loading could cause the whole slew of operations
that preceded it to be discarded instead of leaving the system in a
partially modified state. This is not impossible to build on top of
the existing system, but it takes significant effort, so it is the
kind of thing that Common Lisp systems programmers should do.

You would miss the possibility to undo only a subset of the declarations, like (declare A), (declare B), (undeclare A) but given your motivation, it would not be a problem because you are likely to want to undo all possible declarations made during a test.

You could provide a special form to individually "undeclare" declarations. I'd name it retract, but this might be difficult to specify in some cases. Suppose you declare that x is either a string or a number, can you retract a declaration that says x is a string? What about inline functions, etc? A transaction looks easier to implement, with e.g. a temporary environment.

like image 116
coredump Avatar answered Oct 06 '22 18:10

coredump