whats making this error? ill/formed special form let - functional-programming

When I run this , it says ill-formed special form let..
what could be the reason?
Here is the code :
(define (cm m)
(case m
(#\f)
(do ((i 300 (+ i 100)))
((> i 1300))
(let ((x (* i 2))) (let ((y (/ x 2)) (z (+ x 3))))
(display x) (display " ") (display y) (display " ") (display z) )))
((#\a) 'gold)
((#\c) 3)
(else 4)))

As the other commenters have stated, proper indentation will help significantly. I'm not sure what you're trying to achieve, but this compiles and runs fine:
(define (cm m)
(case m
((#\f)
(do ((i 300 (+ i 100)))
((> i 1300))
(let ((x (* i 2)))
(let ((y (/ x 2))
(z (+ x 3)))
(display x)
(display " ")
(display y)
(display " ")
(display z)))))
((#\a) 'gold)
((#\c) 3)
(else 4)))
(cm #\f)
; 600 300 603800 400 8031000 500 10031200 600 12031400 700 14031600 800 16031800 900 18032000 1000 20032200 1100 22032400 1200 24032600 1300 2603
(cm #\a)
; 'gold

Related

Slimv: Evaluation aborted on <unknown reason>

I'm debugging the following mit-scheme program through vim with the assistance of slimv.
(define (pascal x)
(define (pascal-iter m n max-len)
(cond ((and (> m 0) (> n 0))
(pascal-iter m (- n 1) max-len)
(beauti-print (pascal-item m n) max-len))
((= n 0) (pascal-iter (- m 1) (- m 1) max-len)
(display "\n")
(print-space (* (- x m) max-len)))
((= m 0) "Done")))
(define (pascal-item m n)
(cond ((= n 1) 1)
((= n m) 1)
(else (+ (pascal-item (- m 1) (- n 1))
(pascal-item (- m 1) n)))))
(define (beauti-print item max-len)
(print-space (floor (- max-len
(/ (num-of-digit item) 2))))
(display item)
(print-space (ceiling (- max-len
(/ (num-of-digit item) 2)))))
(define (num-of-digit n)
(+ (floor (/ (log n) (log 10))) 1) )
;; (print-space 1) -> " "
;; (print-space 1.5) -> " "
(define (print-space n)
(cond ((> n 0) (display " ")
(print-space (- n 1)))
(else (display ""))))
(pascal-iter x x (num-of-digit (pascal-item x (/ x 2)))))
(pascal 10)
When I ran the command :!mit-scheme --load "pascal.scm", a pascal triangle is printed on the screen, so there I can't spot any bug in my program. However, when I executed ,d and tried to run this program in slimv's REPL buffer, I got:
(user)> (pascal 10)
; Evaluation aborted on <unknown reason>
(user)> (+ 40 2) ;; other statements are interpreted as expected
42
(user)>
So, what's the <unknown reason> that prevents my program from running properly? Is it my fault, or a bug of slimv?
This is the relevant part of swank.log:
[-Received-] 0.481893
(:return (:abort "<unknown reason>") 8)
[Actionlist] 0.482347
8: finished :listener-eval
[---Sent---] 0.525237
(:emacs-rex (swank-repl:listener-eval "(pascal 12)
") "(user)" :repl-thread 9)

Unexpected error in simple recursion(Scheme Language)

I'm learning Scheme using racket. I made the following program but it gives a contract violation error.
expected: (exact-nonnegative-integer? . -> . any/c)
given: '()
The program finds a list of all numbers in an interval which are divisible by 3 or 5.
#lang racket
;;Global Definitions
(define upper-bound 10)
(define lower-bound 0)
;;set-bounds: Int, Int -> ()
(define (set-bounds m n)
(set! upper-bound (max m n))
(set! lower-bound (min m n)))
;;get-numbers: () -> (Int)
(define (get-numbers)
(build-list upper-bound '()))
;;make-list: Int, (Int) -> (Int)
(define (build-list x y)
(cond
[(= x lower-bound) y]
[(= (modulo x 5) 0) (build-list (sub1 x) (cons x y))]
[(= (modulo x 3) 0) (build-list (sub1 x) (cons x y))]
[else (build-list (sub1 x) y)]))
EDIT: I made the changes suggested by Oscar Lopez.
An alternative method can be with the use of for/list to create the list:
(define (build-list ub lst)
(for/list ((i (range lb ub))
#:when (or (= 0 (modulo i 3))
(= 0 (modulo i 5))))
i))
Usage:
(define lb 0)
(build-list 10 '())
Output:
'(0 3 5 6 9)
Edit:
Actually lst is not needed here:
(define (build-list ub)
(for/list ((i (range lb ub))
#:when (or (= 0 (modulo i 3))
(= 0 (modulo i 5))))
i))
So one can call:
(build-list 10)
Following is a modification of the recursion method (uses 'named let'):
(define (build-list2 ub)
(let loop ((x ub) (lst '()))
(cond
[(= x lb) lst]
[(= (modulo x 5) 0) (loop (sub1 x) (cons x lst))]
[(= (modulo x 3) 0) (loop (sub1 x) (cons x lst))]
[else (loop (sub1 x) lst)])))
Also, if you always have to call your function with an empty list '(), you can put this as default in your argument list:
(build-list x (y '()))
Then you can call with simplified command:
(build-list 10)
You should test first the condition where the recursion stops - namely, when x equals the lower-bound:
(define (build-list x y)
(cond
[(= x lower-bound) y]
[(= (modulo x 5) 0) (build-list (sub1 x) (cons x y))]
[(= (modulo x 3) 0) (build-list (sub1 x) (cons x y))]
[else (build-list (sub1 x) y)]))

Using append in Scheme

I have just started functional programming using Scheme and was trying to print Fibonacci series. Here is my code-
(define (fib n)
(cond
((= n 1)
1)
((= n 0) 0)
((= n 5) '())
(else (append (list(+ (fib (- n 1) ) (fib (- n 2)))) '()))
)
)
(fib 5)
It should ideally output- (0 1 1 2 3) But all I get as output is `(). Can anyone help figuring out the mistake?
Edit
Thanks to #uselpa for pointing out , ((=n 5) '()) was not required. After removing it I am getting the following error-
ListCC cannot be cast to SEIntread: bad syntax, unexpected )
Mess cannot be cast to SEIntMess cannot be cast to SEInt
You call your procedure with n=5 so the condition (= n 5) is true and cond dutifully returns '() as instructed. That's where it stops, nothing else is executed.
EDIT
What you want to do, all performance considerations put aside, is probably something like
(define (fib n)
(if (< n 2)
n
(+ (fib (- n 1))
(fib (- n 2)))))
(define (fib-list n)
(let loop ((i (- n 1)) (res '()))
(if (< i 0)
res
(loop (- i 1) (cons (fib i) res)))))
then
> (fib-list 5)
'(0 1 1 2 3)
(define (fib-list n)
(cond ((< n 0) 'error)
((= n 0) '(0))
(else
(reverse
(let loop ((i 1) (acc-L (list 1 0)))
(if (= i n)
acc-L
(loop (+ i 1) (cons (+ (car acc-L) (cadr acc-L))
acc-L))))))))
(fib-list 7045) -> Some list that overflows my terminal history.
(fib-list 100) ->(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025 20365011074 32951280099 53316291173 86267571272 139583862445 225851433717 365435296162 591286729879 956722026041 1548008755920 2504730781961 4052739537881 6557470319842 10610209857723 17167680177565 27777890035288 44945570212853 72723460248141 117669030460994 190392490709135 308061521170129 498454011879264 806515533049393 1304969544928657 2111485077978050 3416454622906707 5527939700884757 8944394323791464 14472334024676221 23416728348467685 37889062373143906 61305790721611591 99194853094755497 160500643816367088 259695496911122585 420196140727489673 679891637638612258 1100087778366101931 1779979416004714189 2880067194370816120 4660046610375530309 7540113804746346429 12200160415121876738 19740274219868223167 31940434634990099905 51680708854858323072 83621143489848422977 135301852344706746049 218922995834555169026 354224848179261915075)
Should run in N time.

Lisp: How to use loop named, then return-from

This lisp works (SBCL 1.2.15):
(defun roman2 ()
(let ((x nil))
(loop
(cond
((null x) (format t "Enter number:") (setf x (read)))
((> x 39) (format t "too big~%") (setf x nil))
((> x 9) (prin1 'x) (setf x (- x 10)) )
((= x 9) (prin1 'ix) (setf x 0) )
((> x 4) (prin1 'v) (setf x (- x 5)) )
((= x 4) (prin1 'iv) (setf x 0) )
((> x 0) (prin1 'i) (setf x (1- x)) )
((zerop x) (setf x nil) (terpri))
((< x 0) (format t "Bye.") (return))))))
and this doesn't
(defun roman2 ()
(let ((x nil))
(loop named rlp
(cond
((null x) (format t "Enter number:") (setf x (read)))
((> x 39) (format t "too big~%") (setf x nil))
((> x 9) (prin1 'x) (setf x (- x 10)) )
((= x 9) (prin1 'ix) (setf x 0) )
((> x 4) (prin1 'v) (setf x (- x 5)) )
((= x 4) (prin1 'iv) (setf x 0) )
((> x 0) (prin1 'i) (setf x (1- x)) )
((zerop x) (setf x nil) (terpri))
((< x 0) (format t "Bye.") (return-from rlp))))))
with error
caught ERROR:
; during macroexpansion of (LOOP NAMED RLP ...). Use *BREAK-ON-SIGNALS* to
; intercept.
I'm not sure what I've done wrong. It seems like if I've named my loop, I can break out with (return-from rlp)
There are two forms of loop. The first is simply (loop forms...),which is the first one you had. The second is much more complex and uses a sophisticated language built with loop keywords to describe a loop. Once you are using named you're in the latter. Try (loop named name do (cond ...)).

DrRacket and Recursive Statement Binary to Decimal

I am trying to convert a binary number entered as "1010" for 10 using recursion. I can't seem to wrap my head around the syntax for getting this to work.
(define (mod N M)
(modulo N M))
(define (binaryToDecimal b)
(let ([s 0])
(helper b s)))
(define (helper b s)
(if (= b 0)
(begin (+ s 0))
(begin (* + (mod b 2) (expt 2 s) helper((/ b 10) + s 1)))))
Thanks!
Here's a simple recursive solution:
(define (bin->dec n)
(if (zero? n)
n
(+ (modulo n 10) (* 2 (bin->dec (quotient n 10))))))
testing:
> (bin->dec 1010)
10
> (bin->dec 101)
5
> (bin->dec 10000)
16
If you want "1010" to translate to 10 (or #b1010, #o12 or #xa) you implement string->number
(define (string->number str radix)
(let loop ((acc 0) (n (string->list str)))
(if (null? n)
acc
(loop (+ (* acc radix)
(let ((a (car n)))
(- (char->integer a)
(cond ((char<=? a #\9) 48) ; [#\0-#\9] => [0-9]
((char<? a #\a) 55) ; [#\A-#\Z] => [10-36]
(else 87))))) ; [#\a-#\z] => [10-36]
(cdr n)))))
(eqv? #xAAF (string->number "aAf" 16)) ; ==> #t
It processes the highest number first and everytime a new digit is processed it multiplies the accumulated value with radix and add the new "ones" until there are not more chars. If you enter "1010" and 2 the accumulated value from beginning to end is 0, 0*2+1, 1*2+0, 2*2+1, 5*2+0 which eventually would make sure the digits numbered from right to left 0..n becomes Sum(vn*radic^n)
Now, if you need a procedure that only does base 2, then make a wrapper:
(define (binstr->number n)
(string->number n 2))
(eqv? (binstr->number "1010") #b1010) ; ==> #t

Resources