I keep getting random errors when compiling this function:
(defun gcd (a b)
(if (= b 0)
a
(gcd b mod (a b))))
The most common is that it says "undefined function a." So I figured I needed return a in that place. This did not work. I get a to many parameters for if statement error. Any idea what I am doing wrong here? New to Lisp and so far we are not seeing eye to eye.
Running on CLISP on Windows 7.
In Lisp a function call always* starts with '(', so the line
(gcd b mod(a b))
means "call the function gcd with arguments b, mod and the result of calling function a with argument b".
I suspect you really want something like:
(gcd b (mod a b))
*I haven't used Lisp for a little while so I might not be 100% correct on the "always".
(gcd b mod(a b)) should be (gcd b (mod a b))
You mod function call is wrong. Here's my working code:
(defun gcd2(a b)
(if (= b 0) a (gcd2 b (mod a b))))
Usually a compiler can give you more information:
Using LispWorks:
(defun gcd1 (a b)
(if (= b 0)
a
(gcd1 b mod (a b))))
CL-USER 31 > (compile 'gcd1)
;;;*** Warning in GCD1: GCD1 is called with the wrong number of arguments: Got 3 wanted 2
;;;*** Warning in GCD1: MOD assumed special
The following function is undefined:
A which is referenced by GCD1
GCD1
So you see that you call GCD1 with the wrong number of arguments, that MOD is assumed to be a variable and that A is assumed to be a function.
SBCL:
; in: DEFUN GCD1
; (GCD1 B MOD (A B))
;
; caught WARNING:
; The function was called with three arguments, but wants exactly two.
; in: DEFUN GCD1
; (A B)
;
; caught STYLE-WARNING:
; undefined function: A
; (GCD1 B MOD (A B))
;
; caught WARNING:
; undefined variable: MOD
Related
I'm new to scheme and trying to learn functions. I want to create a function where I can count all occurrences of the atom "a" in an argument. This is what I have written so far. I'm not sure what to write in the third condition. Please help out.
(define (count-a arg)
(COND
((null? arg) 0)
((eq? arg 'a) 1)
((list? arg) ( ___ + ( ___ count-a arg)))
(else 0)
))
This is the output i want:
(count-a 'a)
1
(count-a 'aa)
0
(count-a '(a))
1
(count-a '(ab c)
0
(count-a '(a (b c) (c (d a) a) (((a b)))))
5
(___ + ( ___ count-a arg)) doesn't seem right to me. Remember Scheme is a prefix language. It's (+ 1 2 3) instead of 1 + 2 + 3.
In the third one you have two lists parts. eg. '(a a) so you need to call count-a on the car and on the cdr of the list and add the results together. eg. (count-a '(a a)) should give the same result as (+ (count-a 'a) (count-a '(a))
Good luck
Welcome to Stack Overflow!
Solution:
(define (count-a arg)
(cond ((null? arg) 0)
((not (pair? arg))
(if (equal? arg 'a)
1
0))
;; At this point we know arg is a pair, and we recurse.
(else (+ (count-a (car arg)) (count-a (cdr arg))))))
Test:
Here are the tests you specified, compressed into a single line.
;; Chibi-Scheme REPL - other implementations might look different.
> (map count-a '(a aa (a) (ab c) (a (b c) (c (d a) a) (((a b))))))
(1 0 1 0 4)
You didn't say what you want to happen if arg is a dotted pair. But let's check it out just for fun.
> (map count-a '((ab . '()) (ab . a) (a . a)))
(0 1 2)
So when I run your last test on my code, it yields 4 where you expected 5. I maintain that my code is correct and your test specification is incorrect, as there are only four instances of 'a in the argument of count-a.
Discussion:
You specified in your headline that the thing the count-a function will be counting is an atom. So you have to check whether arg is an atom or not. Since Scheme doesn't have an atom? function, I'll assume that an atom is anything that's not '() and not a pair. (This is consistent with the atom function of Common Lisp, as well as other Lisp dialects.)
Since your code already deals with arg being '(), we only have to deal with arg being, or not being a pair.
If arg is not a pair and (equal? arg 'a), then (count-a arg) equals 1. Else, it equals 0.
If arg is a pair, we can recurse into car arg) and (cdr arg), however deeply nested arg may be, and increase our count whenever we find an atom that equals a.
Hope that helps.
I've got a bit exotic situation. I need to compare functions, but rather by their "origin" than by "instances". Here what I actually mean:
(define-values (a b c d) (values #f #f #f #f))
(define (f x)
(let ([g (λ (y) (printf "Please tell ~a this is ~a\n" x y))]
[h (curry printf "Don't tell ~a this is ~a\n" x)])
(if a
(set! b g)
(set! a g))
(if c
(set! d h)
(set! c h))))
(f "me")
(f " me")
(a "possible")
(d "impossible")
(equal? a b) ; <==== Is it possible to compare these guys
(equal? c d) ; <==== to get #t in both cases?
In both cases we get two different "instances" of functions (even with different values captured), but both declared in the same location of the source code. Of course, getting the actual text of the body of those functions will solve the problem, but other answers here on SO tell that this is impossible in Racket. Are there some tricks that can help me?
Edit:
This is not the question on theoretical equivalence of functions. This is completely technical question, much rather on Racket's functions representation in a compiled code. So it can be reformulated, for example, in a following way: can I get the line number of some routine from 'user' code? I suppose this should be feasible because Racket debugger somehow obtains it.
It can be done even without support from racket internals if you control the code that makes the functions. If you keep a counter (or some identifier) that will denote the particular lambda it can wrap different closures in a struct that can have the same identity from macro expansion. Here is a demonstration:
#lang racket
;; makes a procedure object that can have other data connected to it
(struct proc (id obj)
#:property prop:procedure
(struct-field-index obj)
#:methods gen:custom-write
[(define (write-proc x port mode)
(display (format "#<procedure-id-~a>" (proc-id x)) port))])
;; compares the ids of two proc objects if they are proc objects
(define (proc-equal? a b)
(and (proc? a)
(proc? b)
(= (proc-id a) (proc-id b))))
;; extends equal?, candidate to provide
(define (equal*? a b)
(or (proc-equal? a b)
(equal? a b)))
;; the state we keep
(begin-for-syntax
(define unique-proc-id-per-code 0))
;; a macro that changes (lambda* ...) to
;; (proc expansion-id (lambda ...))
(define-syntax (lambda* stx)
(let ((proc-id unique-proc-id-per-code))
(set! unique-proc-id-per-code (add1 unique-proc-id-per-code))
#`(proc #,(datum->syntax stx proc-id) (lambda #,#(datum->syntax stx (cdr (syntax-e stx)))))))
;; test with making a counter
(define counter-from
(lambda* (from)
(lambda* ()
(begin0
from
(set! from (add1 from))))))
;; evaluatin the outer shows it has id 0
counter-from ; ==> #<procedure-id-0>
;; make two counters that both use the inner lambda
(define from10 (counter-from 10))
(define from20 (counter-from 20))
;; both have the same expansion id
from10 ; ==> #<procedure-id-1>
from20 ; ==> #<procedure-id-1>
;; they are not equal?
(equal? from10 from20) ; ==> #f (different object instances of proc)
;; but they are procedure-equal?
(proc-equal? from10 from20) ; ==> #t (same id, thus came from same macroexpansion)
Disclaimer: I'm more a schemer than a racketeer so this could perhaps have been done more elegantly and I have no idea what performance penalties this will give.
This question already has answers here:
Why do we need funcall in Lisp?
(3 answers)
Closed 8 years ago.
I was expecting the Scheme approach:
(defun mmap (f xs)
(if (equal xs NIL)
'()
(cons (f (car xs)) (mmap f (cdr xs)))))
but i get a compiler warning
;Compiler warnings for ".../test.lisp" :
; In MMAP: Undefined function F
I can see that I need to make the compiler aware that f is a function. Does this have anything to do with #'?
Common Lisp is a LISP2. It means variables that are in the first element of the form is evaluated in a function namespace while everything else is evaluated from a variable namespace. Basically it means you can use the same name as a function in your arguments:
(defun test (list)
(list list list))
Here the first list is looked up in the function namespace and the other two arguments are looked up in the variable namespace. First and the rest become two different values because they are fetched from different places. If you'd do the same in Scheme which is a LISP1:
(define (test list)
(list list list))
And pass a value that is not a procedure that takes two arguments, then you'll get an error saying list is not a procedure.
A function with name x in the function namespace can be fetched from other locations by using a special form (function x). Like quote function has syntax sugar equivalent so you can write #'x. You can store functions in the variable namespace (setq fun #'+) and you can pass it to higher order functions like mapcar (CL version of Scheme map). Since first element in a form is special there is a primitive function funcall that you can use when the function is bound in the variable namespace: (funcall fun 2 3) ; ==> 5
(defun my-mapcar (function list)
(if list
(cons (funcall function (car list))
(my-mapcar function (cdr list)))
nil))
(my-mapcar #'list '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
A version using loop which is the only way to be sure not to blow the stack in CL:
(defun my-mapcar (function list)
(loop :for x :in list
:collect (funcall function x)))
(my-mapcar #'list '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
Of course, mapcar can take multiple list arguments and the function map is like mapcar but it works with all sequences (lists, arrays, strings)
;; zip
(mapcar #'list '(1 2 3 4) '(a b c d)) ; ==> ((1 a) (2 b) (3 c) (4 d))
;; slow way to uppercase a string
(map 'string #'char-upcase "banana") ; ==> "BANANA"
functions in CL that accepts functions as arguments also accept symbols. Eg. #'+ is a function while '+ is a symbol. What happens is that it retrieves #'+ by fetching the function represented by + in the global namespace. Thus:
(flet ((- (x) (* x x)))
(list (- 5) (funcall #'- 5) (funcall '- 5))) ; ==> (25 25 -5)
Trivia: I think the number in LISP1 and LISP2 refer to the number of namespaces rather than versions. The very first LISP interpereter had only one namespace, but dual namespace was a feature of LISP 1.5. It was he last LISP version before commercial versions took over. A LISP2 was planned but was never finished. Scheme was originally written as a interpreter in MacLisp (Which is based on LISP 1.5 and is a LISP2). Kent Pittman compared the two approaches in 1988.
I'm supposed to define the function n! (N-Factorial). The thing is I don't know how to.
Here is what I have so far, can someone please help with this? I don't understand the conditionals in Racket, so an explanation would be great!
(define fact (lambda (n) (if (> n 0)) (* n < n)))
You'll have to take a good look at the documentation first, this is a very simple example but you have to understand the basics before attempting a solution, and make sure you know how to write a recursive procedure. Some comments:
(define fact
(lambda (n)
(if (> n 0)
; a conditional must have two parts:
; where is the consequent? here goes the advance of the recursion
; where is the alternative? here goes the base case of the recursion
)
(* n < n))) ; this line is outside the conditional, and it's just wrong
Notice that the last expression is incorrect, I don't know what it's supposed to do, but as it is it'll raise an error. Delete it, and concentrate on writing the body of the conditional.
The trick with scheme (or lisp) is to understand each little bit between each set of brackets as you build them up into more complex forms.
So lets start with the conditionals. if takes 3 arguments. It evaluates the first, and if that's true, if returns the second, and if the first argument is false it returns the third.
(if #t "some value" "some other value") ; => "some value"
(if #f "some value" "some other value") ; => "some other value"
(if (<= 1 0) "done" "go again") ; => "go again"
cond would work too - you can read the racket introduction to conditionals here: http://docs.racket-lang.org/guide/syntax-overview.html#%28part._.Conditionals_with_if__and__or__and_cond%29
You can define functions in two different ways. You're using the anonymous function approach, which is fine, but you don't need a lambda in this case, so the simpler syntax is:
(define (function-name arguments) result)
For example:
(define (previous-number n)
(- n 1))
(previous-number 3) ; => 2
Using a lambda like you have achieves the same thing, using different syntax (don't worry about any other differences for now):
(define previous-number* (lambda (n) (- n 1)))
(previous-number* 3) ; => 2
By the way - that '*' is just another character in that name, nothing special (see http://docs.racket-lang.org/guide/syntax-overview.html#%28part._.Identifiers%29). A '!' at the end of a function name often means that that function has side effects, but n! is a fine name for your function in this case.
So lets go back to your original question and put the function definition and conditional together. We'll use the "recurrence relation" from the wiki definition because it makes for a nice recursive function: If n is less than 1, then the factorial is 1. Otherwise, the factorial is n times the factorial of one less than n. In code, that looks like:
(define (n! n)
(if (<= n 1) ; If n is less than 1,
1 ; then the factorial is 1
(* n (n! (- n 1))))) ; Otherwise, the factorial is n times the factorial of one less than n.
That last clause is a little denser than I'd like, so lets just work though it down for n = 2:
(define n 2)
(* n (n! (- n 1)))
; =>
(* 2 (n! (- 2 1)))
(* 2 (n! 1))
(* 2 1)
2
Also, if you're using Racket, it's really easy to confirm that it's working as we expect:
(check-expect (n! 0) 1)
(check-expect (n! 1) 1)
(check-expect (n! 20) 2432902008176640000)
This is related to this question: elisp functions as parameters and as return value
(defun avg-damp (n)
'(lambda(x) (/ n 2.0)))
Either
(funcall (avg-damp 6) 10)
or
((avg-damp 6) 10)
They gave errors of Symbol's value as variable is void: n and eval: Invalid function: (avg-damp 6) respectively.
The reason the first form does not work is that n is bound dynamically, not lexically:
(defun avg-damp (n)
(lexical-let ((n n))
(lambda(x) (/ x n))))
(funcall (avg-damp 3) 12)
==> 4
The reason the second form does not work is that Emacs Lisp is, like Common Lisp, a "lisp-2", not a "lisp-1"