Print output into a file or not print output? - lisp

I'd like to save or ignore outputs when I execute a specific function in lisp. I use Emacs and CCL. For example,
(defun foo (x) (format t "x = ~s~%" x))
and if I execute the function, it prints out "x = 5". But I don't want to printout in a buffer, because if I have a large amount of iteration, the speed of simulation will be decreased.
Any idea?

You can temporarily redirect standard output by binding *standard-output* to a stream. For example, a broadcast stream with no output streams will serve as a black hole for output:
(let ((*standard-output* (make-broadcast-stream)))
(foo 10)
(foo 20))
;; Does not output anything.
You can also do this with other binding constructs, such as with-output-to-string or with-open-file:
(with-output-to-string (*standard-output*)
(foo 10)
(foo 20))
;; Does not print anything;
;; returns the output as a string instead.
(with-open-file (*standard-output* "/tmp/foo.txt" :direction :output)
(foo 10)
(foo 20))
;; Does not print anything;
;; writes the output to /tmp/foo.txt instead.

Instead of t as the first argument to format, you can give it an output file stream and your output for that statement will be sent to that file stream.
However having excessive disk I/O will also will increase your running time, hence you can consider having two modes like a debug and a release mode for your program where the debug mode prints all the diagnostic messages and the release mode does not print anything at all.

I'm not sure I understand your question, but the second argument to format is a stream. If you set it to t it prints to standard output, but you can also set it to an open file.
So something like this would allow you to select where the output goes:
;;output to file:
(setf *stream* (open "myfile" :direction :output
:if-exists :supersede)
;;alternative to output to standard output:
;;(setf *stream* t)
(defun foo (x) (format *stream* "x = ~s~%" x))
(foo 10)
(close *stream*) ;; only if output sent to a file

Related

How can I read and edit the contents of a file.txt in lisp

I have this txt :
(FIEC01552 LENGUAJES DE PROGRAMACION 40)
(FIEC06411 COMPUTACION Y SOCIEDAD 39)
(FIEC03459 INTELIGENCIA ARTIFICIAL 40)
(ICM01974 ECUACIONES 40)
(ICM00604 ALGEBRA 40)
so I wanted edit or eliminate one of them so my file txt would look like
(FIEC01552 CALCULO INTEGRAL 30)
(FIEC06411 COMPUTACION Y SOCIEDAD 39)
(ICM01974 ECUACIONES 40)
(ICM00604 ALGEBRA 40)
In this moment just have read a file with this code
(let ((in (open "/tmp/materias.txt" :if-does-not-exist nil)))
(when in
(loop for line = (read-line in nil)
while line do (format t "~a~%" line))
(close in)
)
)
at the moment I 'm using clips in windows for this project
First of all, you don't want to use the functions open and close yourself. There is with-open-file which will allow us to open the file, and will automatically close it for us when we are done with it. So now that we can open the file, how can we extract the data from it? Well the data is stored as lists, so we can use the function read which reads in Lisp data structures (in this case lists). So now lets write a function that will read in all of the data in the file.
(defun read-input (file)
"Return a list containing all of the data that is in the file."
(with-open-file (in file :direction :input)
(loop for exp = (read in nil nil) ; Read an expression, if the file is empty
while exp ; exp will be nil, so the while will fail.
collect exp))) ; Collect the data into a list.
Now that we can read in all of the data, we have to eliminate the data that we do not want. Say we have a predicate 'unwanted', which returns true on any piece of data that we want to remove. We can then use the function remove-if which will take a predicate and a list, and will remove all of the elements in the list that satisfy the predicate. So now lets write a function that will do it.
(defun eliminate-unwanted-data (data-list)
"Remove all of the unwanted data from DATA-LIST."
(remove-if #'unwanted data-list))
If you want to edit the data, you are going to have to use a function 'edit-data' that uses something like mapcar, which applies a function to each element of the list. Then all you have to do is write a separate function 'convert-data', which will take a single piece of data and convert it into whatever new data that you want.
So we can now read the data in, and remove all of the unwanted data. All that's left is to write it back into a file. We can use with-open-file again since it allows us to open both input and output files.
(defun write-output (data-list file)
"Write the data out to the file."
(with-open-file (out file :direction :output
;; We want to replace the file if it already exists.
:if-exists :supersede)
(loop for data in data-list ; For each piece of data,
do (print data out)))) ; print it to the file.
So now that we have functions that do all of the pieces that we want, what's left is to chain them together.
(defun run (in-file out-file)
"Do the whole thing."
(write-output (eliminate-unwanted-data (read-input in-file))
out-file))
And we are done! All that's left is to call run with the files we want to use (they can also be the same file).
(run "input-file" "output-file")
Read the entire file as a list of s-exprs. Process that list (e.g. by removing/replacing some s-exprs). Write that list entirely into the file again.

Suppress output from print function in Lisp

I'm fairly new to Lisp, and I've run into a printing issue. I have one function which does printing to the standard output (among other things). I want to then run this function through another function where it still runs the same but instead nothing gets printed to the standard output.
Here is a simple example of what I mean. I have the following two functions described:
(defun does-printing()
(print "This goes to standard output."))
(defun run-other-function (function)
(funcall function)
(values))
Here's a dribble of what happens when I run this,
;; Dribble of #<IO TERMINAL-STREAM> started on 2014-10-05 21:49:49.
#<OUTPUT BUFFERED FILE-STREAM CHARACTER #P"example.out">
[7]> (run-other-function #'does-printing)
"This goes to standard output."
[8]> (dribble)
;; Dribble of #<IO TERMINAL-STREAM> finished on 2014-10-05 21:50:09.
Note that the printing function still prints to the standard output. It'd like to be able to suppress this printing somehow when running does-printing through run-other-function. I have tried many different variations of phrasing of my problem when searching for solutions, but nothing is getting at what I would like to do.
The simplest solution is to create an empty broadcast stream.
(with-open-stream (*standard-output* (make-broadcast-stream))
(call-some-function-1)
...
(call-some-function-n))
If a broadcast stream has no component stream all output will be discarded. Above binds the *standard-output* to such a stream. This does not cons up any data and it is portable.
You can just redirect your standard-output to some place. For example into /dev/null if you have one in your operating system. It looks like very idiomatic UNIX-way output suppressing.
Note, that you shouldn't set it to NIL, because print will signal type error in this case.
(defun does-printing()
(print "This goes to standard output."))
(defun run-other-function (function)
(with-open-file (*standard-output*
"/dev/null"
:direction :output
:if-exists :supersede)
(funcall function)
(values)))
CL-USER> (run-other-function #'does-printing)
; No value
Other option (and it may be better) is to use with-output-to-string, so you can capture this output value or just ignore it. Is think it's better, because why to do IO if we don't need it, and also it must work on any OS.
(defun run-other-function (function)
(with-output-to-string (*standard-output*
(make-array '(0)
:element-type 'base-char
:fill-pointer 0 :adjustable t))
(funcall function)
(values)))
If you doing it a lot, you can wrap it into macro or even function, to use in place of funcall.
(defun does-printing()
(print "This goes to standard output.")
"My result")
(defun funcall-with-no-output (fn)
(with-output-to-string (*standard-output*
(make-array '(0)
:element-type 'base-char
:fill-pointer 0 :adjustable t))
(funcall fn)))
CL-USER> (funcall-with-no-output #'does-printing)
"My result"
But i think macro will be more general and idiomatic for this case (may be I'm wrong).
(defmacro with-suppressed-output (&body body)
`(with-output-to-string (*standard-output*
(make-array '(0)
:element-type 'base-char
:fill-pointer 0 :adjustable t))
,#body))
So you can call many forms in with-suppressed-output.

Read from a file into a Emacs lisp list

I have the following file data.txt
A
B
C
D
I would like to read the contents of this file into a Lisp list, like
(defun read-list-from-file (fn)
(interactive)
(list "A" "B" "C" "D"))
(defun my-read ()
(interactive)
(let (( mylist (read-list-from-file "data.txt")))
(print mylist t)))
How can I modify read-list-from-file such that it returns the same list, but instead reads from the file given as input argument fn.. Each line in the file should be a separate item in the list..
This code:
(with-current-buffer
(find-file-noselect "~/data.txt")
(split-string
(save-restriction
(widen)
(buffer-substring-no-properties
(point-min)
(point-max)))
"\n" t))
UPD:
Here's a version with insert-file-contents:
(defun slurp (f)
(with-temp-buffer
(insert-file-contents f)
(buffer-substring-no-properties
(point-min)
(point-max))))
(split-string
(slurp "~/data.txt") "\n" t)
Much easier, than creating a temporary buffer, is to use f file manipulation library's f-read function that returns textual content of a file (default coding UTF-8).
f is a third-party that you need to install from MELPA, read Xah Lee's tutorial on how to use Emacs package management system. Then you could use either split-string or s string manipulation library's s-split (which is a simple wrapper around the former function):
(s-split "\n" (f-read "~/data.txt") t) ; ("A" "B" "C" "D")
Note: third parameter to s-split set to t omits empty strings. You could use s-lines, but as textual files on *nix systems usually contain a trailing newline, the returned list would be ("A" "B" "C" "D" ""). You can remove the last element with dash list manipulation library's butlast function, but this works in O(n), so probably stick to s-split, unless you want empty lines to be preserved in the list.

How do I print a string in Emacs lisp with ielm?

I'd like to print a string in ielm. I don't want to print the printed representation, I want the string itself. I'd like this result:
ELISP> (some-unknown-function "a\nb\n")
a
b
ELISP>
I can't see any way to do this. The obvious functions are print and princ, but these give me the printable representation:
ELISP> (print "* first\n* second\n* third\n")
"* first\n* second\n* third\n"
I've played with pp and pp-escape-newlines, but these still escape other characters:
ELISP> (setq pp-escape-newlines nil)
nil
ELISP> (pp "a\n")
"\"a
\""
Is this possible? For inspecting large strings, message doesn't cut it.
How about inserting directly into the buffer?
(defun p (x) (move-end-of-line 0) (insert (format "\n%s" x)))
That gets you:
ELISP> (p "a\nb\n")
a
b
nil
ELISP>
EDIT: Use format to be able to print things other than strings.
;;; Commentary:
;; Provides a nice interface to evaluating Emacs Lisp expressions.
;; Input is handled by the comint package, and output is passed
;; through the pretty-printer.
IELM uses (pp-to-string ielm-result) (so binding pp-escape-newlines has an effect in general), but if you want to bypass pp altogether then IELM doesn't provide for that, so I suspect Sean's answer is your best option.
ELISP> (setq pp-escape-newlines nil)
nil
ELISP> "foo\nbar"
"foo
bar"
#Sean's answer is correct if you want to display the string as part of your session.
However, you say you want to inspect large strings. An alternative approach would be to put the string in a separate window. You could use with-output-to-temp-buffer to do this. For instance:
(with-output-to-temp-buffer "*string-inspector*"
(print "Hello, world!")
nil)
A new window will pop up (or if it already exists, its output will be changed). It's in Help mode, so it's readonly and can be closed with q.
If you want to do some more sophisticated stuff in your output buffer you could use with-temp-buffer-window instead, like so:
(with-temp-buffer-window "*string-inspector*"
#'temp-buffer-show-function
nil
(insert "hello, world!!"))

Get files in directory, print each by lines

I'm porting some of my python scripts to Common Lisp. I need to get list of files in some directory and print each file's content by lines.
This code shows me all filenames. But lines are printed only for last file. Why?
Also, what is the best way ti iterate by file lines?
Thanks.
(dolist (file (directory (make-pathname :name :wild
:type :wild
:defaults "path\\to\\files\\")))
(print file)
(with-open-file (stream file)
(do ((line (read-line stream) (read-line stream)))
(nil t)
(print line))))
I would propose to write a function which prints a file given a pathname and a stream.
You iterate with DO. That's okay, but I would use something like LOOP which allows slightly easier to read code.
Your DO is an endless loop. You might want to end the loop when the EOF is reached.
READ-LINE generates an error when it reads past the end of the file. Thus your code signals an error on the end of the first file. This error causes your code to only print the first file.
You need to call READ-LINE such a way that you test for EOF and end the iteration then. See the arguments to READ-LINE. Alternatively you can catch the EOF error, but the other solution is slightly easier.
This seems to work for me:
(dolist (file (directory (make-pathname :name :wild
:defaults "/tmp/lt/files/")))
(print file)
(with-open-file (stream file)
(do ((line (read-line stream nil) (read-line stream nil)))
((null line))
(print line))))