When encountering an unbound identifier error for a racket symbol, how should one find out which module to require for the symbol?
For example, I encountered the following error while execute a racket file (as of 8.6):
....rkt:39:17: symbol=?: reference to an unbound identifier
; at phase: 1; the transformer environment
I tried (help symbol=?), which correctly led me to its documentation page, on "Section 4.2 Booleans". But how can I tell which module to import so that I can have symbol=??
I tried
(require (for-meta 1 racket/base))
but the error remains.
You can get that information from DrRacket Docs- when you search for any symbol, you will see a list of packages/ libraries that provide it.
Look at the results for symbol=?. The most straightforward solution is to use #lang racket (at the beginning of the code) or (require racket/bool).
This is even written in "Section 4.2 Booleans"- there are symbols boolean?, not and immutable?, followed by "4.2.1 Boolean Aliases":
(require racket/bool)
package: base
The bindings documented in this section are provided by the racket/bool and racket libraries, but not racket/base.
Related
I'm starting to work through SICP using DrRacket. I installed the sicp package, and declared #lang sicp at the top of the unit test file and then (require rackunit "xxx.scm"), but I get an unbound identifier error. Is there a mistake, or is it not possible to use rackunit with the sicp package in this way?
You need to use #%require.
#%require is actually a primitive type in the lowest level of racket and it is slightly different than require:
#lang sicp
(#%require rackunit "xxx.scm")
The file you want to test becomes a module so you can use it from other code by providing the identifiers you want to expose:
(#%provide procedure-name)
You can also just require a few needed forms. eg. error and time from racket/base:
(#%require (only racket/base error time))
A hint on finding out where they are is to search the online manuals or from Help > Racket documentation in DrRacket. Eg. here is an example of searching error where you have many choices, but the racket prefixed ones are the ones you're looking for.
NB: Not all forms are compatible across languages. Eg. R5RS has different pair implementation than #lang racket
I have this file:
#lang racket
(provide install global-var)
(define global-var 'test)
(define (install)
(set! global-var '(aaa)))
(install)
And I start the repl, typing so:
Welcome to Racket v5.3.5.
> (define global-var "test007")
> global-var
"test007"
> (require "test.rkt")
'(install)
> global-var
'test
Is it possible to load only some definitions from the file test.rkt, such that the loading does not change the value of global-var, only if I call myself (install), after I load?
I want to use only the standard racket system, not outside packages that are not installed by default in racket.
The short answer is: probably not. You should think of a racket module as a pre-compiled bundle of code that exports certain functions. Any expressions at the top level (such as the call to 'install' here) are conceptually part of the module's setup; allowing a user to use the definitions without running the setup code would invalidate the assumptions of the module writer---not nice for the writer of the module.
To take an example, I have a sound library; requiring the sound library module initializes the sound playback. If there were a tricky way to load the module without running this code, my invariants would be violated.
Perhaps you can explain why it's inconvenient for you to edit the source code?
I tend to use Notepad++ as editor to learn lisp and this helps me with prompting the keywords as I type them on editor. But not all the keywords are enlisted in its language plugin.
I want to add those keywords into it. Is there some command in lisp that it lists its keywords or some source that contains these keywords/function templates etc that I can just add them by pasting them in NP++ plugin.
Manually accomplishing this will be very time consuming.
Assuming, that you want the symbols of the COMMON-LISP package, you can use
(do-external-symbols (sym :common-lisp)
(print sym))
to collect all symbols exposed by the COMMON-LISP package. According to the ANSI standard,
The COMMON-LISP package has as external symbols those symbols enumerated in the figures in Section 1.9 (Symbols in the COMMON-LISP Package), and no others"
so the above should give you exactly the stuff defined by the ANSI common lisp language (and nothing else).
To get a sorted list, try
(let (result)
(do-external-symbols (sym :common-lisp)
(push sym result))
(sort result #'string<))
on the REPL.
Perhaps you can just copy-paste the symbols from CLHS: http://www.lispworks.com/documentation/HyperSpec/Front/X_AllSym.htm
This is how I export symbols :bar and :baz from package foo:
(in-package :cl-user)
(defpackage foo
(:use :cl)
(:export :bar :baz))
(in-package :foo)
When I remove :baz from the list of exported symbols SBCL complains and the compilation fails.
warning:
FOO also exports the following symbols:
(FOO:BAZ)
How can I make SBCL make forget about :baz without reloading SLIME?
SBCL:
* (apropos "unexport")
UNEXPORT (fbound)
* (documentation 'unexport 'function)
"Makes SYMBOLS no longer exported from PACKAGE."
* (apropos "unintern")
UNINTERN (fbound)
* (documentation 'unintern 'function)
"Makes SYMBOL no longer present in PACKAGE. If SYMBOL was present then T is
returned, otherwise NIL. If PACKAGE is SYMBOL's home package, then it is made
uninterned."
Search led me here, but I had slightly different issue.
; caught WARNING:
; MY-PACKAGE also uses the following packages:
; (DEPENDENCY)
For this case, one needs
* (documentation 'unuse-package 'function)
"Remove PACKAGES-TO-UNUSE from the USE list for PACKAGE."
There is plenty of documentation on these issues, which you should read or reread. This package/symbol thing sounds trivial enough at first sight, but it is different enough from what other languages do to be worth some reading (i.e. trying to reuse knowledge from other languages is particularly risky when it comes to packages and symbols).
If, after reading the docs, you still have trouble, try rereading them (the experience gained by having trouble will help you focus on the relevant sections; rereading without getting into trouble between readings is not very productive IMHO).
Some links I found useful:
http://www.lispworks.com/documentation/HyperSpec/Body/11_.htm
http://www.gigamonkeys.com/book/programming-in-the-large-packages-and-symbols.html
http://www.flownet.com/ron/packages.pdf
In C/C++, I can make a library, and make it static one or dll using #include "" in source code, and -labc when linking.
How do I have the same feature in lisp?
As an example of util.lisp in directory A. I define a library function hello.
(defpackage "UTIL"
(:use "COMMON-LISP")
(:nicknames "UT")
(:export "HELLO"))
(in-package util)
(defun hello ()
(format t "hello, world"))
And try to use this library function from main function.
(defun main ()
(ut:hello))
(main)
I tried
clisp main.lisp A/util.lisp
But, I got the following message
*** - READ from #: there is no package with name "UT"
What's the equivalent of #include "" to use the library?
What's the equivalent of -lutil to load the library? What's the command line for clisp/sbcl to use the library?
And for defpackage, Is this equivalent to namespace?
ADDED
I just had to load the library.
(load "./A/util.lisp")
(defun main ()
(ut:hello))
(main)
And run 'clisp main.lisp' works fine.
What you are looking for are called systems. Common Lisp's defpackage has nothing to do with this, and yes, it's about namespaces. Have a look at the HyperSpec, or the idiot's guide (see Xach's comment below) to read more about it.
You can restrict yourself to merely loading files, but usually, a system definition facility is used; mostly ASDF nowadays. A minimal example:
(defsystem my-system
:name "my-system"
:version "0.0.1"
:author "myself"
:license "LLGPL"
:description "it's a system."
:serial t
:components ((:file "packages")
(:file "stuff")
(:file "more_stuff")))
Where packages.lisp would contain the package definition, stuff and more_stuff are the lisp or fasl files to be loaded. This system definition (usually named filename.asd) must be symlinked to (or located in) a directory contained in asdf:*central-registry* for ASDF to find your system. Then, you can load the system thusly:
(asdf:oos 'asdf:load-op 'my-system)
An alternative to this has been added in more recent versions of ASDF:
(asdf:load-system 'my-system)
Or, when using slime, by pressing ,l my-system RET.
You have to load util.lisp before main.lisp:
> (load "util.lisp")
> (load "main.lisp")
> (main)
hello, world
NIL
Practical Common Lisp has a good introduction to defining and using packages.
Common Lisp is an image base language, although usually to a lesser extent than Smalltalk. This means that you use a library by loading it into the image, using LOAD (if used explicitly the often in form (load (compile-file "your-file-here"))), or usually with a system definition facility like ASDF. The loaded code is then available for all code compiled/loaded in the future.
Packages are indeed namespaces. They deal with mapping strings to symbols only, they are not connected directly to files or functions or anything else. You received a package error because you attempted to load a file using a package before a file defining it.