Odd behaviour with nconc in emacs lisp - emacs

I have the following function (simplified to that version):
(defun append-test (xs)
(let ((ys `(foo ,(nconc `(bar) xs))))
(nconc ys `((baz)))))
If I evaluate the function multiple times (append-test '((foo))) the list keeps increasing in size, but I can't understand why. The nconc modifies the original list, but because the original list is either a function argument or let-variable, they should be created anew per every invocation, right? What is happening here?

If you change `(bar) to (list 'bar), then the code returns the same result every time.
nconc modifies all arguments but the last one. Obviously, if the first argument were '(bar), then the quoted list contained within the function definition would be modified, and we would expect to see the result you see. Apparently using a backquote expression that doesn't contain any commas is equivalent to using a quoted list.
Actually, the following piece of code keeps the backquote, but adds a pointless expression to the cdr of the list. Apparently, this makes it allocate a new list every time the function is called, and thus it returns the same result every time:
(defun append-test (xs)
(let ((ys `(foo ,(nconc `(bar . ,(ignore)) xs))))
(nconc ys `((baz)))))

I was bitten by this. Here are some bugs that resulted.
http://comments.gmane.org/gmane.emacs.bugs/50783
http://lists.gnu.org/archive/html/emacs-bug-tracker/2011-09/msg00220.html
This issue seems to be a rite of passage for lisp developers. :-)
From what I understand, lisp evaluation is split in two phases:
Read : A reader that statically allocates storage and reads forms into memory.
Evaluate : The read form is evaluated.
What about quote?
quote simply returns the read form without evaluation.
Implicitly,
When a quote form is evaluated, it just returns the reader allocated
object directly.
When a quote form is re-evaluated (i.e. function call, etc), it returns
the same reader allocated object.
quote does not allocate new memory
Ta-da!

Related

Why do quoted objects stay quoted in lisp?

I have made a simple implementation of LISP using SICP metacircular evaluator as a reference, but even though I know and see the code I don't quite understand something about it. In the apply function that applies a closure to its arguments there is a piece of code that calls eval on each of it's arguments. If I quote an argument, then eval of that argument will give the raw form of that argument.
For clarity of the nature of the question and to present my current understanding of what is happening I will walk through an example.
(define f (lambda (x) (print x)))
(define g (lambda (x) (f x)))
; prints "bar" into the console
(g (quote bar))
First we call g with (quote bar) as the first parameter. The argument to g is evaluated to a symbol bar.
When g is evaluated, it passes it should evaluate it's argument and pass it to function f. But evaluating a symbol will cause a lookup from the environment, which doesn't seem to happen (if it did I should have printed an error, or something like that).
So what I want to know is why does the code print bar and not an error.
I walked through the code with the debugger and now I believe I understand. When g was called, a new environment was created with x associated with the symbol bar. And when a function is executed it's parameters are being evaluated to the things that are stored in the environment. So it's not bar that got evaluated, it's x that got evaluated to bar. And after x is evaluated there's no second-time evaluation.
The reason why quoted things appear to stay quoted is because they actually do get unquoted, but they don't get evaluated as arguments (they only get evaluated once you explicitly call eval on them).

Find max in lisp

I am trying to do Recursive method to find max value in list.
Can anyone explain where I made the mistake on this code and how to approach it next time.
(defun f3 (i)
(setq x (cond (> (car (I)) (cdr (car (I))))
(f3 (cdr (I)))))
)
(f3 '(33 11 44 2) )
also I tried this following method and didn't work:
(defun f3 (i)
(cond ((null I )nil )
(setq x (car (i))
(f3(cdr (i)))
(return-from max x)
)
Thanks a lot for any help. I am coming from java if that helps.
If you're working in Common Lisp, then you do this:
(defun max-item (list)
(loop for item in list
maximizing item))
That's it. The maximizing item clause of loop determines the highest item value seen, and implicitly establishes that as the result value of loop when it terminates.
Note that if list is empty, then this returns nil. If you want some other behavior, you have to work that in:
(if list
(loop for item in list
maximizing item))
(... handle empty here ...))
If the number of elements in the list is known to be small, below your Lisp implementation's limit on the number of arguments that can be passed to a function, you can simply apply the list to the max function:
(defun max-item (list)
(apply #'max list))
If list is empty, then max is misused: it requires one or more arguments. An error condition will likely be signaled. If that doesn't work in your situation, you need to add code to supply the desired behavior.
If the list is expected to be large, so that this approach is to be avoided, you can use reduce, treating max as a binary function:
(defun max-item (list)
(reduce #'max list))
Same remarks regarding empty list. These expressions are so small, many programmers will avoid writing a function and just use them directly.
Regarding recursion, you wouldn't use recursion to solve this problem in production code, only as a homework exercise for learning about recursion.
You are trying to compute the maximum value of a list, so please name your function maximum and your parameter list, not f3 or i. You can't name the function max without having to consider how to avoid shadowing the standard max function, so it is best for now to ignore package issues and use a different name.
There is a corner case to consider when the list is empty, as there is no meaningful value to return. You have to decide if you return nil or signal an error, for example.
The skeleton is thus:
(defun maximum (list)
(if (null list)
...
...))
Notice how closing parentheses are never preceded by spaces (or newlines), and opening parentheses are never followed by spaces (or newlines). Please note also that indentation increases with the current depth . This is the basic rules for Lisp formatting, please try following them for other developers.
(setq x <value>)
You are assigning an unknown place x, you should instead bind a fresh variable if you want to have a temporary variable, something like:
(let ((x <value>))
<body>)
With the above expression, x is bound to <value> inside <body> (one or more expressions), and only there.
(car (i))
Unlike in Java, parentheses are not used to group expressions for readability or to force some evaluation order, in Lisp they enclose compound forms. Here above, in a normal evaluation context (not a macro or binding), (i) means call function i, and this function is unrelated to your local variable i (just like in Java, where you can write int f = f(2) with f denoting both a variable and a method).
If you want to take the car of i, write (car i).
You seem to be using cond as some kind of if:
(cond (<test> <then>) <else>) ;; WRONG
You can have an if as follows:
(if <test> <then> <else>)
For example:
(if (> u v) u v) ;; evaluates to either `u` or `v`, whichever is greater
The cond syntax is a bit more complex but you don't need it yet.
You cannot return-from a block that was undeclared, you probably renamed the function to f3 without renaming that part, or copied that from somewhere else, but in any case return-from is only needed when you have a bigger function and probably a lot more side-effects. Here the computation can be written in a more functionnal way. There is an implicit return in Lisp-like languages, unlike Java, for example below the last (but also single) expression in add evaluates to the function's return value:
(defun add-3 (x)
(+ x 3))
Start with smaller examples and test often, fix any error the compiler or interpreter prints before trying to do more complex things. Also, have a look at the available online resources to learn more about the language: https://common-lisp.net/documentation
Although the other answers are right: you definitely need to learn more CL syntax and you probably would not solve this problem recursively in idiomatic CL (whatever 'idiomatic CL' is), here's how to actually do it, because thinking about how to solve these problems recursively is useful.
First of all let's write a function max/2 which returns the maximum of two numbers. This is pretty easy:
(defun max/2 (a b)
(if (> a b) a b))
Now the trick is this: assume you have some idea of what the maximum of a list of numbers is: call this guess m. Then:
if the list is empty, the maximum is m;
otherwise the list has a first element, so pick a new m which is the maximum of the first element of the list and the current m, and recurse on the rest of the list.
So, we can write this function, which I'll call max/carrying (because it 'carries' the m):
(defun max/carrying (m list)
(if (null list)
m
(max/carrying (max/2 (first list) m)
(rest list))))
And this is now almost all we need. The trick is then to write a little shim around max/carrying which bootstraps it:
to compute the maximum of a list:
if the list is empty it has no maximum, and this is an error;
otherwise the result is max/carrying of the first element of the list and the rest of the list.
I won't write that, but it's pretty easy (to signal an error, the function you want is error).

Why a parameter of an Emacs lisp function is not evaluated?

I want to define a list of accumulators with Emacs Lisp and write the following code, but I got a error saying that initV is a void variable. It seems initV is not evaluated in the function define-accum. Where is I make a mistake? (I just want to know why although I know there is other ways to reach my target.)
(defun define-accum (name initV)
(defalias name (lambda (v) (+ v initV))))
(setq accums '((myadd1 . 1)
(myadd2 . 2)))
(dolist (a accums)
(define-accum (car a) (cdr a)))
(message "result = %d" (+ (myadd1 1) (myadd2 1)))
You need to use backquotes properly. This would work for you, for instance:
(defun define-accum (name initV)
(defalias name `(lambda (v) (+ v ,initV))))
See here for an explanation
Apart from using backquotes, you can activate lexical binding (if you're using Emacs 24 or newer). For example, if I put your code in a .el file and put this on the first line:
;; -*- lexical-binding: t -*-
then I get the output:
result = 5
This works because the lambda function in define-accum will reference the initV in the environment where it's being defined (thus picking the variable in the argument list), and create a closure over this variable. With dynamic binding (the default), the function would look for initV in the environment where it's being called.
To add a little to what others have said -
If the variable (initV) is never actually used as a variable, so that in fact its value at the time the accumulator is defined is all that is needed, then there is no need for the lexical closure that encapsulates that variable and its value. In that case, the approach described by #juanleon is sufficient: it uses only the value at definition time - the variable does not exist when the function is invoked (as you discovered).
On the other hand, the lexical-closure approach lets the function be byte-compiled. In the backquote approach, the function is simply represented at runtime by a list that represents a lambda form. If the lambda form represents costly code then it can make sense to use the lexical-closure approach, even though (in this case) the variable is not really needed (as a variable).
But you can always explicitly byte-compile the function (e.g. ##NAME## in your define-accum. That will take care of the inefficiency mentioned in #2, above.

About macro usage which is described in OnLisp

Just do not understand the description of macro used for operators which creates context.
It seems to me that if there is a binding, macro is the only choice.
Is this cannot be achieved by other means?
What does the text below really mean?
Thanks a lot.
There is another kind of context besides a lexical environment. In the
broader sense, the context is the state of theworld, including the
values of special variables, the contents of data structures, and the
state of things outside Lisp. Operators which build this kind of
context must be defined as macros too, unless their code bodies are to
be packaged up in closures. The names of context-building macros often
begin with with-. The most commonly used macro of this type is
probably with-open-file. Its body is evaluated with a newly opened
file bound to a user-supplied variable:
(with-open-file (s "dump" :direction :output)
(princ 99 s))
......
This operator clearly has to be defined as amacro,because it binds s.
However, operators which cause forms to be evaluated in a new context
must be defined as macros anyway.
A form which needs to be executed in a new environment can be defined in two ways:
a macro which expands into the preparation of the environment and the body for the form
a function, which takes a function which is executed inside
What's not possible is this:
(this-is-some-function-with-some-file-opened (princ 99))
Above is not possible, because the princ form will be executed before the function this-is-some-function-with-some-file-opened. Argument forms are executed before the called function. The values of these argument forms will then be passed to the called function.
Thus for the functional version, the body form needs to be passed as a function, which later will be called with the necessary arguments. The macro variant will already expand into the necessary forms and place the body form inside this.
The typical macro version:
(with-open-file (s "dump" :direction :output)
(princ 99 s))
A version using a function:
(call-with-open-file
(lambda (s)
(princ 99 s))
"dump"
:direction :output)
In above one passes in the body as a function and then various parameter follow. From a functional view this is fine. But Common Lisp does not have this function in the language standard. Common Lisp provides the building blocks (OPEN, CLOSE, UNWIND-PROTECT) and the macro WITH-OPEN-FILE, which expands into code that uses the building blocks.
The drawback is that the body could be long and then the parameters are way at the bottom:
(call-with-open-file
(lambda (s)
(princ 99 s)
; 100 more lines here
)
"dump"
:direction :output)
Thus the macro version is seen as more readable in code, since all the information about the opened stream is located at the top. Note that putting the function at the end and the other parameters at the top would also not be a good option, since in Common Lisp lambda lists we have this: positional parameters come first, then optional and keyword parameters.
But in many libraries one gets both the function and the macro. The macro just expands into the function.

Why should I use 'apply' in Clojure?

This is what Rich Hickey said in one of the blog posts but I don't understand the motivation in using apply. Please help.
A big difference between Clojure and CL is that Clojure is a Lisp-1, so funcall is not needed, and apply is only used to apply a function to a runtime-defined collection of arguments. So, (apply f [i]) can be written (f i).
Also, what does he mean by "Clojure is Lisp-1" and funcall is not needed? I have never programmed in CL.
Thanks
You would use apply, if the number of arguments to pass to the function is not known at compile-time (sorry, don't know Clojure syntax all that well, resorting to Scheme):
(define (call-other-1 func arg) (func arg))
(define (call-other-2 func arg1 arg2) (func arg1 arg2))
As long as the number of arguments is known at compile time, you can pass them directly as is done in the example above. But if the number of arguments is not known at compile-time, you cannot do this (well, you could try something like):
(define (call-other-n func . args)
(case (length args)
((0) (other))
((1) (other (car args)))
((2) (other (car args) (cadr args)))
...))
but that becomes a nightmare soon enough. That's where apply enters the picture:
(define (call-other-n func . args)
(apply other args))
It takes whatever number of arguments are contained in the list given as last argument to it, and calls the function passed as first argument to apply with those values.
The terms Lisp-1 and Lisp-2 refer to whether functions are in the same namespace as variables.
In a Lisp-2 (that is, 2 namespaces), the first item in a form will be evaluated as a function name — even if it's actually the name of a variable with a function value. So if you want to call a variable function, you have to pass the variable to another function.
In a Lisp-1, like Scheme and Clojure, variables that evaluate to functions can go in the initial position, so you don't need to use apply in order to evaluate it as a function.
apply basically unwraps a sequence and applies the function to them as individual arguments.
Here is an example:
(apply + [1 2 3 4 5])
That returns 15. It basically expands to (+ 1 2 3 4 5), instead of (+ [1 2 3 4 5]).
You use apply to convert a function that works on several arguments to one that works on a single sequence of arguments. You can also insert arguments before the sequence. For example, map can work on several sequences. This example (from ClojureDocs) uses map to transpose a matrix.
user=> (apply map vector [[:a :b] [:c :d]])
([:a :c] [:b :d])
The one inserted argument here is vector. So the apply expands to
user=> (map vector [:a :b] [:c :d])
Cute!
PS To return a vector of vectors instead of a sequence of vectors, wrap the whole thing in vec:
user=> (vec (apply map vector [[:a :b] [:c :d]]))
While we're here, vec could be defined as (partial apply vector), though it isn't.
Concerning Lisp-1 and Lisp-2: the 1 and 2 indicate the number of things a name can denote in a given context. In a Lisp-2, you can have two different things (a function and a variable) with the same name. So, wherever either might be valid, you need to decorate your program with something to indicate which you mean. Thankfully, Clojure (or Scheme ...) allows a name to denote just one thing, so no such decorations are necessary.
The usual pattern for apply type operations is to combine a function provided at runtime with a set of arguments, ditto.
I've not done enough with clojure to be able to be confident about the subtleties for that particular language to tell whether the use of apply in that case would be strictly necessary.
Apply is useful with protocols, especially in conjunction with threading macros. I just discovered this. Since you can't use the & macro to expand interface arguments at compile time, you can apply an unpredictably sized vector instead.
So I use this, for instance, as part of an interface between a record holding some metadata about a particular xml file and the file itself.
(query-tree [this forms]
(apply xml-> (text-id-to-tree this) forms)))
text-id-to-tree is another method of this particular record that parses a file into an xml zipper. In another file, I extend the protocol with a particular query that implements query-tree, specifying a chain of commands to be threaded through the xml-> macro:
(tags-with-attrs [this]
(query-tree this [zf/descendants zip/node (fn [node] [(map #(% node) [:tag :attrs])])])
(note: this query by itself will return a lot of "nil" results for tags that don't have
attributes. Filter and reduce for a clean list of unique values).
zf, by the way, refers to clojure.contrib.zip-filter, and zip to clojure.zip. The xml-> macro is from the clojure.contrib.zip-filter.xml library, which I :use