Why this continuation application leads to infinite loop - racket

I'm trying to execute the following simple function inside racket repl:
(define (f x)
(let ((cont null))
(println (+ 10 (call/cc (lambda (cc)
(set! cont cc)
10))))
cont))
((f 1) 10)
this call inifinitely prints 20, while i'm expecting it to be printed at most twice (once for (f 1), and once for continuation procedure call)
How can you interpret this behavior?
update
however when assigned to some top-level var it works:
> (define kont (f 1))
;;=> 20
> (kont 12)
;;=> 22
Can't see what's the conceptual difference

Related

How should I implement my own version of curry in Racket? [duplicate]

I have this curry function:
(define curry
(lambda (f) (lambda (a) (lambda (b) (f a b)))))
I think it's like (define curry (f a b)).
my assignment is to write a function consElem2All using curry,which should work like
(((consElem2All cons) 'b) '((1) (2 3) (4)))
>((b 1) (b 2 3) (b 4))
I have wrote this function in a regular way:
(define (consElem2All0 x lst)
(map (lambda (elem) (cons x elem)) lst))
but still don't know how to transform it with curry. Can anyone help me?
thanks in advance
bearzk
You should begin by reading about currying. If you don't understand what curry is about, it may be really hard to use it... In your case, http://www.engr.uconn.edu/~jeffm/Papers/curry.html may be a good start.
One very common and interesting use of currying is with functions like reduce or map (for themselves or their arguments).
Let's define two currying operators!
(define curry2 (lambda (f) (lambda (arg1) (lambda (arg2) (f arg1 arg2)))))
(define curry3 (lambda (f) (lambda (arg1) (lambda (arg2) (lambda (arg3) (f arg1 arg2 arg3))))))
Then a few curried mathematical functions:
(define mult (curry2 *))
(define double (mult 2))
(define add (curry2 +))
(define increment (add 1))
(define decrement (add -1))
And then come the curried reduce/map:
(define creduce (curry3 reduce))
(define cmap (curry2 map))
Using them
First reduce use cases:
(define sum ((creduce +) 0))
(sum '(1 2 3 4)) ; => 10
(define product (creduce * 1))
(product '(1 2 3 4)) ; => 24
And then map use cases:
(define doubles (cmap double))
(doubles '(1 2 3 4)) ; => (2 4 6 8)
(define bump (cmap increment))
(bump '(1 2 3 4)) ; => (2 3 4 5)
I hope that helps you grasp the usefulness of currying...
So your version of curry takes a function with two args, let's say:
(define (cons a b) ...)
and turns that into something you can call like this:
(define my-cons (curry cons))
((my-cons 'a) '(b c)) ; => (cons 'a '(b c)) => '(a b c)
You actually have a function that takes three args. If you had a curry3 that managed 3-ary functions, you could do something like:
(define (consElem2All0 the-conser x lst) ...)
(like you did, but allowing cons-like functions other than cons to be used!)
and then do this:
(define consElem2All (curry3 consElem2All0))
You don't have such a curry3 at hand. So you can either build one, or work around it by "manually" currying the extra variable yourself. Working around it looks something like:
(define (consElem2All0 the-conser)
(lambda (x lst) ...something using the-conser...))
(define (consElem2All the-conser)
(curry (consElem2All0 the-conser)))
Note that there's one other possible use of curry in the map expression itself, implied by you wrapping a lambda around cons to take the element to pass to cons. How could you curry x into cons so that you get a one-argument function that can be used directly to map?...
Perhaps better use a generalized version:
(define (my-curry f)
(lambda args
(cond ((= (length args) 1)
(lambda lst (apply f (cons (car args) lst))))
((>= (length args) 2)
(apply f (cons (car args) (cdr args)))))))
(define (consElem2All0 x lst)
  (map ((curry cons) x) lst))

Common Lisp Execute expression as parameter in macro

So using common lisp, I want to be able to do something of the sorts of:
(defmacro foo (count &rest someExpression)
`(do
((,count 0 (+ ,count 1)))
((= ,count 5) T)
`(eval ,someExpression)
)
)
(foo (print 1) temp)
With the result of it printing 1 5 times. I do not want to simply call (print 1) directly, but by passing the expression through a macro parameter and calling it via the macro. In other words, the macro foo should handle any expression(s) as input and run it. This case does not seem to work.
Edited to clarify an explicit script and intended function.
Starting with your recent version, which is at least a reasonable candidate for a macro unlike the older one:
(defmacro foo (someExpression count-var)
`(do ((,count-var 0 (+ ,count 1)))
((= ,count-var 5) T)
`(eval (,someExpression))))
Well what is the expansion of (foo (print 1) c)?
(foo (print 1) x)
-> (do ((x 0 (+ x 1))) ((= x 5) t)
`(eval (,someexpression)))
Well, that's a disaster: what is that nested backquote doing? Let's just remove it:
(defmacro foo (someExpression count-var)
`(do ((,count-var 0 (+ ,count 1)))
((= ,count-var 5) T)
(eval (,someExpression))))
(foo (print 1) x)
-> (do ((x 0 (+ x 1))) ((= x 5) t)
(eval ((print 1))))
That's less disastrous, but the eval form is entirely bogus. We can make that 'work' by changing it to be at least syntactically legal:
(defmacro foo (someExpression count)
`(do ((,count 0 (+ ,count 1)))
((= ,count 5) T)
(eval ,someExpression)))
And now
(foo (print 1) x)
-> (do ((x 0 (+ x 1))) ((= x 5) t)
(eval (print 1)))
And this will 'work' but it will work purely by coincidence: because (print 1) returns 1 and the value of 1 is 1.
(foo (print 'foo) x)
-> (do ((x 0 (+ x 1))) ((= x 5) t)
(eval (print 'foo)))
and that's a run-time error.
But ... why are you using eval? eval is a terrible, terrible solution to almost any problem you can think of, unless the solution to the problem is called 'code injection attack', and in this case it's not just terrible: it's wrong. So we just remove it.
(defmacro foo (someExpression count)
`(do ((,count 0 (+ ,count 1)))
((= ,count 5) T)
,someExpression))
And now
(foo (print 'foo) x)
-> (do ((x 0 (+ x 1))) ((= x 5) t)
(print 'foo))
Which looks like the code transformation we want. So, finally:
> (foo (print 'foo) x)
foo
foo
foo
foo
foo
t
Which is, finally, fine. And this works:
> (foo (print x) x)
0
1
2
3
4
t
As with yet another edit to the question it probably is more useful to put the variable name first and allow a bunch of expressions:
(defmacro foo (count-var &body forms)
`(do ((,count-var 0 (+ ,count-var 1)))
((= ,count-var 5))
,#forms))
This will now allow multiple expressions in the body. And we could go further: we could allow it to specify the number of iterations and the return value`:
(defmacro foo ((count-var &optional (count 1) (value 'nil)) &body forms)
`(do ((,count-var 0 (1+ ,count-var)))
((= ,count-var ,count) ,value)
,#forms))
And now
> (foo (x 2)
(print x)
(print (* x 2)))
0
0
1
2
nil
Well, the name of this macro is dotimes of course.

Why my transformation of this function into a Racket macro is generating an infinite recursion?

I am trying to understand Racket's macros. For that, I built this function for a specific purpose:
(define (while-less-fun max)
(cond [(< a (- max 1))
(and (begin (set! a (+ a 1)) (print "x") a) (while-less-fun max))]
[(< a max)
(begin (set! a (+ a 1)) (print "x") a)]
[(>= a max)
(begin (set! a (+ a 1)) (print "x") a)]
))
It works as intended on the REPL:
> a
2
> (while-less-fun 7)
"x""x""x""x""x"7
> a
7
I tried to transform the function above in the macro bellow. My goal would be to generate the same results:
(define-syntax while-less
(syntax-rules (do)
[(while-less maximo do begin-exp)
(cond [(< a (- maximo 1))
(and begin-exp (while-less maximo do begin-exp))]
[(< a maximo)
begin-exp]
[(>= a maximo)
begin-exp])]))
The expected result was:
(define a 2)
(while-less 7 do (begin (set! a (+ a 1)) (print "x") a))
(while-less 7 do (begin (set! a (+ a 1)) (print "x") a))
Evaluating the second line would print "x" 5 times and change a to be 7. Also, evaluating the third line would print "x" 1 time and would change a to be 8.
Unfortunately, this generates an infinite recursion which really surprises me.
What did I do wrong? Why did this infinite recursion happen?
I know that you should avoid writing macros when a function is able to solve the problem. But, is my approach the wrong way of trying to accomplish this task?
In the first cond clause, you call "(while-less maximo do begin-exp)" with the same arguments, the entire body of the macro will be expanded again by calling the same "(while-less maximo do begin-exp)", causing the loop.
What you can do is create a generic while for a condition:
(define-syntax while
(syntax-rules (do)
[(while condition do begin-exp)
(let loop ()
(when condition
begin-exp
(loop)))]))
> (define a 2)
> (while (< a 7) do (begin (set! a (+ a 1)) (print "x") a))
"x""x""x""x""x"
> (while (< a 7) do (begin (set! a (+ a 1)) (print "x") a))
>

How do I call another function in lisp;

My program is supposed to convert a given temperature from Fahrenheit to Centigrade or the other way around. It takes in a list containing a number and a letter. The letter is the temperature and the letter is the unit we are in. Then I call the appropriate function either F-to-C or C-to-F. How do I call the functions with the given list that was first checked in my temperature-conversion function. Here is my code.
(defun temperature-conversion (lst)
(cond
((member 'F lst) (F-to-C))
((member 'C lst) (C-to-F))
(t (print "You didn't enter a valid unit for conversion"))
)
)
(defun F-to-C ()
;;(print "hello")
(print (temperature-conversion(lst)))
)
(defun C-to-F ()
(print "goodbye"))
;;(print (temperature-conversion '(900 f)))
(setf data1 '(900 f))
You have infinite recursion: temperature-conversion calls F-to-C which calls temperature-conversion again.
I would do this:
(defun c2f (c) (+ 32 (/ (* 9 c) 5)))
(defun f2c (f) (/ (* 5 (- f 32)) 9))
(defun temperature-conversion (spec)
(ecase (second spec)
(C (c2f (first spec)))
(F (f2c (first spec)))))
(temperature-conversion '(32 f))
==> 0
(temperature-conversion '(100 c))
==> 212
(temperature-conversion '(100))
*** - The value of (SECOND SPEC) must be one of C, F
The value is: NIL
The following restarts are available:
ABORT :R1 Abort main loop
I think this example is generally used to demonstrate how functions are first-class values.
With a little modification to sds's answer, you can have an ECASE statement that selects the appropriate function, which is then used by a surrounding FUNCALL.
(defun temperature-conversion (spec)
(destructuring-bind (temperature unit) spec
(funcall
(ecase unit (C #'c2f) (F #'f2c))
temperature)))
I added a DESTRUCTURING-BIND in case you don't know yet what it is.

Why (apply and '(1 2 3)) doesn't work while (and 1 2 3) works in R5RS? [duplicate]

This question already has answers here:
Using AND with the apply function in Scheme
(9 answers)
Closed 9 years ago.
I tried it in Racket like this
> (apply and '(1 2 3))
. and: bad syntax in: and
> (and 1 2 3)
3
Does anyone have ideas about this?
and is not a function, it's a macro, so you cannot pass it around like a function.
The reason and is a macro, is to enable short-circuiting behaviour. You can make your own non-short-circuiting version:
(define (my-and . items)
(if (null? items) #t
(let loop ((test (car items))
(rest (cdr items)))
(cond ((null? rest) test)
(test (loop (car rest) (cdr rest)))
(else #f)))))
and my-and can be used with apply.
For comparison, here's what the macro (which does do short-circuiting) looks like:
(define-syntax and
(syntax-rules ()
((and) #t)
((and test) test)
((and test rest ...) (if test
(and rest ...)
#f))))
Chris Jester-Young's answer is right, but there's one other point I want to highlight. The standard and operator is a macro which delays the evaluation of its arguments, by (essentially, if not exactly) turning (and a b c) into (if a (if b c #f) #f). This means that if a is false, b and c do not get evaluated.
We also have the option of defining an and-function such that (and-function a b c) evaluates a, b, and c, and returns true when the values are all true. This means that all of a, b, and c get evaluated. and-function has the nice property that you can pass it around as function because it is a function.
There's still one option that seems to be missing: an and-function-delaying-evaluation that returns return if and only if a, b, and c all return true, but that doesn't evaluate, e.g., b and c if a produces false. This can be had, actually, with a function and-funcalling-function that requires its arguments to be a list of functions. For instance:
(define (and-funcalling-function functions)
(or (null? functions)
(and ((car functions))
(and-funcalling-function (cdr functions)))))
(and-funcalling-function
(list (lambda () (even? 2))
(lambda () (odd? 3))))
; => #t
(and-funcalling-function
(list (lambda () (odd? 2))
(lambda () (even? 3)))) ; (even? 3) does not get evaluated
; => #f
Using a macro and this idiom, we can actually implement something with the standard and semantics:
(define-syntax standard-and
(syntax-rules ()
((standard-and form ...)
(and-funcalling-function (list (lambda () form) ...)))))
(macroexpand '(standard-and (odd? 2) (even? 3)))
; =>
; (and-funcalling-function
; (list (lambda () (odd? 2))
; (lambda () (even? 3))))
The lesson to take away from this, of course, is that you can have an and-like function that you can pass around and still get delayed evaluation; you just need to delay evaluation by wrapping things in functions and letting the and-like function call those functions to produce values. (In Scheme, this might be an opportunity to use promises.)