Files
2025-10-16 16:03:00 +02:00

24 lines
2.5 KiB
XML

= Task 1
== c)
Procedural abstractions are useful because useful stuff usually involves I/O, which is a side effect, and thus impure. Procedures allow for side effects and often buils upon pure functions to allow structuring and reuse in programming.
== d)
A procedure in oz has side effects, and functions do not. This means that if you have the same input to a function in oz, it will always return the same output. This is however not guaranteed for procedures.
= Task 3
== b)
If the List is empty it returns the neutral value for the operator, which in the case of plus is 1 and multiplication is 1. Since $a + 0 = a$ and $a times 1 = a$. This also allows the function to return without further recursion and complete execution. If the list is non-empty, it takes the runs the anonymous function Op on the values of the head of the list and the result of the fold function on the list without the first element. If this list now ends up empty it would return the neutral value and the result computed.
== e)
It would be 1 since $a times 1 = a$
= Task 4
== b)
It starts at a certain number, and then it produces a list with the head set to the value and tail to an anonymous function which takes the previous value and adds one to it. This means that by calling the value of the tail n times and getting the value of the head at that point you get the result of starting value plus n
= Task 6
= a)
I simply need to use an accumulator and a wrapper function that sets the accumulator to 0.
= b)
The benefit is that the code can be optimized for a constant stack size for the duration of the function. If it is not tail call and optimized for that in the compiler, many recursive calls will lead to a rapidly growing stack which can lead to stack overflow since the stack size is usually pretty limited. The compiler essentially has to recognize when it does not need to make a new stack frame.
= c)
It is usually dependent on the compiler and not the language itself, but one example is Java which does not have tail call optimization. This does not mean that it is not possible in Java, but that you are expected to just use loops and an imperative style of programming to avoid the growing stack from recursion. It is usually a matter of programming paradigms, where the functional or declarative programming languages often depend on tail call optimization since the language is designed around functions and recursion, and procedural or imperative programming languages expect you to solve things with procedures and loops instead which does not lead to excessive nested function calling.