What I have in mind is something like:
(run (long-calculation vars) time-limit)
which returns the result of (long-calculation vars) or nil if time-limit is reached.
If you could find an implementation for the amb operator, then you could do something like this:
(defmacro run (comp time-limit)
`(amb comp
(progn (delay ,time-limit)
nil)))
Be careful not to mistake this with the McCarthy amb operator. amb should evaluate both its arguments in separate threads and pick whichever finishes first. For example, in Haskell, it's described in Data.Unamb.
I would suggest using bordeaux-threads, spawning a thread for the computation, and if it doesn't return by the timer, reaping the thread and returning nil.
Found this lisp code out in the wild that seems to do what you want:
http://www.eurogaran.com/downloads/lisp/limitools/limitime.lsp
I launched 'Clozure Common Lisp Version 1.7-r14925M (DarwinX8664)', pasted the lisp code in that site into the listener (it all compiled), and ran this:
? (with-max-time 1 (print 5))
5
5
? (with-max-time 1 (sleep 2) (print 5))
? (quit)
Hopefully this will help you from having to roll out your own.
Related
Is this a conforming Common Lisp program?
(handler-bind ((condition (let ((x 0))
(lambda (c)
(declare (ignore c))
(print (incf x))))))
(signal 'condition)
(signal 'condition))
The output with SBCL (2.0.5.37) is:
1
1
The output with ABCL/CCL/ECL is:
1
2
Which behavior is defined by the Common Lisp standard?
Epilog
This was a bug in SBCL, it is now fixed.
It's not exactly clear. The spec says:
Executes forms in a dynamic environment where the indicated handler bindings are in effect.
and then says
If an appropriate type is found, the associated handler is run in a dynamic environment where none of these handler bindings are visible (to avoid recursive errors).
If you interpret "run" meaning to call the function, that suggests that the handler expressions are evaluted once, when the bindings are made. This is the CCL/ABCL/ECL/LispWorks implementation, so state is maintained in the closure.
But SBCL appears to have intepreted "run" as meaning "evaluated and called". So a new closure is created each time the handler is run, and state is lost.
I suspect the intent was the first interpretation, since CL has no other "lazy" bindings.
If you change the code in the question to this:
(let ((handler
(let ((x 0))
(lambda (c)
(declare (ignore c))
(print (incf x))))))
(handler-bind ((condition handler))
(signal 'condition)
(signal 'condition)))
then SBCL behaves in the same way as the other implementations. I think this makes it fairly clear that the interpretation taken by the other implementations is the intended one, and it also provides a practical workaround for what, if that interpretation is in fact correct, is a bug in SBCL.
I may be asking for the impossible, but am wondering nonetheless.
Is it possible to obtain an analog of the stack-trace for macros? That is, if one set a break-point inside a certain function, the macro-stack-trace would list all macros (perhaps with their inputs) that were macroexpanded to get to that level in the code.
From what I understand, this is currently impossible, but it may be due to my shallow understanding. Does Allegro or SBCL allow or track this kind of information? It appears that this would be really useful for debugging macros.
Any help or advice is appreciated.
As SBCL is a compiler-only implementation meaning all code is automatically compiled (in contrast to being "interpreted"). Calls to macros are expanded as part of compilation, so the fact that something was a macro call is lost.
(defmacro m (n)
`(/ 10 ,n))
(defun foo (x) (m x))
SBCL:
* (foo 0)
debugger invoked on a DIVISION-BY-ZERO in thread
#<THREAD "main thread" RUNNING {1001E06493}>:
arithmetic error DIVISION-BY-ZERO signalled
Operation was /, operands (10 0).
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(SB-KERNEL::INTEGER-/-INTEGER 10 0)
0] backtrace
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1001E06493}>
0: (SB-KERNEL::INTEGER-/-INTEGER 10 0)
1: (FOO 0)
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FOO 0) #<NULL-LEXENV>)
3: (EVAL (FOO 0))
4: (INTERACTIVE-EVAL (FOO 0) :EVAL NIL)
[...]
Some implementations, e.g. Allegro CL, support both interpreted as well as compiled code, the first being helpful in debugging, the second giving better performance. (I show here the command-line interactions. Allegro also offers a GUI to set breakpoints that I'm not familiar with.)
cl-user(4): (foo 0)
Error: Attempt to divide 10 by zero.
[condition type: division-by-zero]
Restart actions (select using :continue):
0: Return to Top Level (an "abort" restart).
1: Abort entirely from this (lisp) process.
[1] cl-user(5): :zoom
Evaluation stack:
(error division-by-zero :operation ...)
->(/ 10 0)
(foo 0)
(eval (foo 0))
[...]
The zoom command takes many options to be more verbose, this shows the form (block foo (m x)):
[1] cl-user(6): :zoom :all t
Evaluation stack:
... 4 more newer frames ...
((:runsys "lisp_apply"))
[... sys::funcall-tramp ]
(excl::error-from-code 17 nil ...)
(sys::..runtime-operation "integer_divide" :unknown-args)
(excl::/_2op 10 0)
->(/ 10 0)
[... excl::eval-as-progn ]
(block foo (m x))
(foo 0)
(sys::..runtime-operation "comp_to_interp" 0)
[... excl::%eval ]
(eval (foo 0))
When you (compile 'foo) the macro calls will be expanded away (like for SBCL) and not show up in backtraces anymore (but Allegro's source-level debugging could help).
In general when it comes to defining macros, to help debugging try to expand into function calls and not big bodies of code. E.g. instead of:
(defmacro with-foo ((var-x var-y thing) &body body)
`(let ((,var-x (..derive from ,thing ..))
(,var-y (..derive from ,thing ..)))
,#body))
I would write it like:
(defmacro with-foo ((var-x var-y thing) &body body)
`(call-with-foo (lambda (,var-x ,var-y) ,#body) ,thing))
(defun call-with-foo (func thing)
(let ((x (..derive from thing ..)
(y (..derive from thing ..))
(funcall func x y)))
so it ends up in the stack trace and is easy to redefine.
See this great post by Kent Pitman:
Incidentally, too, back to CL, you should know that when I write these
WITH-xxx macros, I almost always accompany them with a CALL-WITH-xxx
so that I can do either kind of call. But I find I almost never use
the CALL-WITH-xxx even when I was the one to provide it as an option.
The main reason I write them is not to use them but to make
redefinition easier, since I can redefine the CALL-WITH-xxx without
redefining the macro, and so I don't have to recompile the callers if
the definition changes.
Yes, AllegroCl supports tracing and in general debugging of macros. Quite an effort for not sure how much benefit, but Franz tends to do good things to make CL more viable. Pro tip: there is a an option to turn off what I think they call source-level debugging of macros, and you will want to do that if your code makes heavy use of macros or compilation times can get crazy. Just turn it back on when you think you need the source debugging.
Can someone please explain why Clojure's while macro doesn't return a value?
The documentation says "Presumes
some side-effect will cause test to become false/nil." Okay, so we use swap! to modify the atom which is used in the test case. But can't we still have a return value (perhaps returning repeatedly, as in the case with loop), along with the side effects?
Looking at the source, it seems like the cause could be something to do with how recursion and macros work, but I don't know enough about the internals of that to speculate.
Example:
The following code only returns nil:
(let [a (atom 0)]
(while (< #a 10)
(+ 1 #a)
(swap! a inc)))
That is, it does not return the value of (+ 1 #a), nor does it return any other value or function that is inside the while loop. If we want to get some value calculated via the while loop, we could use print, but then we can't easily use the value in some other operation. For a return value, we have to use a second atom, like this:
(let [a (atom 0)
end (atom 0)]
(while (< #a 10)
(swap! end #(+ 1 %))
(swap! a inc))
#end)
Using (source while) at the REPL, we can see it is implemented like this:
(defmacro while
"Repeatedly executes body while test expression is true. Presumes
some side-effect will cause test to become false/nil. Returns nil"
{:added "1.0"}
[test & body]
`(loop []
(when ~test
~#body
(recur))))
So, it executes the body, then checks the condition, rinse, repeat. By the time the condition is false, the most recent return value from the body is gone.
But what exactly are you trying to do? Do you really need an atom for this?
This code counts up to 10 and returns 10:
(loop [a 0]
(if (< a 10)
(recur (inc a))
a))
Can someone please explain why Clojure's while macro doesn't return a value?
But can't we still ... along with the side effects?
Side effects are there for when you need them, but if you are too free in mixing them throughout your regular code then you are missing out on one of the huge benefits of functional programming.
In clojure.core, the 'functions' that are used for the purpose of realising some side effect are always demarcated as such and it's a good idea to follow this in your own code too.
This question already has answers here:
What can you do with Lisp macros that you can't do with first-class functions?
(8 answers)
Closed 5 years ago.
In my quest to fully understand the so powerful lisp macros a question came to my mind. I know that a golden rule about macros is the one saying "Never use a macro when a function will do the work".
However reading Chapter 9 - Practical: Building a Unit Test Framework - from the book Practical Common Lisp I was introduced to the below macro whose purpose was to get rid of the duplication of the test case expression, with its attendant risk of mislabeling of results.
;; Function defintion.
(defun report-result (result form)
(format t "~:[FAIL~;pass~] ... ~a~%" result form))
;; Macro Definition
(defmacro check (form)
`(report-result ,form ',form))
OK, I understand its purpose but I could have done it using a function instead of a macro, for instance:
(setf unevaluated.form '(= 2 (+ 2 3)))
(defun my-func (unevaluated.form)
(report-result (eval unevaluated.form) unevaluated.form))
Is this only possible because the given macro is too simple ?
Furthermore, is Lisp Macro System so powerful relatively its opponents due to the code itself - like control structures, functions, etc - is represented as a LIST ?
But if it were a macro you, could have done:
(check (= 2 (+ 2 3)))
With a function, you have to do:
(check '(= 2 (+ 2 3)))
Also, with the macro the (= 2 (+ 2 3)) is actually compiled by the compiler, whereas with the function it's evaluated by the eval function, not necessarily the same thing.
Addenda:
Yes, it's just evaluating the function. Now what that means is dependent upon the implementation. Some can interpret it, others can compile and execute it. But the simple matter is that you don't know from system to system.
The null lexical environment that others are mentioning is also a big deal.
Consider:
(defun add3f (form)
(eval `(+ 3 ,form)))
(demacro add3m (form)
`(+ 3 ,form))
Then observe:
[28]> (add3m (+ 2 3))
8
[29]> (add3f '(+ 2 3))
8
[30]> (let ((x 2)) (add3m (+ x 3)))
8
[31]> (let ((x 2)) (add3f '(+ x 3)))
*** - EVAL: variable X has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of X.
STORE-VALUE :R2 Input a new value for X.
ABORT :R3 Abort main loop
Break 1 [32]> :a
That's really quite damning for most use cases. Since the eval has no lexical environment, it can not "see" the x from the enclosing let.
The better substitution would be not with eval, which won't perform as expected for all cases (for example, it doesn't have access to the lexical environment), and is also overkill (see here: https://stackoverflow.com/a/2571549/977052), but something using anonymous functions, like this:
(defun check (fn)
(report-result (funcall fn) (function-body fn)))
CL-USER> (check (lambda () (= 2 (+ 2 3))))
By the way, this is how such things are accomplished in Ruby (anonymous functions are called procs there).
But, as you see, it becomes somewhat less elegant (unless you add syntax sugar) and, there's actually a bigger problem: ther's no function-body function in Lisp (although there may be non-standard ways to get at it). Overall, as you see, for this particular task the alternative solutions are substantially worse, although in some cases such approach could work.
In general, though, if you want to do something with the source code of the expressions passed into the macro (and usually this is the primary reason of using macros), functions would not be sufficient.
The report-result function needs both the source code and the result of the execution.
The macro CHECK provides both from a single source form.
If you put a bunch of check forms into the file, they are easily compiled using the usual process of compiling Lisp files. You'll get a compiled version of the checking code.
Using a function and EVAL (better use COMPILE) you would have deferred the source evaluation to a later time. It would also not be clear if it is interpreted or compiled. In case of compilation, you would then later get the compiler's checks.
Is there any way to write something like this without taking over emacs?
(defun dumb-wait (seconds)
(let ((done (+ (second (current-time)) seconds)))
(while (< (second (current-time)) done)
(message "waiting"))))
(dump-wait 5) will block emacs from 5 seconds. Is there anyway to write this so it doesn't block? I just want to be in a loop and check some condition from time to time, and still be able to use emacs.
Thanks!
(run-at-time time repeat function &rest args) should do it. nil as time means now.
(setq my-timer
(run-at-time nil 5 (lambda () (message "waiting")))) ; returns timer object
;; or
(setq my-timer
(run-at-time nil 5 'message "waiting"))
(cancel-timer my-timer) ; use timer object from above
Edit:
The parameter repeat expects a number as seconds, however there's a function timer-duration, which you can use instead of the number. It returns the number of seconds as provided with a string parameter. This is somewhat easier to read for big intervals.
(timer-duration "3 hours 2 seconds 1 millisec") ; => 10802.001
Possible word you can use are defined in the variable timer-duration-words.
On a related note, there's no general way to write Emacs Lisp code that doesn't block because the language doesn't have features like coroutines, continuations and threading (yet). Instead, you've got to look for asynchronous inbuilts that do something closest to what you want. Example: url-retrieve and async-shell-command. Some applications like SLIME have managed to work around this issue and have implemented a sort of threading on their own, while others like gnus are waiting for Emacs Lisp to improve.