How do you make a value in Racket such that no other code could ever create a value equal? to that one?
The reason I want this is to signify a placeholder inside various other data structures. For example, suppose that we have a little collection of key-value attributes like this:
'((name . breakfast) (successor . lunch) (predecessor . placeholder))
(define (placeholder? x) (eq? x 'placeholder))
The intent is to signify that breakfast's predecessor is currently unknown, so, temporarily, we put a placeholder in that slot. We'll fill it in with a real predecessor later. The above isn't quite correct, because there's no way to say that breakfast's predecessor really is the symbol 'placeholder. (Similarly for representing special things like "doesn't have one".) Something like this would fix this problem:
(define placeholder (make-unique-value)
(define (placeholder? x) (eq? x placeholder))
`((name . breakfast) (successor . lunch) (predecessor . ,placeholder))
Since placeholder is a special value, you can't inadvertently make another one by just making the symbol 'placeholder. It would be nice if the unique placeholder value wouldn't be equal? to anything; that way, it could also serve as a key in hash tables—or anywhere. The point is that you shouldn't have to worry about "gotchas".
If making a unique value like #t or #f isn't the way to do this in Racket, I'd accept an answer that showed the Rackety way to do it.
The best way to do this in Racket is to create a local, opaque struct and create a single instance of that structure type. Since structs are generative (that is, each evaluation of a struct form produces a completely unique structure type), this value is guaranteed to be unique.
The code to do this usually looks something like this:
(define placeholder
(let ()
(struct placeholder ())
(placeholder)))
This creates a unique, opaque value in placeholder:
> placeholder
#<placeholder>
> (equal? placeholder placeholder)
#t
> (equal? placeholder #t)
#f
With the use of gensym you can create a system of unique values.
For instance:
#lang racket
(define placeholder-unique-prefix "#$##")
(define (new-placeholder)
(gensym placeholder-unique-prefix))
(define (placeholder? x)
(and (symbol? x)
(string-prefix? (symbol->string x) placeholder-unique-prefix)))
(define placeholder1 (new-placeholder))
(define placeholder2 (new-placeholder))
(define cons1 (cons 'a placeholder1))
(define cons2 (cons 'b placeholder2))
(eq? (cdr cons1) placeholder1) => #t
(eq? (cdr cons2) placeholder1) => #f
(placeholder? (cdr cons1)) => #t
(placeholder? (cdr cons2)) => #t
I thought of a way to do it. It's probably workable but it bothers me.
(struct unique [])
(define placeholder (unique))
(define (placeholder? x) (eq? x placeholder))
(define not-applicable (unique))
(define (not-applicable? x) (eq? x not-applicable))
(equal? placeholder not-applicable) ; => #f
Something that bothers me is that the way it works is very subtle. It works by exploiting the fact that the struct definition is missing #:transparent. If you make unique transparent, then each unique is equal? to all others, which means they're not really unique:
(struct unique [] #:transparent)
(define placeholder (unique))
(define not-applicable (unique))
(equal? placeholder not-applicable) ; => #t
If possible, I'd like the meaning and validity of the code to be obvious on inspection.
Related
I'm currently reading through Seibel's "Practical common lisp" and found this example macro:
(defmacro check (&rest forms)
`(progn
,#(loop for f in forms collect `(do-stuff ,f ',f))
(defun test ()
(check ( (= (+ 1 2 ) 3) (= (+ 1 2 ) 4 )))
)
do-stuff simply then format the two args in a certain way allowing for 'testing' the truth of a form, but that's not important for my question.
What I was interested in was to translate the loop into a DO, unfortunately, I'm totally lacking in the necessary skill to do so:
(defmacro check (&rest forms)
`(progn
,#(do ((index 0 (list-length forms))
(accumulator nil))
((= index (list-length forms)) accumulator)
(push `(do-stuff ,(nth index forms) ',(nth index forms)) accumulator)
))
This does the job, I can also do this (put every form into a variable inside the do):
(defmacro check (&rest forms)
`(progn
,#(do* ((index 0 (list-length forms))
(accumulator nil)
(f (nth index forms) (nth index forms)))
((= index (list-length forms)) accumulator)
(push `(do-stuff ,f ',f) accumulator)
))
My problem is the following :
Is there a more efficient way to write this do loop ? Is this a good way to implement it ?
Something in the LOOP version is making me wonder if there is not a simple way to extract an element of a list without the need to define an index variable, or to regroup the COLLECTED elements without the need to define an accumulator list...
If you use do you shouldn't use nth. Just iterate over the list, not the indexes.
(do ((l forms (cdr l))
(accumulator nil))
((null l) (nreverse accumulator))
(let ((f (car l)))
(push `(do-stuff ,f ',f) accumulator)))
You can also use the built-in dolist:
(let ((accumulator nil))
(dolist (f forms (nreverse accumulator))
(push `(do-stuff ,f ',f) accumulator)))
Finally there's mapcar:
(mapcar (lambda (f) `(do-stuff ,f ',f)) forms)
Is there a more efficient way to write this do loop ? Is this a good way to implement it ?
The complexity of your code is quadratic to the size N of the list, since for each item you call nth to access an element inside, resulting in a O(N*N) execution time. There is a more efficient way to do it (the original LOOP version is an example of a linear algorithm).
Here is a different version where instead of calling push followed by nreverse, the items are queued at the end of the list during traversal. I added comments to explain what each part does.
By the way I don't claim that this is more efficient that using nreverse, I think we can't know without testing. Note however that there are as many operations in both cases (cons a new item, and eventually mutate the cdr slot), they are just done either in two passes or one pass.
In fact the code below is very not far from being an implementation of MAPCAR where there is only one list to traverse (not the variadic version in the standard).
First, define a helper function that transforms one form:
(defun expand-check (form)
`(do-stuff ,form ',form))
Recall that you could just (mapcar #'expand-check checks) to have the desired result.
Anyway, here is a DO version:
(defun expand-checks (checks)
;; LIST-HOLDER is just a temporary cons-cell that allows us to treat
;; the rest of the queue operations without having to worry about
;; the corner case of the first item (the invariant is that LAST is
;; always a cons-cell, never NIL). Here LIST-HOLDER is initially
;; (:HANDLE), the first value being discarded later.
(let ((list-holder (list :handle)))
;; DO is sufficient because the iterator values are independant
;; from each other (no need to use DO*).
(do (;; descend the input list
(list checks (cdr list))
;; update LAST so that it is always the last cons cell, this
;; is how we can QUEUE items at the end of the list without
;; traversing it. This queue implementation was first
;; described by Peter Norvig as far as I known.
(last list-holder (cdr last)))
;; End iteration when LIST is empty
((null list)
;; In which case, return the rest of the LIST-HOLDER, which
;; is the start of the list that was built.
(rest list-holder))
;; BODY of the DO, create a new cons-cell at the end of the
;; queue by mutating the LAST const cell.
(setf (cdr last)
(list (expand-check
(first list)))))))
Firstly, anything of the form
(loop for v in <list> collect (f v ...))
Can be easily expressed as mapcar:
(mapcar (lambda (v)
(f v ...))
<list>)
The interesting case is when the loop only collects a value sometimes, or when the iteration is over some more complicated thing.
In that case one nice approach is to factor out the iteration bit and the 'collecting values' bit, using do or whatever to perform the iteration and some other mechanism to collect values.
One such is collecting. So, for instance, you could use dolist to iterate over the list and collecting to collect values. And perhaps we might only want to collect non-nil values or something to make it more interesting:
(collecting
(dolist (v <list>)
(when v
(collect (f v ...)))))
All of these are more verbose than the simple loop case, but for instance collecting can do things which are painful to express with loop.
Sorry if the question's topic is oddly phrased (for lack of better terminology -- also one of the reasons I didn't find anything Googling this specific topic), so here's what I mean with an example.
Let's say this function foobar is defined:
(defun foobar (x)
(declare (type (integer -100 100) x))
(format T "X is ~A~%" x))
So with the declare line, x is an integer that must be -100, 100, or any integer in-between. Thus, doing this yields an error:
CL-USER> (foobar 101)
The value 101 is not of type (INTEGER -100 100).
[Condition of type TYPE-ERROR]
Restarts:
(blah blah blah)
Short of changing the function itself to explicitly do clamping, is there a way to specify an override behavior such that doing this, without altering the defun of foobar itself:
(foobar [any-value-over-100])
Clamps it to 100, and likewise with x < -100, without the function body itself having extra lines of code to do so?
Edit: To answer one responder, this is clamping -- keeping a value strictly within a defined minimum and maximum range. In Lisp, this is an example:
CL-USER> (defun clamp (x min max)
(if (> x max)
max
(if (< x min)
min
x)))
CLAMP
CL-USER> (clamp 5 4 9)
5
CL-USER> (clamp -2 4 9)
4
CL-USER> (clamp 123 4 9)
9
While I can easily just make this a macro and put it in the beginning of any function (and I have an odd feeling this'll ultimately be what I'll have to do), this question is asking whether it's possible to tell the Common Lisp error handler to "just do this with the values instead!", rather than having it interrupting the entire program flow as it normally does.
Type declarations in Common Lisp
Your code:
(defun foobar (x)
(declare (type (integer -100 100) x))
(format T "X is ~A~%" x))
The consequences of call above with something like (foobar 120) are entirely undefined in Common Lisp.
it may be completely ignored
it may lead to errors or various runtime problems
it may help the compiler to create better code (this is btw. the main reason for those declarations)
it may be typed checked at compile / or runtime. Only very few Lisp compilers do it.
Portable runtime type checking in Common Lisp
If you want to portably check for runtime type errors use CHECK-TYPE or ASSERT.
(defun foobar (x)
(check-type x (integer -100 100))
(format T "X is ~A~%" x))
Advising
Extending functions without changing their source code is called 'advising' in Lisp. This is not in the Common Lisp standard for normal functions, but there should be tools for it and it is not that difficult to write such a thing.
Extending Generic Functions
Common Lisp has this mechanism built-in for generic functions. The standard method combination has :before, :after and :around advising.
(defmethod foobar ((x integer))
(check-type x (integer -100 100))
(format T "X is ~A~%" x))
In Common Lisp one cannot dispatch on arbitrary types - only on classes. There are classes for basic types like string, integer, ... Here we use that x is an integer.
If you want to clamp foobar's x:
(defmethod foobar :around ((x integer))
(call-next-method (clamp x -200 100)))
Above is an :around method. I calls the next method, the one above, with a changed argument. This is allowed as long as the argument class does not change the dispatch.
Alternative approach: Macro
One goal might be to write less code and have code more declarative.
Maybe one wants to write:
(defun-clamped foobar ((x (integer :min -100 :clampled-max 100)))
(format T "X is ~A~%" x))
Then I would just write the defun-clamped macro, which expands into a normal DEFUN, which does the necessary things.
Ignore Declarations
If you compile the function with the appropriate settings, the type declaration will be ignored.
Redefine Function
Alternatively, you can redefine your function like this:
(defparameter *foobar-orig* (fdefinition *foobar*))
(defun foobar (x)
(funcall *foobar-orig* (whatever-you-want x)))
Use restarts
Your best way forward is to replace declarations with check-type and establish appropriate handlers, e.g.,
(handler-bind ((type-error
(lambda (c)
(let ((et (type-error-expected-type c)))
(store-value (clamp (type-error-datum c) (second et) (third et)))))))
(let ((x 100))
(check-type x (integer 1 10))
(print x)))
The standard does not provide for global error handlers, but implementations usually do.
If I understand you correctly you want to ensure the integer to be in that range, if that is the case I don't think you should handle it with type error, but a (let ...) something like this:
(defun ensure-range (x low high)
(cond ((< x low) low)
((> x high) high)
(t x)))
(defun foobar (x)
(let (x (ensure-range x -100 100))
(format T "X is ~A~%" x)))
Don't declare x to be between -100 and 100 if you can accept something else. I think that an implementation might be free to allow any kinds of memory corruption if a declaration is violated.
So, doing
(declare (optimize (safety 0)))
to avoid the declaration throwing an error is not really a good idea.
You can first clamp the value and then put the rest of the function definition into a LET form.
(defun foo (x)
(declare (type integer x))
(let ((x (clamp x -100 100)))
(declare (type (integer -100 100) ; LET allows declarations, too!
x))
(bar x)))
If you want a macro to do this for you, something like the following should work:
(defmacro defclamp (name (arg min max)
&body body)
`(defun ,name (,arg)
(declare (type real ,arg))
(let ((,arg (clamp ,arg ,min ,max)))
(declare (type (real ,min ,max)
,arg))
,#body)))
I want to iterate over a list, perform an action with the elements and based on some criteria, I want to get rid of the active element. However, when using the function below I end up in an infinite loop.
(defun foo (list action test)
(do ((elt (car list) (car list)))
((null list))
(funcall action elt)
(when (funcall test elt)
(delete elt list))))
(setq list '(1 2 3 4))
(foo list #'pprint #'oddp)
-> infinite loop
Is it not possible as it points to itself? In the end, elt is (car list) of course.
Is this a correct assessment? And how could I solve this efficiently?
The loop is infinite since you are not iterating over anything, you apply the action repeatedly, but if it doesn't mutate the element, as pprint obviously doesn't, then if the test result is negative then it will remain so and the list wouldn't empty even if the deletion worked as you attempt it.
DELETE is a destructive function. In Common Lisp destructive operations are allowed to destroy their argument. You are supposed to discard any references to the argument and use only the return value. After the operation is completed there are no guarantees about the state of the argument. In particular, there might be no effect as implementations are also allowed to act identically to a non-destructive counterpart, but usually the component parts of the sequence will be reassembled in some difficult to predict way. You are also destroying a literal in your example, which has undefined behaviour and it should be avoided.
It is generally best to treat lists in Common Lisp as immutable and destructive operations as a microoptization which should only be used when you are sure they won't break anything. For this problem you might want to iterate over the list using LOOP assembling the result list with conditional COLLECT. See the LOOP chapter of PCL.
Actually you can alter the state of your list while iterating over it. You will just have to use rplacd in addition to delete, and control the advancement along the list not in the iteration clause, but inside the do body:
(defun nfoo (lst action test)
(do* ((list (cons 1 lst))
(elt (cadr list) (cadr list)))
((null (cdr list))
(if (funcall test (car lst)) (cdr lst) lst))
(funcall action elt)
(if (funcall test elt)
(rplacd list (delete elt (cddr list)))
(setf list (cdr list)))))
You should call it via copy-list if you don't want it to destroy the argument list.
If you want to remove from your list not all elements equal to elt that passed the test, but rather all such that will pass the test, then the delete call will need to be passed the test function as the :test argument.
(edit:) and even much simpler and straightforward, like this (non-destructive) version:
(defun foo (list action test)
(do* ((elt (car list) (car list)))
((null list))
(funcall action elt)
(if (funcall test elt)
(setf list (delete elt list))
(setf list (cdr list)))))
I'm a bit new to lisp, so perhaps I'm missing something in your question. Still, I think I understand what you're asking, and I wonder why you're not using some existing structures for this... namely remove-if-not (or remove-if if I have things backwards) and mapcar...
(mapcar #'pprint (remove-if-not #'oddp '(1 2 3 4))
The above prints 1 and 3 (and returns (nil nil), but presumably you can ignore that... or you could do a defun that does the above and ends with (values)). (If you wanted the evens, change remove-if-not to remove-if.)
This strikes me as perhaps a more sensible way to go about things, unless you're doing this for pedagogical reasons or I'm missing something... either of which I admit is quite possible. :)
P.S. Hyperspec info on remove-if, remove-if-not, etc.
I'm trying to read this code:
(define list-iter
(lambda (a-list)
(define iter
(lambda ()
(call-with-current-continuation control-state)))
(define control-state
(lambda (return)
(for-each
(lambda (element)
(set! return (call-with-current-continuation
(lambda (resume-here)
(set! control-state resume-here)
(return element)))))
a-list)
(return 'list-ended)))
iter))
Can anyone explain how call-with-current-continuation works in this example?
Thanks
The essence of call-with-concurrent-continuation, or call/cc for short, is the ability to grab checkpoints, or continuations, during the execution of a program. Then, you can go back to those checkpoints by applying them like functions.
Here's a simple example where the continuation isn't used:
> (call/cc (lambda (k) (+ 2 3)))
5
If you don't use the continuation, it's hard to tell the difference. Here's a few where we actually use it:
> (call/cc (lambda (k) (+ 2 (k 3))))
3
> (+ 4 (call/cc (lambda (k) (+ 2 3))))
9
> (+ 4 (call/cc (lambda (k) (+ 2 (k 3)))))
7
When the continuation is invoked, control flow jumps back to where the continuation was grabbed by call/cc. Think of the call/cc expression as a hole that gets filled by whatever gets passed to k.
list-iter is a substantially more complex use of call/cc, and might be a difficult place to begin using it. First, here's an example usage:
> (define i (list-iter '(a b c)))
> (i)
a
> (i)
b
> (i)
c
> (i)
list-ended
> (i)
list-ended
Here's a sketch of what's happening:
list-iter returns a procedure of no arguments i.
When i is invoked, we grab a continuation immediately and pass it to control-state. When that continuation, bound to return, is invoked, we'll immediately return to whoever invoked i.
For each element in the list, we grab a new continuation and overwrite the definition of control-state with that new continuation, meaning that we'll resume from there the next time step 2 comes along.
After setting up control-state for the next time through, we pass the current element of the list back to the return continuation, yielding an element of the list.
When i is invoked again, repeat from step 2 until the for-each has done its work for the whole list.
Invoke the return continuation with 'list-ended. Since control-state isn't updated, it will keep returning 'list-ended every time i is invoked.
As I said, this is a fairly complex use of call/cc, but I hope this is enough to get through this example. For a gentler introduction to continuations, I'd recommend picking up The Seasoned Schemer.
Basically it takes a function f as its parameter, and applies f to the current context/state of the program.
From wikipedia:
(define (f return)
(return 2)
3)
(display (f (lambda (x) x))) ; displays 3
(display (call-with-current-continuation f)) ; displays 2
So basically when f is called without current-continuation (cc), the function is applied to 2, and then returns 3. When using current-continuation, the parameter is applied to 2, which forces the program to jump to the point where the current-continuation was called, and thus returns 2. It can be used to generate returns, or to suspend execution flow.
If you know C, think about it like this: in C, you can take a pointer to a function. You also have a return mechanism. Suppose the return took a parameter of the same type the function takes. Suppose you could take its address and store that address in a variable or pass it as a parameter, and allow functions to return for you. It can be used to mimic throw/catch, or as a mechanism for coroutines.
This is essentially:
(define (consume)
(write (call/cc control)))
(define (control ret)
(set! ret (call/cc (lambda (resume)
(set! control resume)
(ret 1))))
(set! ret (call/cc (lambda (resume)
(set! control resume)
(ret 2))))
(set! ret (call/cc (lambda (resume)
(set! control resume)
(ret 3)))))
(consume)
(consume)
(consume)
Hope it is easier to understand.
I received an unexpected result when redefining the + operator in a scheme program using guile. I should point out that this occurred while experimenting to try to understand the language; there's no attempt here to write a useful program.
Here's the code:
(define (f a b) 4)
(define (show)
(display (+ 2 2)) (display ",") (display (f 2 2)) (newline))
(show)
; guile & mit-scheme: "4,4"
(define (+ a b) 5)
(define (f a b) 5)
(show)
; mit-scheme: "5,5"
; guile: "4,5" - this "4" is the unexpected result
(define (show)
(display (+ 2 2)) (display ",") (display (f 2 2)) (newline))
(show)
; guile & mit-scheme: "5,5"
In guile the function show uses the predefined definition of + even after I've redefined it, though it uses the new definition of f. I have to redefine show to get it to recognise the new definition of +. In mit-scheme both new definitions are recognised immediately, which is what I was expecting to happen. Also, any further definitions of + are instantly recognised by both interpreters without having to redefine show.
What's going on behind the scenes in guile to make it bind references to these redefined operators differently?
And why the difference between the two interpreters?
It looks like Guile is wrongly assuming that nobody is crazy enough to redefine + and is making the optimization of folding (+ 2 2) => 4, making (display (+ 2 2)) become (display 4). That would explain why you need to redefine show in order to reflect your new +.
Indeed, if you first do (define (+ a b) 4) at the very top of your program, Guile will not do that optimization and you will get 4,4 and 5,5 just like MIT Scheme.
Edit: Actually, it looks like Guile will optimize + to reference its own native + construct, meaning that even if you don't use constants (no constant folding) you will still be unable to redefine + like that.