Common lisp restart to condition binding - error-handling

I'm learning common lisp in my free time and have a questions about the condition system.
When we handle an error in common lisp we specify error-type in a handler to determine which error to handle. Between raising and handling an error I can place some restarts (for example with restart-case) but I cannot specify in restart an error type.
For example, assume I have a function that takes a string and a stream, sends string to stream and read the response from stream and returns it. Assume that if my message is wrong I read from stream an error response. And I want to raise an error and bind a restart that asks for new message like this:
(defun process-message (stream raw-message)
(let ((response (get-response stream raw-message)))
(restart-case
(when (response-error-p response)
(error 'message-error :text response))
(change-raw-message (msg)
(process-message stream msg)))))
Now assume that the message is complicated and I got another function send-command at higher level that can create a message from some arguments and calls the process-message. I want to bind another restart recreate-command-message that will allow user to send new command from arguments if 'message-error acquires. This restart could be places in restart-case at process-message, but it is not fully correct because process-message should not know about such high-level function like send-command and the return values can differ.
But now the stream errors (such as EOF etc.) will be thrown throw recreate-command-message and if socket will fail the recreate-command-message restart will be available in some super-high-level socket-error handler and this restart will be useless and idiomatically wrong.
Is this a program design problem and a program should be designed to avoid such problems, or I just cannot find how to bind restart to error type or I do not understand the condition system correctly?
Thanks.

Maybe this helps:
(define-condition low-level-error (simple-error)
()
(:report (lambda (c s)
(format s "low level error."))))
(define-condition high-level-error (simple-error)
()
(:report (lambda (c s)
(format s "high level error."))))
(defun low-level (errorp)
(restart-case
(when errorp (error 'low-level-error))
(go-on ()
:report "go on from low-level"
t)))
(defun high-level (high-level-error-p low-level-error-p)
(restart-case
(progn
(when high-level-error-p (error 'high-level-error))
(low-level low-level-error-p))
(go-on ()
:report "go on from high level"
:test (lambda (c) (typep c 'high-level-error))
t)))
Try invoking high-level with different values (t or nil) for its arguments and check in the debugger if the respective available restarts fit your needs. The high level restart will only be seen if a high level error is signalled, and since the restart for the higher level is kept up the stack, the lower level function won't have to know about high level means to recover.
For your particular use-case, if I understand you correctly, this would mean: Establish your recreate-command-message restart to re-invoke process-message in send-command, and make it only available for high level errors.
As you probably know after reading the PCL chapter Vsevolod linked above, actually handling those errors, i.e. deciding which restarts to invoke, is done with handler-bind and handler-case.

Related

Emacs function returns Symbol's value as variable is void:

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.

Error propagation in erlang

I have a bit of a conceptual question for error handling in erlang. Let's take, for example, some database call which returns either {ok, Result}, or {error, Err}. I have a library which wraps calls to this database so I can do some pre/post-processing. When this library calls the database, should it do
A) Crash hard on an error, otherwise return the result:
{ok, Result} = db:call(), postprocess(Result).
B) Crash hard on an error, otherwise return the wrapped result:
{ok, Result} = db:call(), {ok, postprocess(Result)}.
C) Actually handle the error and return it:
case db:call() of
{ok, Result} -> {ok, postprocess(Result)};
{error, Err} -> {error, Err}
end.
D) Something else
As a follow-up question, if I have another library which is calling this one, what error propagation should it use? My thinking is that a library should be consistent with its return values, I'm just not clear on how to decide what those should potentially be.
Well, it depends on type of error, and how it should be handled.
The B) seems to be least likely to be used anywhere. Since you can not return any bad value it makes no sense to wrap it in ok tuple.
The A) seems to be a good example for database-connection library. For example when you can expect problems with connection to your database. In general you would not want each time someone makes call to your code to anticipate such case, and restart the server. The erlang way would be to crash the user, and let it's supervisor restart it in good environment, and redo the request. This approach allows for happy path coding in user side, and strong separation between your application logic and code responsible for setting up (and restarting in same way) wright environment.
Similar results could be achieved with the C) approach (and clients matching only on ok tuple), but sticking to A) might give users more idea on what to expect from your side.
The C) handling could be used when the library client can handle your error in mining full way (from point of their logic). Good example might be proplist:get_value/2 where you are either able to pattern match on {Key, Value} response or you get one atom undefined. There is no ok atom returned, but Key is enough to find happy path. And usually clients of this code can easily handle undefined (which is kind of error) in a manner mining full to their logic. And of course they could just pattern match only on happy path, and let it crach. The idea is not handling errors just for sake of handling errors; you only implement your application case.
And one more note. In your C) example you only allow {error, Error} errors to be handled. If you would like to just pass all the errors this might be better approach:
case db:call() of
{ok, Result} ->
{ok, postprocess(Result)};
Else ->
Else
end.

Can't declare constant variable locally Error installing Artificial Intelligence a Modern Approach Code on Ubuntu Trusty Tahr - Common Lisp

Im installing the code for the book Artificial Intelligence a Modern Approach i got here http://aima.cs.berkeley.edu/lisp/doc/install.html its the lisp version im installing btw
I'm on Ubuntu Trusty using Emacs SBCL slime, I placed the code in ~/.emacs.d
so per the instructions at above link i run (load "/home/w/.emacs.d/aima/code/aima.lisp")
which loads fine i get "T" as output
i run (aima-load 'all) that works I get "T" as output
but when i run (aima-compile) I get the error
Can't declare constant variable locally special: +NO-BINDINGS+
[Condition of type SIMPLE-ERROR]
I'm not sure I understand the error I read the Hyperspec on Declare and Special but that didn't help. I'm not opposed to a hack to make this work so if someone can help me reword the code or figure out if its a emacs setting or sbcl setting i could change to get the aforementioned variable declared that would be great. The error message is referring to this file /home/w/.emacs.d/aima/code/logic/algorithms/tell-ask.lisp
this section
(defmethod ask-each ((kb literal-kb) query fn)
"For each proof of query, call fn on the substitution that
the proof ends up with."
(declare (special +no-bindings+))
(for each s in (literal-kb-sentences kb) do
(when (equal s query) (funcall fn +no-bindings+))))
I verified all the permisions of all the files in my aima folder are set to read write for my username with my username as owner as a step to correct....but as far as understanding the error I could use help figuring out the next step one would take to debug this...The code is downloadable here http://aima.cs.berkeley.edu/lisp/code.tar.gz and its an easy install for a veteran emacs/lisp user....any help is appreciated.
Using SBCL:
I tried loading the AIMA code as well, with the same problem in SBCL. Just comment out line in ./logic/algorithms/tell-ask.lisp:
(declare (special +no-bindings+))
like so
;;(declare (special +no-bindings+))
, or delete the whole line altogether. Nevertheless, this is what I did:
(defmethod ask-each ((kb literal-kb) query fn)
"For each proof of query, call fn on the substitution that
the proof ends up with."
;;(declare (special +no-bindings+))
(for each s in (literal-kb-sentences kb) do
(when (equal s query) (funcall fn +no-bindings+))))
You will still have an issue running (aims-compile) with SBCL. It will complain about some constants being redefined. Just look at the possible restarts and select every time:
0: [CONTINUE] GO ahead and change the value.
Do this as many times (about 6 times that is) as it needs to, and it will load eventually. This is probably happening because of AIMA's code non-standard build/compile system. This can be annoying, but an alternative is to trace the code and see why/where some files are being reloaded.
USING Clozure (CCL):
CCL has a different problem with ./utilities/utilities.lisp. CCL has both true and false functions predefined, therefore you have to make sure that both lines:
#-(or MCL Lispworks)
that directly precede both (defun true ...) and (defun false ...) are changed to:
#-(or MCL Lispworks CCL)
also, in the same source, modify error inside for-each macro to look like so:
(error "~a is an illegal variable in (for each ~a in ~a ...)"
var var list)
With these modifications, CCL seems load AIMA code just fine.
In general:
It's a bad idea to redefine constants or to somehow bypass debugger restarts. Best solution is to have (defconstant ...)s evaluated once only, perhaps by placing them in a separate source file and making sure that the build system picks it up only once.
Another solution found here, which entails wrapping calls to defconstantin a macro like so (borrowed from here):
(defmacro define-constant (name value &optional doc)
(if (boundp name)
(format t
"~&already defined ~A~%old value ~s~%attempted value ~s~%"
name (symbol-value name) value))
`(defconstant ,name (if (boundp ',name) (symbol-value ',name) ,value)
,#(when doc (list doc))))
And then replacing all occurrences of defconstant like so:
(defconstant +no-bindings+ '((nil))
"Indicates unification success, with no variables.")
with:
(define-constant +no-bindings+ '((nil))
"Indicates unification success, with no variables.")
If you opt for define-constant "solution", make sure that define-constant is evaluated first.

How can I prevent QuickCheck from catching all exceptions?

The QuickCheck library seems to catch all exceptions that are thrown when testing a property. In particular, this behavior prevents me from putting a time limit on the entire QuickCheck computation. For example:
module QuickCheckTimeout where
import System.Timeout (timeout)
import Control.Concurrent (threadDelay)
import Test.QuickCheck (quickCheck, within, Property)
import Test.QuickCheck.Monadic (monadicIO, run, assert)
-- use threadDelay to simulate a slow computation
prop_slow_plus_zero_right_identity :: Int -> Property
prop_slow_plus_zero_right_identity i = monadicIO $ do
run (threadDelay (100000 * i))
assert (i + 0 == i)
runTests :: IO ()
runTests = do
result <- timeout 3000000 (quickCheck prop_slow_plus_zero_right_identity)
case result of
Nothing -> putStrLn "timed out!"
Just _ -> putStrLn "completed!"
Because QuickCheck catches all the exceptions, timeout breaks: it doesn't actually abort the computation! Instead, QuickCheck treats the property as having failed, and tries to shrink the input that caused the failure. This shrinking process is then not run with a time bound, causing the total time used by the computation to exceed the prescribed time limit.
One might think I could use QuickCheck's within combinator to bound the computation time. (within treats a property as having failed if it doesn't finish within the given time limit.) However, within doesn't quite do what I want, since QuickCheck still tries to shrink the input that caused the failure, a process that can take far too long. (What could alternatively work for me is a version of within that prevents QuickCheck from trying to shrink the inputs to a property that failed because it didn't finish within the given time limit.)
How can I prevent QuickCheck from catching all exceptions?
Since QuickCheck does the right thing when the user manually interrupts the test by pressing Ctrl+C, you might be able to work around this issue by writing something similar to timeout, but that throws an asynchroneous UserInterrupt exception instead of a custom exception type.
This is pretty much a straight copy-and-paste job from the source of System.Timeout:
import Control.Concurrent
import Control.Exception
timeout' n f = do
pid <- myThreadId
bracket (forkIO (threadDelay n >> throwTo pid UserInterrupt))
(killThread)
(const f)
With this approach, you'll have to use quickCheckResult and check the failure reason to detect whether the test timed out or not. It seems to work decent enough:
> runTests
*** Failed! Exception: 'user interrupt' (after 13 tests):
16
Maybe the chasingbottoms package would be useful? http://hackage.haskell.org/packages/archive/ChasingBottoms/1.3.0.3/doc/html/Test-ChasingBottoms-TimeOut.html
Not answering the main question, but your suggested alternative:
What could alternatively work for me is a version of within that prevents QuickCheck from trying to shrink the inputs to a property that failed because it didn't finish within the given time limit
There is noShrinking which should work for that:
https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#v:noShrinking
As a downside, this will disable shrinking also if the tests fails for other reasons besides the timeout.

How to really trap all errors with $etrap in Intersystems Caché?

I've been banging my head a lot because of this. In the way that $etrap (error handling special variable) was conceived you must be careful to really trap all errors. I've been partially successful in doing this. But I'm still missing something, because when run in user mode (application mode) there are internal Cache library errors that are still halting the application.
What I did was:
ProcessX(var)
set sc=$$ProcessXProtected(var)
w !,"after routine call"
quit sc
ProcessXProtected(var)
new $etrap
;This stops Cache from processing the error before this context. Code
; will resume at the line [w !,"after routine call"] above
set $etrap="set $ECODE = """" quit:$quit 0 quit"
set sc=1
set sc=$$ProcessHelper(var)
quit sc
ProcessHelper(var)
new $etrap
; this code tells Cache to keep unwindind error handling context up
; to the previous error handling.
set $etrap="quit:$quit 0 quit"
do AnyStuff^Anyplace(var)
quit 1
AnyStuffFoo(var)
; Call anything, which might in turn call many sub routines
; The important point is that we don't know how many contexts
; will be created from now on. So we must trap all errors, in any
; case.
;Call internal Cache library
quit
After all this, I can see that when I call the program from a prompt it works! But when I call from Cache Terminal Script (application mode, I was told) it fails and aborts the program (the error trapping mechanism doesn't work as expected).
Is is possible that an old-style error trap ($ZTRAP) is being set only in Usermode?
The documentation on this is pretty good, so I won't repeat it all here, but a key point is that $ZTRAP isn't New-ed in the same way as $ETRAP. In a way, it is "implicitly new-ed", in that its value only applies to the current stack level and subsequent calls. It reverts to any previous value once you Quit up past the level it was set in.
Also, I'm not sure if there's a defined order of precedence between $ETRAP and $ZTRAP handlers, but if $ZTRAP is of higher precedence, that would override your $ETRAPs.
You could try setting $ZTRAP yourself right before you call the library function. Set it to something different than $ETRAP so you can be sure which one was triggered.
Even that might not help though. If $ZTRAP is being set within the library function, the new value will be in effect, so this won't make a difference. This would only help you if the value of $ZTRAP came from somewhere further up the stack.
You didn't mention what library function caused this. My company has source code for some library functions, so if you can tell me the function name I'll see what I can find. Please give me the value of $ZVersion too so I can be sure we're talking about the same version of Cache.