Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to get started with Lisp and I have some (messy) code that i want to be able to ask the user for a title and url.
Save them in a variable, and then print them out when called. I am running into troubles though. First of all i don't know how to compile my program to run it. Also, the one time when i did run it i got an error about the variable title being uncalled. Can anyone help me with either of these things? Sorry i can't give you more information about the error.
;;Define a function called make-cd that takes four parameters
(defun make-url( title url ))
(list :title title :url url)
;;In the make-url function create a plist that takes the passed values
;; Define global variable db and set its value to nil
(defvar *db* nil)
;; Define a function that takes one paramter and pushes it to the make-url func.
;;(defun add-url (url) (push url *db*))
;; Define a function that takes the *db* variable and makes the output pretty
(defun dump-db ()
(dolist (url *db*)
(format t "~{~a:~10t~a~%~}~%" url)))
(defun prompt-read (prompt)
(format *query-io* "~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))
Perhaps this will help.
Lisp programs aren't always distributed in compiled form. Having your program as just the source code is even better then only having the FASL (that's how Lisp binaries are called) because it makes it easier to fix problems if they are found later.
Traditionally, more complex programs, are arranged by means of ASDF package asdf:defsystem macro. You can read more about it here: http://common-lisp.net/~mmommer/asdf-howto.shtml . You can find examples on the internet, of how this is usually done through using Quicklisp and looking into its ~/quicklisp/dists/quicklisp/software/<name of the program>/ directory to see how other programs are arranged.
Once system is defined by asdf:defsystem, you would use asdf:oos to "operate" on it, that is load it. However, Quicklisp has become a very popular and easy to use utility for working with Lisp systems (it uses ASDF package underneath too). So, considering you have it, you would then (ql:quickload "your-system").
In order to make your system available locally through Quicklisp, I'd recommend doing it this way: In your $HOME directory (on Linux it is usually aliased with tilde ~) in the file: ~/.config/common-lisp/source-registry.conf (you may need to create one, if it's not there already), add something like:
(:source-registry
(:tree (:home "quicklisp/quicklisp/"))
(:tree (:home "Projects/my-project/"))
:inherit-configuration)
The above would imply that ~/Projects/my-project/ directory contains a system definition file (*.asd), where you have described what files belong to the system and instructed on how to load them etc.
For other options for adding local projects, read the Quicklisp FAQ
For more information about source-registry.conf file format read ASDF manual.
This is a bit involved at the beginning, so I'd advise you to just install one project using Quicklisp and study how it is made. Alexandria could be a good start - besides being a generally useful package, it isn't very large and illustrates the matter very well, IMO.
The code you have provided contains errors and will not compile. The error is in your definition of make-url. The proper definition should be:
(defun make-url( title url )
(list :title title :url url))
Notice the difference in parenthesis placements.
In your code you had an additional parenthesis following the parameter list. This closed the defun, causing make-url to be evaluated as a function with no body. The next line was then evaluated as a call to the built-in function list. The arguments were evaluated, and an error was encountered when it attempted to find a value for title. There is no binding in the global environment, a binding for title only exists within the body of make-url.
Also, your definition of add-url is commented out. A semi-colon begins a comment in Lisp.
How to compile and run your program depends on what compiler you are using. If you are using SBCL the function is sb-ext:save-lisp-and-die. A simple program like this would usually be run in a Read-Eval-Print-Loop(REPL), and most compilers will enter one when started. If you have SBCL installed you can start a repl by entering the command 'SBCL' to the command prompt. If your code is in an external file you can then load that using Load.
Related
Problem
My web front-end calls back-end queries with complex arguments. During development, to avoid time-consuming manual replication of those arguments, I want to capture their values in Vars, which can be used in REPL.
Research
This article shows that inline def is a suitable solution, but I couldn't make it work. After a call from the front-end happened, the Var remained unbound.
I launched the backend with REPL through VS Code + Calva, with the following code:
(defn get-analytics-by-category [params]
(def params params)
...)
And here's the evaluation of the Var in the REPL:
#object[clojure.lang.Var$Unbound 0x1298f89e "Unbound: #'urbest.db.queries/params"]
Question
Why the code above didn't bound value of the argument to the Var? Is there another solution?
The best way that I found is to use scope-capture library. It captures all the local variables with addition of 1 line in a function, and then with another 1-liner you can define all those variables as global, which allows you to evaluate in REPL any sub-expression in the function using runtime values.
If you ever spent a lot of time reproducing complex runtime values, I strongly recommend watching their 8-min demo.
My issue with inline-def was likely caused by reloading namespace after the Var was bound to a value. After restarting VS Code and carefully doing everything again, the issue went away.
Another way to look at the runtime is to use a debugger.
It is more flexible than scope-capture, but requires a bit more work to make variables available outside an execution.
VS Code's Calva extension comes with one, there's also Emacs packages.
Sometimes when I open Emacs, Emacs initialization fail.
That is because .emacs or init.el files have a bug. (My bugs often come from just mistyping.)
I want to find the bug in .emacs or init.el. Is there any way to do this?
To find out what part of your init file (~/.emacs) is causing the behavior you see, bisect your init file recursively: First comment-out half, to see which half is responsible, then 3/4, to see which quarter is responsible,...
To comment out a region of text (e.g. succession of lines that you have selected), I recommend comment-region (which I bind to C-x C-;). With a numeric prefix arg it uses that many ; comment chars. With a plain prefix arg (C-u) it uncomments the region instead of commenting it.
You can also start Emacs with the command-line switch --debug-init. This will cause the debugger to open when an error is raised during Emacs startup, including while your init file is loaded. The debugger backtrace tells you which evaluation raised the error (which function was called), and it shows you which function called the function where the error was raised, which function called that one, and so on.
When you know which function is the problem, if you need to you can debug its evaluation by putting (debug-on-entry 'THE-FUNCTION) near the start of your init file. That will open the debugger when the function is entered instead of just showing what happened when the error was raised. You can then step through the debugger using d (or c to skip through a step), to see just what went wrong.
If you prefer to step through the function starting at some breakpoint, then copy the source code that defines the function to your init file, and insert (debug) at the position where you want the debugger to open.
As always, the Emacs manuals are your friends. See, for instance, node Checklist in the Emacs manual and node Invoking the Debugger in the Elisp manual.
There is another debugger also, called edebug, which is also documented in the manuals. Some people prefer it to debug. (I prefer debug.) Both are good.
Using the debugger is generally more informative if you have loaded Emacs Lisp source files rather than their byte-compiled versions. If you start investigating a particular problem using the debugger, you might want to first load the *.el (not *.elc) file(s) in question.
I've had great success with elisp bug hunter https://github.com/Malabarba/elisp-bug-hunter.
The most common problems are unmatched parenthesis, loading-failed packages.:
Automated error hunting
If your Emacs init file signals an error during startup, but you don’t
know why, simply issue
M-x bug-hunter-init-file RET e
and The Bug Hunter will find it for you. Note that your init.el (or
.emacs) must be idempotent for this to work.
Interactive hunt
If Emacs starts up without errors but something is not working as it
should, invoke the same command, but choose the interactive option:
M-x bug-hunter-init-file RET i
The Bug Hunter will start a separate Emacs instance several times, and
then it will ask you each time whether that instance presented the
problem you have. After doing this about 5–12 times, you’ll be given
the results.
You can debug your .emacs file like this: Debugging a customization file
Start Emacs with the ‘-debug-init’ command-line option. This enables
the Emacs Lisp debugger before evaluating your .emacs file, and places
you in the debugger if something goes wrong. The top line in the
trace-back buffer will be the error message, and the second or third
line of that buffer will display the Lisp code from your .emacs file
that caused the problem.
You can also evaluate an individual function or argument to a function
in your .emacs file by moving the cursor to the end of the function or
argument and typing C-x C-e (M-x eval-last-sexp).
Use C-h v (M-x describe-variable) to check the value of variables
which you are trying to set or use.
I'll add it's good to anticipate. The function below, coming from oremacs.com allows to check the validity of our init file (or any other file) without starting up emacs:
(defun ora-test-emacs ()
(interactive)
(require 'async)
(async-start
(lambda () (shell-command-to-string
"emacs --batch --eval \"
(condition-case e
(progn
(load \\\"~/.emacs\\\")
(message \\\"-OK-\\\"))
(error
(message \\\"ERROR!\\\")
(signal (car e) (cdr e))))\""))
`(lambda (output)
(if (string-match "-OK-" output)
(when ,(called-interactively-p 'any)
(message "All is well"))
(switch-to-buffer-other-window "*startup error*")
(delete-region (point-min) (point-max))
(insert output)
(search-backward "ERROR!")))))
One can even add a Travis CI test.
ps: solutions summed up on wikemacs.
Some good advice has already been given. In particular, I think #Drew's response pretty much covers what you need to do.
I wanted to also mention that how you structure your config file can also help in tracking down problems. For example, grouping similar or related configuration options together can be very helpful.
However, the one thing which I found to be the most helpful was to break up my configuration into separate files. Essentially, my init.el file does nothing but setup some load-path settings so that my actual configuration code can be found and then just calls '''require to load each of the files.
In my .emacs.d directory, I have a directory called lisp and in that directory, I have a bunch of *.el files with names like init-org.el, init-clojure.el, init-javascript.el etc. In each of those files, I have the config settings relevant to the name i.e. org setup stuff in init-org.el, javascript stuff in init-javascript.el etc.
Each of these files ends with a 'provide' form i.e.
(provide 'init-org)
at the end of init-org.el and
(provide 'init-javascript)
at the end of init-javascript.el etc.
In my init.el file, I just have lines like
(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
(require 'init-org)
(require 'init-javascript)
(require 'init-clojre)
The benefit of doing this is that it is now even easier to bisect my init file. I can just comment out the first half of the require statements - many fewer lines.
the other benefit is that sometimes, if I'm having problems with some config, but it isn't really related to the work I need to do now, I can just comment out that require and get back to work. For example, if I am doing some clojure coding, but having some error when starting emacs due to a problem in my javascript setup, then I can just comment out the (require 'init-javascript) line and I'm good to go.
I'm trying to use drracket to work thru the exercises in "How To
Design Programs 2nd Ed".
A number of the exercises in this build up on the answers to previous
questions, so I would like to include the source files from the
answered questions so that I don't have to copy and paste the the body
of the old answer each time.
My main question is: How do I do this?
I have looked thru the documentation and found a method called
include that seems to do what I want, but I cant work out how to use
it correctly.
eg - I have two files:
test.rkt - this compiles and runs fine and contains one function:
(define (test) 1)
(test)
newtest.rkt - I would like this file to to be able to use the function defined in test.rkt.
(require racket/include)
(include "test.rkt")
(define (newtest) (* test 2))
When I try to compile this I get the following error:
module: this function is not defined
(Not very informative, but that's all the information I'm given...)
How do I get this first file to include without getting this error? Is include
even the right function for this, or is my approach completely wrong?
The include form isn't working because when the language is set to "Beginning Student" or one of the other teaching languages, DrRacket actually wraps your program in a module. You can see this if you open "test.rkt" in a regular text editor. The #reader.... bit is what generates the module. But when that gets included into the other file, it doesn't make sense. Thus the error complaining about module.
Unfortunately, as far as I can tell, the HtDP languages still don't have provide, which is what you need to make this work right.
If you really want to get this working, here's a way to hack around it:
Create a new file called "provide.rkt" in the same directory as your other files. While you're editing this file (and only this file), set the Language in DrRacket to "Determine language from source". Put the following two lines in "provide.rkt":
#lang racket
(provide provide)
(That declares a module using the full Racket language that provides only the built-in special form provide.)
Add the following lines to your "test.rkt" program. (Make sure DrRacket's Language is set back to "Beginning Student" or whichever teaching language you're using for this.)
(require "provide.rkt")
(provide test)
Now "test.rkt" is a module that exports your test function. (It was always a module, it just didn't have any exports before, so it wasn't very useful.)
Add the following lines to your "newtest.rkt" program:
(require "test.rkt")
That imports everything provided by "test.rkt": currently just test, but you can add other things to, you just have to provide them.
I'm trying to code up an Emacs script that has to manipulate the clipboard (just getting the last entry and manipulating it as a string). The problem is that I work on Linux (at home) and Windows (at work). In Windows, I have to use the function (w32-get-clipboard-data), whereas Linux uses (x-get-clipboard) for the same purpose (and each OS helpfully errors out when you use the others' equivalent function).
I really don't want to keep two separate files with the same mode definition; is there any way to check, via elisp, which OS Emacs is currently running, so I can use the appropriate function?
PS. Yes, a reasonable solution is "Stop using Windows at work", and I'm working on it, but I'll need to put up with the thing for at least a month or two yet.
You could check if the functions are bound (if they exist) using fboundp. Then if you want to get really clever you could create your own alias that points at the right one. For example:
(defalias 'my-get-clipboard-data
(cond ((fboundp 'w32-get-clipboard-data) 'w32-get-clipboard-data)
((fboundp 'x-get-clipboard) 'x-get-clipboard)
(t nil)))
See the system-type variable.
I use the cscope emacs extension (and find it quite useful). Unfortunately, it's default behaviour of only searching the current directory and below is insufficient for me, so I use the cscope-set-initial-directory to the directory of my choice. Unfortunately this has become insufficient for me as well because I have multiple different projects each with their own "initial" directory.
I have set up hot keys for the three cscope methods I use the most in emacs
(global-set-key [f9] 'cscope-find-this-text-string)
(global-set-key [f8] 'cscope-find-global-definition)
(global-set-key [f7] 'cscope-find-this-symbol)
I figured it would be pretty easy to somehow wrap those calls with a function to run cscope-set-initial-directory on a given path (generated by looking at what the buffer-file-name is). But I have as-yet been unsuccessful!
(global-set-key [f9] (lambda () (interactive) (cscope-set-initial-directory "blah") 'cscope-find-this-text-string))
doesn't work. I've also tried adding hooks to the two cscope-hooks, but neither of those seem to ever get called during my normal usage patterns. I wouldn't even mind running it once every time I switch buffers, but I didn't see a hook for that anywhere either :/.
Can someone help? :)
Disclaimer: I've not installed cscope so cannot test this.
(global-set-key (kbd "<f9>") 'my-cscope-find-this-text-string)
(defun my-cscope-find-this-text-string (dir)
(interactive "DRoot area to start search:")
(let ((default-directory dir))
(call-interactively 'cscope-find-this-text-string)))
The basic idea being you want to prompt for a directory to start from: that's the call to interactive. Then you set the directory: the let statement does that for you. Then you call the original routine you wanted, and by calling it with 'call-interactively you get prompted.
You'd wrap the other two routines similarly.
Once that's working for you, you can get fancier by customizing prompt for a root area to have its own history variable that's shared across the three routines.
Regarding your initial solution, that was a good try. Most don't realize the need for 'interactive to turn the function into a command. The reason the quoted name doesn't work for you is that the quote simply tells the interpreter to treat the symbol as a symbol and not do to anything with it. To call the routine, you'd generally do:
(lambda ()
(c-scope-find-this-text-string "some-string"))
Unfortunately, with a direct call like the one just above, you have to provide an argument (the string to search for). So, you can either add some code to prompt for the string, or use the command's built-in code to do the prompting. That's what the 'call-interactively is used for, it calls the command and invokes its 'interactive form which does the prompting.
Also, it's generally a good idea to bind keystrokes to names of commands, as opposed to bare lambdas, for two reasons: first, if you ever do C-h k (M-x describe-key), you get a meaningful command name, and second, if/when you modify the function, you can do so without having to muck with the binding as well.