Curry-Skip Scheme - list

I have to write a scheme function called curry-skip that recursively that returns the nth element of a list such that
(((curry-skip 1) 'foo) 'bar) => bar
I can't seem to figure out how to do this recursively. I'm still fairly new to Scheme, so any help would be much appreciated!
Thanks

I wrote the following after looking at your example. It seemed fairly simple and as such I can't explain by what reasoning it came to be.
(define (curry-skip n)
(lambda (v) (if (= n 0)
v
(curry-skip (- n 1)))))

I think you have 3 cases here:
n>0 - you recurse down until n=0
n=0 - you memorize the argument, because that's the final value you need to return; memorization is done via a closure
else - ignore parameters until done, then finally return the memorized value
so
(define (res val) ; [procedure used for case 2 - n=0]
(define (res0 . x) (if (null? x) val res0)) ; [case 3]
res0)
(define (curry-skip n)
(cond
((< n 0) (error "n is negative"))
((= n 0) res) ; [case 2 - n = 0]
(else (lambda x (curry-skip (- n 1)))))) ; [case 1 - n > 0]
then
-> (((curry-skip 0) 'foo))
'foo
-> ((((curry-skip 0) 'foo) 'bar))
'foo
-> ((((curry-skip 1) 'foo) 'bar))
'bar
-> (((((curry-skip 0) 'foo) 'bar) 'baz))
'foo
-> (((((curry-skip 1) 'foo) 'bar) 'baz))
'bar
-> (((((curry-skip 2) 'foo) 'bar) 'baz))
'baz
Compared to your question my solution has got an extra pair of parentheses but that's as close as I could get.

(define (curry-skip n)
(if (zero? n)
(lambda (x) x)
(let ((rest (curry-skip (- n 1))))
(lambda (x) rest))))
You want to compute the (- n 1) cases outside of the returned lambda! So, in the above, when n is zero just return the one argument lambda; but, when n is positive, compute the (- n 1) case and return a lambda that ignores its argument and just returns the rest.
Note that, although not part of your question but related to a comment, if you needed a true curry, like in ML, you would need syntactic help as:
(define-syntax curry*
(syntax-rules ()
((_ (a) body ...) (lambda (a) body ...))
((_ (a b ...) body ...)
(lambda (a) (curry* (b ...) body ...)))))
Notice how the recursion creates lexical environments for each of a, b, … so that body can be properly evaluated. The curry-skip doesn't have such a need.
Here is some code addressing the comment about doing the 'curry-skip' inside the returned lambda. Doing the recursion outside of the lambda happens only once creating one closure; doing it inside the lambda creates closures on each invocation.
(define (curry-skip-o n)
(if (zero? n)
(lambda (x) x)
(let ((rest (curry-skip-o (- n 1))))
(lambda (x) rest))))
(define (curry-skip-i n)
(if (zero? n)
(lambda (x) x)
(lambda (x) (curry-skip-i (- n 1)))))
(define (run skipper r n)
(let ((f (skipper n)))
;; Repeat 'r' times with 'f'
(let rep ((r r))
(unless (zero? r)
;; Exhaust f
(let rep ((i 0) (f f))
(if (< i n)
(rep (+ i 1) (f i))
(f 0)))
(rep (- r 1))))))
> (time (run curry-skip-o 10000 10000)) ;; create ~10^4 closures
running stats for (run curry-skip-o 10000 10000):
no collections
376 ms elapsed cpu time, including 0 ms collecting
376 ms elapsed real time, including 0 ms collecting
160032 bytes allocated
> (time (run curry-skip-i 10000 10000)) ;; create ~10^8 closures
running stats for (run curry-skip-i 10000 10000):
191 collections
1587 ms elapsed cpu time, including 965 ms collecting
1588 ms elapsed real time, including 966 ms collecting
1599840048 bytes allocated

Related

Find the longest integer in a vector using while loops

Working on this program that's supposed to take a vector of integers as input and return the one with the longest integer. Example (vector 20 738 5942 125) and would return 4 as its the longest one. I'm pretty sure I have most of this done the only issue I have is in the conditional as I have to call an outside function (count-integers), this is what I have so far:
(require while)
(define (empty-VINT? low high) (> low high))
(define (count-integers n)
(cond [(< n 10) 1]
(else(+ 1 (count-integers [/ n 10])))))
(define (count-digits V)
(local [
(define x (void))
(define accum (void))
(define largest 0)]
(begin
(set! x (vector-length V))
(set! accum 0)
(while (< accum (vector-length V))
(cond [(empty-VINT? x accum) accum]
[(> (count-integers (vector-ref V accum) largest)
(add1 x) accum(vector-ref V accum))]
[else add1 accum])))))
Right now when its run, I get this message: cond: expected a clause with a question and an answer, but found a clause with only one part. Any suggestions would be great, thanks
First of all, it's not clear what do you want to return. 4 isn't the longest integer (that's 5942), 4 is a maximal digit count among integers in given vector.
Secondly, your code isn't idiomatic and without your comment, it's very hard to say what's going on. Programming in functional languages requies functional way of thinking. Forget about while, set!, void, local and nested define and instead spend some time learning about apply, map, filter and foldl.
I would solve this problem like this:
(define (digits number)
(string-length (number->string number)))
(define (max-digit-count vec)
(apply max (map digits (vector->list vec))))
(max-digit-count (vector 20 738 5942 125))
=> 4
From comments:
Design and implement a function to find the number of digits in the longest integer in a (vectorof integer) ...
use ... while loops
So a plan (design) might be:
count-digits: integer -> natural
max-digit-count: (vectorof integer) -> natural
..something while something max count-digits something ???
Implementing count-digits seems straightforward (but
integers can be negative, and in Racket (integer? 123.000) is true).
#lang racket
(define (count-digits int) ;; Integer -> Natural
;; produce count of digits in int
(string-length (number->string (abs (exact-truncate int)))))
As #Gwang-Jin Kim mentions, while could be defined:
(define-syntax-rule (while condition body ...)
;; From: https://stackoverflow.com/questions/10968212/while-loop-macro-in-drracket
(let loop ()
(when condition
body ...
(loop))))
and then one could use it:
(define (max-digit-count vec) ;; VectorOfInteger -> Natural
;; produce maximum of digit counts of vec elements
(define vx 0)
(define acc 0)
(while (< vx (vector-length vec))
(set! acc (max accum (count-digits (vector-ref vec vx))))
(set! vx (add1 vx)))
acc)
(max-digit-count (vector 20 -738.00 5942 125)) ;=> 4
One of the problems with while is that it can't produce a value (where would it come
from if the condition is false on entry?)
If one "enhanced" while a bit:
(define-syntax-rule (while< x-id limit a-id a-init update)
;; "while loop" incrementing x-id from 0 to limit-1, updating a-id
(let loop ([x-id 0] [a-id a-init])
(if (< x-id limit)
(loop (add1 x-id) update)
a-id)))
max-digit-count could be neater:
(define (max-digit-count vec) ;; VectorOfInteger -> Natural
;; produce maximum of digit counts of vec elements
(while< vx (vector-length vec)
acc 0 (max acc (count-digits (vector-ref vec vx)))))
#MartinPuda's answer is quite good.
I would have defined:
(define (digits n (acc 0))
(if (< n 1)
acc
(digits (/ n 10) (+ acc 1))))
(define (max-digits lst)
(digits (car (sort lst >))))
To apply it:
(max-digits (vector->list (vector 20 738 5942 125)))
Why you should not use while
Using while would force you to mutate variable values. It is much more "natural" for lisp languages to follow the functional style (recursive functions instead of while loops or other loops) rather than the imperative style with mutation of variables.
That is why while is not in the lisp languages.
But if you want to use it:
(define-syntax-rule (while condition body ...)
;; From: https://stackoverflow.com/questions/10968212/while-loop-macro-in-drracket
(let loop ()
(when condition
body ...
(loop))))
(define (digits n (acc 0))
(cond ((< n 1) acc)
(else (digits (/ n 10) (+ acc 1)))))
(define (max-digits lst)
(let ((max-digit 0))
(while (not (null? lst))
(let ((digit (digits (car lst))))
(when (< max-digit digit)
(set! max-digit digit))
(set! lst (cdr lst))))
max-digit))
Then you can try:
> (max-digits (vector->list v))
4
> (max-digits '(1111 123456 2345 34))
6
Prefer let over define
Why? Because if you use let, you can control the scope of the to-be-mutated variable very precisely. You can define in your definition, from where on your variable canNOT have any effect on your code (since its scope ended at some point). While with define you don't have this fine-grained control. (Or this control is implicit not explicite like with let). You could delete/unbind the variable explicitely but that is rarely done in real life.
Therefore, in Lisp, for variable declarations use whenever possible let, especially whenever you deal with mutated variables.
All imperative = declarations should be in Lisp languages let expressions!
You can use function arguments instead of let-definitions, because they are anyway implemented using lets
Just you save syntactically some lines - and the fewer lines you occupy the cleaner the code.
#lang racket
(define (digits n)
(string-length (number->string n)))
(define (max-digit a b)
(if (< (digits a) (digits b)) b a))
(define (max-digits lst (res ""))
(while (not (null? lst))
(set! res (max-digit res (car lst)))
(set! lst (cdr lst)))
(digits res))

infinite sequence scheme to make infinite sequence

I have a project in scheme in which I need to implement an infinite sequence of numbers. I can't use any scheme-built-in complex functions, and I just do not know how to make my sequence infinite without program crashing in infinite loop. I don't have to really output it, but I need to be able to use it.
(seq n) ;;output: n,n+1,n+2,n+3.... to infinity (seq 5) ->5,6,7,8,9...
Right now I did a sequence until n+7, but I need this to infinity:
(define (seq n)
(define (asc-order LIST counter)
(cond ((= counter (+ n 7)) LIST)
(else (asc-order (append LIST (cons (+ counter 1) '()))
(+ counter 1)))))
(asc-order '() (- n 1))
)
IO example (It works, but I need it infinite sequence):
>(define s (seq 3))
>(car s)
3
You can represent an infinite sequence as a function that produces one element at a time. The user (consumer) can then call the function each a new element of the sequence is needed.
An example:
(define (f x) (* x x))
(define seq
(let ()
(define n 0) ; current index
(lambda () ; the function that is to be called repeatedly
(define a (f n)) ; compute the new element
(set! n (+ n 1)) ; compute new index
a))) ; return the new element
(seq) ; compute element 0
(seq) ; compute element 1
(seq) ; ...
(seq)
(seq)
(seq)
This evaluates to:
0
1
4
9
16
25
In order to write (sequence->list s n) which computes the first n elements of the sequence s, make a loop that calls s in total n times - and collect the results in a list.
The key is to delay evaluation of the list by wrapping a procedure around it.
Here's the simplest implementation I can think of.
It's only "lazy" in the tail.
(define (seq n)
(cons n (lambda () (seq (+ n 1)))))
(define (seq-car s)
(car s))
(define (seq-cdr s)
((cdr s)))
Example use:
; Get the 'n' first elements of 's'.
(define (seq-take n s)
(if (<= n 0)
'()
(cons (seq-car s) (seq-take (- n 1) (seq-cdr s)))))
> (define s (seq 10))
> s
'(10 . #<procedure>)
> (seq-take 5 s)
'(10 11 12 13 14)
Here is another solution using delayed evaluation:
(use-modules (ice-9 receive))
(define (seq f)
(let loop ((n 0))
(lambda ()
(values (f n) (loop (1+ n))))))
(define squares (seq (lambda (x) (* x x))))
(receive (square next) (squares)
(pk square) ;; => 0
(receive (square next) (next)
(pk square) ;; => 1
(receive (square next) (next)
(pk square) ;; => 4
(receive (square next) (next)
(pk square))))) ;; => 9

Concatenating list elements - Scheme

If i have a scheme code that generates the following result: (i'm using cons)
'((1 . 0) . 0)
How can i take this, and just simply display 100 as if it were just one integer number and not a list presented with those dots and parenthesis?
Thanks!
EDIT:
my full code:
(define (func X)
(if ( <= X 3 )
X
(cons (modulo X 4) (func(floor(/ X 4)) ))
))
If I understand correctly, you're trying to convert a number from base 10 to base 4, and then display it as a number, but there are several problems with your implementation.
You're building a list as output - but that's not what you want, you want a number. Also, you're traversing the input in the wrong order, and that's not the correct way to find the quotient between two numbers. Perhaps this will help:
(define (func X)
(let loop ((n X) (acc 0) (mult 1))
(if (< n 4)
(+ (* mult n) acc)
(loop (quotient n 4)
(+ (* mult (modulo n 4)) acc)
(* mult 10)))))
Alternatively, you could output a string to stress the fact that the output is not in base 10:
(define (func X)
(let loop ((n X) (acc ""))
(if (< n 4)
(string-append (number->string n) acc)
(loop (quotient n 4)
(string-append (number->string (modulo n 4)) acc)))))
It'll work as expected:
(func 16)
=> 100
Oscar Lopez's answer is excellent. I can't help adding that this problem doesn't need the "loop" construct:
;; translate a string to a base-4 string.
(define (func n)
(cond [(< n 4) (number->string n)]
[else (string-append (func (quotient n 4))
(number->string (modulo n 4)))]))

Decimal to Binary in Lisp - make a non-nested list

When reaching my recursion cases, I use list to append the future result with the current one, but I end up with a nested list because of recursion. This causes an error when I have a number that causes recursion for more than five times.
Any ideas how I can get results in a single plain non-nested list, e.g.:
CL-USER 100 : 8 > (BINARY_LIST 4)
(1 0 0)
Code & Example output:
CL-USER 99 : 8 > (defun binary_list (i)
(COND
((= i 0) 0)
((= i 1) 1)
((= (mod i 2) 0) (list (binary_list (truncate i 2)) 0))
(t (list (binary_list (truncate i 2)) 1))
)
)
BINARY_LIST
CL-USER 100 : 8 > (BINARY_LIST 4)
((1 0) 0)
CL-USER 101 : 8 > (BINARY_LIST 104)
((((# 1) 0) 0) 0)
You are almost there. All you need to do is to replace list with nconc:
(defun binary-list (n)
(cond ((= n 0) (list 0))
((= n 1) (list 1))
(t (nconc (binary-list (truncate n 2)) (list (mod n 2))))))
You can avoid calling both truncate and mod by collecting both values in integer division:
(defun binary-list (n)
(assert (>= n 0))
(multiple-value-bind (q r) (floor n 2)
(if (zerop q)
(list r)
(nconc (binary-list q) (list r)))))
Note that this algorithm is quadratic because nconc has to traverse the result on each iteration. This can be avoided by passing an accumulator:
(defun binary-list (n &optional acc)
(assert (>= n 0))
(multiple-value-bind (q r) (floor n 2)
(if (zerop q)
(cons r acc)
(binary-list q (cons r acc)))))
Now we have a tail-recursive function which can be compiled to iteration by a modern compiler.
One more optimization trick you could use (which, in fact, should be done by the compiler - try disassemble to check!) is using ash and logand instead of the much more general and expensive floor:
(defun binary-list (n &optional acc)
(cond ((zerop n) (or acc (list 0)))
((plusp n)
(binary-list (ash n -1) (cons (logand 1 n) acc)))
(t (error "~S: non-negative argument required, got ~s" 'binary-list n))))
Incidentally, lispers usually use dash instead of underscores in symbols, so your binary_list should be binary-list if you do not want to offend our tender aesthetics.
this seems to me to be the most direct, least roundabout manner to achieve the desired results every time:
(defun mvp-binary-from-decimal (n r)
(if (zerop n)
r
(multiple-value-bind (a b)
(floor n 2)
(mvp-binary-from-decimal a (cons b r)))))
(defun binary-from-decimal (n)
(if (and (numberp n) (plusp n))
(mvp-binary-from-decimal n '())
(if (eql n 0) '(0) nil)))
tested in slime, sbcl, clisp - used as follows:
CL-USER> (binary-from-decimal 100)
(1 1 0 0 1 0 0)
CL-USER> (binary-from-decimal 10)
(1 0 1 0)
CL-USER> (binary-from-decimal 0)
(0)
there are some advanced reasons as to why this might be the most desirable manner in which to implement such functionality, but for now, suffice to say that it is clean, polite, readable and always works.

How to return a list of numbers between 1 and x

I'm trying to create a function that takes in user input, x, and displays all of the numbers from 1 up to x. Not quite sure where to go from here:
(define (iota x)
(if (>= x 1)
(display
;; Takes a number n
;; and returns a list with 1..n
;; in order.
(define (make-list n)
(let loop ((n n) (accumulator '()))
(if (zero? n)
accumulator
(loop (- n 1) (cons n accumulator)))))
;; prints data and adds
;; a newline
(define (println x)
(display x)
(newline))
;; prints 1..n by applying println
;; for-each element over the list 1..n
(define (iota n)
(for-each println (make-list n)))
Basically you want to use recursion. So think of it was counting up. As you count up either you've added enough numbers and you are done building your list or you need to add the current number to your list and go on to the next number.
Look at the following code:
(define (range-2 next-num max-num cur-list)
;;if we've added enough numbers return
(if (> next-num max-num)
cur-list
;; otherwise add the current number to the list and go onto the next one
(range-2
(+ 1 next-num)
max-num
(append cur-list (list next-num))
)))
But to get the function you wanted you need to start off with the constants you specified (ie 1), so lets create a convenience function for calling range with the starter values you need to set up the recursion, sometimes called priming the recursion:
(define (range X)
(range-2 1 X `() ))
You could do it without the second function using lambda, but this is pretty common style from what I've seen.
Once you've constructed a list of the numbers you need you just display it using
(display (range 10))
If you're using Racket you're in luck, you can use iterations and comprehensions, for instance in-range:
(define (iota x)
(for ([i (in-range 1 (add1 x))])
(printf "~a " i)))
Or for a more standard solution using explicit recursion - this should work in most interpreters:
(define (iota x)
(cond ((positive? x)
(iota (- x 1))
(display x)
(display " "))))
Either way, it works as expected:
(iota 10)
=> 1 2 3 4 5 6 7 8 9 10
(define iota2
(lambda (y)
(let loop ((n 1))
(if (<= n y)
(cons n (loop (+ n 1)))
'()))))
(define (iota x)
(if (>= x 1)
(begin
(iota (- x 1))
(display x)
(newline))))