Is there a way to collect warnings, but still execute the code to which they pertain?
My first thought is to use handler-case to grab all conditions and just continue from warnings, but SimpleWarning in SBCL seems to have no continue restart.
CL-USER> (handler-case (warn "Nope") (t (c) c))
#<SIMPLE-WARNING "Nope" {1008080D53}>
CL-USER> (compute-restarts (handler-case (warn "Nope") (t (c) c)))
(#<RESTART SWANK::RETRY {10080867F3}> #<RESTART ABORT {1004710323}>
#<RESTART ABORT {1004710073}>)
CL-USER>
You need to lookup what WARN actually does. By default it prints a warning. If you want to have access to the condition object, you need to write a handler. Just returning from the handler already continues then. If you want to get rid of the printed warning, then call MUFFLE-WARNING in the handler. MUFFLE-WARNing uses the restart of the same name.
CL-USER 32 > (let ((conditions ))
(handler-bind ((t (lambda (c) (push c conditions))))
(warn "foo")
(warn "bar")
(format t "~%baz"))
conditions)
Warning: foo
Warning: bar
baz
(#<SIMPLE-WARNING 402011C9B3> #<SIMPLE-WARNING 402011C63B>)
Handler-case unwinds when a condition matches one of its clauses. You should use handler-bind.
Related
SBCL compiler optimizations are based on the idea that if a type is declared, then "open coding" allows generic operations to be replaced with specific ones.
For example
(defun add (a b)
(declare (type fixnum a b))
(+ a b))
Will allow the generic + to be replaced with a single instruction for fixnum.
However, I have found that in practice, this seems to rarely be possible because:
In order for a function to be specialized/optimized it must be inlinable. The declaration must be marked explicitly with a (declaim (inline ...)), so the author of a function must anticipate that others might want to inline it. (In theory the compiler could generate multiple versions, but this doesn't seem to be the case.)
Most standard functions do not appear inlineable.
For example, one would expect that the following declaration is sufficient for open coding to take place:
(defun max-integers (array)
(declare (optimize (speed 3) (space 0) (safety 0)))
(declare (inline reduce))
(declare (type (simple-array fixnum (*)) array))
(reduce (lambda (a b) (if (> b a) b a)) array))
However, the assembly shows it's making a function call to the generic reduce:
; Size: 22 bytes. Origin: #x1001BC8109
; 09: 488B15B0FFFFFF MOV RDX, [RIP-80] ; no-arg-parsing entry point
; #<FUNCTION (LAMBDA
; # ..)>
; 10: B904000000 MOV ECX, 4
; 15: FF7508 PUSH QWORD PTR [RBP+8]
; 18: B8781C3220 MOV EAX, #x20321C78 ; #<FDEFN REDUCE>
; 1D: FFE0 JMP RAX
The conclusion seems to be that the compiler cannot actually do much type optimization, as each usage of reduce, map, etc is a barrier to type propagation, and they are building blocks of everything else.
How can I overcome this and take advantage of optimizations by declaring types?
I really want to avoid writing type specific versions of each function or "macroifying" what should be a function.
I think one answer is that if you want to write FORTRAN-style array-bashing code, write FORTRAN-style array-bashing code. In particular using things like reduce is probably not the way to do this.
For instance if you change your function to the perfectly readable
(defun max-integers/loop (array)
(declare (optimize (speed 3) (space 0) (safety 0))
(type (simple-array fixnum (*)) array))
(loop for i of-type fixnum across array
maximizing i))
Then SBCL does a far, far better job of optimising it.
It's worth pointing out another confusion in your question: You say that for something like
(defun add (a b)
(declare (type fixnum a b))
(+ a b))
SBCL will optimize + to the machine instruction. No, it won't. The reason it won't is because the fixnum type is not closed under addition: consider what (add most-positive-fixnum 1) should do. If you want to generate very fast code for integers you need to make sure that your integer types are small enough that the compiler can be sure that the operations you're doing on them remain machine integers (or, if you want to live dangerously, cover your code with (the fixnum ...) and set safety to 0 when compiling, which seems to allow the compiler to just return the wrong answer for addition in the way people usually expect computers to do).
You can't force the implementation to open-code functions that weren't declared INLINE when they were defind -- it simply hasn't saved the information needed.
However, the overhead of calling REDUCE is probably negligible compared to the actual processing. So what you can do is declare the types of a and b, to optimize the callback function.
(reduce (lambda (a b) (declare (type fixnum a b)) (if (> b a) b a)) array)
I guess you were hoping that if it open-coded reduce it would automatically propagate this type from the declaration of array, so you wouldn't need to do this.
I isolated this function from a larger script and ran it through https://www.jdoodle.com/execute-clisp-online/. Even though there is an error thrown, it seems to follow the rules of LISP unless I'm missing something blatantly obvious.
(defun cannibals-can-eat (state start-state)
(let ((left-bank-missionaries 2)
(left-bank-cannibals 5)
(right-bank-missionaries (- 3 left-bank-missionaries))
(right-bank-cannibals (- 2 left-bank-cannibals)))
(if (or (> left-bank-cannibals left-bank-missionaries)
(> right-bank-cannibals right-bank-missionaries))
t
nil)))
The error is sometimes The variable LEFT-BANK-MISSIONARIES is unbound.unmatched close parenthesis or syntax error near unexpected token('`. With this version of the function the error is the latter.
In Common Lisp there are two forms of local declarations (let):
(let ((var1 exp1)
(var2 exp2)
...
(varn expn))
exp)
and
(let* ((var1 exp1)
(var2 exp2)
...
(varn expn))
exp)
In the first every expression expi is evaluated in the environment holding before the let. In the second every expression expi is evaluated in the environment containing all the previous declarations var1 ... var(i-1).
So in your example the declaration of right-bank-missionaries uses left-bank-missionaries which is undefined since it is declared in the same let.
Simply use let* to allow the use of every variable immediately after its declaration:
(defun cannibals-can-eat (state start-state)
(let* ((left-bank-missionaries 2)
(left-bank-cannibals 5)
(right-bank-missionaries (- 3 left-bank-missionaries))
(right-bank-cannibals (- 2 left-bank-cannibals)))
(or (> left-bank-cannibals left-bank-missionaries)
(> right-bank-cannibals right-bank-missionaries))))
Note that the final if is useless if you want to return a generalized boolean.
I have a few operations I want to thread where each can fail. I would much rather get the error as a value instead of using try-catch which breaks the flow of execution.
I can do the naive version and make my functions use nil as failure:
(if-let (op1 ...)
(if-let (op2 ...)
...
err1)
err2)
but this is nested and makes it harder to read.
I could use some-> which seems like the closest solution but it doesn't say what failed:
(if-let [res (some-> arg
op1
op2)]
res
somethin-failed) ;; what failed though?
I also looked at ->, and cond-> but they don't seem to help.
I know there are macros online to do these kind of things but I would much rather not add macros if something exists to solve this. Hopefully there is something of the form:
(some-with-err-> arg
op1 err1
op2 err2
...)
I may be overlooking something simpler, but I can't seem to find something built-in to address this issue.
I can write a macro to do it but would rather avoid it for now.
There's nothing built-in for this, but there are libraries for monadic error handling (e.g. Failjure) which seems like what you're looking for.
You could derive a version some-with-err-> from the some-> macro definition. The only practical difference is the map function that binds to steps now partitions the forms/error values, wraps step invocations in try and returns a namespaced map on failure:
(defmacro some-with-err->
[expr & forms]
{:pre [(even? (count forms))]}
(let [g (gensym)
steps (map (fn [[step error]]
`(if (or (nil? ~g) (::error ~g))
~g
(try (-> ~g ~step)
(catch Exception _# {::error ~error}))))
(partition 2 forms))]
`(let [~g ~expr
~#(interleave (repeat g) (butlast steps))]
~(if (empty? steps)
g
(last steps)))))
It can be used like some-> but each form must be accompanied by an error return value:
(some-with-err-> 1
(+ 1) :addition
(/ 0) :division
(* 2) :multiplication)
=> #:user{:error :division}
(some-with-err-> " "
(clojure.string/trim) :trim
(not-empty) :empty
(str "foo") :append)
=> nil ;; from not-empty
I am fairly new to Emacs but I know enough to be dangerous. I've built my .emacs file from scratch and now have it in an org file. I am now trying to take it to the next level and make my configuration more user friendly for myself.
I mostly use Emacs for writing. Books, blogs, screenwriting, etc. I am trying to create a function that will turn on multiple modes and add the settings on the fly.
For example, I use olivetti-mode when writing. It centers the text. Each time I have to adjust the olivetti-set-width. I thought I would get fancy and enable the spell checker and turn off linum-mode as well.
However, every time I try it I get the error:
Symbol's value as variable is void: my-writing
Can anyone explain what I am doing wrong? I've google-fu'd quite a bit but I clearly have a gap in my understanding of what I am doing.
#+BEGIN_SRC emacs-lisp
(defun my-writing ()
"Start olivetti mode, set the width to 120, turn on spell-check."
((interactive)
(olivetti-mode)
(setq olivetti-set-width . 120)
(flyspell-mode)
(global-linum-mode 0)))
(add-hook 'olivetti-mode-hook
(lambda () olivetti-mode my-writing t))
#+END_SRC
To disable global-linum-mode for specific major-modes, see automatically disable a global minor mode for a specific major mode
[Inasmuch as olivetti-mode is a minor-mode that is enabled subsequent to whatever major-mode is already present in the buffer, the original poster may wish to turn off linum-mode locally in the current buffer by adding (linum-mode -1) to the tail end of the function my-writing (see below). That idea, however, assumes that the original poster wanted to have linum-mode active in the current buffer just prior to calling my-writing.]
The function my-writing in the initial question contains an extra set of parenthesis that should be omitted, and the hook setting is not in proper form.
olivetti-set-width is a function that takes one argument, so you cannot use setq -- see function beginning at line 197: https://github.com/rnkn/olivetti/blob/master/olivetti.el setq is used when setting a variable, not a function.
Although flyspell-mode is generally buffer-local, it is a good idea to get in the habit of using an argument of 1 to turn on a minor-mode or a -1 or 0 to turn it off. When an argument is omitted, calling the minor-mode works as an on/off toggle.
Unless there are other items already attached to the olivetti-mode-hook that require prioritization or special reasons for using a hook with buffer-local settings, you do not need the optional arguments for add-hook -- i.e., APPEND and LOCAL.
There is no apparent reason to call (olivetti-mode) as part of the olivetti-mode-hook that gets called automatically at the tail end of initializing the minor-mode, so there is now a check to see whether that mode has already been enabled. The olivetti-mode-hook is being included in this example to demonstrate how to format its usage. However, the original poster should consider eliminating (add-hook 'olivetti-mode-hook 'my-writing) as it appears to serve no purpose if the user will be calling M-x my-writing instead of M-x olivetti-mode. The hook would be useful in the latter circumstance -- i.e., when typing M-x olivetti-mode -- in which case, there is really no need to have (unless olivetti-mode (olivetti-mode 1)) as part of my-writing.
#+BEGIN_SRC emacs-lisp
(defun my-writing ()
"Start olivetti mode, set the width to 120, turn on spell-check."
(interactive)
(unless olivetti-mode (olivetti-mode 1))
(linum-mode -1) ;; see comments above
(olivetti-set-width 120)
(flyspell-mode 1))
;; original poster to consider eliminating this hook
(add-hook 'olivetti-mode-hook 'my-writing)
#+END_SRC
lawlist's answer describes how you can go about doing what you're actually trying to accomplish, but the particular error you're getting is because Emacs Lisp (like Common Lisp, but not Scheme) is a Lisp-2. When you associate a symbol with a function using defun, it doesn't make the value of that symbol (as a variable) that function, it makes the function value of that symbol the function. You'll get the same error in a much simplified situation:
(defun foo ()
42)
(list foo)
The symbol foo has no value here as a variable. To get something that you could later pass to funcall or apply, you need to either use the symbol foo, e.g.:
(funcall 'foo)
;=> 42
or the form (function foo):
(funcall (function foo))
;=> 42
which can be abbreviated with the shorthand #':
(funcall #'foo)
;=> 42
You're getting the error because of:
(add-hook 'olivetti-mode-hook
(lambda () olivetti-mode my-writing t))
which tries to use my-writing as a variable, but it has no variable value at that point.
I'm trying to implement a try-catch block in scheme using (call-cc) method but i'm not sure how it can be used for that. I could not find any example.
And found examples contains just error-handling but what i want to do is: if an error occurred, the scheme program has to give a message to user (via display for-example) without suspending the program.
Is that possible?
Typically you'd use the with-handlers form. This lets you display an error message or take any other action before returning a value.
#lang racket
(define (foo x)
(with-handlers ([exn:fail? (lambda (exn)
(displayln (exn-message exn))
#f)])
(/ 1 x)))
(foo 1)
; 1
(foo 0)
; "/: division by zero"
; #f
If you really want to use a continuation directly for some reason, you could use call/ec for an error/escape continuation instead of the general call/cc.
Docs:
with-handlers
call/ec
Since you want to catch all errors, such as ones raised by both raise and raise-continuable you'd need both an exception handler (to deal with raised conditions) and an exit continuation (to avoid continuing with the try body). Simple syntax for try would be:
(import (rnrs base) ; define-syntax
(rnrs exceptions)) ; get `with-exception-handler`
(define-syntax try
(syntax-rules (catch)
((_ body (catch catcher))
(call-with-current-continuation
(lambda (exit)
(with-exception-handler
(lambda (condition)
catcher
(exit condition))
(lambda () body)))))))
This gets used as, for example:
> (try (begin (display "one\n")
(raise 'some-error)
(display "two\n"))
(catch (display "error\n")))
one
error
some-error # the return value.
Note: this is R6RS (and R7RS) Scheme.