I've been searching a way to stop a function after X seconds on lisp and I haven't found anything and have no ideia how to do it.
It's for finding heuristic weights on a function for a tetris game and if the weights are bad the program will run for more than 30 seconds and I don't want that. Any ideias, please?
Common Lisp has a library for that: Trivial Timeout.
The API is simple: Trivial Timeout API.
One possible way is to pass down an "expiry timer" and check if the current time is later than the expiry time in every iteration and, if it has expired, return the best solution so far. The standard function get-universal-time may be useful, but gives you a minimal granularity of seconds. A rough skeleton below. If you use recursive functions, simply pass the expiry timer down with whatever else you pass down and use that as your first recursion termination criterion.
(defun do-tetris-stuff (tetris-weights expiry-time)
(let ((best-solution nil))
(loop while (and (<= expiry-time (get-universal-time))
(not (good-enough-p best-solution)))
do (let ((next-solution ...))
(when (better-than-p next-solution best-solution)
(setf best-solution next-solution))))
best-solution))
Related
I am trying to create a very simple program, intended to measure the time required to select and synchronise across multiple channels. Essentially, the concept is simply that I have one sender and one receiver. Throughout multiple iterations, the sender randomly selects one of the channels the two have been provided and sends a message on that channel. As part of this, I need to be able to control the number of channels involved as a command-line parameter to the program, so I can't hard-code a pre-determined number of channels into the program. The problem is, I can't figure out how to get either sync or choice-evt from the Synchronisation module to work with multiple channels.
The entire program (as I currently have it) is below:
#lang racket
(provide main)
(require racket/random)
(define (sender iterations channels)
(match iterations
[0 (displayln "sender completed")]
[iter
(let ([choice-chan (random-ref channels)])
(channel-put choice-chan iter)
(sender (- iter 1) channels))]))
(define (receiver iterations channels notification-semaphore)
(match iterations
[0 (begin
(displayln "receiver completed")
(semaphore-post notification-semaphore))]
[iter
(let ([ignored-choice (sync (choice-evt (vector->values channels)))])
(begin (displayln ignored-choice)
(receiver (- iter 1) channels notification-semaphore)))]))
(define (experiment iterations num-channels)
(let ([channels
(vector->immutable-vector
(build-vector num-channels (λ (i) (make-channel))))]
[notification-semaphore (make-semaphore)])
(thread (λ () (receiver iterations channels notification-semaphore)))
(thread (λ () (sender iterations channels)))
(semaphore-wait notification-semaphore)))
(define (main iterations num-channels)
(experiment (string->number iterations) (string->number num-channels))
(displayln "SelectTime completed successfully"))
The displayln expressions aren't strictly necessary, they're just there so that I can see that there is indeed something being passed from sender to receiver.
The issue I have is that, when I use only a single channel, everything seems to work fine. With two or more channels, however, I get a runtime error complaining about an arity mismatch - 1 value was expected but 2 (or more if I specified more on the command line) were provided. Best as I can tell, this error occurs inside the receiver function at the evaluation of (choice-evt (vector->values channels)), after processing the inner expression. I have tried every variation I can think of, such as using channels directly without the vector->values; changing the vector to a list; dropping the choice-evt (especially since, if I'm reading the docs right, that isn't actually necessary for my test); moving where the sync happens out of the variable declaration in the let.
How can I sync over multiple channels, when the number of channels won't be known at runtime? It looks like using a vector or list isn't the correct way to go about this, but I'm a bit stumped as to what is the correct way.
P.S. Please do feel free to critique the program in other ways while you're answering if you think that might be helpful :)
You can use apply to make a choice-evt from a variable-length list of channels. For example, in your code above, change the sync call to the following:
(sync (apply choice-evt (vector->list channels)))
I'm trying to write a small system of macros to do iterative tasks in Emacs Lisp. I had taken it for granted that there is nothing beyond while loop. No more primitives or some hidden features, but I decided, I'd better ask.
By "hidden features" I mean something akin to tagbody in Common Lisp, i.e. the very primitive form to model the code in terms of blocks, jumps and labels. Are there any such thing in eLisp? Not even in any "hackish" way, like, for example, through the bytecode? Of course, I know about (catch ... (throw ... )) construct, but it is not quite the same, because it only allows jumping "backwards", but never forward. I also assumed it is a rather complex construct, not suitable for building fast iteration primitives.
Another thing that bugs me is that there doesn't seem to be a way to create an iterator for hash-tables. I.e. a hash-table must be itereated using maphash and once you exit the maphash function, there's no coming back to where you left it. So far I understand, it has to do something like, exporting a vector of keys and a vector of values and iterating over these, but there doesn't seem to be a way to get hold of these vectors / lists / whichever those are. Or am I again wrong?
I've looked into how cl package generates code for loop and dotimes / dolist / do, but they just use while or maphash, whichever is appropriate, and, frankly, I'm not so fond of their code... More than that, if, say, in the loop there are two for-as-hash clauses, they simply ignore the first (you don't even get a warning for that) and generate code for the second :|
Any chance there are some tricks to get hold of these iteration primitives from the user code in eLisp? If not, how feasible it is, and is it really, to write an extension in C?
You can tagbody as a macro:
(defmacro cl-tagbody (&rest tags-or-stmts)
(let ((blocks '()))
(let ((block (list 'cl--preamble)))
(dolist (tag-or-stmt tags-or-stmts)
(if (consp tag-or-stmt) (push tag-or-stmt block)
;; Add a "go to next block" to implement the fallthrough.
(push (nreverse (cons `(go ,tag-or-stmt) block)) blocks)
(setq block (list tag-or-stmt))))
(push (nreverse (cons `(go cl--exit) block)) blocks))
(let ((catch-tag (make-symbol "cl--tagbody-tag")))
(macroexpand-all
`(let ((next-tag 'cl--preamble))
(while
(not (eq (setq next-tag
(catch ',catch-tag
(cl-case next-tag
,#blocks)))
'cl--exit))))
`((go . (lambda (tag) `(throw ',catch-tag ',tag)))
,#macroexpand-all-environment)))))
1. Other looping constructs?
The only general-purpose built-in looping construct in Emacs Lisp is while (see eval.c). The macros dolist and dotimes (in subr.el) are both implemented using while.
There are also built-in functions for mapping over various data structures: mapatoms, mapc, mapcar, map-char-table, mapconcat, maphash, and map-keymap. But these are implemented in such a way that you can't interleave their execution with other Lisp code (see for example maphash in fns.c). If you want to loop over two such data structures, you have to loop over one and then over the other.
So I think you're basically out of luck.
2. Extensions?
Emacs is deliberately designed not to have dynamic C-level extensions, to make it more difficult for someone to mount an "embrace and extend" attack on the freedom of Emacs users (see the emacs-devel thread starting here, for example).
So if you want to add C-level functionality, you have to edit the source code. Good luck!
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.
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.
I've been working through Practical Common Lisp and as an exercise decided to write a macro to determine if a number is a multiple of another number:
(defmacro multp (value factor)
`(= (rem ,value ,factor) 0))
so that :
(multp 40 10)
evaluates to true whilst
(multp 40 13)
does not
The question is does this macro leak in some way? Also is this "good" Lisp? Is there already an existing function/macro that I could have used?
Siebel gives an extensive rundown (for simple cases anyway) of possible sources of leaks, and there aren't any of those here. Both value and factor are evaluated only once and in order, and rem doesn't have any side effects.
This is not good Lisp though, because there's no reason to use a macro in this case. A function
(defun multp (value factor)
(zerop (rem value factor)))
is identical for all practical purposes. (Note the use of zerop. I think it makes things clearer in this case, but in cases where you need to highlight, that the value you're testing might still be meaningful if it's something other then zero, (= ... 0) might be better)
Your macro looks fine to me. I don't know what a leaky macro is, but yours is pretty straightforward and doesn't require any gensyms. As far as if this is "good" Lisp, my rule of thumb is to use a macro only when a function won't do, and in this case a function can be used in place of your macro. However, if this solution works for you there's no reason not to use it.
Well, in principle, a user could do this:
(flet ((= (&rest args) nil))
(multp 40 10))
which would evaluate to NIL... except that ANSI CL makes it illegal to rebind most standard symbols, including CL:=, so you're on the safe side in this particular case.
In generial, of course, you should be aware of both referential untransparency (capturing identifiers from the context the macro is expanded in) and macro unhygiene (leaking identifiers to expanded code).
No, no symbol introduced in the macro's "lexical closure" is released to the outside.
Note that leaking isn't NECESSARILY a bad thing, even if accidental leaking almost always is. For one project I worked on, I found that a macro similar to this was useful:
(defmacro ana-and (&rest forms)
(loop for form in (reverse forms)
for completion = form then `(let ((it ,form))
(when it
,completion))
finally (return completion)))
This allowed me to get "short-circuiting" of things needed to be done in sequence, with arguments carried over from previous calls in the sequence (and a failure signalled by returning NIL). The specific context this code is from is for a hand-written parser for a configuration file that has a cobbled-together-enough syntax that writing a proper parser using a parser generator was more work than hand-rolling.