Racket - Map a function which takes an argument - scheme

I wanna map a function which takes an argument:
(map best-play (cdr tree) true) ;true is the argument I wanna pass
Is it possible?

Yes. You can use a function called curry (or its sibling, curryr), which permits partial application, allowing you to pass in arguments without calling the function to yield a new function.
To understand that, consider this example.
> (define add2 (curry + 2))
> (add2 1)
3
> (add2 2)
4
Effectively, calling curry on + and passing a single argument creates a new function which is equivalent to this:
(lambda (x) (+ 2 x))
The function curryr is similar, but it passes arguments starting from the right, rather than the left. This is useful in functions where order matters.
> (define sub2 (curryr - 2))
> (sub2 4)
2
You can use these functions to perform the mapping you want. If the true argument comes second, then you'd want to use curryr, like this:
(map (curryr best-play true) (cdr tree))

Related

Trying to write a function that returns another function, but Racket says my lambda is not a function definition?

Programming in racket, I am trying to write a function that takes a single integer, and returns a function that increments that integer by another integer. For example:
((incnth 5) 3) --> 8
((incnth 3) -1) --> 2
Unfortunately I don't seem to understand lambda functions still, because my code keeps saying that my lambda is not a function definition. Here is what I wrote.
(define (incnth n)
(lambda (f) (lambda (x) (+ n x))))
You have one more lambda than it's needed. If I understand correctly, the idea is to have a procedure that creates procedures that increment a number with a given number. So you should do this:
(define (incnth n) ; this is a procedure
(lambda (x) (+ n x))) ; that returns a lambda
The returned lambda will "remember" the n value:
(define inc2 (incnth 2))
And the resulting procedure can be used as usual, with the expected results:
(inc2 40)
=> 42
((incnth 5) 3)
=> 8
((incnth 3) -1)
=> 2

application: not a procedure drracket scheme [duplicate]

During the execution of my code I get the following errors in the different Scheme implementations:
Racket:
application: not a procedure;
expected a procedure that can be applied to arguments
given: '(1 2 3)
arguments...:
Ikarus:
Unhandled exception
Condition components:
1. &assertion
2. &who: apply
3. &message: "not a procedure"
4. &irritants: ((1 2 3))
Chicken:
Error: call of non-procedure: (1 2 3)
Gambit:
*** ERROR IN (console)#2.1 -- Operator is not a PROCEDURE
((1 2 3) 4)
MIT Scheme:
;The object (1 2 3) is not applicable.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify a procedure to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
Chez Scheme:
Exception: attempt to apply non-procedure (1 2 3)
Type (debug) to enter the debugger.
Guile:
ERROR: In procedure (1 2 3):
ERROR: Wrong type to apply: (1 2 3)
Chibi:
ERROR in final-resumer: non procedure application: (1 2 3)
Why is it happening
Scheme procedure/function calls look like this:
(operator operand ...)
Both operator and operands can be variables like test, and + that evaluates to different values. For a procedure call to work it has to be a procedure. From the error message it seems likely that test is not a procedure but the list (1 2 3).
All parts of a form can also be expressions so something like ((proc1 4) 5) is valid syntax and it is expected that the call (proc1 4) returns a procedure that is then called with 5 as it's sole argument.
Common mistakes that produces these errors.
Trying to group expressions or create a block
(if (< a b)
((proc1)
(proc2))
#f)
When the predicate/test is true Scheme assumes will try to evaluate both (proc1) and (proc2) then it will call the result of (proc1) because of the parentheses. To create a block in Scheme you use begin:
(if (< a b)
(begin
(proc1)
(proc2))
#f)
In this (proc1) is called just for effect and the result of teh form will be the result of the last expression (proc2).
Shadowing procedures
(define (test list)
(list (cdr list) (car list)))
Here the parameter is called list which makes the procedure list unavailable for the duration of the call. One variable can only be either a procedure or a different value in Scheme and the closest binding is the one that you get in both operator and operand position. This would be a typical mistake made by common-lispers since in CL they can use list as an argument without messing with the function list.
wrapping variables in cond
(define test #t) ; this might be result of a procedure
(cond
((< 5 4) result1)
((test) result2)
(else result3))
While besides the predicate expression (< 5 4) (test) looks correct since it is a value that is checked for thurthness it has more in common with the else term and whould be written like this:
(cond
((< 5 4) result1)
(test result2)
(else result3))
A procedure that should return a procedure doesn't always
Since Scheme doesn't enforce return type your procedure can return a procedure in one situation and a non procedure value in another.
(define (test v)
(if (> v 4)
(lambda (g) (* v g))
'(1 2 3)))
((test 5) 10) ; ==> 50
((test 4) 10) ; ERROR! application: not a procedure
Undefined values like #<void>, #!void, #<undef>, and #<unspecified>
These are usually values returned by mutating forms like set!, set-car!, set-cdr!, define.
(define (test x)
((set! f x) 5))
(test (lambda (x) (* x x)))
The result of this code is undetermined since set! can return any value and I know some scheme implementations like MIT Scheme actually return the bound value or the original value and the result would be 25 or 10, but in many implementations you get a constant value like #<void> and since it is not a procedure you get the same error. Relying on one implementations method of using under specification makes gives you non portable code.
Passing arguments in wrong order
Imagine you have a fucntion like this:
(define (double v f)
(f (f v)))
(double 10 (lambda (v) (* v v))) ; ==> 10000
If you by error swapped the arguments:
(double (lambda (v) (* v v)) 10) ; ERROR: 10 is not a procedure
In higher order functions such as fold and map not passing the arguments in the correct order will produce a similar error.
Trying to apply as in Algol derived languages
In algol languages, like JavaScript and C++, when trying to apply fun with argument arg it looks like:
fun(arg)
This gets interpreted as two separate expressions in Scheme:
fun ; ==> valuates to a procedure object
(arg) ; ==> call arg with no arguments
The correct way to apply fun with arg as argument is:
(fun arg)
Superfluous parentheses
This is the general "catch all" other errors. Code like ((+ 4 5)) will not work in Scheme since each set of parentheses in this expression is a procedure call. You simply cannot add as many as you like and thus you need to keep it (+ 4 5).
Why allow these errors to happen?
Expressions in operator position and allow to call variables as library functions gives expressive powers to the language. These are features you will love having when you have become used to it.
Here is an example of abs:
(define (abs x)
((if (< x 0) - values) x))
This switched between doing (- x) and (values x) (identity that returns its argument) and as you can see it calls the result of an expression. Here is an example of copy-list using cps:
(define (copy-list lst)
(define (helper lst k)
(if (null? lst)
(k '())
(helper (cdr lst)
(lambda (res) (k (cons (car lst) res))))))
(helper lst values))
Notice that k is a variable that we pass a function and that it is called as a function. If we passed anything else than a fucntion there you would get the same error.
Is this unique to Scheme?
Not at all. All languages with one namespace that can pass functions as arguments will have similar challenges. Below is some JavaScript code with similar issues:
function double (f, v) {
return f(f(v));
}
double(v => v * v, 10); // ==> 10000
double(10, v => v * v);
; TypeError: f is not a function
; at double (repl:2:10)
// similar to having extra parentheses
function test (v) {
return v;
}
test(5)(6); // == TypeError: test(...) is not a function
// But it works if it's designed to return a function:
function test2 (v) {
return v2 => v2 + v;
}
test2(5)(6); // ==> 11

Getting elisp to return a function as return value

I'm trying to create a function in elisp that returns another function. I looked at this answer to a similar question (how to return function in elisp) but did not understand the answer (I'm literally just starting learning elisp today, so please excuse my ignorance). I thought a simpler example would help. First, consider a function that test whether a number is divisible by 5:
(defun divisible-by-5 (x)
;; tests whether a number is divsible by 5.
(setq remainder (% x 5))
(if (= remainder 0) 1 0)
)
This works fine:
(divisible-by-5 25)
1
Now suppose I want to create a function that can create more of these kinds of test functions---something like:
(defun divisible-by-z (z)
(lambda (z)
(setq remainder (% x z))
(if (= remainder 0) 1 0))
)
This does not work. E.g.,
(defun divisible-by-3 (divisible-by-z 3))
(divisible-by-3 4)
returns an error. I think even seeing an elisp-idiomatic example of how one would implement this pattern would be helpful.
First, make sure you have lexical-binding enabled. The simplest way to do so is to evaluate (setq lexical-binding t) in your current buffer. More information on the topic can be found here.
Your definition of divisible-by-z is basically correct except that you have a mistype (naming both parameters z; the lambda's parameter should be x). Also, it would be more idiomatic to introduce the binding for remainder with let - setq is generally reserved for mutating bindings that already exist. Here's the result:
(defun divisible-by-z (z)
(lambda (x)
(let ((remainder (% x z)))
(if (= remainder 0) 1 0))))
You can't use defun to create divisible-by-3 in quite the way you've tried - it's expecting the argument list for a new function to be where you have the call to divisible-by-z.
You could either create a global, dynamic binding with
(defvar divisible-by-3 (divisible-by-z 3))
Or a local, lexical binding with
(let ((divisible-by-3 (divisible-by-z 3)))
...)
Either way, you'll then need to use funcall to call the function
(funcall divisible-by-3 9) ; => 1
Of course, you could also skip giving it its own name entirely and simply
(funcall (divisible-by-z 3) 10) ; => 0
funcall is necessary because Emacs Lisp is (basically) a Lisp-2, meaning it can attach both a function and a value to a given symbol. So when you're treating functions as values (returning one from a function or passing one in to a function as a parameter) you essentially have to tell it to look in that value "cell" rather than the usual function cell. If you search for "Lisp-1 vs Lisp-2" you'll find more than you want to know about this.
A possible solution:
(defun divisible-by-3 (x)
(funcall (divisible-by-z 3) x))
Another (perhaps simpler) method is to include x as a variable to be passed to the function:
(defun divisible-by-z (x z) "
Check if x is divisible by z.
If so, return 0.
If not, return the remainder."
(if (% x z) (% x z) 0))
thus:
(divisible-by-z 5 2) --> 1
(divisible-by-z 4 2) --> 0

Unusual way of parameter passing in Scheme

I'm trying to implement a function in scheme that splits the given list with the function that is also given as parameter to function. To exemplify:
(splitby '("a" "b" "cc" "ab" "abc" "a" "b")
(lambda (x y) (= (string-length x) (string-length y))))
should return (("a" "b") ("cc "ab") ("abc") ("a" "b"))
I'm pretty beginner in Scheme so it is really hard to understand how this 'function like' parameter works, and while implementing such a function what should I do?
In Scheme, functions are objects like numbers, strings, etc. So in this case, your example is equivalent to this:
(define (equal-length x y)
(= (string-length x) (string-length y)))
(splitby '("a" "b" "cc" "ab" "abc" "a" "b") equal-length)
The use of the function is to allow the splitting criterion to be customised. In this case, items are in the same group for as long as the given function returns a true value; otherwise a new group is created.
To get started, write a group-equal function, that groups equal elements together:
(define (group-equal lst)
...)
where, for example,
(group-equal '(1 2 2 3 3 3 4))
returns
((1) (2 2) (3 3 3) (4))
If you successfully implement that, then it's identical to your splitby function, except that you use the given function (equal-length, for example) instead of equal? (as group-equal might use).
Firstly, in Scheme, everything is inside parentheses. So If you want to apply the function f to values x and y, you write:
(f x y)
So you simply need to put splitby inside the first set of parens.
Secondly, functions can be passed as values into other functions, just like data is passed.
So if I have a functions:
(define (double x)
(* x 2))
I can write another function which takes double as an argument:
(define (change_result f x)
(f (+ 3 x)))
; (change_result double 6) returns 18
I can also do this the same way, if I use a lambda (anonymous) function:
(change_result (lambda (x) (* 3 x)) 10)

Using "do" in Scheme

What is the difference between CODE SNIPPET 1 and CODE SNIPPET 2?
;CODE SNIPPET 1
(define i 0)
(do ()
((= i 5)) ; Two sets of parentheses
(display i)
(set! i (+ i 1)))
;CODE SNIPPET 2
(define i 0)
(do ()
(= i 5) ; One set of parentheses
(display i)
(set! i (+ i 1)))
The first code snippet produces 01234 and the second produces 5. What is going on? What does the extra set of parentheses do? Also, I have seen [(= i 50)] used instead of ((= i 5)). Is there a distinction? Thanks!
The general structure of a do form is like this:
(do ((<variable1> <init1> <step1>)
...)
(<test> <expression> ...)
<command> ...)
Paraphrasing http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-6.html#node_chap_5, each iteration begins by evaluating <test>, if it evaluates to a true value, <expression>s are evaluated from left to right and the last value is returned as the result of the do form. In your second example = would be evaluated as a boolean meaning true, then i would be evaluated and at last 5 is the return value of the form. In the first case (= i 5) is the test and the do form returns an undefined value. The usual way to write a loop would be more like this:
(do ((i 0 (+ i 1)))
((= i 5) i) ; maybe return the last value of the iteration
(display i))
You don't need an explicit mutation of the loop variable as this is handled by the <step> expression.
In the first case, ((= i 5)) functions as a test for termination. So the do loop is repeated until i = 5.
In the second case, (= i 5) isn't a test. The do loop simply executes the first form, which returns 5.
--
(Per the attached comments) brackets are interchangeable in some dialects of scheme. It is sometimes considered idiomatic to use [] for parameters (i.e. to the parent do).

Resources