Say I've played a bit with SBCL with no SLIME, no whatsoever, plain interpreter. Now I want to save couple of functions in a file. Not an core image, just a bits of code in a text form. How should I do that?
There are two ways to do that: use DRIBBLE and/or FUNCTION-LAMBDA-EXPRESSION
The first is to always use the Common Lisp function DRIBBLE before experimenting:
rjmba:tmp joswig$ sbcl
This is SBCL 1.1.9, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
Dribble takes a pathname for a text file. Once called, the interactive IO will be written to that file.
* (dribble "/Lisp/tmp/2013-09-06-01.text")
* (defun foo (a) (1+ a))
FOO
* (foo 10)
11
* (quit)
See the file:
rjmba:tmp joswig$ cat 2013-09-06-01.text
* (defun foo (a) (1+ a))
FOO
* (foo 10)
11
* (quit)
From above you should be able to see if you have any interesting functions entered...
You could also set your SBCL (for example using the init file) to set up dribble always at start. Calling (dribble) without arguments ends a dribble.
Next: FUNCTION-LAMBDA-EXPRESSION:
* (defun foo (b) (1- b))
FOO
Now you can call FUNCTION-LAMBDA-EXPRESSION to get the definition back. It might be slightly altered, but it should do the job to recover valuable ideas written as code:
* (function-lambda-expression #'foo)
(SB-INT:NAMED-LAMBDA FOO
(B)
(BLOCK FOO (1- B)))
NIL
FOO
If you are using sb-readline or rlwrap you press up until you hit when it got defined and copy and paste itto a file. You might have it in the termial window history too.
If none of these works only compiled definitions are available then the only way to save them is by dumping core image.
For next time, you could make a macro that stores every definition source in a special variable so that you can easily retreive them.
Related
I was asked to write a program in racket in order to change the behaviours of arithmetic operators from prefix to postfix. More precisely:
I want this code: (a b +) to behave like: (+ a b)
I wanted to use define-syntax-rule in order to change the behaviour of the + operator, but I have one problem, while using define-syntax-rule we write at first the name of our macro, and after that we write the arguments.
My question: Is there any way to write the arguments at the beginning and the name at last in racket functions?
The easiest way to accomplish this is to create your own #%app macro. Since you are essentially creating a new language here, you'll want two modules: a 'lang' module that defines your language, and a 'use' module, for the program you want to write in that language. This could be done with two files, or one file using submodules.
Here, I'll show it to you using two files:
lang.rkt
#lang racket
(provide (except-out (all-from-out racket)
#%app)
(rename-out [-app #%app]))
(require syntax/parse/define)
(define-syntax-parse-rule (-app args ... proc)
(#%app proc args ...))
use.rkt
#lang s-exp "lang.rkt"
(3 2 +) ; => 5
Note though that this only changes function calls, not other forms. So:
use2.rkt
#lang s-exp "lang.rkt"
(define x 42)
(2 x *) ; => 84
Edit:
To explain what's happening in lang.rkt. It's taking the racket language, and re-exporting all of it, except the #%app macro. (For reference, all function applications in racket (f args ...) get expanded to (#%app f args ...).)
For the #%app macro, we define another macro -app, which moves the function call from the end to the start, and the uses Racket's #%app macro. We then rename -app to #%app on export.
Section 5.1 of this paper gives you an outline of the same thing, but to turn Racket into a lazy language.
How can I ensure that all modules (and ideally also all other files that have been loaded or included) are up-to-date? When issuing use_module(mymodule), SICStus compares the modification date of the file mymodule.pl and reloads it, if newer. Also include-ed files will trigger a recompilation. But it does not recheck all modules used by mymodule.
Brief, how can I get similar functionality as SWI offers it with make/0?
There is nothing in SICStus Prolog that provides that kind of functionality.
A big problem is that current Prologs are too dynamic for something like make/0 to work reliably except for very simple cases. With features like term expansion, goals executed during load (including file loading goals, which is common), etc., it is not possible to know how to reliably re-load files. I have not looked closely at it, but presumably make/0 in SWI Prolog has the same problem.
I usually just re-start the Prolog process and load the "main" file again, i.e. a file that loads everything I need.
PS. I was not able to get code formatting in the comments, so I put it here instead: Example why make/0 needs to guard against 'user' as the File from current_module/2:
| ?- [user].
% compiling user...
| :- module(m,[p/0]). p. end_of_file.
% module m imported into user
% compiled user in module m, 0 msec 752 bytes
yes
| ?- current_module(M, F), F==user.
F = user,
M = m ? ;
no
| ?-
So far, I have lived with several hacks:
Up to 0.7 – pre-module times
SICStus always had ensure_loaded/1 of Quintus origin, which was not only a directive (like in ISO), but was also a command. So I wrote my own make-predicate simply enumerating all files:
l :-
ensure_loaded([f1,f2,f3]).
Upon issuing l., only those files that were modified in the meantime were reloaded.
Probably, I could have written this also like — would I have read the meanual (sic):
l :-
\+ ( source_file(F), \+ ensure_loaded(F) ).
3.0 – modules
With modules things changed a bit. On the one hand, there were those files that were loaded manually into a module, like ensure_loaded(module:[f1,f2,f3]), and then those that were clean modules. It turned out, that there is a way to globally ensure that a module is loaded — without interfering with the actual import lists simply by stating use_module(m1, []) which is again a directive and a command. The point is the empty list which caused the module to be rechecked and reloaded but thanks to the empty list that statement could be made everywhere.
In the meantime, I use the following module:
:- module(make,[make/0]).
make :-
\+ ( current_module(_, F), \+ use_module(F, []) ).
This works for all "legal" modules — and as long as the interfaces do not change. What I still dislike is its verboseness: For each checked and unmodified module there is one message line. So I get a page full of such messages when I just want to check that everything is up-to-date. Ideally such messages would only show if something new happens.
| ?- make.
% module m2 imported into make
% module m1 imported into make
% module SU_messages imported into make
yes
| ?- make.
% module m2 imported into make
% module m1 imported into make
% module SU_messages imported into make
yes
An improved version takes #PerMildner's remark into account.
Further files can be reloaded, if they are related to exactly one module. In particular, files loading into module user are included like the .sicstusrc. See above link for the full code.
% reload files that are implicitly modules, but that are still simple to reload
\+ (
source_file(F),
F \== user,
\+ current_module(_, F), % not officially declared as a module
setof(M,
P^ExF^ExM^(
source_file(M:P,F),
\+ current_module(M,ExF), % not part of an official module
\+ predicate_property(M:P,multifile),
\+ predicate_property(M:P,imported_from(ExM))
),[M]), % only one module per file, others are too complex
\+ ensure_loaded(M:F)
).
Note that in SWI neither ensure_loaded/1 nor use_module/2 compare file modification dates. So both cannot be used to ensure that the most recent version of a file is loaded.
Hello all I am trying to dynamically build pdf files based on switches in a global defines file.
In file global_defines.rkt i have
#lang racket/base
(provide (all-defined-out))
(define alpha #f)
(define beta #t)
(define gamma #f)
in file foo.scrbl
#lang scribble/base
#(require "../../pdf_gen/global_defines.rkt")
#title{Getting Started}
#if[(or alpha)
#para{Test text}
""]
#if[(or beta)
(begin
#dynamic-require["bar.scrbl" 'doc]
doc)
""]
and in file bar.scrbl
#lang scribble/base
#(require "../../../pdf_gen/global_defines.rkt")
#(provide (all-defined-out))
#title{BAR}
happy marbles
so with the switches as they are currently i would expect to get something similar to the following out
Getting Started
1.BAR
happy marbles
while there are definitly other ways i can do it i would prefer to stick with scribble as it makes formatting and everything much easier than the other methods i can come up with right now. My main concerns are keeping the switches in one place and being able to pick and choose the content that is triggered by the switches being active, as there is content that will be common between several of the documents but not all of them, and quite a bit of content that only belongs in one or 2 places.
Although this answer isn't as elegant as I'd like, it works.
Basically I think you're talking about conditional compilation. In C you'd use a macro for this. In Racket let's use a macro, too (a macro which is just as brain-dead simple as a C macro).
Also we need a macro because Scribble's include-section is syntax (not a function) and must appear at the top-level. As a result, you can't use it inside of an if or when.
Given that:
define.rkt
#lang racket/base
(provide (all-defined-out))
;; Macros to conditionally include literal text.
;; Each of these should return `text`,
;; or (void) for nothing
(define-syntax-rule (when-alpha text)
text)
(define-syntax-rule (when-beta text)
(void))
;; Macros to conditionally include a .scrbl file
;; Each of these should return include-section,
;; or (void) for nothing
(require scribble/base) ;for include-section
(define-syntax-rule (when-alpha/include mod-path)
(include-section mod-path))
(define-syntax-rule (when-beta/include mod-path)
(void) #;(include-section mod-path))
Currently, this is set to show things for "alpha" but omit them for "beta". Unfortunately there's not a simple #t or #f to toggle. You need to edit the body of each one a bit more than that, as explained in the comments.
manual.scrbl example file conditionally including text and another file
#lang scribble/base
#(require "defines.rkt")
#title{Getting Started}
#when-alpha{#para{Text for alpha}}
#(when-beta/include "includee.scrbl")
includee.scrbl example file being conditionally included
#lang scribble/base
#title{BETA TEXT}
I am text for beta version.
What I don't love about this solution is that you have to create/change a pair of macros for each condition -- one for including literal text, and another for include-section-ing a .scrbl file.
I trying to completely automatize sending job applications. First step, to put the name of the company in a letter. It almost works, but it is stuck because it asks what command to use. Reading the documentation, I thought it could be disabled by a prefix argument, but I got something wrong. Also, it doesn't need to flash by visually, it could be done completely as a background process. I'll paste the code and you'll understand immediately:
(Oh, I'm using LaTeX/P mode in emacs - the goal is to not only update the .tex but also the .pdf file)
(defun edit-letter (comp-name)
(let ((path "~/work/letter/comp"))
(edit-letter-file-path comp-name (concat path "/eng/letter.tex"))
(edit-letter-file-path comp-name (concat path "/swe/brev.tex")) ))
(defun edit-letter-file-path (company-name file-path)
(find-file file-path)
(goto-line 14)
(kill-line)
(insert (format "\\textbf{To %s}\n" company-name))
(setq current-prefix-arg nil)
(call-interactively 'TeX-command-master) ; asks what command
(kill-buffer) ) ; doesn't work
(edit-letter "Digital Power Now")
It's not entirely clear from your question what you're after, but if you want to use AucTeX to call a LaTeX/PDFTex/BibTex process without getting prompted for the command name, you can use this:
(TeX-command "LaTeX" 'TeX-master-file)
Try this in place of (call-interactively 'TeX-command-master) above. When you're using LaTeX/P "LaTeX" really means pdflatex.
Haskell's main function does just what I want: evaluate when the file is loaded by itself (e.g. ./myfile.hs or runhaskell myfile.hs) and in no other case. main will not be called when the file is imported by another file. newLISP also has this functionality.
Is there equivalent code for Common Lisp?
I read the source code for CLISP. Here's what happens when the user enters clisp myfile.lisp or ./myfile.lisp:
CLISP saves myfile.lisp as p->argv_execute_file.
CLISP creates the expression (LOAD "p->argv_execute_file") and pushes it onto the Lisp stack.
CLISP saves any additional command-line arguments in a list.
CLISP stores the arguments in the Lisp variable *args*.
CLISP never makes a Lisp variable referring to p->argv_execute_file, so there is no way to discern whether myfile.lisp was loaded directly, by the user in the REPL, or by another Lisp file. If only (car *args*) were myfile.lisp, my task would be easy.
Note: Shebangs give CLISP trouble if the file is loaded from the REPL, so I put this code in ~/.clisprc.lisp:
(set-dispatch-macro-character #\# #\!
(lambda (stream character n)
(declare (ignore character n))
(read-line stream nil nil t)
nil))
I found a solution. It's a bit of shell trickery, but it works. I'll soon modify this to work on CL implementations other than CLISP.
#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$#"}
exit
|#
;;; Usage: ./scriptedmain.lisp
(defun main (args)
(format t "Hello World!~%")
(quit))
;;; With help from Francois-Rene Rideau
;;; http://tinyurl.com/cli-args
(let ((args
#+clisp ext:*args*
#+sbcl sb-ext:*posix-argv*
#+clozure (ccl::command-line-arguments)
#+gcl si:*command-args*
#+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
#+cmu extensions:*command-line-strings*
#+allegro (sys:command-line-arguments)
#+lispworks sys:*line-arguments-list*
))
(if (member (pathname-name *load-truename*)
args
:test #'(lambda (x y) (search x y :test #'equalp)))
(main args)))
(eval-when (situation*) ...)
Update sorry for the confusing answer.
I could be wrong, but it seems to be impossible to do what you want exactly. I would make a shell script and call clisp -i myfile.lisp -x (main).
Is there any reason to not make it executable (described here)?
P.S. Common Lisp is a language and clisp is one of the implementations.