Working with nested input, but not flattening it - recursion

I have a function that will simplify something like:
(or x false) => x
Then function definition takes in the unevaluated expression as its parameter.
I am trying to nest my input like this now:
(or x (and true))
Everywhere I look I see articles about flattening nested input, but that won't work in this case because of the logical operator at the beginning of each list so the innermost list must be processed first, with the result being sent to the next outer list as an argument.
I know I need to call my function within it's own body with the result of the innermost list until I reach the outermost list, but I'm not sure of the way to go about that or what to research in Clojure on how to to this.

What you are describing is nearly exactly the semantics of expression evaluation in clojure :-) so the brief answer would be to run the code :-D though i suspect you are looking for a more interesting answer.
Here is a simple recursive version that works by
recursively simplify each nested expression
apply the simplification rules to the existing expression
This uses an overly-simple rule just as an example:
user> (defn my-eval [e]
(let [expanded-form (if (seq? e)
(map (fn [i]
(if (seq? i) ;; if this is a sequence,
(my-eval i) ;; eval the sequence and include the result here
i)) ;; otherwise use the value unchanged.
e)
e)] ;; if it's not a seq with something in it, leve it unchanged
(if (and
(seq? expanded-form)
(= (first expanded-form) 'or)
(= 2 (count (remove false? expanded-form))))
(second (remove false? expanded-form))
expanded-form)))
#'user/my-eval
First a base case test:
user> (my-eval '(or x (or y false)))
(or x y)
Then with a little recursion:
user> (my-eval '(or (or x false) (or y false)))
(or x y)

Related

Why mutating the list to be only its first element with this approach does not work in Common Lisp?

I am trying to learn Common Lisp with the book Common Lisp: A gentle introduction to Symbolic Computation. In addition, I am using SBCL, Emacs, and Slime.
By the end of chapter 10, on the advanced section there is this question:
10.9. Write a destructive function CHOP that shortens any non-NIL list to a list of one element. (CHOP '(FEE FIE FOE FUM)) should return
(FEE).
This is the answer-sheet solution:
(defun chop (x)
(if (consp x) (setf (cdr x) nil))
x)
I understand this solution. However, before checking out the official solution I tried:
(defun chop (xs)
(cond ((null xs) xs)
(t (setf xs (list (car xs))))))
Using this as a global variable for tests:
(defparameter teste-chop '(a b c d))
I tried on the REPL:
CL-USER> (chop teste-chop)
(A)
As you can see, the function returns the expected result.
Unfortunately, the side-effect to mutate the original list does not happen:
CL-USER> teste-chop
(A B C D)
Why it did not change?
Since I was setting the field (setf) of the whole list to be only its car wrapped as a new list, I was expecting the cdr of the original list to be vanished.
Apparently, the pointers are not automatically removed.
Since I have very strong gaps in low-level stuff (like pointers) I thought that some answer to this question could educate me on why this happens.
The point is about how parameters to functions are passed in Common Lisp. They are passed by value. This means that, when a function is called, all arguments are evaluated, and their values are assigned to new, local variables, the parameters of the function. So, consider your function:
(defun chop (xs)
(cond ((null xs) xs)
(t (setf xs (list (car xs))))))
When you call it with:
(chop teste-chop)
the value of teste-chop, that is the list (a b c d) is assigned to the function parameter xs. In the last line of the body of function, by using setf, you are assigning a new value, (list (car xs)) to xs, that is you are assigning the list (a) to this local variable.
Since this is the last expression of the function, such value is also returned by the function, so that the evaluation of (chop test-chop) returns the value (a).
In this process, as you can see, the special variable teste-chop is not concerned in any way, apart from calculating its value at the beginning of the evaluation of the function call. And for this reason its value is not changed.
Other forms of parameter passing are used in other languages, like for instance by name, so that the behaviour of function call could be different.
Note that instead, in the first function, with (setf (cdr x) nil) a data structure is modified, that is a part of a cons cell. Since the global variable is bound to that cell, also the global variable will appear modified (even if, in a certain sense, it is not modified, since it remains bound to the same cons cell).
As a final remark, in Common Lisp it is better not to modify constant data structures (like those obtained by evaluating '(a b c d)), since it could produce an undefined behaviour, depending on the implementation. So, if some structure should be modifiable, it should be built with the usual operators like cons or list (e.g. (list 'a 'b 'c 'd)).

Finding duplicate elements in a Scheme List using recursion

I'm trying to create a function that will check a list of numbers for duplicates and return either #t or #f. I can only use car, cdr and conditionals, no cons.
This is what I have so far but it's giving me the error "car: contract violation expected: pair? given: #f"
(define (dups a)
(if (null? a)
#f
(if (= (car a)(car(dups(cdr a))))
#t
(dups (cdr))
)
)
)
I'm new to both scheme and recursion, any help/advice would be greatly appreciated.
Your second if doesn't make much sense. I'm assuming you wanted to check whether (car a) appears somewhere further down the list, but (car (dups (cdr a))) doesn't give you that. Also, (car (dups ...)) is a type-issue since dups will return a boolean instead of a list, and car is expecting a list (or actually, a pair, which is what lists are composed of).
What you need is a second function to call in the test of that second if. That function takes an element and a list and searches for that element in the list. Of course, if you're allowed, use find, otherwise implement some sort of my-find - it's quite simple and similar to your dups function.

Racket Code: Higher-Order Functions

I'm trying to implement higher level functions in my Racket code, specifically with regards to this function:
(define (indivisible e L)
(map (remove 0 ((map ((lambda (x y) (modulo x y))) L e)))))
Essentially, I'm trying to remove all the elements that are divisible by e from the list. However, it keeps giving me an error that says that "the expected number of arguments did not match the given number (0 vs 2)". Why is this so?
Several places you have two sets of parentheses. Unless the parentheses are a part of a special form or macro, eg. let, it represent an application. Ie.
((lambda (x y) (modulo x y)))
Here the form (lambda ...) is evaluated and become a function. The second set of parentheses calls this function with no arguments. Since you have two arguments, x and y and not supplying any in your application it signals an error.
Another place where you do the same is around (map ....). Since I know map always evaluates to a list or null it looks kind of strange that you call it as a function ((map ...)).
If you are more familiar with algol languages like python, what you are doing is like someFunc(arg1 args2)() where you clearly see someFunc needs to return a function wince it's immediately called afterwards. The same in Scheme looks like ((some-func arg1 arg2)).
remove removes the first argument from the second argument list. It does not return a function so the outer map won't work.
To solve this I think you are looking for filter. You only need to make a predicate that is #f for the elements you don't want and you're done.

map function parameters onto nested list in Clojure

I think there is a way to do this - I just can't find the exact syntax.
I want to map a function that takes three parameters on a list of tuples of size three. Something like:
(def mylist '((1 2 3)(3 4 5)))
(defn myfunc [a b c] (println "this is the first value in this tuple: " a))
(map myfunc mylist)
Can someone give me the precise syntax?
You just need a pair of square braces in there to destructure the nested list elements.
(defn myfunc
[[a b c]]
(println "this is the first value in this tuple: " a))
Be aware, however, that because map returns a lazy-seq, you may not get the side-effects you're after here, unless you force evaluation of the seq with doall, or inspect the seq in the REPL.
Documentation: http://clojure.org/special_forms#Special Forms--Binding Forms (Destructuring)
d11wtq's answer is a very good one, and it's the right way to go, unless you already have a function you want to map.
So, if myfunc is external function, it's better to use apply rather than write additional wrapper:
(map (partial apply myfunc) mylist)

Racket: Identifying tail recursion?

I wrote two different functions in racket to determine whether a list of numbers is ascending:
(define (ascending list)
(if (<= (length list) 1)
#t
(and (< (car list) (car (cdr list))) (ascending (cdr list)))))
(define (ascending-tail list)
(ascending-tail-helper #t list))
(define (ascending-tail-helper prevBool rest)
(if (<= (length rest) 1)
prevBool
(ascending-tail-helper (and prevBool (< (car rest) (car (cdr rest)))) (cdr rest))))
I had the hardest time determining whether or not the first ascending was tail recursive, so I rewrote it using what I believe to be tail recursion.
The reason why I retrospectively believe the first one to not be tail recursive is that I believe at each level of recursion, the function will be waiting for the second argument in the "and" statement to return before it can evaluate the boolean expression. Conversely, for ascending-tail-helper, I am able to evaluate the lesser than expression before I do my recursive call.
Is this correct, or did I make myself even more confused than before?
DrRacket can help you determine whether a call is in tail position or not. Click the "Syntax Check" button. Then move the mouse pointer to the left parenthesis of the expression in question. In your example I get this:
The purple arrow shows that the expression is in tail-position.
From the manual:
Tail Calls: Any sub-expression that is (syntactically) in
tail-position with respect to its enclosing context is annotated by
drawing a light purple arrow from the tail expression to its
surrounding expression.
You are correct, in the first version the recursive call returns to and, whereas in the second version the recursive call is a tail call.
However, and is a macro, and is generally expanded using if
(define (ascending list)
(if (<= (length list) 1)
#t
(if (< (car list) (car (cdr list)))
(ascending (cdr list))
#f)))
which is tail recursive.
One of the requirements for a function to be in tail position is that it's return value be usable as the return value of the parent function without modification or inspection. That is, the parent function should be able to return immediately, having evaluated the tail position statement.
On first appearance, your first function,inspects the return value of ascending. It seems that doesn't return ascending's value but, instead, a value derived from it. However, according to the relevant section of the R5RS spec, the final expression in an and statement is in tail position. (When I'm properly awake, I know this)
So you are wrong.
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-6.html#%_sec_3.5
(Note: edited to correct my initial hasty answer).
Racket's documentation on tail positions says that the place to check what's in tail position and what's not is the documentation for the particular form:
Tail-position specifications provide a guarantee about the asymptotic space consumption of a computation. In general, the specification of tail positions goes with each syntactic form, like if.
Racket's docs on and say (emphasis added):
(and expr ...)
If no exprs are provided, then result is #t.
If a single expr is provided, then it is in tail position, so the
results of the and expression are the results of the expr.
Otherwise, the first expr is evaluated. If it produces #f, the result
of the and expression is #f. Otherwise, the result is the same as an
and expression with the remaining exprs in tail position with respect
to the original and form.

Resources