slime v.2014-04-27 sbcl v.1.2.0 lisp in-package does not change *package* after compilation and loading command C-c C-k - sbcl

This is the code:
(defpackage :morse
(:use :common-lisp))
(in-package :morse)
...
When I use C-c C-k (Compile/Load file):
CL-USER> *package*
#<PACKAGE "COMMON-LISP-USER">
; compiling file "/home/frederik/Lisp/Code/mycode/marco_baringer.lisp" (written 16 JUN 2014 11:30:15 AM):
; /home/frederik/Lisp/Code/mycode/marco_baringer.fasl written
; compilation finished in 0:00:00.025
CL-USER> *package*
#<PACKAGE "COMMON-LISP-USER">
CL-USER>
I am still in package "COMMON-LISP-USER" when the command "(in-package :morse)" is given in the source code. I should be in "MORSE" I think because when I give the command in the REPL:
...
CL-USER> (in-package :morse)
#<PACKAGE "MORSE">
MORSE> *package*
#<PACKAGE "MORSE">
MORSE>
...
Any idea? Am I wrong?

From: Nick Levine ravenbrook.com>
Subject: Re: SLIME compile and load file REPL stays at "CL-USER" with "(in-package :xyz)" in code and not "XYZ"
Newsgroups: gmane.lisp.slime.devel
Date: 2014-06-17 08:12:34 GMT (15 minutes ago)
From: Frederik Cheeseman evonet.be>
Date: Tue, 17 Jun 2014 07:54:20 +0000 (UTC)
When I do C-c C-k (SLIME compile/load file) the REPL stays at
"CL-USER". Shouldn't it switch to "MORSE" because of the
"(in-package :morse)" code line?
No (and this applies to CL in general, not just to SLIME). This is
because, according to the spec, "load binds readtable and package
to the values they held before loading the file." In effect:
(defun load (file &key ...)
(let ((*package* *package*))
(in-load file ...)))
n

Related

Opening leiningen project in emacs/cider raises classpath error

I'm learning Clojure with 'Clojure for the Brave and True' book and use emacs, cider and leiningen. I've created a project.
lein new app the-divine-cheese-code
Then I've added to source files to the project.
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
In 'core.clj' I refer to the 'svg.clj' namespace.
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
(ns the-divine-cheese-code.core)
;; Ensure that the SVG code is evaluated
(require 'the-divine-cheese-code.visualization.svg)
;; Refer the namespace so that you don't have to use the
;; fully qualified name to reference svg functions
(refer 'the-divine-cheese-code.visualization.svg)
(def heists [{:location "Cologne, Germany"
:cheese-name "Archbishop Hildebold's Cheese Pretzel"
:lat 50.95
:lng 6.97}
{:location "Zurich, Switzerland"
:cheese-name "The Standard Emmental"
:lat 47.37
:lng 8.55}
{:location "Marseille, France"
:cheese-name "Le Fromage de Cosquer"
:lat 43.30
:lng 5.37}
{:location "Zurich, Switzerland"
:cheese-name "The Lesser Emmental"
:lat 47.37
:lng 8.55}
{:location "Vatican City"
:cheese-name "The Cheese of Turin"
:lat 41.90
:lng 12.45}])
(defn -main
[& args]
(println (points heists)))
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
(ns the-divine-cheese-code.visualization.svg)
(defn latlng->point
"Convert lat/lng map to comma-separated string"
[latlng]
(str (:lat latlng) "," (:lng latlng)))
(defn points
[locations]
(clojure.string/join " " (map latlng->point locations)))
Here is the project's entire dir structure.
the-divine-cheese-code
the-divine-cheese-code\.gitignore
the-divine-cheese-code\.hgignore
the-divine-cheese-code\.nrepl-port
the-divine-cheese-code\CHANGELOG.md
the-divine-cheese-code\doc
the-divine-cheese-code\doc\intro.md
the-divine-cheese-code\LICENSE
the-divine-cheese-code\project.clj
the-divine-cheese-code\README.md
the-divine-cheese-code\resources
the-divine-cheese-code\src
the-divine-cheese-code\src\the_divine_cheese_code
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
the-divine-cheese-code\src\the_divine_cheese_code\visualization
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
the-divine-cheese-code\target
the-divine-cheese-code\target\default
the-divine-cheese-code\target\default\classes
the-divine-cheese-code\target\default\classes\META-INF
the-divine-cheese-code\target\default\classes\META-INF\maven
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code\pom.properties
the-divine-cheese-code\target\default\repl-port
the-divine-cheese-code\target\default\stale
the-divine-cheese-code\target\default\stale\leiningen.core.classpath.extract-native-dependencies
the-divine-cheese-code\test
the-divine-cheese-code\test\the_divine_cheese_code
the-divine-cheese-code\test\the_divine_cheese_code\core_test.clj
When I run the project with 'lein run' it executes successfully. However, when I open the core.clj file with emacs/cider and try to compile it, I get classpath error.
CompilerException java.io.FileNotFoundException: Could not locate
the_divine_cheese_code/visualization/svg__init.class or
the_divine_cheese_code/visualization/svg.clj on classpath. Please check
that namespaces with dashes use underscores in the Clojure file name.,
compiling:(c:/temp/the-divine-cheese-code/src/the_divine_cheese_code/core.clj:2:1)
CIDER compiles sources sucessfully if I put them in the same directory (changing namespace correspondingly).
(ns the-divine-cheese-code.core)
(require 'the-divine-cheese-code.svg)
(refer 'the-divine-cheese-code.svg)
(def heists [{:location "Cologne, Germany"
...
So maybe the issue is dealt with OS. I use Windows 7, which is not primary OS for Emacs/CIDER.
After some experimenting I found that the CIDER works without :refer
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg]))
This looks like a CIDER bug and 'lein run' predictably gives error in this case.
If I make it the right way
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg :refer :all]))
the CIDER now gives another error:
Caused by java.lang.IllegalStateException
latlng->point already refers to:
#'the-divine-cheese-code.svg/latlng->point in namespace:
the-divine-cheese-code.core
Would suggest to use the options provided by the ns macro instead of naked require and refer statements - this is the recommended way of doing imports/requires in Clojure and most of the tooling is written with this way of managing namespaces in mind. Even if the below code still doesn't work in CIDER, it will be easier to diagnose it:
;; the-divine-cheese-code\src\the_divine_cheese_code\core.clj
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg :refer :all]))
(def heists ...)
(defn- main ...)
In my case, the error went away after I renamed (to the same name) src/the_divine_cheese_code/ folder and it's contents recursively.
Not sure what caused the issue. My guess is that character encoding was screwed up. I created both the file and folder in Emacs and done the renaming in Double Commander.

How to parse command line arguments in `clojure` using `tools.cli` in better way?

I'm newbie in clojure. I'm learning about parsing arguments using tools.cli library. Here is my code:
1 (ns json.core
2 (:import
3 (com.fasterxml.jackson.core JsonParseException))
4 (:require
5 [cheshire.core :as c]
6 [clojure.tools.cli :refer [parse-opts]])
7 (:gen-class))
8
9 (def json-cli-options
10 [["-j" "--jsonfile INFILE" :default false]
11 ["-d" "--data JSON-DATA" :default false]])
12
13 (defn -main
14 [& args]
15 (case (first args)
16 "parsejson" (let [{:keys [jsonfile data]} (get (parse-opts (rest args) json-cli-options) :options)
17 file-json (if jsonfile (try (c/parse-string (slurp jsonfile))
18 (catch JsonParseException e (println "Invalid file"))))
19 data-json (if data (try (c/parse-string data)
20 (catch JsonParseException e (println "Invalid data"))))
21 complete-json (merge file-json data-json)]
22 (if (and (not data) (not jsonfile)) (do (println "Pass either json-data or json-file or both") (System/exit 1)))
23 (println complete-json))
24 (println "No argument passed")))
It's just a code for paring json data. User can pass json either using --jsonfile or --data or both. User must have to select at least one option, otherwise It will thrown an error. It's like this:
$ lein run parsejson --jsonfile file.json
;;=> {Name Bob, Gen Male}
$ lein run parsejson --data '{"age":21}'
;;=> {age 21}
$ lein run parsejson --jsonfile file.json --data '{"age":21}'
;;=> {Name Bob, Gen Male, age 21}
$ lein run parsejson
;;=>Pass either json-data or json-file or both
But this code is not thrown an error in this case:
$ lein run parsejson --jsonfile file.json --data
I want to implement this feature as well. If I do this:
$ lein run parsejson --jsonfile file.json --data
$ lein run parsejson --data '{"age":21}' --jsonfile
The code should give some message(or error). How can I implement this thing in my code? Please give your suggestion. Thanks.
as my old code follow tools.cli doc, it will save all into a map.
(defn -main
""
[& args]
(let [[options extra-args banner]
(cli args
["-j" "--jsonfile" "json file"]
["-d" "--data" "json data"]
["-h" "--help" "Show help" :default false :flag true]
["-v" "--verbose" "debug mode" :default false :flag true])]
(println options)
(when (:help options)
(println banner)
(System/exit 0))))
out res: --jsonfile 1.json --data '{"age":21}' -h
{:help true, :verbose false, :jsonfile 1.json, :data {"age":21}}
Usage:
Switches Default Desc
-------- ------- ----
-j, --jsonfile json file
-d, --data json data
-h, --no-help, --help false Show help
-v, --no-verbose, --verbose false debug mode
You should be validating the values passed after each flag. See here for an example.

Storing a Lisp compiled function in a database

CLISP allows us to do
(compile nil #'(lambda(x) (+ x 1)))
This returns a compiled function object:
#<COMPILED-FUNCTION NIL>
Is it possible to export this as a binary string, in order to persist it? Say, saving it in a database, and later be able to load and run the compiled function.
Not in portable Common Lisp.
Instead write the function to a file, compile the file with COMPILE-FILE. Then you have the compiled code on the file system. You can later load the file and run the function. You could also store the file contents into the database. If you need it later, you would need to export the data from the database into a file and call LOAD to load the file.
CLISP
Yes, in CLISP you can:
> (defparameter *my-function* (compile nil #'(lambda(x) (+ x 1))))
*MY-FUNCTION*
> *MY-FUNCTION*
#<COMPILED-FUNCTION NIL>
> (write-to-string *my-function* :readably t :pretty nil)
"#Y(|COMMON-LISP|::|NIL| #15Y(00 00 00 00 01 00 00 00 20 02 AD 32 B1 19 02) () (|COMMON-LISP|::|T| |COMMON-LISP|::|NIL| |COMMON-LISP|::|NIL|))"
> (defparameter *my-function-1* (read-from-string (write-to-string *my-function* :readably t)))
*MY-FUNCTION-1*
> (funcall *my-function-1* 10)
11
This is portable across all platforms supported by CLISP, and as long as the CLISP bytecode version is the same (it does not change at every release).
Other implementations
As Rainer said, other CL implementation do not necessarily support this, but you can certainly put your function into a file, compile the file, and read in the string:
(defun function-string (func)
(let ((lambda-expr (function-lambda-expression func)))
(unless lambda-expr
(error "no lambda expression for ~S" func))
(let ((tmp-file "tmp.lisp") comp-file ret)
(with-open-file (o tmp-file :direction :output)
(write (list* 'defun my-tmp-func (cdr lambda-expr))
:stream o :readably t))
(setq comp-file (compile-file tmp-file))
(with-open-file (compiled comp-file :direction :input
:element-type '(unsigned-byte 8))
(setq ret (make-array (file-length compiled)
:element-type '(unsigned-byte 8)))
(read-sequence ret compiled))
(delete-file tmp-file)
(delete-file comp-file)
ret)))
To recover the function, you would need to do use load:
(with-input-from-string (s (function-string *my-function*))
(load s))
(fdefinition 'my-tmp-func)
Notes:
function-lambda-expression's value can legitimately be always nil in a given implementation!
If the implementation compiles to native code, the above string will be platform-dependent.
I glossed over the package issues...

divide by zero exception handling in Linux

I am curious to understand the divide by zero exception handling in linux. When divide by zero operation is performed, a trap is generated i.e. INT0 is sent to the processor and ultimately SIGFPE signal is sent to the process that performed the operation.
As I see, the divide by zero exception is registered in trap_init() function as
set_trap_gate(0, &divide_error);
I want to know in detail, what all happens in between the INT0 being generated and before the SIGFPE being sent to the process?
Trap handler is registered in the trap_init function from arch/x86/kernel/traps.c
void __init trap_init(void)
..
set_intr_gate(X86_TRAP_DE, &divide_error);
set_intr_gate writes the address of the handler function into idt_table x86/include/asm/desc.h.
How is the divide_error function defined? As a macro in traps.c
DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV,
regs->ip)
And the macro DO_ERROR_INFO is defined a bit above in the same traps.c:
193 #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
194 dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
195 { \
196 siginfo_t info; \
197 enum ctx_state prev_state; \
198 \
199 info.si_signo = signr; \
200 info.si_errno = 0; \
201 info.si_code = sicode; \
202 info.si_addr = (void __user *)siaddr; \
203 prev_state = exception_enter(); \
204 if (notify_die(DIE_TRAP, str, regs, error_code, \
205 trapnr, signr) == NOTIFY_STOP) { \
206 exception_exit(prev_state); \
207 return; \
208 } \
209 conditional_sti(regs); \
210 do_trap(trapnr, signr, str, regs, error_code, &info); \
211 exception_exit(prev_state); \
212 }
(Actually it defines the do_divide_error function which is called by the small asm-coded stub "entry point" with prepared arguments. The macro is defined in entry_32.S as ENTRY(divide_error) and entry_64.S as macro zeroentry: 1303 zeroentry divide_error do_divide_error)
So, when a user divides by zero (and this operation reaches the retirement buffer in OoO), hardware generates a trap, sets %eip to divide_error stub, it sets up the frame and calls the C function do_divide_error. The function do_divide_error will create the siginfo_t struct describing the error (signo=SIGFPE, addr= address of failed instruction,etc), then it will try to inform all notifiers, registered with register_die_notifier (actually it is a hook, sometimes used by the in-kernel debugger "kgdb"; kprobe's kprobe_exceptions_notify - only for int3 or gpf; uprobe's arch_uprobe_exception_notify - again only int3, etc).
Because DIE_TRAP is usually not blocked by the notifier, the do_trap function will be called. It has a short code of do_trap:
139 static void __kprobes
140 do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
141 long error_code, siginfo_t *info)
142 {
143 struct task_struct *tsk = current;
...
157 tsk->thread.error_code = error_code;
158 tsk->thread.trap_nr = trapnr;
170
171 if (info)
172 force_sig_info(signr, info, tsk);
...
175 }
do_trap will send a signal to the current process with force_sig_info, which will "Force a signal that the process can't ignore".. If there is an active debugger for the process (our current process is ptrace-ed by gdb or strace), then send_signal will translate the signal SIGFPE to the current process from do_trap into SIGTRAP to debugger. If no debugger - the signal SIGFPE should kill our process while saving the core file, because that is the default action for SIGFPE (check man 7 signal in the section "Standard signals", search for SIGFPE in the table).
The process can't set SIGFPE to ignore it (I'm not sure here: 1), but it can define its own signal handler to handle the signal (example of handing SIGFPE another). This handler may just print %eip from siginfo, run backtrace() and die; or it even may try to recover the situation and return to the failed instruction. This may be useful for example in some JITs like qemu, java, or valgrind; or in high-level languages like java or ghc, which can turn SIGFPE into a language exception and programs in these languages can handle the exception (for example, spaghetti from openjdk is in hotspot/src/os/linux/vm/os_linux.cpp).
There is a list of SIGFPE handlers in debian via codesearch for siagaction SIGFPE or for signal SIGFPE

Printing stack traces

I have a very short test file:
let print_backtrace () = try raise Not_found with
Not_found -> Printexc.print_backtrace stdout;;
let f () = print_backtrace (); Printf.printf "this is to make f non-tail-recursive\n";;
f ();
I compile and run:
% ocamlc -g test.ml
% OCAMLRUNPARAM=b ./a.out
Raised at file "test.ml", line 1, characters 35-44
this is to make f non-tail-recursive
Why isn't f listed in the stack trace? How can I write a function that will print a stack trace of the location it's called from?
The documentation for Printexc.print_backtrace says:
The backtrace lists the program locations where the most-recently raised exception was raised and where it was propagated through function calls.
It actually seems to be doing the right thing. The exception hasn't been propagated back through f.
If I move the call to Printexc.print_backtrace outside the call to f, I see a full backtrace.
$ cat test2.ml
let print_backtrace () = raise Not_found
let f () = let res = print_backtrace () in res ;;
try f () with Not_found -> Printexc.print_backtrace stdout
$ /usr/local/ocaml312/bin/ocamlc -g test2.ml
$ OCAMLRUNPARAM=b a.out
Raised at file "test2.ml", line 1, characters 31-40
Called from file "test2.ml", line 3, characters 21-39
Called from file "test2.ml", line 5, characters 4-8
Here is the code to do what I suggested. I recommend using ocamldebug if at all possible, this code is much too tricky. But it works on my system for this simple example.
let print_backtrace () =
match Unix.fork () with
| 0 -> raise Not_found
| pid -> let _ = Unix.waitpid [] pid in ()
let f () =
begin
print_backtrace ();
Printf.printf "after the backtrace\n";
end
;;
f ()
Here is a test run.
$ /usr/local/ocaml312/bin/ocamlc unix.cma -g test3.ml
$ OCAMLRUNPARAM=b a.out
Fatal error: exception Not_found
Raised at file "test3.ml", line 3, characters 17-26
Called from file "test3.ml", line 8, characters 4-22
Called from file "test3.ml", line 14, characters 0-4
after the backtrace
I realized that because of the uncaught exception, you don't really have any control over the way the child process exits. That's one reason this code is much too tricky. Please don't blame me if it doesn't work for you, but I hope it does prove useful.
I tested the code on Mac OS X 10.6.8 using OCaml 3.12.0.
Best regards,