I am using Fedora 19 SBCL. I'm trying to install eager-future2.
I've downloaded the source, but I can't figure out how to install it. I tried
(asdf:load-system 'eager-future)
and I even tried loading individual .lisp files in the source, but whenever I try to use the pcall function, I get an error, "undefined function PCALL".
If you're using Quicklisp, which works with a number of Common Lisp implementations, you can install this pretty easily. Then, the pcall function is defined in the eager-future2 package, so you'll need to write the package prefix, e.g., eager-future2:pcall, or use the package in your own package. Using apropos is a good way to find out what symbols exist. Thus, I was able to do this:
CL-USER> (quicklisp:quickload "EAGER-FUTURE2")
;=> ("EAGER-FUTURE2")
CL-USER> (apropos "PCALL")
; EAGER-FUTURE2:PCALL (fbound)
; No value
CL-USER> (eager-future2:pcall (lambda () (print 'hello-world)))
;=> #<EAGER-FUTURE2:FUTURE {10059C8713}>
CL-USER> (defparameter *f* (eager-future2:pcall (lambda () (print 'hello))))
;=> *F*
CL-USER> *f*
;=> #<EAGER-FUTURE2:FUTURE {1005F4AD93}>
CL-USER> (eager-future2:ready-to-yield? *f*)
;=> T
CL-USER> (eager-future2:yield *f*)
;=> HELLO
Related
I am trying to learn Common Lisp with the book Common Lisp: A gentle introduction to Symbolic Computation. In addition, I am using SBCL, Emacs, and Slime.
In chapter 14, the last one, the author covers macros. He presents a tool called PPMX which stands for: ‘‘Pretty Print Macro eXpansion’’.
With this tool, you can do:
> (ppmx (incf a))
Macro expansion:
(SETQ A (+ A 1))
The tool is self-contained since the book provides the code definition for it:
(defmacro ppmx (form)
"Pretty prints the macro expansion of FORM."
‘(let* ((exp1 (macroexpand-1 ’,form))
(exp (macroexpand exp1))
(*print-circle* nil))
(cond ((equal exp exp1)
(format t "~&Macro expansion:")
(pprint exp))
(t (format t "~&First step of expansion:")
(pprint exp1)
(format t "~%~%Final expansion:")
(pprint exp)))
(format t "~%~%")
(values)))
Unfortunately, I cannot run it because the compilation does not work. The Slime's REPL throws this error:
ch-14.lisp:3:33:
read-error:
READ error during COMPILE-FILE:
Comma not inside a backquote.
Line: 3, Column: 33, File-Position: 101
Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /tmp/slimeD4xBr3" {10036BFC63}>
Compilation failed.
The comma and left single quote look different in emacs than in SO:
I have had some problems when copying the code from the book to emacs. It was basically inserting ' instead of the left single quote.
1 - Is there a way to fix this?
2 - The book was written in the late 1980s. Thus, I bet there are better tools now. Does Slime or SBCL offer some command to pretty print macro expansions? Maybe a library or another package?
Thanks.
Following #barmar's advice, the user just need to write in the REPL:
CL-USER> *print-pretty*
T
CL-USER> (macroexpand (setf a 1)) ;without the quote it does not work
1
NIL
CL-USER> (macroexpand '(setf a 1)) ;with the quote it does
(SETQ A 1)
T
Working through Little Schemer,
We're required to define a few of our own functions.
I've defined them, only add1 and sub1 appear in the repl after it loads. I'm using Racket v7.0.
#lang racket
(provide atom? add1 sub1)
(define atom?
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
(define add1
(lambda (x)
(+ x 1)))
(define sub1
(lambda (x)
(- x 1)))
I cannot figure out why (atom?) does not load. When I copy paste the s-expression into repl it works. Any ideas?
Since you are unsing #lang racket and provide the correct way to use the file is with require.
$ ls
toys.rkt
$ racket
Welcome to Racket v6.8.
> (require "toys.rkt")
> (atom? '())
#f
So imagine you make a program like this:
#lang racket
(require "toys.rkt")
(if (atom? 'test)
'atom
'no-atom)
You save it and run it:
$ racket program.rkt
'atom
Also note that you can use R6RS and make toys a library. You then need to use plt-r6rs --install toys.rkt and then use (import (rnrs base) (toys)).
I want to use the package cl-ppcre and series directly on my common lisp environment. I use sly, so in my slynkrc I add this code:
(setf (cdr (assoc '*print-length* slynk:*slynk-pprint-bindings*)) 20)
(setf *print-length* 20)
(setf *evaluator-mode* :interpret)
(ql:quickload '(:alexandria
:cl-ppcre
:cl-interpol
:series
:cl-actors
:chanl
:lparallel))
(eval-when (:compile-toplevel :execute :load-toplevel)
(series::install))
(defun λ-reader (stream char)
(declare (ignore char stream))
'LAMBDA)
(set-macro-character #\λ #'λ-reader)
(use-package :cl-ppcre)
(use-package :cl-interpol)
(interpol:enable-interpol-syntax)
The problem with this is whith the symbol function split. that is in both packages defined.
#<THREAD "main thread" RUNNING {10005605B3}>:
USE-PACKAGE #<PACKAGE "CL-PPCRE"> causes name-conflicts in
#<PACKAGE "COMMON-LISP-USER"> between the following symbols:
CL-PPCRE:SPLIT, SERIES:SPLIT
See also:
In Scala you can import, Renaming a class, but in this case I can use shadowing import, and import only what I need, what is the best solution for that, and if it is possible to import and rename a function in common lisp
You could maybe do it like this:
(defun alias% (as symbol &key (package *package*))
(when (fboundp symbol)
(setf (symbol-function as) (symbol-function symbol)))
(when (boundp symbol)
(setf (symbol-value as) (symbol-value symbol)))
(setf (symbol-plist as) (symbol-plist symbol))
;; maybe also documentation of all types
(shadowing-import as package))
(defmacro defalias (as symbol &key (package *package*))
`(eval-when (:compile-toplevel :load-toplevel :execute)
(alias% ',as ',symbol :package ,package)))
Then you can do:
(defalias foo cl:list)
(foo 1 2 3) ; => (1 2 3)
Looking at the doc on CLtL2, I'd say there is no macro to do that. Please prove me wrong.
Maybe the following works ? I didn't test properly edit: it doesn't work as is.
(use-package :cl-ppcre)
(setf (fdefinition 're-split) #'split) ;; create an alias
(unintern 'split)
(use-package :series)
And now use re-split and split.
I'd like to be able to get my SBCL 1.4.5 (Linux x86_64)
Emacs 'inferior-lisp-process' to evaluate a S-Expression (sexp)
in some Emacs buffer that is not the 'slime' buffer - I have
latest quicklisp and slime-2.20 .
I thought this was exactly the same issue as in :
How to run Common Lisp code with Slime in Emacs Lisp
but it is not - my issue is that when I try to run 'slime-eval' or
any slime 'run in inferior-lisp-process' method ALL symbols seem to be
being looked up in ONLY in the SWANK-IO-PACKAGE namespace :
In my Emacs '*scratch*' buffer:
(slime-eval '(symbolp '+) "CL-USER")
Produces a backtrace error:
The function SWANK-IO-PACKAGE::SYMBOLP is undefined.
[Condition of type UNDEFINED-FUNCTION]
Restarts:
0: [CONTINUE] Retry calling SWANK-IO-PACKAGE::SYMBOLP.
1: [USE-VALUE] Call specified function.
2: [RETURN-VALUE] Return specified values.
3: [RETURN-NOTHING] Return zero values.
4: [*ABORT] Return to SLIME's top level.
5: [ABORT] abort thread (#<THREAD "worker" RUNNING {100262C8E3}>)
Backtrace:
0: ("undefined function" SWANK-IO-PACKAGE::+)
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV \
(SWANK-IO-PACKAGE::SYMBOLP (QUOTE SWANK-IO-PACKAGE::+)) \
#<NULL-LEXENV>)
2: (EVAL (SWANK-IO-PACKAGE::SYMBOLP (QUOTE SWANK-IO-PACKAGE::+)))
It makes no difference whether I do :
(slime-eval '(symbolp :+) "CL-USER")
OR
(slime-eval '(symbolp '+))
I still get the same error because '+ and :+ are
always looked up only in the SWANK-IO-PACKAGE namespace.
I found this by simply trying to run, for my first test:
(slime-eval '(+ 2 2) "CL-USER")
which prints in the output buffer another backtrace
The function SWANK-IO-PACKAGE::+ is undefined.
[Condition of type UNDEFINED-FUNCTION]
I did try the code snippet from Question #22456086 :
(require 'slime)
(defun slrepl (str)
"Eval STR as Common Lisp code."
(unless (slime-current-connection)
(let ((wnd (current-window-configuration)))
(slime)
(while (not (and (slime-current-connection)
(get-buffer-window (slime-output-buffer))))
(sit-for 0.2))
(set-window-configuration wnd)))
(let (deactivate-mark)
(cadr (slime-eval `(swank:eval-and-grab-output ,str)))))
So doing:
(slrepl '(symbol-function '+))^X^E
Still results in :
The function SWANK-IO-PACKAGE::SYMBOL-FUNCTION is undefined.
[Condition of type UNDEFINED-FUNCTION]
Access to the default SB_INT namespace seems to be denied .
How to enable it for such cases ?
I'd like to be able to send forms to and read results from the same emacs inferior-lisp-process (sbcl) from any buffer, not just from the slime
'slime repl sbcl' buffer . Is there any way to do this?
Obviously, I can write an Emacs Lisp function to switch-to the
slime repl buffer and evaluate in that buffer.
Of course, all the above examples, eg. (eval '(symbolp '+)) ,
work fine in the slime-repl buffer. I guess there is no way
around switching-to the slime-repl buffer?
This might clarify:
In 'scratch' :
(slime-eval '(SB-INT:symbolp 'SB-INT:+) "CL-USER")^X^E
In slime output buffer:
Invalid protocol message:
The symbol "SYMBOLP" is not external in the SB-INT package.
Line: 1, Column: 26, File-Position: 26
Stream: #<SB-IMPL::STRING-INPUT-STREAM {1002A1CD63}>
(:emacs-rex (SB-INT:symbolp (quote SB-INT:+)) "CL-USER" t 78)
So, in the slime-repl buffer, I can do:
CL-USER> (PROGN (IN-PACKAGE "COMMON-LISP-USER") (+ 2 2))
4
CL-USER> (PROGN (IN-PACKAGE "SB-IMPL") (symbol-function '+))
#<FUNCTION +>
CL-USER> (PROGN (IN-PACKAGE "SB-IMPL") (symbol-function '+))
#<FUNCTION +>
SB-IMPL> (PROGN (IN-PACKAGE "SB-INT") (symbol-function '+))
#<FUNCTION +>
But if I try to run the same 'slime-eval' function in any
other buffer, eg. 'scratch' :
(slime-eval '(PROGN (COMMON-LISP-USER:IN-PACKAGE "COMMON-LISP-USER")
(symbol-function '+)) :COMMON-LISP-USER)
Invalid protocol message:
The symbol "IN-PACKAGE" is not external in the
COMMON-LISP-USER package.
Line: 1, Column: 46, File-Position: 46
I have tried ALL the likely PACKAGE names listed above in the
slime-eval with same results.
The same thing happens whether I use the 'slrepl' code snippet or just plain
slime-eval - no lisp standard syntax symbols are available. Do I need to
load the lisp syntax table or something ?
RE: can I switch to slime repl buffer and do it ? : NO ! :
(require 'slime)
(let ((slbuf (get-buffer "*slime-repl sbcl*")))
(if (eq nil slbuf)
(error "please start slime (M-x slime)")
(progn (set-buffer slbuf)(slime-eval '(+ 2 2) "COMMON-LISP-USER"))
)
)^X^E
Still results in :
The function SWANK-IO-PACKAGE::+ is undefined.
[Condition of type UNDEFINED-FUNCTION]
I am a rusty / returning LISP user and new to SBCL and slime .
I'd really like to integrate Emacs' great Editing and File management
& interacation facilitties with external CL XML & HTML generation & parsing
tools. But to start, I'd just like to get to the root of this problem...
Common Lisp symbols like + and symbolp are in the COMMON-LISP package. Short name CL. These symbols are usually not exported from package CL-USER. Thus symbolp can be referenced as cl:symbolp. These symbols are accessible in package CL-USER, but not exported from there. Thus you can also reference cl:symbolp as cl-user::symbolp -> note the two colons.
CALLING IN-PACKAGE in a form does not have an effect on the form itself, since the form is already read. Though it has an effect calling reader functions or functions like find-symbol.
CL-USER 5 > (defpackage "FOO" (:use))
#<The FOO package, 0/16 internal, 0/16 external>
CL-USER 6 > (progn (in-package "FOO")
(list 'bar (read-from-string "BAR")))
(COMMON-LISP-USER::BAR BAR) ; we now print from package "FOO"
Using SLIME-EVAL in Emacs Lisp
Best use it with a form, that reads the expression on the Common Lisp side and does not involve the Emacs Lisp reader/printer:
ELISP> (slime-eval '(cl:eval (cl:read-from-string "(+ 1 2)")) "CL-USER")
3 (#o3, #x3, ?\C-c)
ELISP> (slime-eval '(cl:eval (cl:read-from-string "'foo")) "CL-USER")
common-lisp-user::foo
But here you see that the result is brought back into Emacs Lisp via the Emacs Lisp reader - where packages don't exist.
Thus SLIME-EVAL makes very little sense as a simple remote execution interface...
This now works! Thanks !
(require 'slime)
(defun CL$ (str)
(let ((slbuf (get-buffer "*slime-repl sbcl*")))
(if (eq nil slbuf)
(error "Please start slime (M-x slime).")
(progn
(set-buffer slbuf)
(slime-eval str "CL")
)
)
)
)
(CL$ '(cl:+ 2 2))
=> 4
But I don't fully understand why I have to prepend all symbols with CL or
why this still does not work:
(slime-eval '(+ 2 2) "CL")
but this does:
(slime-eval '(cl:+ 2 2) "CL")
I thought the third parameter was meant to be made into the current package?
So why do I have to append 'cl' to every symbol .
But thanks for the help, and an otherwise great slime + sbcl .
As suggested in a macro-related question I recently posted to SO, I coded a macro called "fast" via a call to a function (here is the standalone code in pastebin):
(defun main ()
(progn
(format t "~A~%" (+ 1 2 (* 3 4) (+ 5 (- 8 6))))
(format t "~A~%" (fast (+ 1 2 (* 3 4) (+ 5 (- 8 6)))))))
This works in the REPL, under both SBCL and CMUCL:
$ sbcl
This is SBCL 1.0.52, an implementation of ANSI Common Lisp.
...
* (load "bug.cl")
22
22
$
Unfortunately, however, the code no longer compiles:
$ sbcl
This is SBCL 1.0.52, an implementation of ANSI Common Lisp.
...
* (compile-file "bug.cl")
...
; during macroexpansion of (FAST (+ 1 2 ...)). Use *BREAK-ON-SIGNALS* to
; intercept:
;
; The function COMMON-LISP-USER::CLONE is undefined.
So it seems that by having my macro "fast" call functions ("clone","operation-p") at compile-time, I trigger issues in Lisp compilers (verified in both CMUCL and SBCL).
Any ideas on what I am doing wrong and/or how to fix this?
Some remarks about your code.
multiple tests of an object for equality can be replaced by MEMBER
backquote with a following comma does nothing. You can just remove that.
you can ensure that your functions are available for a macro by a) moving these functions to an additional file and compile/load that before use of the macro, by b) using EVAL-WHENto inform the compiler to evaluate the definition of the functions or by c) adding the functions to the macro as local functions
Example:
(defmacro fast (&rest sexpr)
(labels ((operation-p (x)
(member x '(+ - * /)))
(clone (sexpr)
(if (consp sexpr)
(destructuring-bind (head . tail) sexpr
(if (operation-p head)
`(the fixnum (,head ,#(clone tail)))
(cons (clone head) (clone tail))))
sexpr)))
(car (clone sexpr))))
Note that this and your version of FAST are not complete code walkers. They recognize only simple function calls (and not the other Lisp constructs like LAMBDA, LET, FLET, LABELS, etc.).
Never mind, I figured it out: I had to move the functions invoked by the macro (and therefore required during compilation) in a separate file, "compile-file" it first, "load" it, then "compile-file" the one with the macro.
Macro-expansion tie happens (typically) during compile time.
That means that any functions used during the macro expansion (note, not necessarily in the macro-expansion, the return value as it were) must be defined when the macro is encountered during compilation.