How Do For Loops Work In Scheme? - for-loop

I'm having some difficulty understanding how for loops work in scheme. In particular this code runs but I don't know why
(define (bubblesort alist)
;; this is straightforward
(define (swap-pass alist)
(if (eq? (length alist) 1)
alist
(let ((fst (car alist)) (scnd (cadr alist)) (rest (cddr alist)))
(if (> fst scnd)
(cons scnd (swap-pass (cons fst rest)))
(cons fst (swap-pass (cons scnd rest)))))))
; this is mysterious--what does the 'for' in the next line do?
(let for ((times (length alist))
(val alist))
(if (> times 1)
(for (- times 1) (swap-pass val))
(swap-pass val))))
I can't figure out what the (let for (( is supposed to do here, and the for expression in the second to last line is also a bit off putting--I've had the interpreter complain that for only takes a single argument, but here it appears to take two.
Any thoughts on what's going on here?

That's not a for loop, that's a named let. What it does is create a function called for, then call that; the "looping" behavior is caused by recursion in the function. Calling the function loop is more idiomatic, btw. E.g.
(let loop ((times 10))
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))
gets expanded to something like
(letrec ((loop (lambda (times)
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))))
(loop 10))

This isn't actually using a for language feature but just using a variation of let that allows you to easily write recursive functions. See this documentation on let (it's the second form on there).
What's going on is that this let form binds the name it's passed (in this case for) to a procedure with the given argument list (times and val) and calls it with the initial values. Uses of the bound name in the body are recursive calls.
Bottom line: the for isn't significant here. It's just a name. You could rename it to foo and it would still work. Racket does have actual for loops that you can read about here.

Related

User input to a list

I'm trying to take in user input and add it to a list but I have not been able to get it working. I'm still new to scheme and have been browsing around to try to figure it out but I haven't had any luck.
(display "Continue to enter numbers until satisfied then enter e to end")
(newline)
(define (intlist number)
(define number(read-line))
(cond (number? number)
(cons lst (number))
(else
(display lst)
done')))
this is what I have so far. Any help or direction to where I can learn a bit more is appreciated.
Your solution is almost correct, but it doesn't work, because:
Variable lst doesn't exist and with this expression (number), you are calling some undefined function number.
done' is badly written 'done.
Function cons expects element as first argument and other element or list as second argument.
See these examples:
> (cons 1 2)
'(1 . 2)
> (cons 1 '())
'(1)
> (cons 1 (cons 2 (cons 3 '())))
'(1 2 3)
Last example is important here- your function will be recursive and it will return a cons cell in each step. If I will follow your solution, this can be enough:
(define (list-from-user)
(let ((number (read)))
(if (number? number)
(cons number (list-from-user))
'())))
(Note that I used read instead of read-line, because read-line returns string, and let instead of define.)
If you really want to wait for e, you must decide, what happens if user enters something that isn't number and isn't e- maybe just ignore it?
(define (list-from-user)
(let ((user-input (read)))
(cond ((number? user-input) (cons user-input (list-from-user)))
((eq? user-input 'e) '())
(else (list-from-user)))))
Then just add some wrapping function with output:
(define (my-fn)
(begin (display "Continue to enter numbers until satisfied then enter e to end")
(newline)
(list-from-user)))
and call it
> (my-fn)
Note that my function returns list with numbers, instead of some useless 'done, so I can use that function in other functions.
(define (sum-of-list)
(let ((lst (my-fn)))
(format "Sum of given list is ~a." (apply + lst))))
> (sum-of-list)

How to count the number of if-statements in a separate file of code

I am trying to write a scheme program that counts the number of if-statement a file containing code. I know how to read in the file but I don't know how to go about counting the number of if-statements.
This is very hard without actually implementing reducing the language to a more primitive form. As an example, imagine this:
(count-ifs '(let ((if +))
(if 1 2 3)))
; ==> 0
0 is the correct amount as if is a binding shadowing if and Scheme supports shadowing so the result of that expression is 6 and not 2. let can be rewritten such that you can check this instead:
(count-ifs '((lambda (if)
(if 1 2 3))
+))
; ==> 0
It might not look like an improvement, but here you can actually fix it:
(define (count-ifs expr)
(let helper ((expr expr) (count 0))
(if (or (not (list? expr))
(and (eq? (car expr) 'lambda)
(memq 'if (cadr expr))))
count
(foldl helper
(if (eq? (car expr) 'if)
(add1 count)
count)
expr))))
(count-ifs '((lambda (if)
(if 1 2 3))
(if #t + (if if if))))
; ==> 2
Challenge is to expand the macros. You actually need to make a macro expander to rewrite the code such that the only form making bindings would be lambda. This is the same amount of work as making 80% of a Scheme compiler since once you've dumbed it down the rest is easy.
A simple way to do it could be recursion structure like this:
(define (count-ifs exp)
(+ (if-expression? exp 1 0)))
(if (pair? exp)
(+ (count-ifs (car exp)) (count-ifs (cdr exp))))
0)))
But this might overcount.
A more correct way to do it would be to process the code by checking each type of expression you see - and when you enter a lambda you need to add the variables it binds to a shadowed symbols list.

Product of squares of odd elements in list in Scheme

I wanted to write a code in Scheme that writes the square odd elements in list.For example (list 1 2 3 4 5) for this list it should write 225.For this purpose i write this code:
(define (square x)(* x x))
(define (product-of-square-of-odd-elements sequence)
(cond[(odd? (car sequence)) '() (product-of-square-of-odd-elements (cdr sequence))]
[else ((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))
For run i write this (product-of-square-of-odd-elements (list 1 2 3 4 5))
and i get error like this:
car: contract violation
expected: pair?
given: '()
What should i do to make this code to run properly? Thank you for your answers.
First of all, you need to do proper formatting:
(define (square x) (* x x))
(define (product-of-square-of-odd-elements sequence)
(cond
[(odd? (car sequence))
'() (product-of-square-of-odd-elements (cdr sequence))]
[else
((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))
Now there are multiple issues with your code:
You are trying to work recursively on a sequence, but you are missing a termination case: What happens when you pass '() - the empty sequence? This is the source of your error: You cannot access the first element of an empty sequence.
You need to build up your result somehow: Currently you're sending a '() into nirvana in the first branch of your cond and put a value into function call position in the second.
So let's start from scratch:
You process a sequence recursively, so you need to handle two cases:
(define (fn seq)
(if (null? seq)
;; termination case
;; recursive case
))
Let's take the recursive case first: You need to compute the square and multiply it with the rest of the squares (that you'll compute next).
(* (if (odd? (car seq)
(square (car seq))
1)
(fn (cdr seq)))
In the termination case you have no value to square. So you just use the unit value of multiplication: 1
This is not a good solution, as you can transform it into a tail recursive form and use higher order functions to abstract the recursion altogether. But I think that's enough for a start.
With transducers:
(define prod-square-odds
(let ((prod-square-odds
((compose (filtering odd?)
(mapping square)) *)))
(lambda (lst)
(foldl prod-square-odds 1 lst))))
(prod-square-odds '(1 2 3 4 5))
; ==> 225
It uses reusable transducers:
(define (mapping procedure)
(lambda (kons)
(lambda (e acc)
(kons (procedure e) acc))))
(define (filtering predicate?)
(lambda (kons)
(lambda (e acc)
(if (predicate? e)
(kons e acc)
acc))))
You can decompose the problem into, for example:
Skip the even elements
Square each element
take the product of the elements
With this, an implementation is naturally expressed using simpler functions (most of which exist in Scheme) as:
(define product-of-square-of-odd-elements (l)
(reduce * 1 (map square (skip-every-n 1 l))))
and then you implement a helper function or two, like skip-every-n.

Efficiency issue on Guile SCHEME: member and equal?

I am new on SCHEME programming and after some while I succeeded on writing a couple of scripts to deal with long maths formulas.
The issue is that its execution is pretty slow. After profiling I realized that the execution takes about 35% of the time executing the built-in functions equal? and member.
My question is regarding whether there exist more efficient version of those functions or I should re-factor the code in order to remove its calls?
I'm about to re-write the code so I would really appreciate any piece of advice.
Thanks!
EDIT 1:
I add some code for making the question clearer. The following function takes two parameters, a pair (x,y) and a term, x and y are usually variable names(symbols), but they may be a symbol and a number, a list and a symbol, etc. The term is a list such as
(+ w y z (* (- 1) x))
so after the function execution I would get something like
(+ w z)
The code looks like the following:
(define (simp-by-term_eq t_CC t)
(cond
((and (member (list '* (list '- 1) (car t_CC)) (cdr t))
(member (cadr t_CC) (cdr t)))
(delete-1st (cadr t_CC)
(delete-1st (list '* (list '- 1) (car t_CC)) (cdr t)))
)
((and (member (list '* (car t_CC) (list '- 1)) (cdr t))
(member (cadr t_CC) (cdr t)))
(delete-1st (cadr t_CC)
(delete-1st (list '* (car t_CC) (list '- 1)) (cdr t)))
)
(else t)
)
)
There are several conditions like the previous one on the function.
The equal function calls are mainly used into filter callse such as
(filter (lambda (x) (and (not (equal? (list '* (car t_CC) (list '- 1)) x))
(not (equal? (list '* (list '- 1) (car t_CC)) x)))) t)
equal? needs to test every part of list structure so basically it traverses both operands until it has touched all sequences and compared all atomic values. If you need to test if it's the same you can use eq? which only checks that the pair has the same address. Thus it will evaluate to #f even when the list structure look the same. Sometimes that's ok. eqv? is similar to eq? but it also works for numbers and characters (but not strings).
You can use memq that uses eq? instead of equal? and you can use memqv that uses eqv? which also works for numbers and characters.
I'm not that familiar with Guile but if you have performance issues and are using member perhaps you should consider hash tables instead?
It could happen you need to rethink the algorithm you use too if you really need to use equal?, but without specific code it's difficult to be more specific.

Scheme - How do I return a function?

This function is displaying the correct thing, but how do I make the output of this function another function?
;;generate an Caesar Cipher single word encoders
;;INPUT:a number "n"
;;OUTPUT:a function, whose input=a word, output=encoded word
(define encode-n
(lambda (n);;"n" is the distance, eg. n=3: a->d,b->e,...z->c
(lambda (w);;"w" is the word to be encoded
(if (not (equal? (car w) '()))
(display (vtc (modulo (+ (ctv (car w)) n) 26)) ))
(if (not (equal? (cdr w) '()))
((encode-n n)(cdr w)) )
)))
You're already returning a function as output:
(define encode-n
(lambda (n)
(lambda (w) ; <- here, you're returning a function!
(if (not (equal? (car w) '()))
(display (vtc (modulo (+ (ctv (car w)) n) 26))))
(if (not (equal? (cdr w) '()))
((encode-n n)(cdr w))))))
Perhaps a simpler example will make things clearer. Let's define a procedure called adder that returns a function that adds a number n to whatever argument x is passed:
(define adder
(lambda (n)
(lambda (x)
(+ n x))))
The function adder receives a single parameter called n and returns a new lambda (an anonymous function), for example:
(define add-10 (adder 10))
In the above code we created a function called add-10 that, using adder, returns a new function which I named add-10, which in turn will add 10 to its parameter:
(add-10 32)
=> 42
We can obtain the same result without explicitly naming the returned function:
((adder 10) 32)
=> 42
There are other equivalent ways to write adder, maybe this syntax will be easier to understand:
(define (adder n)
(lambda (x)
(+ n x)))
Some interpreters allow an even shorter syntax that does exactly the same thing:
(define ((adder n) x)
(+ n x))
I just demonstrated examples of currying and partial application - two related but different concepts, make sure you understand them and don't let the syntax confound you.

Resources