Racket - Writing a predicate - racket

So I'm slightly confused on an introduction to Racket.
I need to write a function called "extend" that takes an element and a predicate, and "extends" the predicate to include the element. For example:
((extend 1 even?) 1)
#t
((extend 3 even?) 3)
#f
I'm fairly new to the language but I don't understand how to get a function to be used or return as a predicate. Not sure if I'm overthinking it or what.

A function is just a value and extend is just a variable like + and cons that evaluate to a function value. functions can be passed as arguments and you just use whatever name you have given it as if it's a function, by using parentheses, and it just works.
A function returns the value the last expression evaluate to. To get it to be a function it either needs to be a variable that evaluate to a function or a lambda that also evaluate to a function.
(define (double-up fn)
(lambda (value)
(fn (fn value)))) ; see. Just use fn as if it is a procedure
((double-up add1) 4) ; ==> 6
(define add2 (double-up add1))
(add2 4) ; ==> 6
(define error-use (double-up 5)) ; works like a charm
(error-use 4)
; Signals "application: not a procedure"
; since `5` isn't a procedure.
Here is another example which is more similar to your assignment. It takes a number, then returns a function that takes another number and then adds them together. Here I choose to define it locally and then leave it as the last expession so that it becomes the result.
(define (make-add initial-value)
(define (adder new-value)
(+ initial-value new-value))
adder) ; this is the result
((make-add 5) 7) ; ==> 12
A predicate is what we call functions often called in predicate position in conditionals (like if and cond). Thus just a function that either return #t or #f and often bound to variables ending with question mark as a naming convention.

Related

Define a function as argument and passing a number in Racket

I'm trying to define a function as an argument and then passing a number to that function. It should look like this:
> (function-3 sqrt)
1.7320508075688772
I was thinking of just defining function-3 to equal to 3 but it seems like it doesn't work... this is what I have so far:
(define function-3
(λ (x)
(3)))
I don't know if I'm thinking on the right path...but it would be great if someone can just point me in the right direction. Thanks
You’re close—you just want to apply the argument of function-3 to the number 3, like this:
(define function-3
(λ (x)
(x 3)))
More idiomatically, using the shorthand function syntax, it would probably be written like this:
(define (function-3 f)
(f 3))
(The name f is often used instead of x when the value is a function.)
But why?
Functions in Racket (as in its parent language, Scheme) are just ordinary values. Behind all the parentheses, the syntax for function application is actually extremely simple. Here’s an example scheme expression:
(f a b c)
^ ^^^^^
| |
function expression argument expressions
Note that each of these two roles is an expression. Obviously, the arguments can be expressions, not just variables, since you can do things like this:
> (+ 1 (* 2 3))
7
Notably, though, the function itself can be an expression, too. You can have a form that produces a function, and that expression can be used in a function invocation:
> ((λ (x) (* x 2)) 3)
6
So when you call (function-3 sqrt), the sqrt function itself gets passed into the function and bound to the first argument of the function implementation. Therefore, all you need to do is put that argument in function expression position, and it will be invoked like any other function.
You're so close!
(define function-3
(lambda (x)
(x 3)))

How to use `apply-partially`?

I'm trying to use apply-partially in a local context:
((apply-partially '+ 1) `(1))
This give me the following error: eval: Invalid function: (apply-partially (quote +) 1)
similarly:
(let ((addone (apply-partially #'+ 1)))
(addone 2))
Why any of this example doesn't work?
That's because Emacs Lisp has separate namespaces for variables and functions. A function that has been defined using defun can be called by putting its name first in a list and evaluating that, but if you have a function as a value (as returned by apply-partially) you need to use funcall or apply.
The difference between funcall and apply is that funcall just calls the function with the arguments given, while apply treats its last argument as a list that should be appended to the argument list. Thus, your first example needs to be written with apply, since + doesn't work with lists:
(apply (apply-partially '+ 1) `(1))
For your second example, use funcall, since the function argument is not wrapped in a list:
(let ((addone (apply-partially #'+ 1)))
(funcall addone 2))

Still about quote in Lisp

I am a novice in Lisp, learning slowly at spare time... Months ago, I was puzzled by the error report from a Lisp REPL that the following expression does not work:
((if (> 2 1) + -) 1 2)
By looking around then I knew that Lisp is not Scheme...in Lisp, I need to do either:
(funcall (if (> 2 1) '+ '-) 2 1), or
(funcall (if (> 2 1) #'+ #'-) 2 1)
I also took a glimpse of introductary material about lisp-1 and lisp-2, although I was not able to absort the whole stuff there...in any case, I knew that quote prevents evaluation, as an exception to the evaluation rule.
Recently I am reading something about reduce...and then as an exercise, I wanted to write my own version of reduce. Although I managed to get it work (at least it seems working), I realized that I still cannot exactly explain why, in the body of defun, that some places funcall is needed, and at some places not.
The following is myreduce in elisp:
(defun myreduce (fn v lst)
(cond ((null lst) v)
((atom lst) (funcall fn v lst))
(t (funcall fn (car lst) (myreduce fn v (cdr lst))))))
(myreduce '+ 0 '(1 2 3 4))
My questions are about the 3rd and 4th lines:
The 3rd line: why I need funcall? why not just (fn v lst)? My "argument" is that in (fn v lst), fn is the first element in the list, so lisp may be able to use this position information to treat it as a function...but it's not. So certainly I missed something here.
The 4th line in the recursive call of myreduce: what kind of fn be passed to the recursive call to myreduce? '+ or +, or something else?
I guess there should be something very fundamental I am not aware of...I wanted to know, when I call myreduce as shown in the 6th/last line, what is exactly happening afterwards (at least on how the '+ is passed around), and is there a way to trace that in any REPL environment?
Thanks a lot,
/bruin
Common Lisp is a LISP-2 and has two namespaces. One for functions and one for variables. Arguments are bound in the variable namespace so fn does not exist in the function namespace.
(fn arg) ; call what fn is in the function namespace
(funcall fn ...) ; call a function referenced as a variable
'+ is a symbol and funcall and apply will look it up in the global function namespace when it sees it's a symbol instead of a function object. #'+ is an abbreviation for (function +) which resolves the function from the local function namespace. With lots of calls #'+ is faster than '+ since '+ needs a lookup. Both symbol and a function can be passed as fn to myreduce and whatever was passed is the same that gets passed in line 4.
(myreduce '+ 0 '(1 2 3 4)) ; here funcall might lookup what '+ is every time (CLISP does it while SBLC caches it)
(myreduce #'+ 0 '(1 2 3 4)); here funcall will be given a function object looked up in the first call in all consecutive calls
Now if you pass '+ it will be evaluated to + and bound to fn.
In myreduce we pass fn in the recursion and it will be evaluated to + too.
For #'+ it evaluates to the function and bound to fn.
In myreduce we pass fn in the recursion and it will be evaluated to the function object fn was bound to in the variable namespace.
Common Lisp has construct to add to the function namespace. Eg.
(flet ((double (x) (+ x x))) ; make double in the function namespace
(double 10)) ; ==> 20
But you could have written it and used it on the variable namespace:
(let ((double #'(lambda (x) (+ x x)))) ; make double in the variable namespace
(funcall double 10))
Common Lisp has two (actually more than two) namespaces: one for variables and one for functions. This means that one name can mean different things depending on the context: it can be a variable and it can be a function name.
(let ((foo 42)) ; a variable FOO
(flet ((foo (n) (+ n 107))) ; a function FOO
(foo foo))) ; calling function FOO with the value of the variable FOO
Some examples how variables are defined:
(defun foo (n) ...) ; n is a variable
(let ((n 3)) ...) ; n is a variable
(defparameter *n* 41) ; *n* is a variable
So whenever a variable is defined and used, the name is in the variable namespace.
Functions are defined:
(defun foo (n) ...) ; FOO is a function
(flet ((foo (n) ...)) ...) ; FOO is a function
So whenever a function is defined and used, the name is in the function namespace.
Since the function itself is an object, you can have function being a variable value. If you want to call such a value, then you need to use FUNCALL or APPLY.
(let ((plus (function plus)))
(funcall plus 10 11))
Now why are things like they are? ;-)
two namespaces allow us to use names as variables which are already functions.
Example: in a Lisp-1 I can't write:
(defun list-me (list) (list list))
In Common Lisp there is no conflict for above code.
a separate function namespace makes compiled code a bit simpler:
In a call (foo 42) the name FOO can only be undefined or it is a function. Another alternative does not exist. So at runtime we never have to check the function value of FOO for actually being a function object. If FOO has a function value, then it must be a function object. The reason for that: it is not possible in Common Lisp to define a function with something other than a function.
In Scheme you can write:
(let ((list 42))
(list 1 2 3 list))
Above needs to be checked at some point and will result in an error, since LIST is 42, which is not a function.
In Common Lisp above code defines only a variable LIST, but the function LIST is still available.

Simply Scheme Exercises. Chapter 06 True and False

Greets, I'm new to SO so please take care of me.
Exercise 6.1 in Simply Scheme has the expression:
(cond (empty? 3)
(square 7)
(else 9))
My mind says it should evaluate (square 7) and return that. (empty? 3) is evaluated instead (returned the atom — tried it with other atoms and lists, same deal).
I'm confused.
What I know:
Everything in Scheme that is not false is true. If 3 is true and is not empty (#f), why does the cond expression return (empty? 3)?
The first argument to a cond expression is evaluated and where it is true, returns #t, the value defined or #undefined dependent on context. If false, it continues evaluating the cond arguments successively until it does so (or finds no suitable return value) then exits the cond.
What I don't know:
(empty? 3) on its own returns #f. Why does the cond terminate here and not evaluate (square 7)?
Why does the evaluation of (empty? 3) within the cond return the atom, not #t or #f?
I am using SCM with Slib and the additional libraries supplied with Simply Scheme (simply.scm, functions.scm, ttt.scm, match.scm, database.scm) loaded.
The empty? definition in simply.scm is beyond my scheme grasp at this point.
The cond form is like this:
(cond (something-to-check-for-truthiness value-if-truthiness-succeed)
...other checks in the same format as above )
Now if you put your code into this format then.
empty? i.e just the function empty (not its call) fits in place of something-to-check-for-truthiness and a function is always a truth value hence number 3 is returned which is after empty? and fits into value-if-truthiness-succeed slot. So, there is no call to empty?function at all.
That's not quite what cond does.
cond accepts one or more arguments, each argument which must be a list of scheme-expressions.
(cond (#t)) is a valid cond statement.
It evaluates the first expression, and if true, evaluates as many additional s-epressions in that list, and returns the value of the last expression evaluated.
(cond (#t 1 2 3 4 (if (number? 0) "Yeah, sanity!" "It rubs lotion on it's skin"))) is a valid cond statement

What is "Call By Name"?

I'm working on a homework assignment where we are asked to implement an evaluation strategy called "call by name" in a certain language that we developed (using Scheme).
We were given an example in Scala, but I don't understand how "call by name" works and how it is different to "call by need"?
Call-by-need is a memoized version of call-by-name (see wikipedia).
In call-by-name, the argument is evaluated every time it is used, whereas in call-by-need, it is evaluated the first time it is used, and the value recorded so that subsequently it need not be re-evaluated.
Call by name is a a parameter passing scheme where the parameter is evaluated when it is used, not when the function is called. Here's an example in pseudo-C:
int i;
char array[3] = { 0, 1, 2 };
i = 0;
f(a[i]);
int f(int j)
{
int k = j; // k = 0
i = 2; // modify global i
k = j; // The argument expression (a[i]) is re-evaluated, giving 2.
}
The argument expression is lazily evaluated when accessed using the current values of the argument expression.
Add this to the above answers:
Work through the SICP section on Streams. It gives a good explanation of both call-by-name and call-by-need. It also shows how to implement those in Scheme. BTW, if you are looking for a quick solution here is a basic call-by-need implemented in Scheme:
;; Returns a promise to execute a computation. (implements call-by-name)
;; Caches the result (memoization) of the computation on its first evaluation
;; and returns that value on subsequent calls. (implements call-by-need)
(define-syntax delay
(syntax-rules ()
((_ (expr ...))
(let ((proc (lambda () (expr ...)))
(already-evaluated #f)
(result null))
(lambda ()
(if (not already-evaluated)
(begin
(display "computing ...") (newline)
(set! result (proc))
(set! already-evaluated #t)))
result)))))
;; Forces the evaluation of a delayed computation created by 'delay'.
(define (my-force proc) (proc))
A sample run:
> (define lazy (delay (+ 3 4)))
> (force lazy)
computing ... ;; Computes 3 + 4 and memoizes the result.
7
> (my-force lazy)
7 ;; Returns the memoized value.