Increment variable lisp in local function [duplicate] - lisp

This question already has answers here:
Variable references in lisp
(7 answers)
Closed 8 years ago.
How can i increment a variable in a local function and the change to persist ?
(defun inc(x) (+ x 1))
(setq a 1)
I want this (inc a) to change the value of a to 2
I searched this problem , and i find something with setf but i couldn't resolve the problem.

Depending on your exact problem, this may be answered in Variable references in lisp, which discusses the particular issues of lexical scope that you may be encountering. It even uses the same example of incrementing the value of a variable, so it's particularly relevant.
However, if you're just looking for how to increment a value, then you may be interested in the standard function 1+, where (1+ x) is equivalent to (+ x 1), and the macro incf for incrementing the value of a place by 1.
(let ((a 1)) (let ((a 1))
(1+ a)) (incf a)
a)
;=> 2 ;=> 2
However, depending on exactly what you're trying to do, these might not work for you (and the possible duplicate is more appropriate). If you're trying to call a function with the value of a variable, and then have the body of the function effect a change in the binding of the variable, then you can't do it. That is, there is no function that can make this work:
(let ((a 1))
(foo a)
a)
;=> 2
The function foo is called with the value of the variable a, which is the number 1; it doesn't have any access to the variable, so it can't bind the variable to a new value. However, a macro can work with the unevaluated forms it is called with, so you can have the sort of side effects that you may be looking for. E.g.:
(let ((a 1))
(incf a)
a)
;=> 2
However, as explained above, you can't do:
(defun my-incf (x)
(incf x)) ; modifies the binding of x
(let ((a 1))
(my-incf a)
a)
;=> 2
because the call to incf changes the binding of x, which is a variable that is local to my-incf.

Related

How Lisp (Allegro Common Lisp) uses variables in lambda with ' vs #'

I am hoping someone can explain why tests 1-5 work but test 6 does not. I thought that quoting a lambda with ' and using #' in front of a lambda both returned pointers to the function with the only difference being that the #' will compile it first.
(defun test-1 (y)
(mapcar (lambda (x) (expt x 2))
'(1 2 3)))
(defun test-2 (y)
(mapcar (lambda (x) (expt x y))
'(1 2 3)))
(defun test-3 (y)
(mapcar #'(lambda (x) (expt x 2))
'(1 2 3)))
(defun test-4 (y)
(mapcar #'(lambda (x) (expt x y))
'(1 2 3)))
(defun test-5 (y)
(mapcar '(lambda (x) (expt x 2))
'(1 2 3)))
(defun test-6 (y)
(mapcar '(lambda (x) (expt x y))
'(1 2 3)))
I am using the free version of Franz Industries Allegro Common Lisp. The following are the outputs:
(test-1 2) ; --> (1 4 9)
(test-2 2) ; --> (1 4 9)
(test-3 2) ; --> (1 4 9)
(test-4 2) ; --> (1 4 9)
(test-5 2) ; --> (1 4 9)
(test-6 2) ; --> Error: Attempt to take the value of the unbound variable `Y'. [condition type: UNBOUND-VARIABLE]
For a start, you should be aware that your tests 1-4 are conforming Common Lisp, while your tests 5 and 6 are not. I believe Allegro is perfectly well allowed to do what it does for 5 and 6, but what it is doing is outside the standard. The bit of the standard that talks about this is the definition of functions like mapcar, which take function designators as argument, and the definition of a function designator:
function designator n. a designator for a function; that is, an object that denotes a function and that is one of: a symbol (denoting the function named by that symbol in the global environment), or a function (denoting itself). The consequences are undefined if a symbol is used as a function designator but it does not have a global definition as a function, or it has a global definition as a macro or a special form. [...]
From this it is clear that a list like (lambda (...) ...) is not a function designator: it's just a list whose car happens to be lambda. What Allegro is doing is noticing that this list is in fact something that can be turned into a function and doing that.
Well, let's just write a version of mapcar which does what Allegro's does:
(defun mapcar/coercing (maybe-f &rest lists)
(apply #'mapcar (coerce maybe-f 'function) lists))
This just uses coerce which is a function which knows how to turn lists like this into functions, among other things. If its argument is already a function, coerce just returns it.
Now we can write the two tests using this function:
(defun test-5/coercing (y)
(mapcar/coercing '(lambda (x) (expt x 2))
'(1 2 3)))
(defun test-6/coercing (y)
(mapcar/coercing '(lambda (x) (expt x y))
'(1 2 3)))
So, after that preamble, why can't test-6/explicit work? Well the answer is that Common Lisp is (except for for special variables) lexically scoped. Lexical scope is just a fancy way of saying that the bindings (variables) that are available are exactly and only the bindings you can see by looking at the source of the program. (Except, in the case of CL for special bindings, which I'll ignore, since there are none here.)
So, given this, think about test-6/coercing, and in particular the call to mapcar/coercing: in that call, coerce has to turn the list (lambda (x) (expt z y)) into a function. So it does that. But the function it returns doesn't bind y and there is no binding for y visible in it: the function uses y 'free'.
The only way that this could work is if the function that coerce constructs for us were to dynamically look for a binding for y. Well, that's what dynamically-scoped languages do, but CL is not dynamically-scoped.
Perhaps a way of making this even clearer is to realise that we can lift the function creation right out of the function:
(defun test-7 (y f)
(mapcar f '(1 2 3)))
> (test-7 1 (coerce '(lambda (x) (expt x y)) 'function))
It's clear that this can't work in a lexically-scoped language.
So, then, how do tests 1-4 work?
Well, firstly there are only actually two tests here. In CL, lambda is a macro and (lambda (...) ...) is entirely equivalent to (function (lambda (...) ...)). And of course #'(lambda (...) ...) is also the same as (function (lambda (...) ...)): it's just a read-macro for it.
And (function ...) is a magic thing (a special form) which says 'this is a function'. The important thing about function is that it's not a function: it's a deeply magic thing which tells the evaluator (or the compiler) that its argument is the description of a function in the current lexical context, so, for instance in
(let ((x 1))
(function (lambda (y) (+ x y))))
The x referred to by the function this creates is the x bound by let. So in your tests 2 and 4 (which are the same):
(defun test-4 (y)
(mapcar (function (lambda (x) (expt x y)))
'(1 2 3)))
The binding of y which the function created refers to is the binding of y which is lexically visible, which is the argument of test-4 itself.
Let's add a y parameter to avoid closing over variables and see what kind of values we are manipulating:
USER> (type-of #'(lambda (x y) (expt x y)))
FUNCTION
USER> (type-of (lambda (x y) (expt x y)))
FUNCTION
USER> (type-of '(lambda (x y) (expt x y)))
CONS
As you can see, the two first lambda-like forms are evaluated as functions, while the third is evaluated as a cons-cell. As far as Lisp is concerned, the third argument is just a tree of symbols with no meaning.
Reader macros
I thought that quoting a lambda with ' and using #' in front of a lambda both returned pointers to the function with the only difference being that the #' will compile it first.
Let's go back to the definitions, ' and #' are reader macros, respectively Single-Quote and Sharpsign Single-Quote. They are found in front of other forms, for example 'f is read as (quote f) and #'f is read as (function f). At read-time, f and the resulting forms are just unevaluated data.
We will see below how both special operators are interpreted, but what matters really is the lexical scope, so let's open a parenthesis.
Lexical environment
Lexical environments are the set of bindings in effect at some point of your code. When you evaluate a let or an flet it enriches the current environment with new bindings. When you call EVAL on an expression, you start evaluating from a null lexical environment, even if the call to eval itself is in a non-null environment.
Here x is just unbound during eval:
(let ((x 3)) (eval '(list x))) ;; ERROR
Here we build a let to be evaluated by eval:
(eval '(let ((x 3)) (list x)))
=> (3)
That's all for the crash course on lexical environments.
Special operators
FUNCTION
Special operator FUNCTION takes an argument that is either the name of a function (symbol or setf), or a lambda expression; in particular:
The value of function is the functional value of name in the current lexical environment.
Here the lambda expression is evaluated in the current lexical environment, which means it can refer to variable outside the lambda expression. That's the definition of closures, they capture the surrounding bindings.
NB. you do not need to prefix lambda with #', because there is a macro named (lambda ...) that expands into (function (lambda ...)). It looks like this could expand recursively forever, but this is not the case: at first the macro is expanded so that (lambda ...) becomes (function (lambda ...)), then the special operator function knows how to evaluate the lambda expression itself.
This means that (lambda ...) and #'(lambda ...) are equivalent. Note in particular that there is nothing about whether one form is compiled or not at this point, the compiler will see the same expression after macroexpansion.
QUOTE
Special operator QUOTE evaluates (quote f) as f, where f itself is unevaluated. In test-5 and test-6, there is no function, just an unevaluated structured expression that can be interpreted as code.
Type coercion
Now, certain functions like MAPCAR are used to apply functions. Notice how the specification says that the function parameter is a function designator:
function --- a designator for a function that must take as many arguments as there are lists.
A designator for a type is not necessarily a value of that type, but can be a value that can be coerced to that type. Sometimes a user wants to specify a pathname, and enters a string, but a string is not a value of type pathname: the system has to converts the string into a pathname.
Common Lisp defines a COERCE function with rules regarding how values can be converted to other values. In you case, mapcar first does (coerce (lambda ...) 'function). This is defined as follows:
If the result-type is function, and object is a lambda expression, then the result is a closure of object in the null lexical environment.
The value is thus evaluated in a null lexical environment, so it does not have access to the surrounding bindings; y is a free variable in your lambda expression, and since it is evaluated in a null environment, it is unbound. That's why test-5 pass but test-6 fails.
Name resolution, compilers and late binding
There is a difference whether you write #'f or 'f when referring to a function f where f is a symbol: in the first case, the expression evaluated to an object of type function, and in the second case, you only evaluate a symbol.
Name resolution for this function can change depending and how the compiler works. With a symbol as a function designator, the function does not even need to be defined, the name is resolved when the symbols has to be coerced as a function.
When you write #'f, some compilers may remove one level of indirection and directly make your code jump to the code associated with the function, without having to resolve the name at runtime.
However, this also means that with such compilers (e.g. SBCL), you need to recompile some call sites on function redefinition, as-if the function was declared inline, otherwise some old code will still reference the previous definition of #'f. This is something that is not necessarily important to consider at the beginning, but it can be a source of confusion to keep in mind when you are live coding.

Elisp: Bind a lambda in a Let and execute it [duplicate]

This question already has answers here:
What is the difference between Lisp-1 and Lisp-2?
(2 answers)
Closed 6 years ago.
I am attempting to understand the lambda notion found within Emacs Lisp.
In ielm, executing:
((lambda (x) (* x x)) 5)
gives us 25, and
(let ((x 4)) (* x x))
gives us 16. However when I do:
(let ((f (lambda (x) (* x x)))) (f 7))
it does not give me 49, but instead informs me:
*** Eval error *** Symbol's function definition is void: f
Don't know why, I am sure the syntax is right and f is defined in the let?
Using cl-flet to define let-ed function
We can actually do this without using funcall. The cl module includes standard functions from Common Lisp. We first import it:
(require 'cl)
Thereafter we can use cl-flet to define our function:
(cl-flet ((f (x) (* x x)))
(f 7))
I'd be surprised if this isn't a duplicate, but I can't find it readily here on Stack Overflow. In "Lisp-2" languages (e.g., Emacs Lisp and Common Lisp), there are separate namespaces for functions and variables. A function call looks like:
((lambda ...) ...) ; call the lambda function
or
(f ...) ; call the function binding of f
If you want to call the function that is the value of a variable, then you need to use funcall or apply:
(apply f ...)
(funcall f ...)
The difference between apply and funcall is well documented in other places, but the quick difference is that apply expects an argument list (in some Lisps, a "spreadable argument list"), whereas funcall takes the arguments directly. E.g.,
(let ((f (lambda (a b) (+ a b))))
(funcall f 1 2) ; arguments directly
(apply f '(1 2))) ; arguments in a list
In a "Lisp-1", (like Scheme), you don't need funcall, since there's only one space for bindings. In Scheme you can do:
(let ((f (lambda (a b) (+ a b))))
(f 1 2))
The difference between Lisp-1 and Lisp-2 languages is described more in What is the difference between Lisp-1 and Lisp-2?. The big difference is when the system sees a function call, how it figures out what function to call. In a Lisp-1, variables have values, and that's all. So when the system sees something like:
(f ...)
f is a variable, and the only possible thing to call is the value of f. In a Lisp-2, the systems tries to call the function value of f, which doesn't have to have anything do with the value of the variable f. That can be a bit confusing at first, but it's actually pretty handy in many cases, because it makes it harder to accidentally obscure functions with common names. E.g., in a Lisp-1, you'll see lots of people use lst as an argument name instead of list, because if they named the argument list, then they couldn't use the (standard) function list within the function.

IF error in LISP

I am relatively new to Lisp and I was trying to do a linear search on LISP. But I haven't been able to do so. I am always getting an error that says that "IF has too few parameters".
(setq a '(8 6 2 3 9 5 1))
(LET (key))
(setq key (read))
(loop
(if(= (first a) (key)))
(return t)
(return NIL)
(setq a (rest a))
)
Many problems in your code:
Globally setq an undefined variable
(let (key)) alone does nothing. If you want to define a global variable, use defparameter or defvar.
You if has only a test, and no branches. The special operator if takes a condition, a then expression and an optional else expression: (if test then [else])
If you intended to have your return inside the if, your linear search would stop at the first comparison, because of (return NIL). Indeed, what you would have written would be equivalent to (return (= (first a) key)) and the loop would not even be needed in that case. Maybe you intended to use return to return a value from the if, but if is an expression an already evaluates as a value. return exits the loop (there is an implicit (block NIL ...) around the loop).
(setq a (rest a)) is like (pop a) and would indeed be the right thing to do if you did not already returned from loop at this point.
Just to be sure, be aware that = is for comparing numbers.
The beginning of your code can be written as:
(let ((a '(8 6 2 3 9 5 1))
(key (read)))
(linear-search key a)
Then, how you perform linear-search depends on what you want to learn. There are built-in for this (find, member). You can also use some with a predicate. Loop has a thereis clause. You can even try with reduce or map with a return-from. If you want to learn do or tagbody, you will have an occasion to use (pop a).

SICP: Can or be defined in lisp as a syntactic transformation without gensym?

I am trying to solve the last part of question 4.4 of the Structure and Interpretation of computer programming; the task is to implement or as a syntactic transformation. Only elementary syntactic forms are defined; quote, if, begin, cond, define, apply and lambda.
(or a b ... c) is equal to the first true value or false if no value is true.
The way I want to approach it is to transform for example (or a b c) into
(if a a (if b b (if c c false)))
the problem with this is that a, b, and c would be evaluated twice, which could give incorrect results if any of them had side-effects. So I want something like a let
(let ((syma a))
(if syma syma (let ((symb b))
(if symb symb (let ((symc c))
(if (symc symc false)) )) )) )
and this in turn could be implemented via lambda as in Exercise 4.6. The problem now is determining symbols syma, symb and symc; if for example the expression b contains a reference to the variable syma, then the let will destroy the binding. Thus we must have that syma is a symbol not in b or c.
Now we hit a snag; the only way I can see out of this hole is to have symbols that cannot have been in any expression passed to eval. (This includes symbols that might have been passed in by other syntactic transformations).
However because I don't have direct access to the environment at the expression I'm not sure if there is any reasonable way of producing such symbols; I think Common Lisp has the function gensym for this purpose (which would mean sticking state in the metacircular interpreter, endangering any concurrent use).
Am I missing something? Is there a way to implement or without using gensym? I know that Scheme has it's own hygenic macro system, but I haven't grokked how it works and I'm not sure whether it's got a gensym underneath.
I think what you might want to do here is to transform to a syntactic expansion where the evaluation of the various forms aren't nested. You could do this, e.g., by wrapping each form as a lambda function and then the approach that you're using is fine. E.g., you can do turn something like
(or a b c)
into
(let ((l1 (lambda () a))
(l2 (lambda () b))
(l3 (lambda () c)))
(let ((v1 (l1)))
(if v1 v1
(let ((v2 (l2)))
(if v2 v2
(let ((v3 (l3)))
(if v3 v3
false)))))))
(Actually, the evaluation of the lambda function calls are still nested in the ifs and lets, but the definition of the lambda functions are in a location such that calling them in the nested ifs and lets doesn't cause any difficulty with captured bindings.) This doesn't address the issue of how you get the variables l1–l3 and v1–v3, but that doesn't matter so much, none of them are in scope for the bodies of the lambda functions, so you don't need to worry about whether they appear in the body or not. In fact, you can use the same variable for all the results:
(let ((l1 (lambda () a))
(l2 (lambda () b))
(l3 (lambda () c)))
(let ((v (l1)))
(if v v
(let ((v (l2)))
(if v v
(let ((v (l3)))
(if v v
false)))))))
At this point, you're really just doing loop unrolling of a more general form like:
(define (functional-or . functions)
(if (null? functions)
false
(let ((v ((first functions))))
(if v v
(functional-or (rest functions))))))
and the expansion of (or a b c) is simply
(functional-or (lambda () a) (lambda () b) (lambda () c))
This approach is also used in an answer to Why (apply and '(1 2 3)) doesn't work while (and 1 2 3) works in R5RS?. And none of this required any GENSYMing!
In SICP you are given two ways of implementing or. One that handles them as special forms which is trivial and one as derived expressions. I'm unsure if they actually thought you would see this as a problem, but you can do it by implementing gensym or altering variable? and how you make derived variables like this:
;; a unique tag to identify special variables
(define id (vector 'id))
;; a way to make such variable
(define (make-var x)
(list id x))
;; redefine variable? to handle macro-variables
(define (variable? exp)
(or (symbol? exp)
(tagged-list? exp id)))
;; makes combinations so that you don't evaluate
;; every part twice in case of side effects (set!)
(define (or->combination terms)
(if (null? terms)
'false
(let ((tmp (make-var 'tmp)))
(list (make-lambda (list tmp)
(list (make-if tmp
tmp
(or->combination (cdr terms)))))
(car terms)))))
;; My original version
;; This might not be good since it uses backquotes not introduced
;; until chapter 5 and uses features from exercise 4.6
;; Though, might be easier to read for some so I'll leave it.
(define (or->combination terms)
(if (null? terms)
'false
(let ((tmp (make-var 'tmp)))
`(let ((,tmp ,(car terms)))
(if ,tmp
,tmp
,(or->combination (cdr terms)))))))
How it works is that make-var creates a new list every time it is called, even with the same argument. Since it has id as it's first element variable? will identify it as a variable. Since it's a list it will only match in variable lookup with eq? if it is the same list, so several nested or->combination tmp-vars will all be seen as different by lookup-variable-value since (eq? (list) (list)) => #f and special variables being lists they will never shadow any symbol in code.
This is influenced by eiod, by Al Petrofsky, which implements syntax-rules in a similar manner. Unless you look at others implementations as spoilers you should give it a read.

Implenting simultaneous bindings

I'm writing a Lisp (code at GitHub) and I want to implement local bindings. Currently I have two syntaxes:
(let <var> <val> <expr>)
for binding a single variable or function, and
(with (<var1> <val1> ... <varN> <valN>) <expr>)
to bind multiple values at once.
At present, the bindings are evaluated sequentially, and each new function binding retains a copy of the environment it was defined in, so <var2> can refer to <var1> but not vice-versa.
I would like to modify the code so that when binding multiple values at once you effectively have simultaneous binding. For example, I would like to be able to write (this is a trivial example, but it should illustrate the idea):
(define (h y)
(with ((f x) (if (eq? x 0) #t (g (- x 1)))
(g x) (if (eq? x 0) #f (f (- x 1))))
(f y))
At the moment this code doesn't run - g closes over f, but not the other way around.
Is there a canonical way to implement simultaneous binding in Lisp?
In SICP there's a section on internal definitions which covers this subject. In particular, the exercises 4.16, 4.18, 4.19 tell you how to implement different strategies for achieving simultaneous definitions.
The syntax is a bit different, but the idea in the book boils down to transforming this code:
(lambda <vars>
(define u <e1>)
(define v <e2>)
<e3>)
Into this code:
(lambda <vars>
(let ((u '*unassigned*)
(v '*unassigned*))
(set! u <e1>)
(set! v <e2>)
<e3>))
The same idea applies to your with special form. Take a look at the linked book for more implementation details.
In (with (a (+ 2 2))) we are binding a to the value of the expression (+ 2 2), so a becomes 4. But in (with ((f x) (+ x x))) we are doing something else: we are binding f to a function. This is a syntactic sugar for (with (f (lambda (x) (+ x x)))).
To handle this situation, you have to process the bindings in two passes. First collect all the variables and create the environment which contains all of them. Then evaluate the initializing experssions and store their values in the corresponding variables. The evaluation of these expressions takes place in that environment, so every expression has visibility over all the variables. The initialization is done by assignment. The variables can be initially nil or have some trap value which blows up if they are accessed.