I am trying to create a lisp code that reads 2 integers and outputs all numbers between the two. my current code is
(defun range (x y)
(if (< x y)
x
(1+ (range(x y))))
the code compiles and runs but only outputs "1".
Not sure what exactly you want but the closest I could come up with is:
(defun range (x y)
(when (< x y)
(print x)
(range (1+ x) y)))
Testing
CL-USER> (range 3 7)
3
4
5
6
NIL
Pay attention to
indent your code properly
use when (or cond or progn ...) if you want to do more than one action after a condition
the 1+ is used to increment a parameter, not the complete expression; think of it as a loop variable in a traditional language
your variable only becomes 'visible' outside the function if you print it, or add it to a result list.
Also, tag your question common-lisp for better visibility.
EDIT
proof that the original code does run on some instances of CLISP:
Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>
[1]> (range 1 5)
*** - EVAL: undefined function RANGE
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of (FDEFINITION 'RANGE).
RETRY :R2 Retry
STORE-VALUE :R3 Input a new value for (FDEFINITION 'RANGE).
ABORT :R4 Abort main loop
Break 1 [2]>
[3]> (defun range (x y)
(if (< x y)
x
(1+ (range(x y)))))
RANGE
[4]> (range 1 5)
1
[5]>
Related
I am new to scheme and am trying to gain an understanding of how the following piece of code is able to recursively multiply two numbers provided (how is the function stack occurring here):
;Recursive Arithmetic
(define increment
(lambda (x)
(+ x 1)))
(define decrement
(lambda (x)
(- x 1)))
(define recursive-add
(lambda (x y)
(if (zero? y)
x
(recursive-add (increment x) (decrement y)))))
"Define Multiplication Recursively"
(define recursive-mult
(lambda (x y)
(if (zero? y)
0
(recursive-add x (recursive-mult x (decrement y)))))) ;else
(recursive-mult 9 5)
My first doubt is what part of the else section is executed first?
In the else section, if (decrement y) is executed first, then y is first decremented by 1, then the(recursive-mult x section runs next by which function calls itself, so the section (recursive-add x never gets called in this same line of code.
Now, if in the else section, the recursive-add x is executed first, x gets added first, then the recursive-mult x runs which runs the the whole function again and the (decrement y) is never reached.
Now I know either of my two assumptions above, or maybe both are wrong. Would someone be able to point me in the right direction please? I apologize if my question displays a high level of inadequacy in this subject but I really want to learn scheme properly. Thank you.
This is an answer in Common Lisp, in which I am more familiar, but the approach is the same. Here is a translation of your code:
(defpackage :so (:use :cl))
(in-package :so)
(defun add (x y)
(if (zerop y)
x
(add (1+ x) (1- y))))
(defun mul (x y)
(if (zerop y)
0
(add x (mul x (1- y)))))
The increment and decrement functions are not defined, I'm using 1+ and 1- which are equivalent.
In the else section, if (decrement y) is executed first, then y is first decremented by 1, then the(recursive-mult x section runs next by which function calls itself, so the section (recursive-add x never gets called in this same line of code.
You can use the substitution model to evaluate recursive functions.
(add (add 1 3) 1)
Let's evaluate first the first argument of the top-most and:
(add (add 2 2) 1)
(add (add 3 1) 1)
(add (add 4 0) 1)
(add 4 1)
Here the call eventually returned and the first argument is 4. Once the execution is resumed, the rest of the code for (add (add 1 3) 1) is executed, which is equivalent to:
(add 5 0)
And finally:
5
Each time you invoke the function a new frame is pushed on the call stack, which is what is shown in a trace:
(trace mul add)
The macro above in Common Lisp makes it so the mul and add functions are traced.
Now when I run a program, a trace is printed when they are entered and exited.
Let's try with small values:
(mul 2 3)
The trace is printed as follows (don't mind the SO:: prefix, this is part of the fully-qualified name of symbols):
0: (SO::MUL 2 3)
1: (SO::MUL 2 2)
2: (SO::MUL 2 1)
3: (SO::MUL 2 0)
3: MUL returned 0
3: (SO::ADD 2 0)
3: ADD returned 2
2: MUL returned 2
2: (SO::ADD 2 2)
3: (SO::ADD 3 1)
4: (SO::ADD 4 0)
4: ADD returned 4
3: ADD returned 4
2: ADD returned 4
1: MUL returned 4
1: (SO::ADD 2 4)
2: (SO::ADD 3 3)
3: (SO::ADD 4 2)
4: (SO::ADD 5 1)
5: (SO::ADD 6 0)
5: ADD returned 6
4: ADD returned 6
3: ADD returned 6
2: ADD returned 6
1: ADD returned 6
0: MUL returned 6
The difference with Scheme is that Scheme does not define the order by which function arguments are evaluated (it is left unspecified), so maybe your code would not exactly behave as above, but it should still compute the same answer (because there are no side effects).
Scheme has eager evaluation so if you have
(op1 expr1 (op2 1 (op3 expr2 expr3)))
Then op1 form will depend on expr1 and the form with op2 to be complete before op1 can be applied. If we have an implementation that
does left to right evaluation it will do it like this:
(let ((vexpr1 expr1)
(vexpr2 expr2)
(vexpr3 expr3))
(let ((vop3 (op3 vexpr2 vexpr3)))
(let ((vop2 (op2 1 vop3)))
(op1 vexpr1 vop2))))
So to answer your question the order in the same left to right Scheme will be:
(let ((vdy (decrement y)))
(let ((vrm (recursive-mult x vdy)))
(recursive-add x vrm)))
Same in CPS:
(decrement& y
(lambda (vdy)
(recursive-mult& x
vy
(lambda (vrm)
(recursive-add& x vrm continuation)))))
So in practice the application for the first round doesn't happen before the whole recursive-mult for the smaller expression happens first. Thus (recursive-mult 3 3) turns into
(recursive-add 3 (recursive-add 3 (recursive-add 3 0)))
And as you can see the last one is being done first, then the second one and the last addition to be performed is the one of the first round before recursion.
I'm working on some numerical computations in Common Lisp and I need to compute a linear combination of several vectors with given numerical coefficients. I'm rewriting a piece of Fortran code, where this can be accomplished by res = a1*vec1 + a2*vec2 + ... + an*vecn. My initial take in CL was to simply write each time something like:
(map 'vector
(lambda (x1 x2 ... xn)
(+ (* x1 a1) (* x2 a2) ... (* xn an)))
vec1 vec2 ... vecn)
But I soon noticed that this pattern would recur over and over again, and so started writing some code to abstract it away. Because the number of vectors and hence the number of lambda's arguments would vary from place to place, I figured a macro would be required. I came up with the following:
(defmacro vec-lin-com (coefficients vectors &key (type 'vector))
(let ((args (loop for v in vectors collect (gensym))))
`(map ',type
(lambda ,args
(+ ,#(mapcar #'(lambda (c a) (list '* c a)) coefficients args)))
,#vectors)))
Macroexpanding the expression:
(vec-lin-com (10 100 1000) (#(1 2 3) #(4 5 6) #(7 8 9)))
yields the seemingly correct expansion:
(MAP 'VECTOR
(LAMBDA (#:G720 #:G721 #:G722)
(+ (* 10 #:G720) (* 100 #:G721) (* 1000 #:G722)))
#(1 2 3) #(4 5 6) #(7 8 9))
So far, so good...
Now, when I try to use it inside a function like this:
(defun vector-linear-combination (coefficients vectors &key (type 'vector))
(vec-lin-com coefficients vectors :type type))
I get a compilation error stating essentially that The value VECTORS is not of type LIST. I'm not sure how to approach this. I feel I'm missing something obvious. Any help will be greatly appreciated.
You've gone into the literal trap. Macros are syntax rewriting so when you pass 3 literal vectors in a syntax list you can iterate on them at compile time, but replacing it with a bindnig to a list is not the same. The macro only gets to see the code and it doesn't know what vectors will eventually be bound to at runtime when it does its thing. You should perhaps make it a function instead:
(defun vec-lin-com (coefficients vectors &key (type 'vector))
(apply #'map
type
(lambda (&rest values)
(loop :for coefficient :in coefficients
:for value :in values
:sum (* coefficient value)))
vectors))
Now you initial test won't work since you passed syntax and not lists. you need to quote literals:
(vec-lin-com '(10 100 1000) '(#(1 2 3) #(4 5 6) #(7 8 9)))
; ==> #(7410 8520 9630)
(defparameter *coefficients* '(10 100 1000))
(defparameter *test* '(#(1 2 3) #(4 5 6) #(7 8 9)))
(vec-lin-com *coefficients* *test*)
; ==> #(7410 8520 9630)
Now you could make this a macro, but most of the job would have been done by the expansion and not the macro so basically you macro would expand to similar code to what my function is doing.
Remember that macros are expanded at compile-time, so the expression ,#(mapcar #'(lambda (c a) (list '* c a)) coefficients args) has to be meaningful at compile-time. In this case, all that mapcar gets for coefficients and args are the symbols coefficients and vectors from the source code.
If you want to be able to call vec-lin-com with an unknown set of arguments (unknown at compile-time, that is), you'll want to define it as a function. It sounds like the main problem you're having is getting the arguments to + correctly ordered. There's a trick using apply and map to transpose a matrix that may help.
(defun vec-lin-com (coefficients vectors)
(labels
((scale-vector (scalar vector)
(map 'vector #'(lambda (elt) (* scalar elt)) vector))
(add-vectors (vectors)
(apply #'map 'vector #'+ vectors)))
(let ((scaled-vectors (mapcar #'scale-vector coefficients vectors)))
(add-vectors scaled-vectors))))
This isn't the most efficient code in the world; it does a lot of unnecessary consing. But it is effective, and if you find this to be a bottleneck you can write more efficient versions, including some that can take advantage of compile-time constants.
I'm looking for a way how to use map function in more custom way. If there is a different function for what I'm trying to achieve, could you please let me know this.
;lets say i have addOneToEach function working as bellow
(defn plusOne[singleInt]
(+ 1 singleInt))
(defn addOneToEach[intCollection] ;[1 2 3 4]
(map plusOne intCollection)) ;=>(2 3 4 5)
;But in a case I would want to customly define how much to add
(defn plusX[singleInt x]
(+ x singleInt))
(defn addXToEach[intCollection x] ;[1 2 3 4]
;how do I use plusX here inside map function?
(map (plusX ?x?) intCollection)) ;=>((+ 1 x) (+ 2 x) (+ 3 x) (+ 4 x))
I'm not looking for a function that adds x to each in the collection, but a way to pass extra arguments to the function that map is using.
another option to the already mentioned would be partial (note that in the example the order of the params does not matter, since you just add them, but partial binds them from left to right, so beware):
user=> (doc partial)
-------------------------
clojure.core/partial
([f] [f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more])
Takes a function f and fewer than the normal arguments to f, and
returns a fn that takes a variable number of additional args. When
called, the returned function calls f with args + additional args.
nil
user=> (defn plus-x [x i] (+ x i))
#'user/plus-x
user=> (map (partial plus-x 5) [1 2 3])
(6 7 8)
There are several ways to go about it. One is using an explicit local function via letfn:
(defn add-x-to-each [ints x]
(letfn [(plus-x [i]
(+ i x))]
(map plus-x ints)))
For this small piece of code this is probably overkill and you can simply streamline it via an anonymous function:
(defn add-x-to-each [ints x]
(map #(+ % x) ints))
Both of these solutions basically apply the use of a closure which is an important concept to know: it boils down to defining a function dynamically which refers to a variable in the environment at the time the function was defined. Here we defer the creation of plus-x (or the anonymous) function until x is bound, so plus-x can refer to whatever value is passed in to add-x-to-each.
You almost got it right.
There are several possible ways:
1.
(defn addXToEach[intCollection x]
(map #(plusX % x) intCollection))
#(%) means same as (fn [x] (x)) (be aware that x is being evaluated here).
2.
(defn addXToEach[intCollection x]
(map (fn [item] (plusX item x)) intCollection))
3.
(defn addXToEach[intCollection x]
(map #(+ % x) intCollection))
and then you don't have to define your plusX function.
Hope it helps!
You are applying map to one collection, so the function that map applies must take one argument. The question is, how is this function to be composed?
The function
(defn plusOne [singleInt]
(+ 1 singleInt))
... works. It is otherwise known as inc.
But the function
(defn plusX [singleInt x]
(+ x singleInt))
... doesn't work, because it takes two arguments. Given a number x, you want to return a function that adds x to its argument:
(defn plusX [x]
(fn [singleInt] (+ x singleInt))
You can use a function returned by plusX in the map.
It is when you compose such a function that you can use extra arguments. This kind of function, composed as an expression involving captured data, is called a closure.
For example, (plusX 3) is a function that adds 3 to its argument.
(map (plusX 3) stuff)
;(4 5 6 7)
As you see, you don't need to name your closure.
Specifically for + the following will also work:
(map + (repeat 4) [3 4 9 0 2 8 1]) ;=> (7 8 13 4 6 12 5)
Of course, instead '4' put your number, or wrap with (let [x 4] ...) as suggested above.
It might not be the most performant, although, I guess.
I am trying to format an arbitrary expression, say (+ 2 3), and at the same time, its result, 5.
I have the following:
(defun expr-and-result (expr)
(format t "~a returns ~a~%" expr (eval expr)))
CL-USER> (expr-and-result '(+ 2 3))
(+ 2 3) returns 5
Though it's a simple matter by using eval, I'm curious if this effect can be accomplished without it (because I heard a lot that eval is to be avoided).
I understand that quoting the argument is necessary, because otherwise the given expression will be evaluated as the first step in calling expr-and-result, and only its result could be used inside expr-and-result. Therefore, any possible solution requires the input to be quoted, right?
I thought a bit about macros but I feel like it's the wrong approach to what I am looking for.
Edit: My intent was to construct a simple test-suite, such as:
(progn
(mapcar #'expr-and-result
'((= (my-remainder 7 3) 1)
(= (my-remainder 7 3) 2)))
'end-of-tests)
Outputs:
(= (MY-REMAINDER 7 3) 1) returns T
(= (MY-REMAINDER 7 3) 2) returns NIL
END-OF-TESTS
After reading Paulo's comment, it seems that eval is the shortest and cleanest solution for my purposes.
Here is a simple macro:
(defmacro exec-and-report (form)
`(format t "~S returns ~S~%" ',form ,form))
(macroexpand '(exec-and-report (+ 1 2)))
==>
(FORMAT T "~S returns ~S~%" '(+ 1 2) (+ 1 2)) ;
T
(exec-and-report (+ 1 2))
==>
(+ 1 2) returns 3
NIL
PS. I second #Sylvester's suggestion not to reinvent the wheel
I am brand new to Scheme and am working on an assignment to implement stochastic gradient descent. So far I believe I have the structure of the program correct however my procedure that takes the derivative of a function f(x) is giving me some trouble. In my "try" loop at the bottom of the code I recursively call (try (func-eval guess)) where (func-eval guess) calculates the next guess of my function's local minimal with the formula *x - alpha*f'(x)* where alpha = 0.1.
I seem to be getting an error when calculating the derivative... I am using Dr.Racket IDE and it has highlighted this following line as being problematic:
(f (+ x dx)) ... which is the second line in my local derivative procedure:
(define (local-minimal first-guess)
;A way to check a guess
(define(good-enough? val1 val2)
(<(abs(- val1 val2)) 0.00001))
; x_new = x_old - alpha*f'(x) /// f(x)=(x+1)^2+2 //// alpha = 0.1
(define (func-eval x)
(- x (* 0.1((derivative (+ 2(expt (+ x 1) 2)) 0.00001)x))))
(define (derivative f dx)
(lambda (x)
(/ (- (f (+ x dx)) (f x))
dx)))
; trys the guess
(define (try guess)
(if (good-enough? guess -1)
guess
(try (func-eval guess))))
(try first-guess))
I am getting an error saying:
application: not a procedure;
expected a procedure that can be applied to arguments
given: 3
arguments...:
-1.99999
Is this a syntax error? I thought that I would be able to say f(x+dx) by using (f (+ x dx)) .... does this mean that I need to put an operator before the f in those parenthesis?
The highlighting and error message are together telling you something useful: the thing derivative is receiving as its first argument f isn't a function, which it needs to be to called in (f (+ x dx)). Where does the argument come from? We could run DrRacket's debugger, but here we can just look at the code -- the only place derivative is called from is the first line of func-eval, so that's where we must have passed a number instead of a function. Sure enough, (+ 2 (expt (+ x 1) 2)) (with x bound) is just a number, and trying to apply this gives an error.
When calling derivative, the first argument has to be a function. In the following procedure call, the expression in the first argument gets evaluated to a number, not a function:
(derivative (+ 2 (expt (+ x 1) 2)) 0.00001)
To fix it, pack the expression inside a lambda, which makes it an actual function:
(derivative (lambda (x) (+ 2 (expt (+ x 1) 2))) 0.00001)