Tail-Recursive Power Function in Scheme - function

I am having trouble writing a tail-recursive power function in scheme. I want to write the function using a helper function. I know that I need to have a parameter to hold an accumulated value, but I am stuck after that. My code is as follows.
(define (pow-tr a b)
(define (pow-tr-h result)
(if (= b 0)
result
pow-tr a (- b 1))(* result a)) pow-tr-h 1)
I edited my code, and now it works. It is as follows:
(define (pow-tr2 a b)
(define (pow-tr2-h a b result)
(if (= 0 b)
result
(pow-tr2-h a (- b 1) (* result a))))
(pow-tr2-h a b 1))
Can someone explain to me why the helper function should have the same parameters as the main function. I am having a hard time trying to think of why this is necessary.

It's not correct to state that "the helper function should have the same parameters as the main function". You only need to pass the parameters that are going to change in each iteration - in the example, the exponent and the accumulated result. For instance, this will work fine without passing the base as a parameter:
(define (pow-tr2 a b)
(define (pow-tr2-h b result)
(if (= b 0)
result
(pow-tr2-h (- b 1) (* result a))))
(pow-tr2-h b 1))
It works because the inner, helper procedure can "see" the a parameter defined in the outer, main procedure. And because the base is never going to change, we don't have to pass it around. To read more about this, take a look at the section titled "Internal definitions and block structure" in the wonderful SICP book.
Now that you're using helper procedures, it'd be a good idea to start using named let, a very handy syntax for writing helpers without explicitly coding an inner procedure. The above code is equivalent to this:
(define (pow-tr2 a b)
(let pow-tr2-h [(b b) (result 1)]
(if (= b 0)
result
(pow-tr2-h (- b 1) (* result a)))))

Even though it has the same name, it's not the same parameter. If you dug into what the interpreter is doing you'll see "a" defined twice. Once for the local scope, but it still remembers the "a" on the outer scope. When the interpreter invokes a function it tries to bind the values of the arguments to the formal parameters.
The reason that you pass the values through rather mutating state like you would likely do in an algol family language is that by not mutating state you can use a substitution model to reason about the behaviour of procedures. That same procedure called at anytime with arguments will yeild the same result as it is called from anywhere else with the same arguments.
In a purely functional style values never change, rather you keep calling the function with new values. The compiler should be able to write code in a tight loop that updates the values in place on the stack (tail call elimination). This way you can worry more about the correctness of the algorithm rather than acting as a human compiler, which truth be told is a very inefficient machine-task pairing.

(define (power a b)
(if (zero? b)
1
(* a (power a (- b 1)))))
(display (power 3.5 3))

Related

racket - how to use the elements of a list as a procedure (function)

I have a list that contains the "names" of some functions (for example '(+ - *))
I want to use that list to call the functions
(define list_of_names_of_functions '(+ - *))
(define sum (car list_of_names_of_functions))
(sum 2 3)
However, sum is a list, so can't be used as a procedure.
How should i do it?
The variable list_of_names_of_functions has symbol representation and not the actual function. you should perhaps make an alist with name and function like this:
(define ops `((+ . ,+) (- . ,-) (* . ,*)))
If you evaluate ops you'll see something like:
((+ . #<procedure:+>)
(- . #<procedure:->)
(* . #<procedure:*>))
There is no standard on how a function/procedure object should be represented, but it is expected that that value can be applied as any other function:
((cdar ops) 1 2) ; ==> 3
Thus you can search for + using:
(assq '+ ops)
; ==> (+ . #<procedure:+>)
(assq '/ ops)
; ==> #f
Thus if the result is truthy the cdr will contain a procedure:
(apply (cdr (assq '+ ops)) '(1 2)) ; ==> 3
If you are making a special kid of eval then you would consider the list an environment and it can easily be added to such that you can add /. You can also supply anything callable so an op doesn't need to exist in the host system. eg. `(square . ,(lambda (v) (* v v)) works as well.
Consider using the naming convention of Scheme (and Lisp). Eg. instead of list_of_names_of_functions it should be named list-of-names-of-functions
The simple and immediate fix is to use (define list_of_functions (list+ - *)), then with (define sum (car list_of_functions)) it will work.
(edit:) This happens because list is a function which evaluates its argument(s) and returns the results in a list. Whereas quote (or ' in front of an expression) prevents its argument from being evaluated.
'(A B ...) is equivalent to (quote (A B ...)); that (A B ...) thing is a list of symbols, and quote preserves it as such.
It is a list of symbols because this is how Lisp code is read, either from a source file or from the REPL, i.e. at the interpreter's prompt. Other languages have their code as strings in a source code file, and compiler is some external magic which lives and works completely outside of the language. In Lisp-like languages, code is data. Code is read from textual source code file as (i.e. strings are turned into) nested lists of symbols, and explicit eval, as well as implicit evaluation, is deep inside the language itself.
Thus what you had is equivalent to the list
(define list_of_names (list '+ '- '*))
which contains unevaluated symbols, as opposed to the list
(define list_of_functions (list + - *))
which contains their values, which happen to be the usual built-in functions denoted by those "names".
And we can call a function, but we can't call a symbol (not in Scheme anyway).
As I mentioned in a comment, using eval is not the right answer to this: it 'works' but it opens the way to horrors.
If you have a symbol like + and you want to get its dynamic value then the Racket approach to doing this is to use namespaces. A namespace is really a machine which turns symbols into values in the same way that eval does, but that's all it does, unlike eval. Unfortunately I don't understand namespaces very well, but this will work:
(define-namespace-anchor nsa)
(define ns (namespace-anchor->namespace nsa))
(define (module-symbol-value s (in ns))
(namespace-variable-value s #t #f in))
Then
(define function-names '(+ - / *))
(define sum (module-symbol-value (first function-names)))
And now
> (sum 1 2 3)
6
> (eq? sum +)
#t
>
The problem with this approach is that it's leaky: if you have something like this:
(module msv racket
(provide module-symbol-value)
(define-namespace-anchor nsa)
(define ns (namespace-anchor->namespace nsa))
(define secret "secret")
(define (module-symbol-value s (in ns))
(namespace-variable-value s #t #f in)))
(require 'msv)
(define oops (module-symbol-value 'secret))
Now oops is secret. A way around this is to use make-base-namespace to get a namespace which is equivalent to racket/base.
I have just found the answer, sorry.
Solution will be to use the "eval" function
(define list_of_names_of_functions '(+ - *))
(define sum (car list_of_names_of_functions))
((eval sum) 2 3)

Is there an ignore function in Racket?

In other words, does there exist a function f such that f x does not evaluate x and just returns void? I tried to implement something similar by using (define (ignore x) (if true void x)) but it still evaluates x.
You can also use
(when #f x)
which does not require a macro definition. This has the advantage that someone reading your code does not have to look at the definition of your macro.
Racket has the #; reader macro to comment out expressions; consider whether this might make sense. For instance,
> (+ 1 2 #;3 4)
7

Scheme nested lambda function

I am a beginner in Scheme. I found this question in MIT exam 1 for SICP lecture.
What's the value and type for –
((lambda (a) (lambda (b) (+ (sqrt a) (sqrt b)))) 5)
I am having a hard time understanding how this function works. I am really confused about the parameter b. Only 5 is passed as a parameter to the outer lambda function, then what value does b take for the inner lambda function?
I tried running this function in mit-scheme but the resulting value gets incremented each time it's run.
You're correct that only the outer lambda form is applied to the argument 5. Then it returns its body with a replaced with 5, so it would return
(lambda (b) (+ (sqrt 5) (sqrt b)))
which is itself a function. This could later be applied to another argument, to produce an actual numeric value.

What is the advantage of a symbol that binds to a value and function at the same time?

In lisp, a symbol can be bound to both a value and a function at the same time.
For example,
Symbol f bound to a function
(defun f(x)
(* 2 x))
Symbol f bound to a value
(setq f 10)
So i write something like this:
(f f)
=> 20
What is the benefit of such a feature?
The symbol can have both a function and a value. The function can be retrieved with SYMBOL-FUNCTION and the value with SYMBOL-VALUE.
This is not the complete view. Common Lisp has (at least) two namespaces, one for functions and one for variables. Global symbols participate in this. But for local functions the symbols are not involved.
So what are the advantages:
no name clashes between identifiers for functions and variables.
Scheme: (define (foo lst) (list lst))
CL: (defun foo (list) (list list))
no runtime checks whether something is really a function
Scheme: (define (foo) (bar))
CL: (defun foo () (bar))
In Scheme it is not clear what BAR is. It could be a number and that would lead to a runtime error when calling FOO.
In CL BAR is either a function or undefined. It can never be anything else. It can for example never be a number. It is not possible to bind a function name to a number, thus this case never needs to be checked at runtime.
It's useful for everyday tasks, but the main reason is because of macros, you'll understand why once you study it.

When would it make sense to pass a function to a function?

Ok, so it is possible to pass a function to another function.
Passing a function to another function in Actionscript 3
This is obviously very powerful, but a more important question is, when would it make sense to do so, as there are performance overheads whenever you call another function?
If you have much actionscript knowledge you probably use one example of this all the time without even noticing.
The addEventListener of the EventDispatcher class actually requires a function be passed into it when it's called:
addEventListener(type:String,
listener:Function, useCapture:Boolean
= false, priority:int = 0, useWeakReference:Boolean = false):void
http://livedocs.adobe.com/flex/3/langref/flash/events/EventDispatcher.html
Passing functions around is used a hell of a lot for callbacks. There are numerous other uses but this highlights one of the more simple scenarios.
The performance overhead is no worse than calling a virtual method in any contemporary OO language.
It makes sense to pass procedures to other procedures when it makes your code smaller. Less code has fewer bugs and is easier to maintain. Here's an example. These are two functions that respectively sum a list of numbers and multiple a list of numbers.
(define sum
(lambda (ls)
(if (null? ls)
0
(+ (car ls) (sum (cdr ls))))))
(define product
(lambda (ls)
(if (null? ls)
1
(* (car ls) (product (cdr ls))))))
They're identical except the operators + and - and the corresponding identity value (0 and 1). We've unfortunately duplicated a lot of code.
We can reduce complexity by abstracting the operator and the identity. The rewritten code looks like this.
(define fold
(lambda (proc id)
(lambda (ls)
(if (null? ls)
id
(proc (car ls) (fold (cdr ls) proc id))))))
(define sum (fold + 0))
(define product (fold * 1))
It's easier now to see the essential difference between sum and product. Also, improvements to the core code only have to be made in one place. Procedural abstraction is a fabulous tool, and it depends on being able to pass procedures to other procedures.
A function that takes a function as its argument is called a higher-order function. Google has a lot of information on these.
Examples of higher-order functions:
function compose(f, g) {
return function(x) {
return f(g(x));
};
}
function map(f, xs) {
var ys = [];
for(var i = 0; i < xs.length; ++i)
ys.push(f(xs[i]));
return ys;
}
With that, you can transform an array with two functions in a row:
var a = ["one", "two", "three"];
var b = map(compose(toUpperCase, reverse), a);
// b is now ["ENO", "OWT", "EERHT"]
1 example is a javascript AJAX call
namespace.class.method(parm1, parm2, callback,onErr);
The method will run asynchrously on the server, and once it is complete it will run the callBack method which is passed
function callback(result) {
$('#myDiv').innerHTML = result;
}
There are a host of other examples, just look at event handling as an example.
Another reason to pass a function to a function is if you want the receiving function to be flexible in the work that it does, for instance I had a recursive function that would process a directory tree, on each directory it would call the supplied function and pass it the current directory. This way I could use the same structure to scan a directory, copy a directory or delete a directory. And the "work" function just had to be complicated enough to process one directory not a tree. This is mostly with procedural programming with OO there are preferred ways to do this, inheritance, delegates, etc.
Another very common example is sorting where you pass a predicate i.e. how to sort e.g.
(sort > list-to-sort)
Here > is the function to apply whilst sorting. This is a very simple example using greater than so your list must be numeric but it could be anything e.g.
(sort (lambda(a b) (> (string-length a) (string-length b))) list-to-sort)
Here a closure is passed that does a greater than comparison on string lengths so assumes the list contains strings.
These types of things just suck in languages without closures or HOFs because of all the object/interface/type nonsense that is required to acheive the same.