Why is the lisp function evaluating the wrong argument? - lisp

I define a function to do repeated function calls:
(defun repeat (n f x)
(if (zerop n) x
(repeat ((- n 1) f (funcall f x)))))
Now I want to want to apply cdr:
(repeat (1 (function cdr) '(1 2 4 5 6 7)))
I am clearly supplying n=1, f=cdr, and x='(1 2 3 4 5 6 7). It should apply cdr once. This is the error message I get:
Error: Funcall of 1 which is a non-function.
[condition type: TYPE-ERROR]
But I have a funcall of cdr, not 1.
I am using the free version of Franz's Allegro Lisp.

Function call syntax in Lisp is:
(<function> <arg1> <arg2> <arg3> ...)
So the expression ...
(1 (function cdr) '(1 2 4 5 6 7))
... is evaluated as "call the function 1 on the arguments cdr and '(1 2 4 5 6 7)".
In other words, you have an extra set of parenthesis. Try:
(repeat 1 (function cdr) '(1 2 4 5 6 7))
Same problem exists in your recursive call.

Related

I'm struggling to understand why some Lisp data changes when I alter some value in a list and others doesn't [duplicate]

This question already has an answer here:
Unexpected persistence of data [duplicate]
(1 answer)
Closed 2 years ago.
I'm struggling two understand why when i change the values of l1 list the double-args macro changes the value in the result list and the double-list doesn't. Let me show the steps to be more clear.
I have defined the list l1 with values '(1 2 3 4),
(setq l1 '(1 2 3 4))
then i load this code below
(defmacro double-args (&rest args)
`(let ((ret nil))
( dolist (x ,#args )
(setq ret (append ret (list x x))))
ret) )
(defun macroteste (&rest x) (double-args x))
;; first simple macro example:
(defmacro double-list (a-list)
(let ((ret (gensym)))
`(let ((,ret nil))
(dolist (x ,a-list)
(setq ,ret (append ,ret (list x x))))
,ret)))
;; use the macro:
(defun doublelistmacro (x)
(double-list x))
after this, i had executed the macro, macroteste with the list l1 and stored in l2
(setq l2 (macroteste l1))
then i executed the doublelistmacro with arg l1 and stored in l3
(setq l3 (doublelistmacro l1))
so i got from l2,
((1 2 3 4) (1 2 3 4))
and from l3,
(1 1 2 2 3 3 4 4)
then i had change the second value of l1,
(setf (nth 1 l1) 9)
and i got theses results:
l1
(1 9 3 4)
l2
((1 9 3 4) (1 9 3 4))
l3
(1 1 2 2 3 3 4 4)
why when i changed l1 the l2 has changed too but l3 not?
First, a remark: in code you should not modify literal constants like '(1 2 3 4). The effects are undefined.
In your case the difference boils down to this
CL-USER 2 > (let ((foo (list 1 2 3 4)))
(let ((l1 (list foo foo))
(l2 (loop for e in foo append (list e e))))
(values l1 l2)))
((1 2 3 4) (1 2 3 4))
(1 1 2 2 3 3 4 4)
The first list l1 is a new list with the original list twice as its element.
The second list l2 is a completely new constructed list.
If you change the original list, it will be visible in the first result -> it has them directly as elements.
It will not be visible in the second list, because the list is completely fresh.
Note also that the macros are complicating the issue. As such they also make very little sense.

Introducing new symbols into Common-Lisp Function/Macro

I want to define a functionality in common lisp which uses some words/symbols not known to lisp, for example having such a function/macro:
(my-func-or-macro lst key-word idx)
which returns items in the lst upto the idx if the key-word is to and from the idx to the end if the key-word is from.
So practically it should work like:
(my-func-or-macro '(1 2 3 4 5 6) from 3) => '(4 5 6)
and
(my-func-or-macro '(1 2 3 4 5 6) to 3) => '(1 2 3)
Since macros don't evaluate their arguments i think i should be using a macro which doesn't care about from and to (note i don't want to pass quoted args like 'from 'to).
Since every argument to a function is evaluated before the function is executed, you need a symbol that evaluates to itself.
Such symbols are already part of the language: all symbols in the special KEYWORD package evaluate to themselves. Symbols that are written with a leading colon, e. g. :foo are interned into that package.
Also part of the language are keyword arguments that use such keywords to identify parameters:
(defun my-func (list &key from)
(subseq list from))
(my-func '(0 1 2 3 4 5) :from 3)
=> (3 4 5)
You can give default values to such parameters:
(defun my-func (list &key (from 0) (to (length list)))
(subseq list from to))
(my-func '(0 1 2 3 4 5) :from 3)
=> (3 4 5)
(my-func '(0 1 2 3 4 5) :to 3)
=> (0 1 2)
(my-func '(0 1 2 3 4 5) :from 1 :to 4)
=> (1 2 3)
Keyword arguments can be given in any order:
(my-func '(0 1 2 3 4 5) :to 4 :from 1)
=> (1 2 3)

How can I write a MEMBER function using the DO macro in Common Lisp?

I am trying to make a function which works like MEMBER function in Common Lisp.
So, I want to make this function work like this :
(my-member 2 '(1 4 5 5 3 2 5 6 9))
=> (2 5 6 9)
This is exactly same as how MEMBER function works.;
(member 2 '(1 4 5 5 3 2 5 6 9))
=> (2 5 6 9)
The condition is that I should use 'DO' macro to make this function.
This is my code that I have written to make this function :
(defun my-member (item x)
"This function works like MEMBER function."
(do ((z x (rest z))
(e (first x) (first z)))
(:when (equal item (first z))
(return z))))
But it doesn't work..
(my-member 2 '(3 4 5 2 1 1))
-> (3 4 5 2 1 1)
What should I do to solve this problem?
Here is the correct way to use do:
(do ((var 0 (1+ var))
(lst '() (cons var lst)))
((= var 5) lst)))
; ==> (4 3 2 1 0)
So both var and lst are variables initialised to 0 and () and after each iteration the variable is set to (1+ var) and (cons var lst).
What determines when it should stop is (= var 5) becoming not nil and when that happens the result of the whole do form is lst. This is the second part of the do and the last this has since I do not supply a body.
You can make an equivalent of the member function with using only one variable and a second part with an end condition and what should be the result of the do. Good luck!

Scheme: vector function that returns the first odd number

I can't figure out on how to write a vector function that returns the first odd number in the list.
Ex: (check-expect (first-oddnumb 2 3 4 5 6) 3)) ;;it returns 3 because 3 is the first odd number in the list.
I can't figure out on how to write a vector function that returns the first odd number in the list.
My confusion is the same as #Sylwester's: "vector function"? The rest of the question seems to make sense tho.
I can help you write a function that returns the first odd number in the list.
We want the function to work like this
(first-odd-number 2 3 4 5 6) ;; => 3
So the first thing we have to do is learn how to write a function that accepts a variable number of arguments
(define (variadic . xs) xs)
(variadic 1 2) ;; => '(1 2)
(variadic 1 2 3) ;; => '(1 2 3)
(variadic 1 2 3 4) ;; => '(1 2 3 4)
(variadic) ;; => '()
Note the . before the xs parameter. This gives us a way to collect all of the passed arguments into the bound identifier, xs. Notice how the arguments are collected into a list. Also pay attention to how xs will still be a list (empty list '()) even if no arguments are given in the function call.
Now we can begin writing your function
(define (first-odd-number . xs)
;; so we know xs will be a list here ...
)
Let's talk about the possible states of xs
xs could be empty, in which case what should we return? maybe a 0 or something? (more on this later)
Otherwise, xs has at least one number ...
is the first number an odd number? if so, return that number
is the first number an even number? if so, return first-odd-number of the remaining numbers in xs
OK, we can pretty much define this in Racket verbatim
(define (first-odd-number . xs)
;; begin case analysis of xs
(cond
;; is the list of numbers empty? return 0
[(empty? xs) 0]
;; the list is not empty, continue ...
;; is the first number odd?
[(odd? (car xs)) (car xs)]
;; otherwise...
;; the number even, check remaining numbers
[else (apply first-odd-number (cdr xs))]))
(first-odd-number 2 3 4 5 6) ;; => 3
(first-odd-number 3 4 5 6) ;; => 3
(first-odd-number 4 5 6) ;; => 5
(first-odd-number) ;; => 0
And that's pretty much it !
Improvements...
If you're like me tho, that 0 is making you feel uneasy. What if you were given a list of only even numbers? What should the return value be?
(first-odd-number 2 4 6) ;; => 0
This is kind of weird. We could use the 0 to mean that no odd number was found, but Maybe there's a better way ...
(struct Just (value) #:transparent)
(struct None () #:transparent)
(define (first-odd-number . xs)
(cond
;; no odd number was found; return None
[(empty? xs) (None)]
;; an odd number was found, return (Just n)
[(odd? (car xs)) (Just (car xs))]
;; otherwise check the remaining numbers
[else (apply first-odd-number (cdr xs))]))
(first-odd-number 2 3 4 5 6) ;; => (Just 3)
(first-odd-number 3 4 5 6) ;; => (Just 3)
(first-odd-number 4 5 6) ;; => (Just 5)
(first-odd-number) ;; => (None)
Now when the caller of our first-odd-number is working with the function, we don't have to don't have to remember that 0 is a special case we need to consider
(define (print-the-first-odd-number . xs)
(match (apply first-odd-number xs)
[(Just x) (printf "the number is ~a\n" x)]
[(None) (printf "no odd number was found\n")]))
(print-the-first-odd-number 2 3 4 5 6) ;; the number is 3
(print-the-first-odd-number 2 4 6) ;; no odd number was found
Another way is to use a comprehension to iterate over the vector (or whatever), specifically, for/first, which returns the value returned by the first body that gets evaluated, combined with a #:when clause to limit said evaluation to the first odd element of a vector:
#lang racket/base
(define (first-odd-number container)
(for/first ([num container]
#:when (odd? num))
num))
(displayln (first-odd-number #(2 3 4 5 6))) ; 3, passing a vector
(displayln (first-odd-number '(2 3 4 5 6))) ; 3, passing a list
If no odd number is present, it returns #f.
While you get better performance by using type specific sequence builders like in-vector with a for loop, using a container directly like this gives more flexibility (It would also work with sets of numbers and a few other standard types)
If instead wanting a function that takes a variable number of arguments, use a hardcoded in-list and the appropriate formals:
(define (first-odd-number . numbers)
(for/first ([num (in-list numbers)]
#:when (odd? num))
num))

Is there any difference between using “MIT-style curried-procedure forms” and lambda-expressions passed to the `curry` function?

Given the code snippet that follows, is there any meaningful difference between example-func-A and example-func-B?
#lang racket/base
(require (only-in racket/function curry))
(define (((example-func-A x) y) z)
(+ x y z))
(define example-func-B
(curry
(lambda (x y z)
(+ x y z))))
Yes, example-func-A (which uses the MIT-style curried-procedure syntax) is less flexible than example-func-B, in that it expects to only be called with a single argument at a time:
> (((example-func-A 4) 5) 6)
15
> (example-func-A 4 5 6)
example-func-A: arity mismatch;
the expected number of arguments does not match the given number
expected: 1
given: 3
arguments...:
4
5
6
context...:
/opt/homebrew-cask/Caskroom/racket/6.4/Racket v6.4/collects/racket/private/misc.rkt:87:7
In contrast, example-func-B accommodates receiving multiple (or even zero!) arguments:
> (((example-func-B 4) 5) 6)
15
> (example-func-B 4 5 6)
15
> ((((example-func-B) 4)) 5 6)
15
(Presumably the flexibility of curry comes with a bit of a performance hit at runtime.)