Get code from REPL - lisp

If I'm entering code into the REPL using clisp, as in the program you get when you do sudo apt-get install clisp, is there a way to take all the code you've entered so far and save it in a file? I'm a Lisp beginner so I don't know if that's a ridiculous request or not.

You can start output recording with the function DRIBBLE.
Other than that I would run CLISP from a terminal program which can save input / output.
As the minimum I would usually use Emacs, run a shell via M-x shell and start the Lisp there. That way the I/O goes into an Emacs shell buffer.
There is also SLIME, which sets up quite a bit more functionality inside Emacs to communicate with a 'slave' Common Lisp. A 'listener' (aka REPL) is part of that.

There is probably a better way, but... If you are using a decent terminal program, you should be able to select the text in the terminal and save it to file. This would include your typed input as well as output, so you would have to manually remove the output.

Related

How the input is provided in LISP?

I am totally new to lisp, but I came accross this code https://github.com/wjur/sym-diff-lisp/blob/master/sym-diff.lsp which calculates derivatives in lisp and I wanted to know how to run it. I see the examples in comments in the beginning but I am not sure how to run it.
I just installed clisp in ubuntu and tried to run 'clisp sym-diff.lsp' but I dont know where am i supposed to pass the exact functions that I want to differentiate. Should I pass it as arguments when running sym-diff.lsp?
Start CLISP - you should have a terminal window, which is waiting for you to do something. This is your REPL.
You have to load the code, thus:
(cd "file-location")
(load "filename")
Once you done that then you can type in your examples into the REPL.

"illegal terminating character after a colon: #\" in portacle, though no colons in code

I've recently set up Portacle 1.3 for learning common lisp on Win 7. However, whenever I run my code I get the error, even if there is no code.
Running individual lines works fine, however. The error only shows when I run the whole file.
I tried putting some code in an EVAL function, but I believe that only accepts one argument at a time, so I couldn't run a whole program in it.
I've found a similar error in this stackoverflow page, but their code contains colons and that's where their error lies.
I think it might be an error in the code that runs mine, seeing as I get the error even if I compile with no code, however I know nothing.
The full error:
main.lisp:1:1:
read-error:
READ error during COMPILE-FILE:
illegal terminating character after a colon: #\
Line: 1, Column: 13, File-Position: 12
Stream: #<SB-INT:FORM-TRACKING-STREAM for "file [path to file]\\main.lisp" {1005F5F0D3}>
Compilation failed.
Portacle is a standalone Emacs packaged with everything needed for Common Lisp development and which uses SBCL as the Common Lisp implementation.
I believe what you do when you say 'compile the whole file' is call slime-compile-and-load-file which is bound to the key sequence C-c C-k by default. There are a lot of moving components here:
Emacs is the text editor here. It also takes care of launching all the necessary components for Common Lisp development.
Slime is one such component. It serves as interface between Emacs and your Common Lisp implementation (SBCL in this case, but supports any Lisp in theory). Basically it sends the code you wrote in Emacs to your Lisp for evaluation.
SBCL is the Common Lisp implementation. In this case it is a compiler. This is what evaluates the code it receives and spews out the answers to the user interface in Emacs, through Slime. It also 'lives', in the sense that you interact with it by modifying the state of the loaded Lisp image, keeping track of defined functions, global dynamic variables and much more. This is why you can have the REPL, and why you need Slime to interact with it.
So to debug your problem, I would try to:
Launch SBCL from the Windows shell and run a simple .lisp file to check that everything works. You can put for example (format t "~a" (lisp-implementation-type)) in a .lisp file and run it in SBCL from the shell by calling (load "...\\file.lisp"). It should return "SBCL".
Create a completely new file using Emacs (and not weird Windows programs that could mess up the files) (C-x C-f), and try to call the compile from there (C-c C-k).
And I believe you made the right choice of IDE. Portacle is arguably the simplest tool out there if you are a total beginner in Common Lisp and do not know Emacs configuration. The keybindings are a bit daunting though.

Running a 'Hello World' app in Agda emacs

I installed an Agda compiler, binarys can be from here: http://ocvs.cfv.jp/Agda/how-to-install-windows.html
... and I'm trying to make it compile a simple hello world app (I found the Agda 'Hello World' code online)
But I've never used Emacs before, and I don't know where to begin, or which commands to use to compile and run. I'm new to Agda, which seems to have limited options for compilers, and is lacking any step by step tutorial. Below is a screenshot of the Emacs compiler with the code I found:
open import System.IO using ( _>>_ ; putStr ; commit )
module System.IO.Examples.HelloWorld where
main = putStr "Hello, World\n" >> commit
I'm looking for step by step instructions to run a simple 'Hello World' program
A working example with another compiler would also be an acceptable answer
Thanks!
This looks like you attempted something like the general M-x compile rather than any specific Agda functionality.
The Agda:run mode indicator in the Emacs mode line suggests that you have a running Agda process in another buffer, but you're not looking at it. The Agda mode probably has something like agda-eval-buffer which should pass your current program to that process, and bring up the results in the lower half of the pane. (Try switching to a buffer called something like *inferior-agda* manually if you somehow cannot reach that buffer by other means.)
The site you link to says it's Agda 1 and you should probably actually look for Agda 2 on a different site.
Below the line is my original answer, which may still provide some useful insight.
The error message indicates that you need to install make.
I'm guessing there may be additional missing dependencies after you fix this one. Ideally the documentation should explicitly specify exactly what you need to install.
make is just a wrapper to run whatever cormands are found in the local Makefile. If there is no such file, you will probably want to change the compilation command to something else. (Typically Emacs asks you for a command to run, but supplies a plausible default.)
Given I am running on Linux and am no agda expert, this solution might not be worth it. But still I will give it a try.
When I installed agda and agda-stdlib on my system, it provides me with a file called agda2.el in /usr/share/agda/emacs-mode. That said I just had the following in my ~/.emacs.d/init.el file:
(load-file (let ((coding-system-for-read 'utf-8))
(shell-command-to-string "agda-mode locate")))
Since, you already have agada mode setup in Emacs the above wont be useful unless your version of agda mode is old.
We can compile the current file you have opened in Emacs using M-x agda2-compile. Doing this will open up another prompt asking you for a Backend. I used GHC as input and it compiled it. Yes, and I got some errors I don't know how to fix. So, I queried on a search engine and came up with:
module memo where
open import IO.Primitive using (IO; putStrLn)
open import Data.String using (toCostring; String)
open import Foreign.Haskell using (Unit)
main : IO Unit
main = putStrLn (toCostring "Hello, Agda!")
I need to point out that the first line module memo where should be same as the filename which for your case is memo.agda.
I now have a hello world program running on my machiene.
The following code compiles and works
open import Common.IO
main = putStrLn "Hello, world, strings working!"
is the code, stored in the file 'hello.agda', which I compile in emacs to 'hello'. I compile in emacs by selecting agda > compile, an option that is available on emacs when agda is installed correctly.
I can't give a detailed tutorial as to how to install agda on emacs as a friend did it for me, but the above code works, and compiles on emacs on linux, which is the set up which is working for me.

Setting TERM variable for Emacs shell

Is it possible to set the TERM environment variable for Emacs shell to some other value than "dumb"? In order to make TRAMP work I'm adjusting some parts of .bashrc on remote machines according to $TERM == "dumb" condition but for the shell I'd like these ignored (opposite approach - setting the TERM for TRUMP - would also be applicable).
Let me give your answer in two parts: first, one that technically answers your question but isn't very useful, and second, one that probably answers your needs even though it takes a different tack to get there.
Setting TERM in the shell
When starting shell-mode with M-x shell, Emacs starts the shell you want (usually the same as your login shell, but this can be changed if you really want to) and then sources a file, if it exists, based on the shell's name. The places it looks are
~/.emacs_$SHELLNAME
~/.emacs.d/init_${SHELLNAME}.sh
In this file you can set TERM. For instance, if you use zsh, and create the file
# ~/.emacs_zsh or ~/.emacs.d/init_zsh.sh
export TERM=emacs
then you'll get what you asked for: shells started with M-x shell will have the TERM set to emacs instead of dumb.
While this technically answers your question, though, it's not particularly useful—if you try it, here's what you'll get when you start a shell:
zsh: can't find terminal definition for emacs
$ echo $TERM
emacs
$
The issue here is that shell-mode doesn't implement any terminal emulation. In other words, dumb is exactly the right TERM value to use.
(Note there are modes that emulate terminals—see, for instance, M-x ansi-term—and they set TERM=eterm-color or similar, but they're designed to let you use Emacs as an xterm replacement for visual-mode shell commands, whereas M-x shell is designed to let you run shell commands while still interacting with the input and output in an Emacs-y way.)
When you choose a TERM value that isn't supported by termcap, you'll get the above error and some programs may get confused about what's happening (and some will refuse to run at all). If you select a full-featured TERM value like xterm instead, you'll get "line-noise" characters as the programs attempt to send formatting codes to a terminal emulator that isn't there.
You could probably get away with finding some termcap that was limited enough in capabilities that it won't bother you with noise too much, but if this is just to let you differentiate Emacs interactive shells from either Emacs non-interactive shells or non-Emacs interactive shells, there's a better choice.
This choice, in fact, isn't even sufficient. That's because this special shell script is loaded by both shell-mode and by TRAMP, so the above still wouldn't let you differentiate the two—you'd just get emacs in both cases instead of dumb!
So this is where the better choice comes in:
Using the INSIDE_EMACS environment variable
While, as you noted, the interactive shell and TRAMP both set TERM to dumb by default, they also set an environment variable INSIDE_EMACS.
Its existence (or not) alone is useful for your shell startup scripts, but its power for your use case lies in its value—which, for interactive (M-x shell) use, is something like 25.2.2,comint, but for TRAMP is 25.2.2,tramp.
So, to check for the three cases, here's what you can do (and what I personally have done myself in my ~/.zshrc for many years):
# Setup for all shells--Emacs or not, interactive or not, goes
# here
PATH=...
source $my_functions_file
# Now dumb terminals
if [[ "${TERM}" == "dumb" ]]; then
# Here put anything you want to run in any dumb terminal,
# even outside Emacs.
PATH=...
alias lsF='ls -F'
etc
# Now, just configs for shells inside Emacs
case ${INSIDE_EMACS/*,/} in
(comint)
do_comint_stuff
;;
(tramp)
do_tramp_stuff
;;
(term*)
# For M-x ansi-term, etc., you get a value like
# 25.2.2,term:0.96, but those shouldn't coincide with
# TERM being `dumb`, so warn....
echo "We somehow have a dumb Emacs terminal ${INSIDE_EMACS/*,/}" >&2
;;
("")
# Empty means we're $TERM==dumb but not in Emacs, do nothing
;;
(*)
# We shouldn't get here, so write a warning so we can
# figure out how else Emacs might be running a shell,
# but send it to stderr so that it won't break anything
echo "Something is wrong: INSIDE_EMACS is ${INSIDE_EMACS}" >&2
;;
esac
# finish shell setup for dumb now--the rest of the file will
# be skipped
return
fi
# Stuff for non-dumb, interactive visual, shells goes here
setup_prompt
setup_keybindings
etc
We don't reset TERM to a different value inside the case statement because dumb is exactly what it should be.
Note that above, in the (tramp) section of the case statement, you could do what you mentioned in your question—set TERM to something else just for TRAMP—but that would be a bad idea, since Emacs actually reads and acts on responses it gets from TRAMP shells, and the line noise would be an even bigger problem. TRAMP can do some really amazing things, but only when the shell output it's reading is in the format TRAMP expects.
(One final thing: using the code as above, with the INSIDE_EMACS checks nested instead the dumb terminal check, we don't have a single place to put code to be run in all Emacs-spawned shells regardless of type, including M-x ansi-term and its ilk. You could write a separate statement for that in your shell config... but that's exactly what ~/.emacs.d/init_${SHELLNAME}.sh is for, so probably a better choice if you need this for some reason.)

large output in common lisp linux terminal

I wrote a clisp program that prints out n sets of x*y random integers. I'd like to make n=100, but I can't copy and paste the whole thing because my linux terminal doesn't go back far enough, for lack of a better word.
I'd like the simplest way possible to capture 2200 lines of linux terminal readout.
From Lisp there are various ways to have your output in a file.
you can have the REPL interaction saved to a file. See the DRIBBLE function.
you can also enclose your code with WITH-OPEN-FILE.
example:
(with-open-file (*standard-output* "/tmp/foo.text" :direction :output)
(your-print-function-here))
Further to the comment above, I use sbcl on the command line to capture output. Simply load your library and then evaluate what you need.
example:
sbcl --noinform --load "compass.lisp" \
--eval "(print (table-egs (cocomo81)))" \
--eval "(quit)" > copy.txt
There are several different Linux terminal programs. They all have more or less accessible ways to configure the number of scrollback lines. I am not on my Linux box right now, but I recall this being in a relatively obvious place under the Preferences menu option for GNOME's terminal, and I would imagine KDE is similar.
I second the recommendation to use shell redirection, though; that's the more generally useful tactic.