I am trying to recursively sum integers input by the user - recursion

I am brand spanking new to scheme. To the extent that tonight is the first time I've ever played around with it aside from what a powerpoint slide explained to me in class. I have to write a scheme program that takes a user input operator and then performs that operation on the numbers that follow it. (in other words implement my own version of schemes built-in '+', '*', etc operators). The catch is that I have to use recursion. Trying to maneuver my way around this scheme syntax is making it very difficult for me to even figure out where to start.
So, I decided to start with some code that at least recursively sums up values entered by the user (without worrying about recognizing the user inputting an operator and parentheses). I just plain can't figure out how to make it work. Here's what I'm trying:
(define run (lambda (x)
(cond
((eqv? x "a") (display x) )
(else (+ x (run(read))))
)))
(run (read))
The condition to check if x equals "a" was intended to be a way for me to break the recursion right now. In the final version, the input will be in between a set of parenthesis, but I thought I'd cross that bridge when I come to it. Anyways, the code just keeps accepting input, and never stops. So, the condition to display x is never getting called I guess. I know I'm probably doing everything wrong, and I would really appreciate some pointers.
EDIT: OK, I'm at least starting to realize that something isn't making sense. Such as my displaying x won't actually give the sum since I'm not storing the sum in x in any way. However, I still don't understand why the code isn't at least stopping when I enter the letter a.
EDIT 2: I've got it to work but only when the condition is equal to 1. How can I get it to recognize an input of a char or better yet a right parenthesis to get it to end the recursion just like it is with the 1? :
(define run (lambda (x)
(cond
((eq? x 1) 0)
(else (+ x (run(read))))
)))
(run (read))

End-Of-File (EOF) marks the end of input. Scheme has a procedure eof-object? for this. Your code is basically correct:
(define (run x)
(if (eof-object? x)
0
(+ x (run (read)))))
You end the run using Control-D. If for some reason you don't have access to eof-object? just use a special character like X. In that case your test would be (eq? x #\X)

(define (addition-loop)
(let ((answer (read)))
(if (number? answer)
(+ answer (addition-loop))
0)))
This will break as soon as you enter something that isn't a number.
In addition as you can see, you can have a function of zero arguments.
Anyways the problem with your code is when you enter a into read, it's value it actually the same a 'a or (quote a), rather than "a".
(eqv? 'a "a")
;Value: #f

Related

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.

move for a chess game

I have a move procedure that applies a legal move to a chess piece on the board by passing a pair:
(cons source dest) so (cons 1 2) takes a piece on position 1 from the board and moves it to position 2.
I'm trying to make a procedure that applies the same move it made before. I tried to do
(move (reverse move)) which would pass in (cons 2 1) thereby moving the piece back.
unfortunately, reverse doesnt work for pairs. I can't convert it to a list because that would have to change a lot of the code to accommodate for the null at the end.
Can anyone think of anything?
I'm using MIT Scheme by the way.
You need to implement your own reverse-pair procedure for this, it can be as simple as this:
(define (reverse-pair p)
(cons (cdr p) (car p)))
Or this, a bit fancier but less readable:
(define (reverse-pair p)
`(,(cdr p) . ,(car p)))
Either way it works as intended:
(reverse-pair '(1 . 2))
=> '(2 . 1)
If the reverse function doesn't work on pairs, write your own reverse-pair function then. I don't remember the scheme syntax for that but I think you already have the tools for that, since you would basically need to know how to read the two values from the pair (something you already do on your "move" function) and then how to build a new tuple based on that data.
I don't see why you think this would complicate things too much either. As far as the code outside the new function goes, it would look just the same as the original version you proposed using the "reverse" function.
If you limit yourself to pairs of `(a . b) then it's pretty easy to flip them. Something as simple as
(define reverse-pair
(lambda (p)
(cons (cdr p) (car p))))
Will do it. From your context I gather that your not going to be in the position where you have '(1 2 3 4 . 5) and need to reverse that so you should be fine with the one above.

Accumulators, conj and recursion

I've solved 45 problems from 4clojure.com and I noticed a recurring problem in the way I try to solve some problems using recursion and accumulators.
I'll try to explain the best I can what I'm doing to end up with fugly solutions hoping that some Clojurers would "get" what I'm not getting.
For example, problem 34 asks to write a function (without using range) taking two integers as arguments and creates a range (without using range). Simply put you do (... 1 7) and you get (1 2 3 4 5 6).
Now this question is not about solving this particular problem.
What if I want to solve this using recursion and an accumulator?
My thought process goes like this:
I need to write a function taking two arguments, I start with (fn [x y] )
I'll need to recurse and I'll need to keep track of a list, I'll use an accumulator, so I write a 2nd function inside the first one taking an additional argument:
(fn
[x y]
((fn g [x y acc] ...)
x
y
'())
(apparently I can't properly format that Clojure code on SO!?)
Here I'm already not sure I'm doing it correctly: the first function must take exactly two integer arguments (not my call) and I'm not sure: if I want to use an accumulator, can I use an accumulator without creating a nested function?
Then I want to conj, but I cannot do:
(conj 0 1)
so I do weird things to make sure I've got a sequence first and I end up with this:
(fn
[x y]
((fn g [x y acc] (if (= x y) y (conj (conj acc (g (inc x) y acc)) x)))
x
y
'()))
But then this produce this:
(1 (2 (3 4)))
Instead of this:
(1 2 3 4)
So I end up doing an additional flatten and it works but it is totally ugly.
I'm beginning to understand a few things and I'm even starting, in some cases, to "think" in a more clojuresque way but I've got a problem writing the solution.
For example here I decided:
to use an accumulator
to recurse by incrementing x until it reaches y
But I end up with the monstrosity above.
There are a lot of way to solve this problem and, once again, it's not what I'm after.
What I'm after is how, after I decided to cons/conj, use an accumulator, and recurse, I can end up with this (not written by me):
#(loop [i %1
acc nil]
(if (<= %2 i)
(reverse acc)
(recur (inc i) (cons i acc))))
Instead of this:
((fn
f
[x y]
(flatten
((fn
g
[x y acc]
(if (= x y) acc (conj (conj acc (g (inc x) y acc)) x)))
x
y
'())))
1
4)
I take it's a start to be able to solve a few problems but I'm a bit disappointed by the ugly solutions I tend to produce...
i think there are a couple of things to learn here.
first, a kind of general rule - recursive functions typically have a natural order, and adding an accumulator reverses that. you can see that because when a "normal" (without accumulator) recursive function runs, it does some work to calculate a value, then recurses to generate the tail of the list, finally ending with an empty list. in contrast, with an accumulator, you start with the empty list and add things to the front - it's growing in the other direction.
so typically, when you add an accumulator, you get a reversed order.
now often this doesn't matter. for example, if you're generating not a sequence but a value that is the repeated application of a commutative operator (like addition or multiplication). then you get the same answer either way.
but in your case, it is going to matter. you're going to get the list backwards:
(defn my-range-0 [lo hi] ; normal recursive solution
(if (= lo hi)
nil
(cons lo (my-range-0 (inc lo) hi))))
(deftest test-my-range-1
(is (= '(0 1 2) (my-range-0 0 3))))
(defn my-range-1 ; with an accumulator
([lo hi] (my-range-1 lo hi nil))
([lo hi acc]
(if (= lo hi)
acc
(recur (inc lo) hi (cons lo acc)))))
(deftest test-my-range-1
(is (= '(2 1 0) (my-range-1 0 3)))) ; oops! backwards!
and often the best you can do to fix this is just reverse that list at the end.
but here there's an alternative - we can actually do the work backwards. instead of incrementing the low limit you can decrement the high limit:
(defn my-range-2
([lo hi] (my-range-2 lo hi nil))
([lo hi acc]
(if (= lo hi)
acc
(let [hi (dec hi)]
(recur lo hi (cons hi acc))))))
(deftest test-my-range-2
(is (= '(0 1 2) (my-range-2 0 3)))) ; back to the original order
[note - there's another way of reversing things below; i didn't structure my argument very well]
second, as you can see in my-range-1 and my-range-2, a nice way of writing a function with an accumulator is as a function with two different sets of arguments. that gives you a very clean (imho) implementation without the need for nested functions.
also you have some more general questions about sequences, conj and the like. here clojure is kind-of messy, but also useful. above i've been giving a very traditional view with cons based lists. but clojure encourages you to use other sequences. and unlike cons lists, vectors grow to the right, not the left. so another way to reverse that result is to use a vector:
(defn my-range-3 ; this looks like my-range-1
([lo hi] (my-range-3 lo hi []))
([lo hi acc]
(if (= lo hi)
acc
(recur (inc lo) hi (conj acc lo)))))
(deftest test-my-range-3 ; except that it works right!
(is (= [0 1 2] (my-range-3 0 3))))
here conj is adding to the right. i didn't use conj in my-range-1, so here it is re-written to be clearer:
(defn my-range-4 ; my-range-1 written using conj instead of cons
  ([lo hi] (my-range-4 lo hi nil))
  ([lo hi acc]
    (if (= lo hi)
      acc
      (recur (inc lo) hi (conj acc lo)))))
(deftest test-my-range-4
(is (= '(2 1 0) (my-range-4 0 3))))
note that this code looks very similar to my-range-3 but the result is backwards because we're starting with an empty list, not an empty vector. in both cases, conj adds the new element in the "natural" position. for a vector that's to the right, but for a list it's to the left.
and it just occurred to me that you may not really understand what a list is. basically a cons creates a box containing two things (its arguments). the first is the contents and the second is the rest of the list. so the list (1 2 3) is basically (cons 1 (cons 2 (cons 3 nil))). in contrast, the vector [1 2 3] works more like an array (although i think it's implemented using a tree).
so conj is a bit confusing because the way it works depends on the first argument. for a list, it calls cons and so adds things to the left. but for a vector it extends the array(-like thing) to the right. also, note that conj takes an existing sequence as first arg, and thing to add as second, while cons is the reverse (thing to add comes first).
all the above code available at https://github.com/andrewcooke/clojure-lab
update: i rewrote the tests so that the expected result is a quoted list in the cases where the code generates a list. = will compare lists and vectors and return true if the content is the same, but making it explicit shows more clearly what you're actually getting in each case. note that '(0 1 2) with a ' in front is just like (list 0 1 2) - the ' stops the list from being evaluated (without it, 0 would be treated as a command).
After reading all that, I'm still not sure why you'd need an accumulator.
((fn r [a b]
(if (<= a b)
(cons a (r (inc a) b))))
2 4)
=> (2 3 4)
seems like a pretty intuitive recursive solution. the only thing I'd change in "real" code is to use lazy-seq so that you won't run out of stack for large ranges.
how I got to that solution:
When you're thinking of using recursion, I find it helps to try and state the problem with the fewest possible terms you can think up, and try to hand off as much "work" to the recursion itself.
In particular, if you suspect you can drop one or more arguments/variables, that is usually the way to go - at least if you want the code to be easy to understand and debug; sometimes you end up compromising simplicity in favor of execution speed or reducing memory usage.
In this case, what I thought when I started writing was: "the first argument to the function is also the start element of the range, and the last argument is the last element". Recursive thinking is something you kind of have to train yourself to do, but a fairly obvious solution then is to say: a range [a, b] is a sequence starting with element a followed by a range of [a + 1, b]. So ranges can indeed be described recursively. The code I wrote is pretty much a direct implementation of that idea.
addendum:
I've found that when writing functional code, accumulators (and indexes) are best avoided. Some problems require them, but if you can find a way to get rid of them, you're usually better off if you do.
addendum 2:
Regarding recursive functions and lists/sequences, the most useful way to think when writing that kind of code is to state your problem in terms of "the first item (head) of a list" and "the rest of the list (tail)".
I cannot add to the already good answers you have received, but I will answer in general. As you go through the Clojure learning process, you may find that many but not all solutions can be solved using Clojure built-ins, like map and also thinking of problems in terms of sequences. This doesn't mean you should not solve things recursively, but you will hear -- and I believe it to be wise advice -- that Clojure recursion is for solving very low level problems you cannot solve another way.
I happen to do a lot of .csv file processing, and recently received a comment that nth creates dependencies. It does, and use of maps can allow me to get at elements for comparison by name and not position.
I'm not going to throw out the code that uses nth with clojure-csv parsed data in two small applications already in production. But I'm going to think about things in a more sequency way the next time.
It is difficult to learn from books that talk about vectors and nth, loop .. recur and so on, and then realize learning Clojure grows you forward from there.
One of the things I have found that is good about learning Clojure, is the community is respectful and helpful. After all, they're helping someone whose first learning language was Fortran IV on a CDC Cyber with punch cards, and whose first commercial programming language was PL/I.
If I solved this using an accumulator I would do something like:
user=> (defn my-range [lb up c]
(if (= lb up)
c
(recur (inc lb) up (conj c lb))))
#'user/my-range
then call it with
#(my-range % %2 [])
Of course, I'd use letfn or something to get around not having defn available.
So yes, you do need an inner function to use the accumulator approach.
My thought process is that once I'm done the answer I want to return will be in the accumulator. (That contrasts with your solution, where you do a lot of work on finding the ending-condition.) So I look for my ending-condition and if I've reached it, I return the accumulator. Otherwise I tack on the next item to the accumulator and recur for a smaller case. So there are only 2 things to figure out, what the end-condition is, and what I want to put in the accumulator.
Using a vector helps a lot because conj will append to it and there's no need to use reverse.
I'm on 4clojure too, btw. I've been busy so I've fallen behind lately.
It looks like your question is more about "how to learn" then a technical/code problem. You end up writing that kind of code because from whatever way or source you learned programming in general or Clojure in specific has created a "neural highway" in your brain that makes you thinking about the solutions in this particular way and you end up writing code like this. Basically whenever you face any problem (in this particular case recursion and/or accumulation) you end up using that "neural highway" and always come up with that kind of code .
The solution for getting rid of this "neural highway" is to stop writing code for the moment, keep that keyboard away and start reading a lot of existing clojure code (from existing solutions of 4clojure problem to open source projects on github) and think about it deeply (even read a function 2-3 times to really let it settle down in your brain). This way you would end up destroying your existing "neural highway" (which produce the code that you write now) and will create a new "neural highway" that would produce the beautiful and idiomatic Clojure code. Also, try not to jump to typing code as soon as you saw a problem, rather give yourself some time to think clearly and deeply about the problem and solutions.

Common Lisp Binary Tree

I am trying to write a program in Common Lisp using GNU ClISP to compile it. I would like to enter a list such as (A(B (C) ()) (D (E) (F (G) ()))) and depending on the first word print out the pre-, in-, or post-order traversal. Example:
(pre '(A(B (C)... etc))
I am having trouble putting my logic into Clisp notation. I currently have the following code:
(defun leftchild (L)(cadr L))
(defun rightchild (L)(caddr L))
(defun data (L)(car L))
(defun pre (L)(if (null L) '()((data L)(pre(leftchild L))(pre(rightchild L)))))
... similar in and post functions
I get compiling errors saying that I should use a lambda in my pre function. I think this is due to the double (( infront of data because it is expecting a command, but I am not sure what I should put there. I don't think cond would work, because that would hinder the recursive loop. Also, will data L print as it is now? The compiler did not recognize (print (data L)).
I have been working on this code for over a week now, trying to troubleshoot it myself, but I am at a loss. I would greatly appreciate it if someone could explain what I am doing incorrectly.
Another question that I have is how can I make the program prompt a line to the user to enter the (pre '(A... etc)) so that when I run the compiled file the program will run instead of giving a funcall error?
Thank you for your time.
Short answer: If you want to use if, note that you'll need a progn in order to have more than one form in the consequent and alternative cases.
Long answer – also explains how to traverse accumulating the visited nodes in a list:
I guess this is homework, so I won't give you a full solution, but your question shows that you have basically the right idea, so I'll show you an easy, idiomatic way to do this.
First, you're right: The car of an unquoted form should be a function, so basically anything like (foo ...), where foo is not a function (or macro, special form ...), and the whole thing is to be evaluated, will be an error. Note that this does not hold inside special forms and macros (like cond, for example). These can change the evaluation rules, and not everything that looks like (foo bar) has to be a form that is to be evaluated by the normal evaluation rules. The easiest example would be quote, which simply returns its argument unevaluated, so (quote (foo bar)) will not be an error.
Now, about your problem:
An easy solution would be to have an accumulator and a recursive helper function that traverses the tree, and pushes the values in the accumulator. Something like this:
(defun pre (node)
(let ((result (list)))
(labels ((rec (node)
(cond (...
...
...))))
(rec node)
(nreverse result))))
The labels just introduces a local helper function, which will do the actual recursion, and the outer let gives you an accumulator to collect the node values. This solution will return the result as a list. If you just want to print each nodes value, you don't need the accumulator or the helper function. Just print instead of pushing, and make the helper your toplevel function.
Remember, that you'll need a base case where the recursion stops. You should check for that in the cond. Then, you'll need the recursive steps for each subtree and you'll need to push the node's value to the results. The order in which you do these steps decides whether you're doing pre-, in-, or post-order traversal. Your code shows that you already understand this principle, so you'll just have to make it work in Lisp-code. You can use push to push values to result, and consp to check whether a node is a non-empty list. Since there's nothing to do for empty lists, you'll basically only need one test in the cond, but you can also explicitly check whether the node is null, as you did in your code.

lazy-seq for recursive function

Sorry for the vague title, I guess I just don't understand my problem well enough to ask it yet but here goes. I want to write a recursive function which takes a sequence of functions to evaluate and then calls itself with their results & so on. The recursion stops at some function which returns a number.
However, I would like the function being evaluated at any point in the recursion, f, to be wrapped in a function, s, which returns an initial value (say 0, or the result of another function i) the first time it is evaluated, followed by the result of evaluating f (so that the next time it is evaluated it returns the previously evaluated result, and computes the next value). The aim is to decouple the recursion so that it can proceed without causing this.
I think I'm asking for a lazy-seq. It's a pipe that's filling-up with evaluations of a function at one end, and historical results are coming out of the other.
Your description reminds me some of reductions? Reductions will perform a reduce and return all the intermediate results.
user> (reductions + (range 10))
(0 1 3 6 10 15 21 28 36 45)
Here (range 10) creates a seq of 0 to 9. Reductions applies + repeatedly, passing the previous result of + and the next item in the sequence. All of the intermediate results are returned. You might find it instructive to look at the source of reductions.
If you need to build a test (check for value) into this, that's easy to do with an if in your function (although it won't stop traversing the seq). If you want early exit on a condition being true, then you'll need to write your own loop/recur which amalloy has already done well.
I hate to say it, but I suspect this might also be a case for the State Monad but IANAMG (I Am Not A Monad Guy).
I don't understand your entire goal: a lot of the terms you use are vague. Like, what do you mean you want to evaluate a sequence of functions and then recur on their results? These functions must be no-arg functions (thunks), then, I suppose? But having a thunk which first returns x, and then returns y the next time you call it, is pretty vile and stateful. Perhaps trampoline will solve part of your problem?
You also linked to something you want to avoid, but seem to have pasted the wrong link - it's just a link back to this page. If what you want to avoid is stack overflow, then trampoline is likely to be an okay way to go about it, although it should be possible with just loop/recur. This notion of thunks returning x unless they return y is madness, if avoiding stack overflow is your primary goal. Do not do that.
I've gone ahead and taken a guess at the most plausible end goal you might have, and here's my implementation:
(defn call-until-number [& fs]
(let [numeric (fn [x] (when (number? x) x))]
(loop [fs fs]
(let [result (map #(%) fs)]
(or (some numeric result)
(recur result))))))
(call-until-number (fn [] (fn [] 1))) ; yields 1
(call-until-number (fn [] (fn [] 1)) ; yields 2
(fn [] 2))
(call-until-number (fn f [] f)) ; never returns, no overflow

Resources