Lisp - allow variable to be used *or* unused? - lisp

If I (declare (ignore foo)) then lisp* won't warn me about unused variables, but will warn if I do use the variable. Is there a way I can turn off warnings either way?
Asking because I want to write some macros that introduce common/standard variable names in my application, but I don't want to have to always declare the unused ones where I use the macros, but I also don't want the warnings.
I'd rather not turn them off globally, and it'd be nice to avoid any logic that has to scan the forms fed into the macro, that seems like it would just complicate the logic.
* SBCL, if it makes any difference

Use (declare (ignorable foo)).
See IGNORABLE in the Common Lisp HyperSpec.

Related

Are Lisp macros just syntactic sugar? [duplicate]

This question already has answers here:
What makes Lisp macros so special?
(15 answers)
Closed 3 months ago.
I keep reading that Lisp macros are one of the most powerful features of the language. But reading over the specifications and manuals, they are just functions whose arguments are unevaluated.
Given any macro (defmacro example (arg1 ... argN) (body-forms)) I could just write (defun example (arg1 ... argN) ... (body-forms)) with the last body-form turned into a list and then call it like (eval (example 'arg1 ... 'argN)) to emulate the same behavior of the macro. If this were the case, then macros would just be syntactic sugar, but I doubt that syntactic sugar would be called a powerful language feature. What am I missing? Are there cases where I cannot carry out this procedure to emulate a macro?
I can't talk about powerful because it can be a little bit subjective, but macros are regular Lisp functions that work on Lisp data, so they are as expressive as other functions. This isn't the case with templates or generic functions in other languages that rely more on static types and are more restricted (on purpose).
In some way, yes macros are simple syntactic facilities, but you are focused in your emulation on the dynamic semantics of macros, ie. how you can run code that evaluates macros at runtime. However:
the code using eval is not equivalent to expanded code
the preprocessing/compile-time aspect of macros is not emulated
Lexical scope
Function, like +, do not inherit the lexical scope:
(let ((x 30))
(+ 3 4))
Inside the definition of +, you cannot access x. Being able to do so is what "dynamic scope" is about (more precisely, see dynamic extent, indefinite scope variables). But nowadays it is quite the exception to rely on dynamic scope. Most functions use lexical scope, and this is the case for eval too.
The eval function evaluates a form in the null lexical environment, and it never has access to the surrounding lexical bindings. As such, it behaves like any regular function.
So, in you example, calling eval on the transformed source code will not work, since arg1 to argnN will probably be unbound (it depends on what your macro does).
In order to have an equivalent form, you have to inject bindings in the transformed code, or expand at a higher level:
(defun expand-square (var)
(list '* var var))
;; instead of:
(defun foo (x) (eval (expand-square 'x))) ;; x unbound during eval
;; inject bindings
(defun foo (x) (eval `(let ((z ,x)) (expand-square z))))
;; or expand the top-level form
(eval `(defun foo (x) ,(expand-square 'x)))
Note that macros (in Common Lisp) also have access to the lexical environment through &environment parameters in their lambda-list. The use of this environment is implementation dependent, but can be used to access the declarations associated with a variable, for example.
Notice also how in the last example you evaluate the code when defining the function, and not when running it. This is the second thing about macro.
Expansion time
In order to emulate macros you could locally replace a call to a macro by a form that emulates it at runtime (using let to captures all the bindings you want to see inside the expanded code, which is tedious), but then you would miss the useful aspect of macros that is: generating code ahead of time.
The last example above shows how you can quote defun and wrap it in eval, and basically you would need to do that for all functions if you wanted to emulate the preprocessing work done by macros.
The macro system is a way to integrate this preprocessing step in the language in a way that is simple to use.
Conclusion
Macros themselves are a nice way to abstract things when functions can't. For example you can have a more human-friendly, stable syntax that hides implementation details. That's how you define pattern-matching abilities in Common Lisp that make it look like they are part of the language, without too much runtime penalty or verbosity.
They rely on simple term-rewriting functions that are integrated in the language, but you can emulate their behavior either at compile-time or runtime yourself if you want. They can be used to perform different kinds of abstraction that are usually missing or more cumbersome to do in other languages, but are also limited: they don't "understand" code by themselves, they don't give access to all the facilities of the compiler (type propagation, etc.). If you want more you can use more advanced libraries or compiler tools (see deftransform), but macros at least are portable.
Macros are not just functions whose arguments are unevaluated. Macros are functions between programming languages. In other words a macro is a function whose argument is a fragment of source code of a programming language which includes the macro, and whose value is a fragment of source code of a language which does not include the macro (or which includes it in a simpler way).
In very ancient, very rudimentary, Lisps, before people really understood what macros were, you could simulate macros with things called FEXPRs combined with EVAL. A FEXPR was simply a function which did not evaluate its arguments. This worked in such Lisps only because they were completely dynamically scoped, and the cost of it working was that compilation of such things was not possible at all. Those are two enormous costs.
In any modern Lisp, this won't work at all. You can write a toy version of FEXPRs as a macro (this may be buggy):
(defmacro deffex (fx args &body body)
(assert (every (lambda (arg)
(and (symbolp arg)
(not (member arg lambda-list-keywords))))
args)
(args) "not a simple lambda list")
`(defmacro ,fx ,args
`(let ,(mapcar (lambda (argname argval)
`(,argname ',argval))
',args (list ,#args))
,#',body)))
So now we could try to write a trivial binding construct I'll call with using this thing:
(deffex with (var val form)
(eval `(let ((,var ,val)) ,form)))
And this seems to work:
> (with a 1 a)
1
Of course, we're paying the cost that no code which uses this construct can ever be compiled so all our programs will be extremely slow, but perhaps that is a cost we're willing to accept (it's not, but never mind).
Except, of course, it doesn't work, at all:
> (with a 1
(with b 2
(+ a b)))
Error: The variable a is unbound.
Oh dear.
Why doesn't it work? It doesn't work because Common Lisp is lexically scoped, and eval is a function: it can't see the lexical bindings.
So not only does this kind of approach prevent compilation in a modern Lisp, it doesn't work at all.
People often, at this point, suggest some kind of kludge solution which would allow eval to be able to see lexical bindings. The cost of such a solution is that all the lexical bindings need to exist in compiled code: no variable can ever be compiled away, not even its name. That's essentially saying that no good compilers can ever be used, even for the small part of your programs you can compile at all in a language which makes extensive use of macros like CL. For instance, if you ever use defun you're not going to be able to compile the code in its body. People do use defun occasionally, I think.
So this approach simply won't work: it worked by happenstance in very old Lisps but it can't work, even at the huge cost of preventing compilation, in any modern Lisp.
More to the point this approach obfuscates the understanding of what macros are: as I said at the start, macros are functions between programming languages, and understanding that is critical. When you are designing macros you are implementing a new programming language.

Can Lisp's macro system also extend its commenting syntax?

I love Racket's #;. I want to see it in every language that I ever use again. Can it be added to other Lisps via their macro systems? Or does the commenting character break the macro system's ability to read the code?
A sufficient answer will demonstrate a macro being built in any Lisp other than Racket that allows for a change in the commenting system. You need not actually implement Racket's #;, but I would like it if you do. Lisps with the least similarity to Racket, e.g. Clojure or any non-Scheme will be particularity nice to see.
#; isn't a macro, it's what Common lisp would call a readmacro: what it does is defined at read time, not later than that. Read macros which aim to completely suppress input are mildly perilous because there needs to be a way of saying 'read the following thing, but ignore it', and that's only possible if any other readmacros behave well: there's nothing to stop someone defining a readmacro which produces some side-effect even if reading is suppressed.
However, well-behaved readmacros (which includes all of the standard ones and the rest of the standard reader) in CL won't do that: they'll listen to whether reading is being suppressed, and behave accordingly.
CL allows you to do this as standard by using its conditionalisation on features, and in particular #+(or) <expr> will always skip <expr>.
But you can define your own: #; is not predefined so you can define it:
(set-dispatch-macro-character
#\# #\;
(lambda (stream char n)
(declare (ignore char))
(let ((*read-suppress* t))
(dotimes (i (or n 1) (values))
(read stream)))))
After this, or at least with a better tested version of this, then #; <expr> (or obviously #;<expr>) will read as whitespace, and #2; ... ... will skip two following expressions:
> (let ((x #;1 #2; 2 3 4)) x)
4
What you are looking for is #+(or) reader macro.
Since (or) evaluates to nil, the condition is always false the following form is never evaluated.

Common Lisp - CCL, why a warning when passing a global to a local function?

I’m learning Common Lisp, using CCL.
I get a warning when I use a global variable locally. Why does CCL provide this functionality? What is the purpose of this?
(setf n 75)
;;;This function works, but gets a warning about
;;;n being an undeclared free variable.
(defun use-global ()
(write n)
)
;;;This function works without warnings.
(defun global-to-local (x)
(write x)
)
(use-global)
(global-to-local n)
Setf and setq do not introduce new variables, they modify existing ones.
In order to define something like global variables, use defvar or defparameter. These are conventionally written with a leading and ending *, and they are automatically declared globally special. This means that whenever you re-bind them, this binding is in effect for the entire call stack above it, whatever functions you call from there etc..
In your example, the toplevel setf did not do that, so when compiling the function use-global, the compiler does not see that n is meant as such and issues the warning. In correct and idiomatic Common Lisp code, this warning should generally be treated as an error, since it then indicates a misspelling or typo.
The warning provides little value. The variable is bound by a prior top-level assignment, which creates a binding in the global environment making that variable a global variable. It simply being accessed, which is likely what is intended by the programmer.
An unbound variable warning is very valuable when no definition of a variable is seen because it catches misspellings of variable references. But a top-level setf or setq should be noticed by the implementation and treated as a definition.
It is useful to have a warning for cases when a variable is defined by a top-level setf and then later subject to a let:
(setf n 42)
(let ((n 43)) (func))
Here, it looks like the programmer might be expecting n to be a special variable, but it wasn't defined that way. func will see the top level binding of n which holds 42, and not the lexical n which holds 43. So there is a good reason to have a diagnostic here. The intent of the code requires n to have been declared via defvar or defparameter, or proclaimed special.
(Of course, we cannot warn about (let ((n 43)) ...) when no top-level n has been seen, because this is the usual situation for the vast majority of lexical variables.)
There is a bit of a defect in ANSI Common Lisp in that the section 3.1.2.1.1 Symbols as Forms says that there are only three kinds of variables: dynamic, lexical and constant. A dynamic variable is one that is declared special, and so according to this reasoning, setf is not enough to create a dynamic variable. However, section 3.1.1.1 clearly spells out that there exists a global environment. Confusingly, it says that it contains bindings that have indefinite extent and scope, and that it contains dynamic variables. But then "dynamic variable" is defined in the glossary as being a variable with a binding in the dynamic environment, and a dynamic environment is defined as containing bindings with "dynamic extent". So that can't be the global environment. You know, that one which 3.1.1.1 says contains dynamic variables!
Anyway, all this ANSI confusion has created the misconception that setf or setq cannot create a variable, which lends support to bogus compiler diagnostics.
Quick googling suggests in Common Lisp is it done as something like:
(defvar *n* 75)
(defun use-global () (write *n*))
(use-global)
Note the asterisk that decorate global names by convention.

How to live with Emacs Lisp dynamic scoping?

I've learned Clojure previously and really like the language. I also love Emacs and have hacked some simple stuff with Emacs Lisp. There is one thing which prevents me mentally from doing anything more substantial with Elisp though. It's the concept of dynamic scoping. I'm just scared of it since it's so alien to me and smells like semi-global variables.
So with variable declarations I don't know which things are safe to do and which are dangerous. From what I've understood, variables set with setq fall under dynamic scoping (is that right?) What about let variables? Somewhere I've read that let allows you to do plain lexical scoping, but somewhere else I read that let vars also are dynamically scoped.
I quess my biggest worry is that my code (using setq or let) accidentally breaks some variables from platform or third-party code that I call or that after such call my local variables are messed up accidentally. How can I avoid this?
Are there a few simple rules of thumb that I can just follow and know exactly what happens with the scope without being bitten in some weird, hard-to-debug way?
It isn't that bad.
The main problems can appear with 'free variables' in functions.
(defun foo (a)
(* a b))
In above function a is a local variable. b is a free variable. In a system with dynamic binding like Emacs Lisp, b will be looked up at runtime. There are now three cases:
b is not defined -> error
b is a local variable bound by some function call in the current dynamic scope -> take that value
b is a global variable -> take that value
The problems can then be:
a bound value (global or local) is shadowed by a function call, possibly unwanted
an undefined variable is NOT shadowed -> error on access
a global variable is NOT shadowed -> picks up the global value, which might be unwanted
In a Lisp with a compiler, compiling the above function might generate a warning that there is a free variable. Typically Common Lisp compilers will do that. An interpreter won't provide that warning, one just will see the effect at runtime.
Advice:
make sure that you don't use free variables accidentally
make sure that global variables have a special name, so that they are easy to spot in source code, usually *foo-var*
Don't write
(defun foo (a b)
...
(setq c (* a b)) ; where c is a free variable
...)
Write:
(defun foo (a b)
...
(let ((c (* a b)))
...)
...)
Bind all variables you want to use and you want to make sure that they are not bound somewhere else.
That's basically it.
Since GNU Emacs version 24 lexical binding is supported in its Emacs Lisp. See: Lexical Binding, GNU Emacs Lisp Reference Manual.
In addition to the last paragraph of Gilles answer, here is how RMS argues in favor of dynamic scoping in an extensible system:
Some language designers believe that
dynamic binding should be avoided, and
explicit argument passing should be
used instead. Imagine that function A
binds the variable FOO, and calls the
function B, which calls the function
C, and C uses the value of FOO.
Supposedly A should pass the value as
an argument to B, which should pass it
as an argument to C.
This cannot be done in an extensible
system, however, because the author of
the system cannot know what all the
parameters will be. Imagine that the
functions A and C are part of a user
extension, while B is part of the
standard system. The variable FOO does
not exist in the standard system; it
is part of the extension. To use
explicit argument passing would
require adding a new argument to B,
which means rewriting B and everything
that calls B. In the most common case,
B is the editor command dispatcher
loop, which is called from an awful
number of places.
What's worse, C must also be passed an
additional argument. B doesn't refer
to C by name (C did not exist when B
was written). It probably finds a
pointer to C in the command dispatch
table. This means that the same call
which sometimes calls C might equally
well call any editor command
definition. So all the editing
commands must be rewritten to accept
and ignore the additional argument. By
now, none of the original system is
left!
Personally, I think that if there is a problem with Emacs-Lisp, it is not dynamic scoping per se, but that it is the default, and that it is not possible to achieve lexical scoping without resorting to extensions. In CL, both dynamic and lexical scoping can be used, and -- except for top-level (which is adressed by several deflex-implementations) and globally declared special variables -- the default is lexical scoping. In Clojure, too, you can use both lexical and dynamic scoping.
To quote RMS again:
It is not necessary for dynamic scope to be the only scope rule provided, just useful
for it to be available.
Are there a few simple rules of thumb that I can just follow and know exactly what happens with the scope without being bitten in some weird, hard-to-debug way?
Read Emacs Lisp Reference, you'll have many details like this one :
Special Form: setq [symbol form]...
This special form is the most common method of changing a
variable's value. Each SYMBOL is given a new value, which is the
result of evaluating the corresponding FORM. The most-local
existing binding of the symbol is changed.
Here is an example :
(defun foo () (setq tata "foo"))
(defun bar (tata) (setq tata "bar"))
(foo)
(message tata)
===> "foo"
(bar tata)
(message tata)
===> "foo"
As Peter Ajtai pointed out:
Since emacs-24.1 you can enable lexical scoping on a per file basis by putting
;; -*- lexical-binding: t -*-
on top of your elisp file.
First, elisp has separate variable and function bindings, so some pitfalls of dynamic scoping are not relevant.
Second, you can still use setq to set variables, but the value set does not survive the exit of the dynamic scope it is done in. This isn't, fundamentally, different from lexical scoping, with the difference that with dynamic scoping a setq in a function you call can affect the value you see after the function call.
There's lexical-let, a macro that (essentially) imitates lexical bindings (I believe it does this by walking the body and changing all occurrences of the lexically let variables to a gensymmed name, eventually uninterning the symbol), if you absolutely need to.
I'd say "write code as normal". There are times when the dynamic nature of elisp will bite you, but I've found that in practice that is surprisingly seldom.
Here's an example of what I was saying about setq and dynamically-bound variables (recently evaluated in a nearby scratch buffer):
(let ((a nil))
(list (let ((a nil))
(setq a 'value)
a)
a))
(value nil)
Everything that has been written here is worthwhile. I would add this: get to know Common Lisp -- if nothing else, read about it. CLTL2 presents lexical and dynamic binding well, as do other books. And Common Lisp integrates them well in a single language.
If you "get it" after some exposure to Common Lisp then things will be clearer for you for Emacs Lisp. Emacs 24 uses lexical scoping to a greater extent by default than older versions, but Common Lisp's approach will still be clearer and cleaner (IMHO). Finally, it is definitely the case that dynamic scope is important for Emacs Lisp, for the reasons that RMS and others have emphasized.
So my suggestion is to get to know how Common Lisp deals with this. Try to forget about Scheme, if that is your main mental model of Lisp -- it will limit you more than help you in understanding scoping, funargs, etc. in Emacs Lisp. Emacs Lisp, like Common Lisp, is "dirty and low-down"; it is not Scheme.
Dynamic and lexical scoping have different behaviors when a piece of code is used in a different scope than the one it was defined in. In practice, there are two patterns that cover most troublesome cases:
A function shadows a global variable, then calls another function that uses that global variable.
(defvar x 3)
(defun foo ()
x)
(defun bar (x)
(+ (foo) x))
(bar 0) ⇒ 0
This doesn't come up often in Emacs because local variables tend to have short names (often single-word) whereas global variables tend to have long names (often prefixed by packagename-). Many standard functions have names that are tempting to use as local variables like list and point, but functions and variables live in separate name spaces are local functions are not used very often.
A function is defined in one lexical context and used outside this lexical context because it's passed to a higher-order function.
(let ((cl-y 10))
(mapcar* (lambda (elt) (* cl-y elt)) '(1 2 3)))
⇒ (10 20 30)
(let ((cl-x 10))
(mapcar* (lambda (elt) (* cl-x elt)) '(1 2 3)))
⇑ (wrong-type-argument number-or-marker-p (1 2 3))
The error is due to the use of cl-x as a variable name in mapcar* (from the cl package). Note that the cl package uses cl- as a prefix even for its local variables in higher-order functions. This works reasonably well in practice, as long as you take care not to use the same variable as a global name and as a local name, and you don't need to write a recursive higher-order function.
P.S. Emacs Lisp's age isn't the only reason why it's dynamically scoped. True, in those days, lisps tended towards dynamic scoping — Scheme and Common Lisp hadn't really taken on yet. But dynamic scoping is also an asset in a language targeted towards extending a system dynamically: it lets you hook into more places without any special effort. With great power comes great rope to hang yourself: you risk accidentally hooking into a place you didn't know about.
The other answers are good at explaining the technical details on how to work with dynamic scoping, so here's my non-technical advice:
Just do it
I've been tinkering with Emacs lisp for 15+ years and don't know that I've ever been bitten by any problems due to the differences between lexical/dynamic scope.
Personally, I've not found the need for closures (I love 'em, just don't need them for Emacs). And, I generally try to avoid global variables in general (whether the scoping was lexical or dynamic).
So I suggest jumping in and writing customizations that suit your needs/desires, chances are you won't have any problems.
I entirely feel your pain. I find the lack of lexical binding in emacs rather annoying - especially not being able to use lexical closures, which seems to be a solution I think of a lot, coming from more modern languages.
While I don't have any more advice on working around the lacking features that the previous answers didn't cover yet, I'd like to point out the existance of an emacs branch called `lexbind', implementing lexical binding in a backward-compatible way. In my experience lexical closures are still a little buggy in some circumstances, but that branch appears to a promising approach.
Just don't.
Emacs-24 lets you use lexical-scope. Just run
(setq lexical-binding t)
or add
;; -*- lexical-binding: t -*-
at the beginning of your file.

Lisp style: setq vs. setf

Peter Norvig mentions in Paradigms of Artificial Intelligence Programming, on page 50, the trade off between specificity and consistency and when choosing to use setq or setf to update a variable to a value. What do you recommend? Have you ever run into a situation where it mattered much beyond readability?
Using setq is more low-level, but the performance of setf is not a problem. And setf allows you (or library writers) to provide custom setf behavior, like setting parts of custom data structures. I say: go with setf everywhere unless you have a reason not to.
Also see Practical Common Lisp, chapter 3: "The SETF macro is Common Lisp's main assignment operator." PCL is available online for free: http://gigamonkeys.com/book/
FWIW, I always use setf. If I change the structure of my code slightly, I just need to change the "place" instead of the place and the operator (setq -> setf).
Also, don't worry about performance, setf is exactly the same as setq for symbols:
CL-USER> (macroexpand '(setf foo 42))
(SETQ FOO 42)
You can use setf wherever you could use setq. In fact, setf is actually a macro which builds on setq. So, this should be purely a readability and style issue.
Almost all the code I've seen avoids the use of setq and uses setf.
setf is "set field", it changes a place and can have user extensions.
setq is set with quoting first argument.
I recommend you follow Norvig's final advice in that section: be consistent. 'Readability' is of course the most important reason to make any choice in programming. If it is important to communicate to the reader (perhaps you in 2 months' time) that you are dealing with the entire value cell of a symbol, then use setq; otherwise use setf. But only if you're being consistent.
You will not be wrong if you used setf everywhere instead of setq.
It's the things like this that drags Common Lisp from going forward, lots of unused stuff that implementors still need to support.