I've set up Quicklisp to run whenever SBCL runs, and added the following line to the top of my file that I'm trying to use the priority-queue library in (as suggested in the answer to my earlier question, Priority queue for Common Lisp?). However, when I try to use it, I get errors from SBCL, saying that the functions from priority-queue are not defined! What am I missing?
For reference, I tried to write something like this:
(ql:quickload "priority-queue")
(defparameter *heap* (make-pqueue #'<))
And I get an error saying that make-pqueue is not defined.
In common lisp, anything that's named (a variable, a function, a macro) is attached to a symbol. In this case, you have a function which is attached to the symbol make-pqueue. Symbols are separated from each other using packages. This keeps collisions to a minimum and also allows for things like internal variables/functions that aren't exported by the package.
Sounds like you need to do one of three things:
Use the package name before the function: (priority-queue:make-pqueue #'<). This method is good if you want people reading your source to know exactly what code is being run. however, it can get cumbersome if you call the package many times.
Use the priority-queue package in the current package you're in:
(use-package :priority-queue)
(make-pqueue #'<)
What this does is import every exported symbol from the priority-queue package into the current package you're in (most likely cl-user). While this is good for testing, you generally want to create your own package. See next item.
Define your own package that uses priority-queue:
(defpackage :queue-test (:use :cl :priority-queue))
(in-package :queue-test)
(make-pqueue #'<)
Defining your own packages seems like a lot of work at first, but you'll start to like the separation you get, especially if you start integrating different pieces of your code together.
Related
I just started learning Common Lisp a few weeks ago, so sorry if this is an obvious question. How can I load modules programmatically? I have a directory of "tasks", each a Lisp program, and would like to import each and run a specific function that they all contain.
I found out a way to iterate over a directory (via UIOP:DIRECTORY-FILES). But I'm stuck trying to figure out a way to load a module "as" a specific name, as in Python. That would allow me to load "module-1.lisp" as mod and then load "module-2.lisp" as mod in a loop.
Pseudocode:
for path in directory
(load path as mod)
(mod:function)
If there is a better way to achieve what I am trying to do, feel free to say so! Thanks in advance for any help!
Quick summary of packages and systems
"Loading as" is not something meaningful in Common Lisp, because loading is not the same as defining a new system or package. In Python, a file is a module etc. but not in Lisp.
Lisp has a concept of packages, which are namespaces. They are used to organize symbols (symbols are first-class values). In other words, they use, export or maybe shadow symbols from other packages and that's it. When you evaluate (in-package pack), you can write all accessible symbols from pack directly, like my-fun, otherwise you need to fully qualify symbols, as some-package:their-func.
There are extensions that allows you to import a package with a different name, but this is not standard (see https://github.com/phoe/trivial-package-local-nicknames)
Loading a Lisp script is not necessarily the same as defining a package, it depends on what belongs in the file (if it as defpackage forms).
When you want to organize your source code in Lisp, you define a system, using ASDF. A system list all its dependencies, its components (files) and the dependencies between their components. That's how you describe in which order files should be loaded, compiled, tested, etc.
Packages and systems are independant but in small systems you often have the the same name for a system and the unique package it defines. For larger systems there might be multiple packages.
See 21. Programming in the Large: Packages and Symbols.
Your question
Each of your file needs to define a package, to avoid polluting a single namespace, for example:
(defpackage :common-name.01
(:use :cl :utils)
(:export #:run-me))
(in-package :common-name.01)
;; some code
But once they are all loaded, either using your approach or by defining a proper ASDF system, you want to be able to access all the RUN-ME functions, in all the packages.
You can write some introspective code that lists packages, etc. but I think a better approach would be to have a way for each of your file to declare that their RUN-ME functions should be registered in your framework, like test frameworks do.
For example, at the end of your files, you could write:
(provide-function 'run-me)
This assumes that e.g. your utils package defines and exports a function named provide-function that stores values in a central registry.
For example, in utils.lisp:
(defpackage :utils
(:use :cl)
(:export #:provide-function
#:run-all))
(in-package :utils)
(defvar *all-interesting-functions* nil)
(defun provide-function (f)
(pushnew f *all-interesting-functions* :test #'eql))
And when you want to run all the functions, you can iterate over this list:
(defun run-all ()
(mapcar #'funcall *all-interesting-functions*))
Looked around and still not sure what is the difference between library()/require() and source() in r? According to this SO question: What is the difference between require() and library()? it looks like library() and require() are the same thing, maybe one is legacy. Is source() for lazy developers that don't want to create a library? When do you use each of these constructs?
The differences between library and require are already well documented in What is the difference between require() and library()?.
So, I will focus on how source differs from these. In fact they are fundamentally quite different commands. Neither library nor require actually execute any code. They simply attach a namespace, in a lazy fashion, meaning that individual functions in the package are not run unless they are actually called later. Source on the other hand does something quite different which is to execute all of the code in the file at that time.
A small caveat: packages can be made to actually run some code at the time of package loading or attaching, via the .onLoad and .onAttach functions. Have a look here: https://stat.ethz.ch/R-manual/R-devel/library/base/html/ns-hooks.html
source runs the code in a .R file, line by line.
library and require load and attach R packages.
Is source() for lazy developers that don't want to create a library?
You're correct that source is for the cases when you don't have a package. Laziness is not the only reason, sometimes packages are not appropriate---packages provide functionality, but don't do things. Perhaps I have a script that pulls data from a database, fits a model, and makes some predictions. A package may provide functions to help me do that, but it does not actually do it. A script saved in a .R file and run with source() could run the commands and complete the task.
I do want to address this:
it looks like library() and require() are the same thing, maybe one is legacy.
They both do the same thing (load and attach a package). The main difference is that library() will throw an error and stop the script if the package is not available, whereas require() will return TRUE or FALSE depending on its success. The general consensus is that library is better so that your script stops with a nice clear error and you can install the missing package before proceeeding. The question linked has a more thorough discussion which I won't try to replicate here.
I would like to add an idiosyncratically modified function to package written by someone else, with an R Script, i.e. just for the session, not permanently. The specific example is, let's say, bls_map_county2() added to the blscrapeR package. bls_map_county2 is just a copy of the bls_map_county() function with an added ... argument, for purposes of changing a few of the map drawing parameters. I have not yet inserted the additional parameters. Running the function as-is, I get the error:
Error in BLS_map_county(map_data = df, fill_rate = "unemployed_rate", :
could not find function "geom_map"
I assume this is because my function does not point to the blscrapeR namespace. How do I assign my function to the (installed, loaded) blscrapeR namespace, and is there anything else I need to do to let it access whatever machinery from the package it requires?
When I am hacking on a function in a particular package that in turn calls other functions I often use this form after the definition:
mod_func <- function( args) {body hacked}
environment(mod_func) <- environment(old_func)
But I think the function you might really want is assignInNamespace. These methods will allow the access to non-exported functions in loaded packages. They will not however succeed if the package is not loaded. So you may want to have a stopifnot() check surrounding require(pkgname).
There are two parts to this answer - first a generic answer to your question, and 2nd a specific answer for the particular function that you reference, in which the problem is something slightly different.
1) generic solution to accessing internal functions when you edit a package function
You should already have access to the package namespace, since you loaded it, so it is only the unexported functions that will give you issues.
I usually just prepend the package name with the ::: operator to the non exported functions. I.e., find every instance of a call to some_internal_function(), and replace it with PackageName:::some_internal_function(). If there are several different internal functions called within the function you are editing, you may need to do this a few times for each of the offending function calls.
The help page for ::: does contain these warnings
Beware -- use ':::' at your own risk!
and
It is typically a design mistake to use ::: in your code since the
corresponding object has probably been kept internal for a good
reason. Consider contacting the package maintainer if you feel the
need to access the object for anything but mere inspection.
But for what you are doing, in terms of temporarily hacking another function from the same package for your own use, these warnings should be safe to ignore (at you own risk, of course - as it says in the manual)
2) In the case of blscrapeR ::bls_map_county()
The offending line in this case is
ggplot2::ggplot() + geom_map(...
in which the package writers have specified the ggplot2 namespace for ggplot(), but forgotten to do so for geom_map() which is also part of ggplot2 (and not an internal function in blscrapeR ).
In this case, just load ggplot2, and you should be good to go.
You may also consider contacting the package maintainer to inform them of this error.
I have a library, let's say mylibrary.dll, that has c++ code that I want to run in R. I did this:
dyn.load("mylibrary.dll")
.Call("myfun")
I get:
Error in .Call("myfun") : C symbol name "myfun" not in load table
Now, I've seen several answers to similar problems, on here and on other websites, but when I attempted each solution, each seemed to be to require having access to the original source code, for example adding something like this: extern "C" to the C++ code or re-compiling the code in a certain way. All I have is a .dll file, and I'd like to use that directly to call from R the functions contained within it.
Solution: the name of the function was different than what I expected. I went to the thread that Alexey suggested in the comments, and from there was able to use one of the suggested tools (DLL export viewer) to get a list of the functions, where I found the correct name.
(Alas, I now need to figure out why R is locking up when I call the function, but my question here is done!)
A time ago I started learning Common Lisp, but now I have come to my first real stumbling block, understanding a concept. I started to change my learning projects to move from single file sources to packages. Everything so far went as expected, but then, I stumbled upon one file, a sudoku game I coded, that behaves other then I thought. You can find it here: https://github.com/Silberbogen/cl-sudoku
When I started (spiele-sudoku) after I switched inside the package via (in-package :cl-sudoku), everything works fine, but when I start it via (cl-sudoku:spiele-sudoku), only my input of coordinates is excepted, while any other input seems not to be interpreted.
What concept do I miss, so I could start the game via (cl-sudoku:spiele)?
You use read-from-string to read your input. That will intern any word encountered as a symbol into the current package.
In your main function, you use case to compare with symbols, but those are interned into the cl-sudoku package. So, if your current package is cl-sudoku, it will work, otherwise not.
You should not use read or read-form-string to parse user input (if you absolutely must, at least bind *read-eval* to nil). Instead call intern yourself (possibly in combination string-upcase) to create symbols in the right package. If you want to use package-independent symbols, intern them into the KEYWORD package, so that you can do case on keywords.
It might be helpful to use ecase or ccase, or at least log some debug information on invalid input.