I can't figure out why the below code would first print "eof" (On the interactions window). I am using DrRacket.
(find-first-path (car
(regexp-split #px"\n"
(with-output-to-string
(λ () (system "find /usr/lib/ -name
libpython2.7.so"))))))
The system library function starts a shell process that takes its input
from (current-input-port). In DrRacket, this causes the creation of a (short-
lived) subwindow of the interactions window into which you can type input that
you want to be treated as input to the subprocess.
So, for instance, try running this program
#lang racket
(system "cat")
Each line that you type into the input window will wind up being piped to the
cat process. When you're finished, though, you need a way to send an EOF to
the subprocess. This is what the "EOF" button on the right does.
If you don't want to see this window, you can create an empty input stream
to your subprocess, e.g.:
(parameterize ([current-input-port (open-input-string "")])
(system "find /usr/lib/ -name libpython2.7.so"))
Related
I'm on ubuntu 19.
Using emacs, slime and sbcl to practice some lisp.
Currently I have one buffer in slime mode in one window and the slime-description in the other window.
When I want to execute a line, I write it on the buffer and press C-c C-p.
But when I try to do the same for the line
(defvar *name* (read))
to set the the name var with the user input, nothing is happening.
Why ?
Also I would like to execute the whole script and not one line at a time, how do I do that ?
'Nothing is happening' because read is waiting for you to type something at the REPL. If you look at the REPL you will be confused because the form you are evaluating is not displayed, so all you see is ... nothing, but you need to type something at it. Further, it's not clear from your description what buffers you have displayed, but I suspect the REPL is not one of them, which is going to make things even worse.
I don't know how other people use SLIME, but what I do is to have at least the REPL (the thing you get after typing M-x-slime in one window, and a file I am working on in another. You can then interact with the REPL just by typing at it, and send code to the running lisp from the file with C-M-x or any of the other commands (in particular things like C-c C-k which compiles & loads the file.
However you almost never want a file you are compiling or loading to include anything which causes read to be called at compilation or load time: the results are going to be mysterious to put it mildly: the system will just stop with no prompt waiting for you to type something. It makes much more sense to do that in the REPL:
CL-USER> (defvar *name* (read))
(here is the data I am typing in)
*NAME*
Indeed, even when you go to some lengths to make calls to read non-mysterious in files being loaded, you have to go to yet further lengths to make them safe. Consider this file, toxin.lisp:
(defvar *my-thing*
(progn
(format *query-io* "~&thing? ")
(finish-output *query-io*)
(read *query-io*)))
Now:
$ lisp
[...]
(load "toxin" :verbose t)
;Loading #P"toxin"...
thing? #.(quit)
Of course there are much worse things I could have said than that to the Lisp.
I'm using Emacs python-mode and ipython as my IDE to write the python code. Python-mode provides a nice function "py-execute-line" to run one line code, and I've bound it to key "F7".
So for the following code:
cell = "Human" # Move the cursor to this line and run it by pressing F7
print cell # Move the cursor to this line and run it by pressing F7
I can get the output printed in the ipython buffer.
In [80]:
In [81]: Human
I'm wondering whether there's more direct way to check the value of "cell" without the print command. Something like move the cursor to the variable, press some key, and then the value is printed in the ipython output buffer.
cell = "Human" # Move the cursor to this line and run it by pressing F7
cell = "Human" # Move the cursor to "cell" and print its value by pressing ?? key or function
I have tried function (py-execute-expression-ipython), but there is no output printed ...
Thanks in advance!
Without highlighting, I use:
(defun python-eval-expression ()
(interactive)
(let ((py-command (read-string "Command: ")))
(save-excursion
(setq elpy-shell-echo-output t)
(setq elpy-shell-echo-input t)
(elpy-shell--with-maybe-echo (python-shell-send-string py-command)))))
Should be easy to adapt to choose the current selection if exists (using
Maybe consider a feature request at
https://bugs.launchpad.net/python-mode
Not exactly what you want, but you can highlight a region (by pressing C-SPC to activate the mark and moving to the other side of the region) and then type M-| to run shell-command-on-region. Then simply type python RET to run Python on the region.
For example, select these two lines:
message = "Hello, Stack Overflow!"
print message
Then type M-| python RET. `Hello, Stack Overflow!" will appear as a message at the bottom of the screen. You can do this in any mode, with any shell command. See also: Shell Commands.
So I just got Land of Lisp and started to do the first program.
I have a couple questions.
Is there a way to just write some code and run it through a compiler, or interpreter, and not use the REPL thing? I don't like it much. I can't seem to go back if I messed up. It just kinda says "Ha you screwed up, retype that whole function."
I would also like to know what the point of REPL is.
Non-REPL work flow
Edit your file
Compile the file using compile-file; fix errors and warnings; repeat.
Load the file using load; evaluate the form you want; repeat
Example
$ cat > f.lisp <<EOF
(defun f (x) (if (zerop x) 1 (* (f (1- x)) x)))
EOF
$ clisp -q -norc -c f.lisp
;; Compiling file /home/sds/f.lisp ...
;; Wrote file /home/sds/f.fas
0 errors, 0 warnings
$ clisp -q -norc -i f.fas -x '(f 10)'
;; Loading file f.fas ...
;; Loaded file f.fas
3628800
$
The Right Way
Use an IDE, e.g., Emacs with SLIME.
This way, you edit the code in an editor which supports auto-indent and shows you help for each standard symbol.
You compile and test the functions as soon as you write them, giving you a very short development cycle. Under the hood this is accomplished by the IDE interacting with the REPL (this answers your last question).
What is REPL?
Read-Eval-Print loop is a faster, more versatile version of the Edit-Compile-Run loop.
Instead of operating in terms of whole programs (which can be slow to compile and whose execution can be tedious to navigate to the specific location being tested), you operate in terms of a specific function you work on.
E.g., in gdb, you can execute a function with print my_func(123), but if you change my_func, you have to recompile the file and relink the whole executable, and then reload it into gdb, and then restart the process.
With Lisp-style REPL, all you need to do is re-eval the (defun my-func ...) and you can do (my-func 123) at the prompt.
The specific problem I'm trying to solve is
send a command to a running telnet session
echo the result of the command with message
But the general problem is sending a command to an inferior (comint) process
and waiting for output to come back and a new prompt to appear, and return the output.
I have:
(defun dired-vlc-test ()
(interactive)
(let* ((buf (process-buffer dired-vlc-telnet-proc))
(old-max (with-current-buffer buf
(point-max))))
(telnet-simple-send dired-vlc-telnet-proc "get_time")
(accept-process-output dired-vlc-telnet-proc 5)
(message (buffer-substring-no-properties old-max (with-current-buffer buf
(point-max))))))
However the output I always get is "get_time", i.e. Emacs is not waiting for new output.
I got the accept-process-output idea from this question
accept-process-output returns too early in your case because it returns as soon as it has accepted some output, but in your case you want to keep accepting output until you get a new prompt. Notice that the remote process does not tell Emacs "here's a prompt", so you will have to tweak your process filter to recognize "Oh, we received something that looks like a prompt" and you will have to call accept-process-output in a loop until the process filter tells it (via some global variable, probably) that it has seen a prompt.
I'm a beginner programmer and am going through the book "Land of Lisp".
I have been typing in the examples from the book with the REPL. Is it possible to save my current program as a .lisp file so I can load it and continue working on it later? I know I can just create the .lisp files in a text editor and load them in, but I am enjoying using the REPL in full screen mode to do the examples.
Short answer
No. Once you enter a function into the REPL, the source form is gone and you just have the interpreted or compiled form. You can do some clever things, but I suspect you don't want to deal with them right now.
Long answer
Use Emacs and SLIME
First, I know you are enjoying the REPL, but I would encourage you to look at some of the editors with Lisp support, such as Emacs with SLIME (http://common-lisp.net/project/slime/) that gives you the best of both worlds. You type into the editor, it types into the REPL, and you really don't know the difference from how you are doing things now. Then you can copy and paste the functions you like into a "proper" .lisp file. The other advantage of using Emacs is that it's based on a variant of Lisp called Elisp, so you can program your editor in Lisp. You can pretty print your code, reformat and refactor it into multiple functions, and do all kinds of excellent things.
Enough preaching!
If you still just want to type clisp and play at the REPL, then you still have options.
If you want to log the output of your REPL session, check out DRIBBLE. It will log your session to a file, and you can edit that later to extract what you want.
For example, this is a simple session:
ataylor:~ $ clisp
blah blah
[1]> (dribble "/Users/ataylor/jerome.lisp")
#<OUTPUT BUFFERED FILE-STREAM CHARACTER #P"/Users/ataylor/jerome.lisp">
[2]> (defun add-two (a b) (+ a b))
ADD-TWO
[3]> (add-two 1 2)
3
[4]> (dribble)
#<CLOSED OUTPUT BUFFERED FILE-STREAM CHARACTER #P"/Users/ataylor/jerome.lisp">
[5]>
Bye.
Viewing the contents of the file is easy, but it can get big quickly.
ataylor:~ $ cat jerome.lisp
;; Dribble of #<IO TERMINAL-STREAM> started on 2011-09-14 18:16:57.
#<OUTPUT BUFFERED FILE-STREAM CHARACTER #P"/Users/ataylor/jerome.lisp">
[2]> (defun add-two (a b) (+ a b))
ADD-TWO
[3]> (add-two 1 2)
3
[4]> (dribble)
;; Dribble of #<IO TERMINAL-STREAM> finished on 2011-09-14 18:17:16.
You could copy (defun add-two (a b) (+ a b)) and paste it into a file for later.
Loading that file (I added it to jerome1.lisp) is very simple.
ataylor:~ $ cat jerome1.lisp
(defun add-two (a b) (+ a b))
ataylor:~ $ clisp
blah blah
[1]> (load "/Users/ataylor/jerome1.lisp")
;; Loading file /Users/ataylor/jerome1.lisp ...
;; Loaded file /Users/ataylor/jerome1.lisp
T
[2]> (add-two 1 2)
3
[3]>
Bye.
Saving a session
The easiest thing you can do is saving your Lisp session to an image. It will save all of the functions you've created or compiled, along with most state. When you load it at your next session, it will be almost as if you hadn't exited clisp. The way to do this is implementation dependent, and differs between clisp, sbcl, etc. I'll show you what you would do for clisp.
The problem with this is that you can't open a file and edit it, post it on github, or whatever. I'll give a brief example.
ataylor:~ $ clisp
blah blah
[1]> (defun add-two (a b) (+ a b))
ADD-TWO
[2]> (add-two 1 2)
3
[3]> (EXT:SAVEINITMEM)
;; Wrote the memory image into lispinit.mem (3,422,616 bytes)
Bytes permanently allocated: 171,840
Bytes currently in use: 3,243,400
Bytes available until next GC: 808,130
3243400 ;
808130 ;
171840 ;
1 ;
65640 ;
7834
[4]>
Bye.
Note that message about where clisp wrote the memory image. You'll give that back to clisp with the -M flag when starting it the next time.
ataylor:~ $ clisp -M lispinit.mem
blah blah
[1]> (add-two 1 2)
3
I wanted a better answer to this same question for the following reasons:
(1) When learning a language, oftentimes you more want to experiment than to actually write a full application.
(2) When experimenting, it can be really nice to look through your history and see what you entered and what results you got.
(3) I come from the world of bash, where you can literally dump your command history into a text file and call it a "script" (though this is only a tiny fraction of the power you can get with actual bash scripting, it still serves the purpose of after-the-fact-automation, with a little cleanup.)
So, from the world of bash, I just went with the simple route—I automated a cleanup of the stdout dump. If you're using a terminal with scrollback history (anything but a virtual terminal—and if you code lisp in a VT you're just strange) to play with clisp interactively, just copy the entire terminal scrollback history to a file, then run:
sed -n -e 's/^\[[0-9]\+\]> //;tstuff' -e 'b;:stuff' -e 'p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/{s/.*//;h;d;};h;n;p;x;G;brep' myfile.lisphist > myfile.lisp
Magic! You have a working lisp program. (Obviously you should clean it up; the purpose is to have your history, not really to use it as a program. But it will only contain the lisp commands you entered, not the output/result, so it could be used directly as the program file.)
Then you can run clisp -repl myfile.lisp and voila! You're back where you got to in the last session. Of course, to load it interactively, you should take out the final (quit) line. :)
As for that sed command, what it does is look for the clisp prompt [number]>, then print that line (removing the prompt) and then try to balance the parentheses. If it succeeds, it scans for the next prompt; if the parentheses don't balance, it prints lines until they do.
Actually, it can be simplified slightly to:
sed -n -e '/^\[[0-9]\+\]> /{s///;p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}' myfile.lisphist > myfile.lisp
(Note: I don't use emacs; I've been using just clisp called directly at the command line. I don't know if there is a scrollback history within SLIME.