mit-scheme REPL with command line history and tab completion - read-eval-print-loop

I'm reading SICP and I'm using mit-scheme installed on my os x 10.8 laptop via homebrew.
Everything works as advertised, however I'm spoiled by the ease with which I get tab completion and command line history in REPL's for runtimes like Python and Node.js.
I'm not looking for anything heavy duty, but these features are pretty easy to come by in modern REPL's (it's just a simple startup file in Python and can be implemented in a few lines in Node.js).
Is there an easy way to get tab completion and command history in the mit-scheme REPL without a heavy-duty application or having to switch to emacs (i.e. in an xterm terminal)?

Install the readline wrapper:
brew install rlwrap
Once installed, rlwrap scheme will give you persistent history, paren matching, and tab completion. I typically use rlwrap with the following arguments:
-r Put all words seen on in- and output on the completion list.
-c Complete filenames
-f Specify a list of words to use for tab completion. I'm using an abridged list of bindings from the MIT Scheme Reference Manual.
Rather than republish the list here, you can find it in this gist.
I have this file stored in "$HOME"/scheme_completion.txt
rlwrap -r -c -f "$HOME"/scheme_completion.txt scheme
1 ]=> (flo:a <tab tab>
flo:abs flo:acos flo:asin flo:atan flo:atan2
1 ]=> (flo:abs -42.0)
;Value: 42.

I would actually recommend that you use Emacs, and use Geiser within that to access both the REPL and to help with scheme file editing. It also makes dealing with various Scheme REPLs such as Chez Scheme, Racket, MIT Scheme, Guile, Chicken, Gambit and Chibi Scheme effortless. Emacs remains very well tuned to use with Scheme and LISP. Highly recommended.

Related

Without Emacs, how does Bash command line editing work in Emacs mode?

Without Emacs installed on my Linux system, Bash command line editing default mode is still Emacs. How does this work without Emacs present?
I tried to search the Bash source code, but still can't understand. Does Bash integrate Emacs within itself?
$ set -o
allexport off
braceexpand on
emacs on
: :
vi off
xtrace off
The GNU(1) readline library is what does the heavy lifting for bash (and any other interactive input systems that choose to use it).
That's the source code you should be looking at, if you want to understand how it works.
The readline packages are hosted alongside bash.
(1) Yes, the same GNU that's responsible for the emacs editor.
The reference to emacs has little to do with the emacs editor itself. It refers to the 'style' of key bindings used by the GNU readline library which bash uses. Readline supports two key binding modes - emacs style and vi style. The default is usually emacs style. The readline library is very powerful, but to be honest, in 25 years of Linux use, I've never bothered with most of the advanced features and have never even tried the vi mode (even when VI was my default editor).
Read the section on readline in the bash manual for more details.

How to use key-bindings when using SBCL & Clozure CL on Terminal

I'd like to use key-bindings when I use SBCL & Clozure CL on Terminal.
You can use key-bindings when you use Clisp on Terminal. For example, when you type "Control-p", you can list the history of codes you typed. You can even delete a letter when you type "Control-d".
Do you know how to do the same things on SBCL & Clozure CL on terminal as you can do with Clisp?
I use Macbook, and the OS is 10.11.6.
I'd appreciate your help.
These characteristics are present in CLISP since it is integrated with readline, a package that provides a way to edit the command line in a shell (see the CLISP summary). SBCL and CCL are not integrated with readline, so it is not possible to use those commands with them.
The best solution to use them in a powerful environment with lot of commands is through the combination of the Emacs editor together with the SLIME package. Many tutorials exists on the net on how to install and use them. An added benefit is that Emacs and SLIME work for any implementation of Common Lisp.
It's possible if you install "rlwrap" through MacPorts.
If you run sbcl with "rlwrap sbcl" on Terminal, you can use the key-bindings.
(Note: This answer is based on the article: How to customize the SBCL REPL?
How to customize the SBCL REPL?
)

How To Run Scheme in Mac Emacs? - "process scheme exited abnormally with code 1 / 126"

Questions with similar titles (linked) do not cover the specific errors I am encountering, hence the new ask.
Context:
I am trying to set up an environment for working with scheme in emacs so I can work through the SICP book. I understand it is possible to integrate the two nicely so they work well together. I understand there are many ways of doing this even with extra features (I've seen the names quack/racket ...) but those seem like the more advanced options. Since I am having trouble setting up this bare basics 'run-scheme' in emacs I have not looked into these options extensively.
Where I'm at / What I've tried:
I downloaded MIT:GNU scheme 9.2 for OS X (x86-64). This works as expected and I can run the interpreter either from the terminal with:
$ scheme
or by executing the file "/Applications/MIT:GNU Scheme.app/Contents/Resources/mit-scheme" (which opens the interpreter in a new terminal window).
At this point M-x run-scheme returns a message saying that no such file or directory exists.
I read these two questions for reference and then:
I created a symbolic link to the binary/exec file "/Applications/MIT:GNU Scheme.app/Contents/Resources/mit-scheme" (which works perfectly when executed from finder/the terminal), then placed this file in "/usr/bin" with name "scheme".
At this point M-x run-scheme returns:
/usr/local/Cellar/emacs/24.5/Emacs.app/Contents/MacOS/Emacs:/usr/bin/scheme: Exec format error
Process scheme exited abnormally with code 126
The symlink file looked very out of place in the bin folder so not knowing what else to try I removed the symlink and instead created an actual copy of the mit-scheme exec file and placed that in "/usr/bin".
M-x run-scheme now returns this:
/usr/bin/scheme: can't find a readable default for option --band.
searched for file all.com in these directories:
/Applications/mit-scheme.app/Contents/Resources
Inconsistency detected.
Process scheme exited abnormally with code 1
Searching for help with understanding these error messages lead me to threads about issues with setting up scheme on windows OS, which is confusing, and I feel I am now out of my depth -
hoping someone knows where I'm going wrong.
End
It seems strange because I know that the 'M-x run-scheme' command is trying to access the location "/usr/bin/scheme" and I have made sure that such a location exists, and that the scheme exec file at that location works properly - I don't understand what other requirements emacs has for this to work.
What is the run-scheme command actually doing? What other requirements does it have to function as expected?
MIT Scheme looks for its libraries (including its 'bands') in a location derived from the executable's path. If the libraries are in a non-standard location, then the mit-scheme executable won't find them.
For example, in my setup, MIT scheme is located at: /usr/local/scheme/bin/mit-scheme and the band, and other stuff, is located at /usr/local/scheme/lib/mit-scheme/.
For Emacs I've defined:
(defun mit-scheme ()
(interactive)
(run-scheme "/usr/local/scheme/bin/mit-scheme -library /usr/local/scheme/lib/mit-scheme"))
Which ensures mit-scheme can find its library when, in Emacs, I perform M-x mit-scheme. If I want MIT Scheme to be the default, I would use:
(setq scheme-program-name "/usr/local/scheme/bin/mit-scheme -library /usr/local/scheme/lib/mit-scheme")
You'll need to set your values according to your installation. You also might have an option of setting MIT Scheme related environment variables to point to your library location. The relevent one is MITSCHEME_LIBRARY_PATH.
$ mit-scheme --help
Usage: mit-scheme --OPTION ARG ... --OPTION ARG ...
This machine accepts the following command-line options. The options
may appear in any order, but they must all appear before any options
for the band.
--library PATH
Sets the library search path to PATH. This is a colon-separated
list of directories that is searched to find various library files,
such as bands. If this option is not given, the value of the
environment variable MITSCHEME_LIBRARY_PATH is used; if that isn't
defined, "/usr/local/lib/mit-scheme" is used.
--band FILENAME
Specifies the initial band to be loaded. Searches for FILENAME in
the working directory and the library directories, returning the
full pathname of the first readable file of that name. If this
option isn't given, the filename is the value of the environment
variable MITSCHEME_BAND, or if that isn't defined, "runtime.com"; in
these cases the library directories are searched, but not the
working directory.
...
I'm also trying to play with the materials from SICP. It took a couple of hours and attempts to get things working.
I realized my paths were wrong after following Don't Panic! on Mojave (macOS 10.14).
I installed mit-scheme 10.1.5 from source running the installation steps from here and in the readme. My paths were different, which caused the --band command to fail.
If you're having issues double check all your paths are what you expect.
I used make install with default paths to install to /usr/local/bin and /usr/local/lib
Mac comes with emacs 22.1.1, which is old, but it works with the extra scripts from the professor for customizing emacs.
NOTE: If you quit emacs 22.1.1, it doesn't warn you about stopping scheme, which will lead to a 100% CPU usage process that you can't stop without Activity Monitor. Newer versions of emacs will prompt you to quit the scheme process before exiting (there may be a setting for older versions as well).
I installed emacs 26.1 using Homebrew and was able to get everything running after fixing these issues:
There is an error on newer versions of emacs (24+?) with ad-advised-definition-p, fix it by commenting out the function in "multi-term.el" around line 334:
; (defcustom multi-term-dedicated-skip-other-window-p nil
; "Default, can have `other-window' select window in cyclic ordering of windows.
; In cases you don't want to select `multi-term' dedicated window, use `other-window'
; and make `multi-term' dedicated window as a viewable sidebar.
;
; So please turn on this option if you want to skip `multi-term' dedicated window with `other-window'.
;
; Default is nil."
; :type 'boolean
; :set (lambda (symbol value)
; (set symbol value)
; (when (ad-advised-definition-p 'other-window)
; (multi-term-dedicated-handle-other-window-advice value)))
; :group 'multi-term)
Path setup
I had a warning:
Warning (initialization): Your ‘load-path’ seems to contain
your ‘.emacs.d’ directory: ~/.emacs.d
This is likely to cause problems...
Consider using a subdirectory instead, e.g.: /Users/paulsolt/.emacs.d/lisp
Which I solved by pointing the top line of the ~/.emacs file to:
;; (setq load-path (append (list "~/.emacs.d") load-path))
(setq load-path (append (list "/Users/paulsolt/.emacs.d/config") load-path))
The config folder already had all the scripts, that I think I was having issues getting Emacs to see.
I installed scheme from source without modifying install paths, so I changed this line:
;; This is the place where you have installed scheme. Be sure to set
;; this to an appropriate value!!!
;;(setq scheme-root "/mit/6.945")
(setq scheme-root "/usr/local")
Next to fix the issue that was causing --band to fail I modified this line.
(setq scheme-program-name
(concat
scheme-root "/bin/mit-scheme "
"--library " scheme-root "/lib/mit-scheme-c "
;;"--band " scheme-root "/lib/mit-scheme-c/all.com "
"--band " scheme-root "/lib/mit-scheme-x86-64/all.com "
"-heap 10000"))
My scheme library was installed in a mit-scheme-x86-64 folder.
Lastly, it appears that there's some other commands I had to comment out, since they don't seem to exist ...
;;(tool-bar-mode -1)
;;(scroll-bar-mode -1)
After all that setup I'm now able to create a scheme script in emacs, and I can run the script using the meta key (iTerm set my Alt key to Esc+):
M-x run-scheme
Tip: Being newer to emacs, I'm working through the emacs tutorial (C-h t) which is essential if you're going the text-based approach. In college I used emacs outside of terminal, but I'm giving it go inside the terminal this time to learn more hotkeys.

How do I type the code to the exercises in SICP?

I have been using the print eval loop, but should I be using something else?
Use DrRacket. Download it here: http://download.racket-lang.org/
The REPL is the place to do it, yes.
Most people use something on top of the REPL in the command line, like emacs, for example. I use xscheme an emacs library. The alternatives are not very good in my opinion, and using command line only is just intolerable.
If you're using Racket, just use DrRacket.
If you're using MIT Scheme, you may wish to use Edwin, a derivative of Emacs bundled with Mit Scheme, the scheme implementation SICP was originally built for. Edwin is an emacs derivative, so if you already know Emacs, you'll get along with Edwin fine. If you don't know emacs, the basics are:
C-f, C-b, C-n, and C-p for forwards, backwards, up and down, respectively.
C-Space to start selecting a region (highlight a piece of text to operate on). The region will stay there until you get rid of it with C-Space, or do something with it.
C-w to cut the region
C-k to cut the line, from your cursor onwards
C-y to paste
C-x C-e to execute the line of code directly behind your cursor in the scratch/repl buffer (the default window)
C-c C-c to halt execution of something you ran with C-x C-e
C-x C-c to quit
That should be enough to start using Edwin. It's incredibly nice to be able to just edit your definition of a function, re-evaluate the definition you edited, and have the new version start working in your repl environment on the fly.
Use Emacs, and use Geiser within that to access both the REPL and to help with scheme file editing. It also makes dealing with various Scheme REPLs such as Chez Scheme, Racket, MIT Scheme, Guile, Chicken, Gambit and Chibi Scheme effortless.
You can write the scripts in GNU Guile Scheme to implement the exercises in SICP. Most of the inbuilt procedures work with no problem and there is no difference in syntax.
In Linux,
Write the scripts using shebang notation at the beginning of the script file
#!/usr/..<address to guile interpreter> \
-e <name of procedure which should run first> -s
!#
An Example
#!/usr/local/bin/guile \
-e main -s
!#
(define main (args)
(display (+ 3 4))
(newline))
Make the file executable using chmod + <filename> and run it ./<filename>
P.S. Scheme files are saved using .scm file extension.

How to get rlwrap to work inside Emacs' shell / eshell?

When I try to get rlwrap to work inside an Emacs (version 24.3.50.1) shell buffer (either M-x shell or M-x eshell), I get this error message:
rlwrap: Oops, crashed (caught SIGFPE) - this should not have happened!
For example:
rlwrap telnet google.com 80
wors fine from a regular terminal (like xterm), but crashes from a shell inside an Emacs buffer.
Several people are having similar issue but the only "answer" I could find so far is a "RTFM" style answer on mailing lists. I did read that part of Emacs' doc and I don't understand what I'm supposed to do to make rlwrap work from within Emacs.
Try using M-xansi-term instead of shell/eshell.
shell and eshell do not provide terminal emulation functionality, but readline requires terminal emulation capabilities to move the cursor etc.

Resources