I'm new to scheme. When I run the following code
(define lst '(1))
(let ((func1 (lambda lst
(begin (display lst)
lst))))
(begin (display lst)
(func1 lst)))
I got (1)((1))'((1)), which means lst displays as (1) when called in the fourth line, but when send it to the function func1, it becomes ((1)). What exactly happened here?
(lambda Args E) means: bind the variable-length argument list of this function to Args. E.g.
(define f (lambda args `(got ,(length args) arguments)))
(display (f 'foo 'bar 'baz))
will print (got 3 arguments). If you change the lambda expression to
(lambda (lst) (begin (display lst) lst))
;;; ^---^
then the function will print, and return, its single argument.
In a lambda form, when you write this:
(lambda x <body>)
... you're declaring that x is a list of parameters with zero or more elements. On the other hand, this:
(lambda (x) <body>)
... is stating that x is a single parameter. In the question, this code (the begin is unnecessary for the body part in a lambda):
((lambda lst (display lst) lst) '(1))
... will display and return the list of parameters; if we pass '(1) it will evaluate to '((1)): a list with a single element which happens to be a list.
Surely you intended to do this instead:
((lambda (lst) (display lst) lst) '(1))
... which will display and return the single parameter it receives - in case of passing '(1) the above expression will evaluate to '(1), the parameter itself.
Related
I am new to Scheme and I am trying to write a function which return a descending prefix of a list. Can someone explain where am I wrong with my code? I tested it with (prefix (list 3 2 1 5)) and I continuously get this error:
cdr: contract violation
expected: pair?
given: '()
(define (prefix lst)
(define (prefix-helper kur result)
(let((next (car(cdr lst))))
(if (<= (car lst) next) result
((prefix-helper (cdr kur) (cons next result))))))
(prefix-helper lst (car lst)))
There are 4 errors in your code.
You are probably using lst in your helper, which is the same during the whole process, while you probably should be using kur which is the rest of the list at each iteration. Because of this your base condition does not hit on any of the iterations. This is probably the root cause of the error you are seeing.
A list where there is no element that is smaller or equal to the next element you don't check if kur is null?. Doing (cdr kur) when kur is null? signals a contract violation since cdr should always be presented a pair. This is the error you are seeing.
There are parentheses around prefix-helper in the alternative to if. That means that the result of the recursion is assumed to be another function that is then applied. Since result is a list structure it will signal an application: not a procedure if it doesn't fail on other errors first.
You start off the helper with the first element. That means your result becomes a dotted list eg. (1 2 . 3). If this wasn't intended then you should start it with a list with the first element instead of just the element.
Use of 'named let' may help clarify the steps:
(define (prefix lst)
(let loop ((lst lst) ; starting with full list
(pf '())) ; empty prefix list
(cond
[(empty? lst) ; if list over, return prefix list
(reverse pf)]
[(or (empty? pf) ; if just starting or
(< (first lst) (first pf))) ; still descending
(loop (rest lst) ; add element to prefix list and
(cons (first lst) pf))] ; loop again with rest of the list
[else ; if not descending, return prefix list;
(reverse pf)]
)))
I'm trying to define a function in scheme that prints a message when called, followed by a newline. To do this I've attempted to use nested lambda like this:
(define message
(lambda (msg)
(lambda (newL)
(newline)
)
(display msg))
)
However, when I do this, and call the function like:
(message "#f")
it only prints the #f, and does not create a newline. If I reverse the lambda orders in the function and swap the position of the newL and msg lambda's, then it only prints a newline and doesn't display the message!
The function is called in this block of code:
(define (permute upList)
(if (null? upList)
(message "#f")
;permutation code
)
)
The error message received when not using nested lambda's is as follows:
Error: call of non-procedure: #
Call history:
<syntax> (permute (quote ()))
<syntax> (quote ())
<syntax> (##core#quote ())
<eval> (permute (quote ()))
<eval> [permute] (null? upList)
<eval> [permute] (message "#f")
<eval> [message] ((display msg) (newline))
<eval> [message] (display msg)
<eval> [message] (newline) <--
Any help would be appreciated.
In this code, you only create a procedure object, which is then immediately discarded:
(define message
(lambda (msg)
(lambda (newL)
(newline))
(display msg)))
It's like doing:
(define message
(lambda (msg)
1234
(display msg)))
The 1234 here is evaluated, but the value is completely ignored.
If you have a procedure and you want to call it immediately, you have to wrap in an extra set of parentheses (because in Scheme, in general, parens represent application):
(define message
(lambda (msg)
((lambda (newL)
(newline)) #f)
(display msg)))
But, as others have pointed out, there's no need to create a nested lambda in this case. Plus, the procedure ignores its argument anyway, which is why I had to invent an argument to pass; I used #f because that's the typical "don't care" value. You can just do:
(define message
(lambda (msg)
(newline)
(display msg)))
I am going through a practice exam for my programming languages course. One of the problems states:
Define a function named function+ that “adds” two functions together and returns this composition. For example:
((function+ cube double) 3)
should evaluate to 216, assuming reasonable implementations of the functions cube and double.
I am not sure how to approach this problem. I believe you are supposed to use the functionality of lambdas, but I am not entirely sure.
If you need a procedure which allows you two compose to unary procedures (procedure with only 1 parameter), you'll smack yourself in the head after seeing how simple the implementation is
(define (function+ f g)
(λ (x) (f (g x))))
(define (cube x)
(* x x x))
(define (double x)
(+ x x))
((function+ cube double) 3)
;=> 216
Basically if you need to do that you just do (x (y args ...)) so if you need to have a procedure that takes two arguments proc1 and proc2 returns a lambda that takes any number of arguments. You just use apply to give proc1 arguments as a list and pass the result to proc2. It would look something like this:
(define (compose-two proc2 proc1)
(lambda args
...))
The general compose is slightly more complicated as it takes any number of arguments:
#!r6rs
(import (rnrs))
(define my-compose
(let* ((apply-1
(lambda (proc value)
(proc value)))
(gen
(lambda (procs)
(let ((initial (car procs))
(additional (cdr procs)))
(lambda args
(fold-left apply-1
(apply initial args)
additional))))))
(lambda procs
(cond ((null? procs) values)
((null? (cdr procs)) (car procs))
(else (gen (reverse procs)))))))
(define (add1 x) (+ x 1))
((my-compose) 1) ;==> 1
((my-compose +) 1 2 3) ; ==> 6
((my-compose sqrt add1 +) 9 15) ; ==> 5
I want to define a function with a parameter that defines another function with that parameter as the name.
example that dont work:
(DEFUN custom (name op const var)
(DEFUN name (var) (op const var)))
The problem is that name isnt evaluated and so the function that is defined is always called name.
I know that FUNCALL and APPLY can evaluate parameter dynamically, but i don't know how to call FUNCALL DEFUN... correctly.
I don't think you can use nested defuns.
You can either use a defun to return a lambda:
(defun custom (op const)
(lambda (arg) (funcall op const arg)))
and then use fdefinition:
(setf (fdefinition '+42) (custom '+ '42))
or use defmacro:
(defmacro custom (name op const)
(let ((arg (gensym)))
`(defun ,name (,arg)
(,op ,const ,arg))))
(custom +42 + 42)
PS. I think you need to explain why you are trying to do this, then we will be able to explain your options better.
It seems to me you might want to curry a function. Imagine you did this:
(defun curry (op arg1)
(lambda (&rest args) (apply op (cons arg1 args))))
(funcall (curry #'+ 10) 20) ; ==> 30
(mapcar (curry #'+ 10) '(1 2 3 4)) ; ==> (11 12 13 14)
Now defun makes a function in the global namespace always. It's not like in Scheme where it creates a closure. To do the same as defun we use symbol-function and setf:
(defun create-curried (name op arg1)
(setf (symbol-function name)
(lambda (&rest args) (apply op (cons arg1 args)))))
(create-curried '+x #'+ 10) ; ==> function
(+x 20) ; ==> 30
;; since it's a function, it even works with higher order functions
(mapcar create-curried '(+x -x /x *x) (list #'+ #'- #'/ #'*) '(10 10 10 10))
(/x 2) ; ==> 5
Last. With macros you can prettify it.
(defmacro defun-curried (newname oldname arg)
(if (and (symbolp newname) (symbolp oldname))
`(create-curried ',newname (function ,oldname) ,arg)
(error "Newname and Oldname need to be symbols")))
(defun-curried +xx + 20)
(+xx 10) ; ==> 30
oldname is taken from the lexical scope so you may use flet or labels with this but it ends up being global, just like with defun.
The main problem is that DEFUN isn't a function, it's a macro that treats its arguments specially (specifically, it doesn't evaluate "the function name", "the argument list", not "the function body").
You could probably make something work by careful use of (setf (symbol-function ...) ...), something like:
(defun define-custom-function (name op const)
(setf (symbol-function name) (lambda (var) (funcall op const var))))
This binds the function definition of the symbol to an anonymous function that calls your "operator" on your fed-in constant.
* (defun define-custom-function (name op const)
(setf (symbol-function name) (lambda (var) (funcall op const var))))
DEFINE-CUSTOM-FUNCTION
* (define-custom-function 'add3 #'+ 3)
#<CLOSURE (LAMBDA (VAR) :IN DEFINE-CUSTOM-FUNCTION) {1002A4760B}>
* (add3 5)
8
However, unless you absolutely need to define (or re-define) these custom functions dynamically, you are probably better off defining a custom DEFUN-like macro.
I'm working on a function that takes in a list of structures and then using that list of structures produces a function that processes a list of symbols into a number. Each structure is made up of a symbol, that will be in the second list consumed, and a number. This function produced has to turn the list of symbols into a number by assigning each symbol a value based on the previous structures. Using abstract list functions btw.
Example: ((function (list (make-value 'value1 10) (make-value 'value2 20)))
(list 'value1 'value2 'nothing 'value1)) would produced 40.
Heres my code but it only works for specific cases.
(define (function lst)
(lambda (x) (foldr + 0 (map (lambda (x)
(cond
[(equal? x (value-name(first lst)))(value-value (first lst))]
[else (value-value (second lst))]))
(filter (lambda (x) (member? x (map value-name lst)))x)))))
Looks like a homework. Basic shape of your solution is ok. I think the reason you have a problem here is that there is no decomposition in your code so it's easy to get lost in parentheses.
Let's start with your idea of fold-ing with + over list of integers as a last step of computation.
For this subtask you have:
1) a list of (name, value) pairs
2) a list of names
and you need to get a list of values. Write a separate function which does exactly that and use it. Like this
(define (function lst)
(lambda (x) (foldr +
0
(to-values x lst)))
(define (to-values names names-to-values)
(map (lambda (name)
(to-value name names-to-values))))
(define (to-value n ns-to-vs)
...)
Here we map over the names with another little function. It will lookup the n value in ns-to-vs and return it or 0 if there is no one.
There are two approaches for solving the problem with foldr, it'd be interesting to study and understand both of them. The first one, attempted in the question, is to first produce a list with all the values and let foldr take care of adding them. It can be implemented in a simpler way like this:
(define (function lst)
(lambda (x)
(foldr +
0
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x))))
Alternatively: maybe using foldr is overkill, applying + is simpler:
(define (function lst)
(lambda (x)
(apply +
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x))))
In the second approach we take the input list "as is" and let foldr's lambda perform the addition logic. This is more efficient than the first approach using foldr, because there's no need to create an intermediate list - the one generated by map in the first version:
(define (function lst)
(lambda (x)
(foldr (lambda (e a)
(cond ((assoc e lst) => (lambda (p) (+ a (value-value p))))
(else a)))
0
x)))
In both approaches I'm using assoc for finding the element in the list; it's easy to implement as a helper function if you're not allowed to use it or if it doesn't work for the values created with make-value: assoc takes a list of name-value pairs and returns the first pair with the given name. The => syntax of cond passes the pair returned by assoc to a lambda's parameter and executes it.
And because you're using Racket, there's a bit of syntactic sugar that can be used for returning a function from another function, try this equivalent code, for simplicity's sake:
(define ((function lst) x)
(foldr +
0
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x)))
Or this:
(define ((function lst) x)
(foldr (lambda (e a)
(cond ((assoc e lst) => (lambda (p) (+ a (value-value p))))
(else a)))
0
x))
Anyway, the result is as expected:
((function (list (make-value 'value1 10) (make-value 'value2 20)))
(list 'value1 'value2 'nothing 'value1))
=> 40