Lisp &rest parameters and recursive calls - function

I have the following Common Lisp Function:
(defun test(A &rest indexes)
(if (null (first indexes))
A
(test (nth (+ 1 (first indexes)) A) (rest indexes))
)
)
As far as I know &rest parameters are treated as a list in the function body but since
(rest indexes) also returns a list I'm stuck with nested Lists as parameters.
For example (test '("a" "b" "c" ("d" "e")) 3 1 6 7)
would cause indexes to be ((1 6 7)) at the second call.
Is there any way to pass my list without having this problem?

Basic style rule: don't use &rest arguments for list processing functions.
Why? Common Lisp implementations are allowed to only support up to the value of CALL-ARGUMENTS-LIMIT number of arguments. This number is 50 or larger, depending on implementation.
This means your function might in some implementation process lists not larger as fifty items.
Better: pass the list as a separate argument.
(defun test (A indexes)
...)
(test '("a" "b" "c" ("d" "e")) '(3 1 6 7))
Wrong solution: don't use apply, since it does not solve the problem of limited argument lists.
CLISP
[1]> call-arguments-limit
4096
[2]> (defun l1 (&rest l) l)
L1
[3]> (apply #'l1 (loop repeat 5000 collect 1))
*** - APPLY: too many arguments given to
#<FUNCTION L1 (&REST L)
(DECLARE (SYSTEM::IN-DEFUN L1))
(BLOCK L1 L)>
The following restarts are available:
ABORT :R1 Abort main loop

rest is a accessor function that is paired together with first to give you the first element and the rest of the list. rest is the same as cdr.
&rest is a lambda list keyword that slurps the remaining arguments in the variable name that follows it.
You are really looking for apply. Imagine I make a function that can take 0 or more numeric parameters and add them together:
(defun add (&rest numbers)
(apply #'+ numbers))
Apply can take more than two arguments. The first is the function to call and all but the last are extra arguments that are put in front of the last arguments element. You are guaranteed the implementation supports 50 arguments or upto the number of arguments a function can take in that particular implementation supports above 50.
(apply #'+ 1 2 '(3 4 5)) ; ==> 15
Now recursing by &rest and apply makes inefficient code so you should use higher order functions, loop macro, or make a helper:
;; higher order function
(defun fetch-indexes (a &rest indexes)
(mapcar (lambda (i) (nth i a)) indexes))
;; loop macro
(defun fetch-indexes (a &rest indexes)
(loop :for i :in indexes
:collect (nth i a)))
;; helper function
(defun fetch-indexes (a &rest indexes)
(labels ((helper (indexes)
(if (endp indexes)
'()
(cons (nth (first indexes) a)
(helper (rest indexes))))))
(helper indexes)))
;; test (works the same with all)
(fetch-indexes '(a b c d) 2 3 0 1)
; ==> (c d a b)
Using apply in recursion should be avoided, but I'll show how it's done.
(defun fetch-indexes (a &rest indexes)
(if (endp indexes)
'()
(cons (nth (first indexes) a)
(apply #'fetch-indexes a (rest indexes)))))
In your example you have nested lists. In order for that to work you would need to flatten it as well. I haven't done that so these supports one proper list of elements.

Another solution, albeit a bit more verbose, but less reliant on details of apply is to use a sub-function for the recursion, which just takes a list. The outer "main" entry point takes the &rest indices syntax, while the inner function takes it as a list:
(defun test (a &rest indices)
(labels ((internal-test (indices)
;; ... the recursion thing calling internal-test
))
(internal-test indices)))
In contrast to the (defun add (&rest args) ... ) example, you might still have some arguments before the rest, which in case of using apply would require you to append those to the variable arguments list.
Of course, as Rainer Joswig pointed out, you need to take care only to use this, when the number of variable args is small.

Related

I'm stuck trying to implement this function in Racket and ML

I have this assignment:
Consider a list where every element is a nested list of length 2. The first
element of each nested list is either a 0 or a 1. The second element of each nested list
is some integer. An example input in Scheme is written below.
'((0 1) (1 2) (1 3) (0 4) (0 3))
For the purposes of this question, let’s call the first element of each nested list the
key and the second element of the nested lists the value. Now consider a function,
count_by_cat, that takes such a list as input and yields a two-element list where
the first element is the sum of the values of all nested lists with 0 as the key,
and
the second element is the sum of the values of all nested lists with 1 as the key
Implement count_by_cat in
(a) Racket, and
(b) ML.
It might be helpful to create helper functions. Also do not forget about map and filter
(filter is not a built-in in ML).
I'm new to Racket and ML. I'm stuck at using accessing lists and stuff in Racket. Some help with ML would also be great.
Well you're suggested to use higher order functions like map and filter.
And indeed it is easy to manipulate our data as a whole instead of focusing, mentally, on one element at a time. Which approach (i.e. the former one) some might argue, is the essence of functional programming paradigm.
In Racket,
(define (count_by_cat ls)
"return a two-element list"
(list
;; .....
;; ..... ))
where the first element is the sum of
(sum-of
the values of all nested lists
(map value
with 0 as the key
(filter (lambda (x) (= 0 (key x))) ls)))
and the second element is the sum of the values of all nested lists
(sum-of
(map value
with 1 as the key
(filter (lambda (x) (= 1 (key x))) ls))) ))
And so we need to define the helper functions accessing the nested lists,
(define (key n) (car n))
(define (value n) (cadr n))
and also the sum-of function, for summing up the numerical values in a list:
(require math/base)
(define (sum-of ls)
(sum ls))
This was easy to write, and will be easy to maintain.
The more performant code would do everything in one pass over the input, like is shown in the other answer. It has all the logic fused into one loop body. It could be more brittle to write and maintain.
The hint about map and filter is a bit of a red herring (As well as being wrong about them not being in ML languages); a helper function is very useful, but it's a fold you want, which basically calls a function with the current element of a list and an accumulator value, and uses what it returns as the accumulator for the next element and ultimately the return value of the entire fold.
For example, in ocaml, using a fold to sum a list of integers:
let sum = List.fold_left (+) 0 [ 1; 2; 3; 4; 5 ];;
((+) is the function version of the infix operator +).
Or your problem in Racket, using the for/fold comprehension, and returning two values instead of a two-element list, which is more idiomatic in Racket and Scheme (In ocaml and presumably Standard ML, you'd return a two-element tuple instead of a list, and take a list of tuples).
(define (count-by-cat lol)
(for/fold ([zero-sum 0]
[one-sum 0])
([elem (in-list lol)])
(case (first elem)
[(0) (values (+ zero-sum (second elem)) one-sum)]
[(1) (values zero-sum (+ one-sum (second elem)))])))
You could also use foldl, but for/fold is often easier to use, especially when working with multiple values or other non-trivial cases.

racket - how to use the elements of a list as a procedure (function)

I have a list that contains the "names" of some functions (for example '(+ - *))
I want to use that list to call the functions
(define list_of_names_of_functions '(+ - *))
(define sum (car list_of_names_of_functions))
(sum 2 3)
However, sum is a list, so can't be used as a procedure.
How should i do it?
The variable list_of_names_of_functions has symbol representation and not the actual function. you should perhaps make an alist with name and function like this:
(define ops `((+ . ,+) (- . ,-) (* . ,*)))
If you evaluate ops you'll see something like:
((+ . #<procedure:+>)
(- . #<procedure:->)
(* . #<procedure:*>))
There is no standard on how a function/procedure object should be represented, but it is expected that that value can be applied as any other function:
((cdar ops) 1 2) ; ==> 3
Thus you can search for + using:
(assq '+ ops)
; ==> (+ . #<procedure:+>)
(assq '/ ops)
; ==> #f
Thus if the result is truthy the cdr will contain a procedure:
(apply (cdr (assq '+ ops)) '(1 2)) ; ==> 3
If you are making a special kid of eval then you would consider the list an environment and it can easily be added to such that you can add /. You can also supply anything callable so an op doesn't need to exist in the host system. eg. `(square . ,(lambda (v) (* v v)) works as well.
Consider using the naming convention of Scheme (and Lisp). Eg. instead of list_of_names_of_functions it should be named list-of-names-of-functions
The simple and immediate fix is to use (define list_of_functions (list+ - *)), then with (define sum (car list_of_functions)) it will work.
(edit:) This happens because list is a function which evaluates its argument(s) and returns the results in a list. Whereas quote (or ' in front of an expression) prevents its argument from being evaluated.
'(A B ...) is equivalent to (quote (A B ...)); that (A B ...) thing is a list of symbols, and quote preserves it as such.
It is a list of symbols because this is how Lisp code is read, either from a source file or from the REPL, i.e. at the interpreter's prompt. Other languages have their code as strings in a source code file, and compiler is some external magic which lives and works completely outside of the language. In Lisp-like languages, code is data. Code is read from textual source code file as (i.e. strings are turned into) nested lists of symbols, and explicit eval, as well as implicit evaluation, is deep inside the language itself.
Thus what you had is equivalent to the list
(define list_of_names (list '+ '- '*))
which contains unevaluated symbols, as opposed to the list
(define list_of_functions (list + - *))
which contains their values, which happen to be the usual built-in functions denoted by those "names".
And we can call a function, but we can't call a symbol (not in Scheme anyway).
As I mentioned in a comment, using eval is not the right answer to this: it 'works' but it opens the way to horrors.
If you have a symbol like + and you want to get its dynamic value then the Racket approach to doing this is to use namespaces. A namespace is really a machine which turns symbols into values in the same way that eval does, but that's all it does, unlike eval. Unfortunately I don't understand namespaces very well, but this will work:
(define-namespace-anchor nsa)
(define ns (namespace-anchor->namespace nsa))
(define (module-symbol-value s (in ns))
(namespace-variable-value s #t #f in))
Then
(define function-names '(+ - / *))
(define sum (module-symbol-value (first function-names)))
And now
> (sum 1 2 3)
6
> (eq? sum +)
#t
>
The problem with this approach is that it's leaky: if you have something like this:
(module msv racket
(provide module-symbol-value)
(define-namespace-anchor nsa)
(define ns (namespace-anchor->namespace nsa))
(define secret "secret")
(define (module-symbol-value s (in ns))
(namespace-variable-value s #t #f in)))
(require 'msv)
(define oops (module-symbol-value 'secret))
Now oops is secret. A way around this is to use make-base-namespace to get a namespace which is equivalent to racket/base.
I have just found the answer, sorry.
Solution will be to use the "eval" function
(define list_of_names_of_functions '(+ - *))
(define sum (car list_of_names_of_functions))
((eval sum) 2 3)

Equality of Function Designators

Are two Common Lisp function objects with the same symbol designator always eq? For example, this comparison seems to work:
(defun foo (fn)
(let ((ht (make-hash-table)))
(eq (symbol-function (hash-table-test ht)) fn)))
FOO
* (foo #'eql)
T
*(foo #'equal)
NIL
But this may rely on implementations not making latent copies of functions, presumably for reasons of efficiency. Since hash-table-test returns a symbol designator, the other (possibly better) eq alternative would be to derive the symbol from the function object? Is one approach better than the other?
Are two Common Lisp function objects with the same symbol designator always eq?
In Common Lisp a function is a piece of code, be it compiled or not. From the Glossary:
function n. 1. an object representing code, which can be called with zero or more arguments, and which produces zero or more values. 2. an object of type function.
A function designator, on the other hand, can be a symbol:
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).
So, a symbol which is a function designator is something that, when evaluated in a certain context, or with a certain syntax like #'symbol or (function symbol), produces a function, and the comparison of two function designators is a comparison of the functions that they denote:
CL-USER> (eql #'car #'cdr)
NIL
CL-USER> (eql #'car (symbol-function 'car))
T
But note that this equality test is just a comparison of the identity of the functional objects (the pieces of code), like in:
CL-USER> (eq #'car #'car)
T
CL-USER> (let ((a (lambda (x) (1+ x))))
(eq a a))
T
but not of the actual bytes that represent them (the code!):
CL-USER> (let ((a (lambda (x) (car x)))
(eq a #'car))
NIL
CL-USER> (defun f (x) (1+ x))
F
CL-USER> (defun g (x) (1+ x))
G
CL-USER> (equalp (function f) (function g))
NIL
CL-USER> (equalp (lambda (x) (1+ x)) (lambda (x) (1+ x)))
NIL
Note that, in all these cases, the two functions compared have not only the same “meaning”, but in most cases the same “source code”, are compiled in the same way, and behaves identically on the same input data. This is because a function is mathematically a (possibly) infinite set of pairs (input, output) and one cannot compare infinte objects.
But this may rely on implementations not making latent copies of functions, presumably for reasons of efficiency.
There is no way for the user to copy a function (neither the system has any reason to perform a copy of a piece of code!), so any function is equal to itself in the same way as any pointer is equal only to itself.
Since hash-table-test returns a symbol designator, the other (possibly better) eq alternative would be to derive the symbol from the function object? Is one approach better than the other?
(I suppose you intend function designator, instead of symbol designator)
Actually, hash-table-test normally returns a function designator only as a symbol, as said in the manual:
test---a function designator. For the four standardized hash table test functions (see make-hash-table), the test value returned is always a symbol. If an implementation permits additional tests, it is implementation-dependent whether such tests are returned as function objects or function names.
So:
CL-USER> (type-of (hash-table-test (make-hash-table)))
SYMBOL
CL-USER> (eq 'eql (hash-table-test (make-hash-table)))
T
CL-USER> (eq #'eql (hash-table-test (make-hash-table)))
NIL
Note that in the last case we are comparing a function (the value of #'eql) with a symbol (what is returned by hash-table-test) and obviously this comparison returns a false value.
In conclusion:
It is not very reasonable to compare functions, unless you want to know if two functions are in effect the same object in memory (for istance if the two things are the same compiled code).
It is always important to distinguish functions from their designations as symbols (function names) or lists, like (LAMBDA parameters body), and decide what we want to actually compare.
#'eql is equivalent to (function eql). Unless there's a lexical function binding of eql, this is defined to return the global function definition of the symbol eql. That's also what (symbol-function 'eql) is defined to return.
So for any globally defined function f that isn't shadowed by a lexical definition,
(eq #'f (symbol-function 'f))
should always be true.

Is there a standard argument sequence identity function in Clojure?

Is there a function in the Clojure standard library equivalent to the following?
(fn [& args] args)
If not, why?
Example usage:
(take 10 (apply (fn [& args] args) (range)))
;=> (0 1 2 3 4 5 6 7 8 9)
;; ironically, map isn't lazy enough, so let's take it up to 11
(defn lazy-map [f & colls]
(lazy-seq (cons (apply f (map first colls))
(apply lazy-map f (map rest colls)))))
(defn transpose [m]
(apply lazy-map (fn [& args] args) m))
(defn take-2d [rows cols coll]
(take rows (map (partial take cols) coll)))
(take-2d 3 3 (transpose (map (partial iterate inc) (range))))
;=> ((0 1 2) (1 2 3) (2 3 4))
Please note that I am not asking for a transformative, eager function such as vector or list.
There is no such function, you are free to implement and use it as you like:
(defn args [& args] args)
(set (map type (apply map args [[1 2 3][4 5 6][7 8 9]])))
=> #{clojure.lang.ArraySeq}
Why isn't it already available?
This is rarely fruitful question: not only we don't know what happens in the mind of implementors, it is impracticable to ask them to justify or document why they did not do something. Was adding this function ever considered? How can we know? Is there really a reason, or did it just happen?
On the other hand, I agree that args feels simpler because it passes around an already existing immutable sequence.
I also can understand if you think that not converting the arguments as a persistent list in the first place is better, if only for the sake of parcimony.
But this is not how it is implemented, and the overhead of using list is really negligible (and specialized when building from an instance of ArraySeq).
You are supposed to code to an interface and never look behind the curtain, and from this point of view, list and args are equivalent, even though they do not return identical results.
You added a remark about laziness, and you are right: if you ever need to take the arguments from a variadic function and pass it to a function which operates on sequences, The version with list will consume all the given arguments whereas args will not. In some cases, as with (apply list (range)), where you literally pass an infinite number of arguments, this might hang forever.
From that point of view, the little args function is in fact interesting: you can move from arguments to actual sequences without introducing potential problems.
I am however not sure how often this case happens in practice.
In fact, I have a hard time finding a use case where laziness in the argument list really matters as far as args is concerned.
After all, in order to pass an infinite sequence, the only way (?) is to use apply:
(apply f (infinite))
In order to have a use-case for args, that means that we want to convert from an argument list back to a single list so that another function g can use it as a sequence, like so:
(g (apply args (infinite)))
But in that case, we could directly call:
(g (infinite))
In your example, g would stand for cons inside lazy-map, but since f is given in input, we cannot write (cons (map ...) ...) directly. The example thus looks like a genuine use case for args, but you should document the function heavily because the snippet you gave is quite complex. I tend to think that giving an unbounded number of arguments to a function is a code smell: should every function with an [& args] signature avoid consuming all arguments because the given sequence might in fact be infinite, like lazy-map does? I'd rather have a single argument be a lazy sequence for this kind of usage (and pass identity where needed) instead of the whole argument list, to clarify the intent. But in the end, I am not strongly opposed to the use of args either.
So to conclude, unless you manage to convince Rich Hickey to add args as a core function, I am confident that almost nobody will want to depend on an external library which does just this1: it is unfamiliar, but also trivial to implement and mostly useless. The only reward is knowing that you skip a little transformation step which costs nothing in most cases. Likewise, do not worry about having to choose between a vector and a list: it has practically no influence on your code and you can still modify the code later if you can prove it is necessary.
Regarding laziness, while I agree that wrapping arguments in lists or vectors can be problematic with unbounded argument lists, I am not sure the problem actually arises in practice.
1. Of course, if it ever reaches clojure.core, everybody will be quick to say that is is a fundamental operation which is most useful and definitely idiomatic </cynic>
There's identity function. It takes an argument and just returns that argument. Clojure's identity is single arity though.
usage:
(identity 4) ;=> 4
(identity [1 2 3 4]) ;=> [1 2 3 4]
I don't think there's much sense in having the identity function with variable arity since Clojure functions return only one value. If you want to return multiple values from a function, then you can wrap them in a seq which you can later destructure. In that case you can have something like this:
(defn varity-identity [& args]
(map identity args))
(varity-identity 1 2 3 4 5) ;=> (1 2 3 4 5)
Hope this helps.

Tail-recursive?

I'm writing a function that takes a list and returns the sum of the squares of all items in the list. Called on (1 2 3) it should return 14: (12 + 22 + 32).
I have this sqsum function:
(define (sqsum lis)
(if (null? lis)
0
(+ (* (car lis) (car lis)) (sqsum (cdr lis)))
)
)
Is this tail recursive? I think it is recursive but not tail recursive.
This is part of my homework and I'm not looking for solution: I just want to know if this is tail recursive or not. If not then I need to read more and find new solutions.
To be tail recursive the recursion has to happen at the very last function, i.e. you cannot do anything with the results from the recursiv call. Here you pass it to +, which makes it non-tail-recursive. The compiler could optimize this away though, and it's pretty easy to do yourself too.
No, it is not tail recursive.
The general approach to making a non-tail recursive function tail-recursive is to include an accumulator, which is an extra argument that carries the current evaluation of the procedure through your recursive calls.
Incidentally, this is also where "helper" functions are very useful. The general practice is to define your function so that it does not take the accumulator, define a helper function within it that does take the accumulator, and then have the main function do little besides call the helper function. You'll see what I mean in a sec.
In your case (if I'm remembering my Scheme properly :p):
(define (sqsum lis)
(define (sqsum-h lis acc)
(if (null? lis)
acc
(sqsum-h (cdr lis) (+ acc (* (car lis) (car lis))))
)
)
(sqsum-h lis 0)
)
This is tail-recursive because the last thing any recursive call does is immediately return the result of another function without modifying it.