# Demonstration 1
# Problem 1
(define mystery
(lambda (l)
(cond [(null? l) '()]
[(null? (cdr l)) l]
[else
(cons (cadr l) (cons (car l) (mystery (cddr l))))])))
### 1
+ (mystery '())
---> '()
+ (mystery '(a b))
--->(cons (cadr '(a b) (cons (car '(a b)) (mystery (cddr '(a b))) )) )
--->(cons ('(b) (cons ('(a) (mystery '())))))
--->(cons ('(b) (cons ('(a) '()))))
--->'(b a)
+ (mystery '(a b c d e))
--->(cons (cadr '(a b c d e)) (cons (car '(a b c d e)) (mystery (cddr '(a b c d e))) ))
--->(cons ('(b) (cons ('(a) (mystery '(c d e)) ))))
--->(cons ('(b) (cons ('(a) (cons (cadr '(c d e)) (cons (car '(c d e)) (mystery (cddr '(c d e)) )))))))
--->(cons ('(b) (cons ('(a) (cons ('(d) (cons ('(c) mystery '(e)))))))))
--->(cons ('(b) (cons ('(a) (cons ('(d) (cons ('(c) '(e)))))))))
--->(cons ('(b) (cons ('(a) (cons ('(d) '(c e)))))))
--->(cons ('(b) (cons ('(a) '(d c e)))))
---> (cons ('(b) '(a d c e)))
---> '(b a d c e)
### 2
So the program basically accepts a list as input and outputs a new list with the characters at odd (nth) position interchanged with the characters at their subsequent even ((n+1)th) position.
# Problem 2
### 1
## Call-by-value
(define avg-3
(lambda (x y z)
(/ (+ x (+ y z)) 3)
(avg-3 (+ 1 1) (* 3 8) (/ 1 2))
---> (avg-3 2 24 0.5 )
---> (/ (+ 2 (+ 24 0.5)) 3)
---> (/ (+2 24.5) 3)
---> (/ 26.5 3)
---> 8.8333
### 2
## Call-by-name
(avg-3 (+ 1 1) (* 3 8) (/ 1 2))
---> (/ (+ (+ 1 1) (+ (* 3 8) (/1 2))) 3)
---> (/ (+ 2 (+ 24 0.5)) 3)
---> (/ (+2 24.5) 3)
---> (/ 26.5 3)
---> 8.8333
### 3
a. For (triple (f x)), it is more efficient to use call-by-value as calling by name would mean that the same value would have to be calculated thrice, thereby increasing time complexity and reducing efficiency.
b. Ideally, call-by-value and call-by-reference should return the same value. However, in the case of (triple (f x)), it depends on what the computation (f x) does. If (f x) produces a decimal and rounds it off as an estimation, then the final result for (triple (f x)), might be different for call-by-value and call-by-name.
### 4
If we know that a language is confluent, then the ideal strategy should be call-by-value as it ensures efficiency in terms of time complexity. However, if we ignore efficiency and we know that the same outcome is guaranteed either way, we should go by call-by-name as we are not saving the value of the compution in a different variable, thereby saving memory on the RAM during execution.
Let's consider an example of a scenario where we want to calculate the average timespan for 3 events. The user needs to input the start time and the end time for all 3 events. There are two ways to do this.
(define average-timespan
(lambda (a b c)
(/ (+ a b c) 3)))
If the timespan is simply entered as duration (i.e. call by value e.g. (average-timespan 0.5 4 7)), the function evaluation is fairly simple. However, if a,b & c are entered as difference between values of start time and end time (i.e. call by name e.g. (average-timespan (- 10.5 10) (- 9 5) (- 15 8)), the function evualtion gets complicated in terms of time complexity.
If the language is confluent,and we are ignoring efficiency, it should not make a difference either way.
### 5
(define confluence-test
( lambda (a b)
(while (equal? a b)
(printf ("infinite-loop-test")))
(printf (- a b)))
In this case, we see a difference in evaluation of the function confluence-test when done in call-by-value vs call-by-name. When we directly a & b as direct numbers, it leads to an infinite loop (i.e. if both are equal, for example (confluence-test 8.33 8.33)). However, if we input one of them as a function instead(even if both are equal, for example (confluence-test (/ 25 3) 8.33)), the loop condition isn't satified and we get the value of a-b.
### 6
I do not believe that if a language does not have infinite loops, it is confluent. This is because confluency or lack of it thereof can arise from many different factors, and depends upon the evaluation of conditionals in a certain way. If the input format differs (i.e. decimals vs fractions), then the same program could result in different outputs. These factors may or may not have anything to do with infinite loops.