Break loop and return in Racket Scheme - function

I'm trying to find the first missing key in a hash table, that should contain keys [1 ... N], using Scheme.
So far, I have the following code:
(define (find-missing n ht)
(define c 1)
(let forVertices ()
(cond (not (hash-has-key? ht c))
(c)
)
(set! c (+ c 1))
(when (>= n c) (forVertices))
)
)
When I execute the function to test it, nothing is returned. What am I doing wrong?

You have a couple of problems with the parentheses, and the else case is missing. This should fix the mistakes:
(define (find-missing n ht)
(define c 1)
(let forVertices ()
(cond ((not (hash-has-key? ht c))
c)
(else
(set! c (+ c 1))
(when (>= n c)
(forVertices))))))
… But you should be aware that the way you wrote the procedure is not idiomatic, at all. In general, in Scheme you should avoid mutating state (the set! operation), you can write an equivalent procedure by correctly setting up the recursion and passing the right parameters. Also, it's a good idea to return something whenever the recursion exits (for instance: #f), otherwise your procedure will return #<void> if there are no keys missing. Here, this is what I mean:
(define (find-missing n ht)
(let forVertices ((c 1))
(cond ((> c n) #f)
((not (hash-has-key? ht c)) c)
(else (forVertices (+ c 1))))))

Related

Where is the argument coming from?

You can notice the v in the lambda in the function body, where is the v coming from, what it is based on?
(define (cached-assoc xs n)
(letrec ([memo (make-vector n #f)]
[acc 0]
[f (lambda(x)
(let ([ans (vector-assoc x memo)])
(if ans
(cdr ans)
(let ([new-ans (assoc x xs)])
(begin
(vector-set! memo acc (cons x new-ans))
(set! acc (if (= (+ acc 1)) 0 (+ acc 1)))
new-ans)))))])
(lambda (v) (f v))))
The whole expression is returning a lambda as a result, and in that lambda there's a formal parameter named v. It doesn't have a value yet, you'll need to call the lambda to bind a value to v and produce a result (assuming the code is working):
((letrec ([memo (make-vector n #f)] ; notice the extra opening `(`, we want to call the returned lambda
[acc 0]
[f (lambda(x)
(let ([ans (vector-assoc x memo)])
(if ans
(cdr ans)
(let ([new-ans (assoc x xs)])
(begin
(vector-set! memo acc (cons x new-ans))
(set! acc (if (= (+ acc 1)) 0 (+ acc 1)))
new-ans)))))])
(lambda (v) (f v)))
10) ; <- the value 10 gets bound to `v`
However, your code isn't right. You are referring to variables named n and xs, but they are not defined anywhere and need a value of their own. The procedure vector-assoc doesn't exist. Also, the lambda at the end is redundant, you could simply return f, there's no need to wrap it in an additional lambda. Finally: you should define the whole expression with a name, it'll make it easier to call it.
I won't go into more details because first you need to fix the function and make it work, and is not clear at all what you want to do - but that should be a separate question.

where does racket lambda argument come from?

I asked a similar question before, I just want to make sure I understand the idea, in the -lambda(x)- line 4, what is the x, where it is coming from?
(define (cached-assoc xs n)
(letrec ([memo (make-vector n #f)]
[acc 0]
[f (lambda(x)
(let ([ans (vector-assoc x memo)])
(if ans
(cdr ans)
(let ([new-ans (assoc x xs)])
(begin
(vector-set! memo acc (cons x new-ans))
(set! acc (if (= (+ acc 1)) 0 (+ acc 1)))
new-ans)))))])
f))
Your cached-assoc procedure returns f, a function which has x as an unbound parameter. It doesn’t have a value yet, the value will be whatever you pass to it when you finally invoke it:
((cached-assoc xs n) 10)
In the above example x will be bound to 10, and xs and n will be whatever you defined for them before calling cached-assoc. I believe the source of the confusion is the fact that cached-assoc is returning a lambda, once you understand this it'll be clear.

"Smart" comparison of functions in Racket

I've got a bit exotic situation. I need to compare functions, but rather by their "origin" than by "instances". Here what I actually mean:
(define-values (a b c d) (values #f #f #f #f))
(define (f x)
(let ([g (λ (y) (printf "Please tell ~a this is ~a\n" x y))]
[h (curry printf "Don't tell ~a this is ~a\n" x)])
(if a
(set! b g)
(set! a g))
(if c
(set! d h)
(set! c h))))
(f "me")
(f " me")
(a "possible")
(d "impossible")
(equal? a b) ; <==== Is it possible to compare these guys
(equal? c d) ; <==== to get #t in both cases?
In both cases we get two different "instances" of functions (even with different values captured), but both declared in the same location of the source code. Of course, getting the actual text of the body of those functions will solve the problem, but other answers here on SO tell that this is impossible in Racket. Are there some tricks that can help me?
Edit:
This is not the question on theoretical equivalence of functions. This is completely technical question, much rather on Racket's functions representation in a compiled code. So it can be reformulated, for example, in a following way: can I get the line number of some routine from 'user' code? I suppose this should be feasible because Racket debugger somehow obtains it.
It can be done even without support from racket internals if you control the code that makes the functions. If you keep a counter (or some identifier) that will denote the particular lambda it can wrap different closures in a struct that can have the same identity from macro expansion. Here is a demonstration:
#lang racket
;; makes a procedure object that can have other data connected to it
(struct proc (id obj)
#:property prop:procedure
(struct-field-index obj)
#:methods gen:custom-write
[(define (write-proc x port mode)
(display (format "#<procedure-id-~a>" (proc-id x)) port))])
;; compares the ids of two proc objects if they are proc objects
(define (proc-equal? a b)
(and (proc? a)
(proc? b)
(= (proc-id a) (proc-id b))))
;; extends equal?, candidate to provide
(define (equal*? a b)
(or (proc-equal? a b)
(equal? a b)))
;; the state we keep
(begin-for-syntax
(define unique-proc-id-per-code 0))
;; a macro that changes (lambda* ...) to
;; (proc expansion-id (lambda ...))
(define-syntax (lambda* stx)
(let ((proc-id unique-proc-id-per-code))
(set! unique-proc-id-per-code (add1 unique-proc-id-per-code))
#`(proc #,(datum->syntax stx proc-id) (lambda #,#(datum->syntax stx (cdr (syntax-e stx)))))))
;; test with making a counter
(define counter-from
(lambda* (from)
(lambda* ()
(begin0
from
(set! from (add1 from))))))
;; evaluatin the outer shows it has id 0
counter-from ; ==> #<procedure-id-0>
;; make two counters that both use the inner lambda
(define from10 (counter-from 10))
(define from20 (counter-from 20))
;; both have the same expansion id
from10 ; ==> #<procedure-id-1>
from20 ; ==> #<procedure-id-1>
;; they are not equal?
(equal? from10 from20) ; ==> #f (different object instances of proc)
;; but they are procedure-equal?
(proc-equal? from10 from20) ; ==> #t (same id, thus came from same macroexpansion)
Disclaimer: I'm more a schemer than a racketeer so this could perhaps have been done more elegantly and I have no idea what performance penalties this will give.

Lisp- modifying a local variable inside multiple statements on a function

I'm new to lisp, trying to understand how lisp works, and I don't know how exactly to work with a local variable inside a large function.
here I have a little exc that I send a number to a function and if it is divisible by 3, 5 and 7 I must return a list of (by3by5by7), if only by 7, return (by7) and so on....
here is my code:
(defun checknum(n)
let* (resultt '() ) (
if(not(and(plusp n ) (integerp n))) (cons nil resultt) (progn
(if (zerop (mod n 7)) (cons 'by7 resultt) (cons nil resultt))
(if (zerop (mod n 5)) (cons 'by5 resultt) (cons nil resultt))
(if (zerop (mod n 3)) (cons 'by3 resultt) (cons nil resultt) )) ))
but if i send 21 for ex, I only get nil, instead of (by3by7) I guess the local variable is not affected by my if statements and I don't know how to do it...
(cons x y) creates a new cons cell and disposes of the result. To change the value of a variable you need to use setq, setf, push or the like, for example:
(defun checknum (n)
(let ((resultt nil))
(when (and (plusp n) (integerp n))
(when (zerop (mod n 7)) (push 'by7 resultt))
(when (zerop (mod n 5)) (push 'by5 resultt))
(when (zerop (mod n 3)) (push 'by3 resultt)))
resultt))
or perhaps, more elegantly using an internal function to factor out the repetition:
(defun checknum (n)
(when (and (plusp n) (integerp n))
(labels ((sub (d nsym res)
(if (zerop (mod n d))
(cons nsym res)
res)))
(sub 7 'by7
(sub 5 'by5
(sub 3 'by3 nil)))))
Testing:
CL-USER> (checknum 12)
(BY3)
CL-USER> (checknum 15)
(BY3 BY5)
CL-USER> (checknum 105)
(BY3 BY5 BY7)
CL-USER> (checknum 21)
(BY3 BY7)
Most lisp forms/functions don't modify their arguments. The ones that do will be explicitly documented as doing so. See adjoin and pushnew, for instance, or remove and delete.
To the point of 'trying to understand how lisp works', writing the same function in various different ways helped me a lot, so you might want to think about how you can write your function without modifying a variable at all, and why and when you would want to / not want to use destructive modifications.
Something like the below makes two passes, and will be too slow if there are a large quantity of numbers you need to check, but doesn't destructively modify anything.
(defun checknum (n)
(remove nil
(mapcar #'(lambda (m sym)
(when (zerop (mod n m)) sym))
'(7 5 3)
'(by7 by5 by3))))
The above approach can be written to not require two passes, etc.

Lisp function which adds parentheses in a certain way

I'm trying to write a function which adds parentheses like this: (parens '(a b c d e)) returns (a (b (c (d (e))))). I'm just not seeing the pattern very well. What I have so far just returns a list with parentheses around each element. I can't seem to figure out how to make it look like that.
(DEFUN PARENS (L)
(COND ((NULL L) NIL)
(T (CONS (LIST (CAR L)) (PARENS (CDR L))))))
There are no parenthesis in a list. You're starting with a list of five elements, (a b c d e), and getting back a list of two elements, (a (b (c (d (e))))). The first element is a, and the second is another list, (b (c (d (e)))).
It's very easy to get close to this using reduce:
CL-USER> (reduce 'list '(a b c d e) :from-end t)
(A (B (C (D E))))
You can think of reduce as "injecting" the function list into (a b c d e) to produce
(list a (list b (list c (list d e))))
It's almost what you want. You actually want:
(list a (list b (list c (list d (list e)))))
How would you produce that? You can recurse down the list, and for each sublist (x . ys) you want to return (list x (recurse ys)), with the exception being when ys is (). You don't want to recurse into (), because you don't want a list with two elements, you actually want nothing. So the trick is stop recursing earlier than you typically do with a list. Thus:
(defun parens (l)
(cond
((endp l) '())
((endp (rest l)) l)
((list (first l) (parens (rest l)))))) ; *
CL-USER> (parens '(a b c d e))
(A (B (C (D (E)))))
CL-USER> (parens '(a b))
(A (B))
CL-USER> (parens '(a))
(A)
CL-USER> (parens '())
NIL
*Omitting the t test in the last clause is intentional. If there are no body forms in a cond clause, then the value of the test is returned. Thus (list …) serves both as the test form and the value form.
We can actually clean that up a little bit. The case of ((endp l) '()) could be ((endp l) l) since l is the empty list. But that means that in both the first and second cases, we can return l. We can call (rest '()) in Common Lisp and get back (), so (rest l) will be () when l is something like (e) and when l is (). This means that we can use:
(defun parens (l)
(cond
((endp (rest l)) l)
((list (first l) (parens (rest l))))))
If we just have one test, though, we might as well just use if:
(defun parens (l)
(if (endp (rest l))
l
(list (first l) (parens (rest l)))))
You can actually do it with reduce and some special consideration for the end:
(defun unflatten (list)
(reduce #'list list
:from-end t
:end (1- (length list))
:initial-value (last list)))
Note that last returns a list of the last n (default 1) elements.