I have to write a game in Lisp. In order to make it clear, I wanted to split the code in different .lisp files.
How can I call a function out of a function in the other file?
E.g. file1.lisp has a function called function1 and file2.lisp has a function called function2.
How can I call function2 out of function1?
Thanks!
Just so you know, there are a variety of different Lisp systems. I'll post the answer for Common Lisp.
The naive way is to use (load "filename.lisp"), but that doesn't really work very well after a while. Therefore...
Common Lisp has a library called "ASDF", which handles packaging and file management. There's a bit of setup to ASDF.
Create directory where ASDF looks for files.
Add this information to my Lisp system's init file.
I use this in my .sbclrc file (assuming that I created a .asdf file in ~) :
(pushnew "~/.asdf/" asdf:*central-registry* :test #'equal)
I usually use a previously built ASDF file and then modify it.
Here's a sample ASDF file's contents:
(asdf:defsystem #:cl-linq
:depends-on ( #:alexandria #:anaphora)
:components ((:file "cl-linq"))
:name "cl-linq"
:version "0.1"
:maintainer "Paul Nathan"
:author "Paul Nathan"
:licence "LLGPL"
:description "CL LINQ style interface with strains of SQL"
:long-description
"DSL for managing and querying datasets in a SQL/LINQ style
syntax. cl-linq provides a simple and usable set of primitives to
make data examination straightforward. ")
I put this code in a file cl-linq.asd next to my source code (cl-linq.lisp from the component "cl-linq" in the defsystem) and then symlink the cl-linq.asd file to my ~/.asdf/ directory.
Within my cl-linq.lisp file I include this:
(defpackage :cl-linq
(:use
:common-lisp
:anaphora)
(:export
#:query
#:cl-linq-select))
(in-package :cl-linq)
So for your case, I would have 2 components; each with their own defpackage form, exporting the functions out that the other package needed.
For the examples, I've taken the code from CL-LINQ, a project of mine. You are quite free to use it as a template.
This is for Emacs Lisp (aka elisp)
Create a file at this location: ~/.emacs.d/init.el
Create a file at this location: ~/.emacs.d/file1.el
Create a file at this location: ~/.emacs.d/file2.el
Now, open up ~/.emacs.d/init.el and write (and then save):
(load "~/.emacs.d/file1.el")
(load "~/.emacs.d/file2.el")
(defun run-both-functions ()
(interactive)
(switch-to-buffer "*Messages*")
(first-function)
(sit-for 2)
(second-function))
Now, open up ~/.emacs.d/file1.el and write (and then save):
(defun first-function ()
(message "My name is Fred."))
Now, open up ~/.emacs.d/file2.el and write (and then save):
(defun second-function ()
(message "My name is George."))
Now, restart Emacs and type: M-x run-both-functions RET
Any functions that you put into any of the three (3) files mentioned above will be accessible to other functions. You will note that run-both-functions includes an (interactive) statement, which means that the user can call the function with M-x or a keyboard shortcut.
If you use the function load it can be useful to not specify the file type.
Loading files: fasl or source
Instead of (load "foo.lisp") one can call (load "foo"). Typically Common Lisp provides the feature of compiling Lisp files to fasl (fast load) files. Those are usually pre-compiled byte code or native code. Typically the Common Lisp implementation will load the compiled code if a file exists for it. This saves time (because compiled code usually can be loaded much faster than Lisp source code) and the code usually is faster (because a file compiler has compiled it).
Often one uses a function to load the compiled file if it is newer, or first compile the source file to a new compiled file.
Loading a file, based on the current file being loaded
In (load "foo") the file foo is not a complete filename. For example we don't know the directory where it is loaded from. This depends on things like the value of *default-pathname-defaults* or in some implementations on a current directory (typical for Unix systems). It may be useful to load the file based on the file we are currently loading - if loading one file triggers more files to be loaded. For this Common Lisp has the variables *load-pathname* and *load-truename* (which is the real filename as used with the filesystem).
To load a file foo in the same directory as the currently loaded file call:
(load (merge-pathnames "foo" *load-pathname*))
To load a file foo in a subdirectory bar of the same directory as the currently loaded file call:
(load (merge-pathnames "bar/foo" *load-pathname*))
With Common Lisp I done it like this:
In file1.lisp I define a function sayHello and export that function under the package name helloLisp
(defpackage :helloLisp
(:use :common-lisp)
(:export #:sayHello))
(in-package :helloLisp)
(defun sayHello () (print "Hello!"))
In the file file2.lisp I require this file like that:
(require "helloLisp" "./file1.lisp")
(helloLisp:sayHello)
Tested with SBCL 1.4.11
Related
I've been looking for emacs config files for a while, so that I learn how to structure my Emacs config in the most optimal way. Now i'm looking at purcell's config files which look very tidy and simple to read.
However, for every config file I've found there's always the same problem: "free variable"
and "function not known to be defined" warnings on all the included files. It is quite frustrating to see all the red underlines from flymake everytime, and it also makes me question if this really is the best way to write the config file.
Here's a file from the repository mentioned above:
;;; init-python.el --- Python editing -*- lexical-binding: t -*-
(setq auto-mode-alist
(append '(("SConstruct\\'" . python-mode)
("SConscript\\'" . python-mode))
auto-mode-alist))
;;WARNING: assignment to free variable ‘python-shell-interpreter’
(setq python-shell-interpreter "python3")
(require-package 'pip-requirements)
(when (maybe-require-package 'toml-mode)
(add-to-list 'auto-mode-alist '("poetry\\.lock\\'" . toml-mode)))
;;WARNING: reference to free variable ‘black’
(when (maybe-require-package 'reformatter)
(reformatter-define black :program "black" :args '("-")))
(provide 'init-python)
;;WARNING: the following functions are not known to be defined: require-package, maybe-require-package, reformatter-define
;;; init-python.el ends here
The python-shell-interpreter is a variable defined from the python-mode package.
The require-package and maybe-require-package are defined in a custom local file called init-elpa.el which is requires'd by the init.el file and thus they're not directly recognized by this file.
The black variable warning is the mostr "intricate": I guess it's caused by the fact that the reformatter package isn't included because maybe-require-package isn't included as well.
This gives me a headache. If I see it correctly, the root problem is the fact that the included files (init-python.el et al.) depend on stuff from the including file (init.el) without it being explicitly stated.
Is there a better way to structure an Emacs Lisp config among multiple files?
The python-shell-interpreter is a variable defined from the python-mode package.
Add (require 'python-mode) to the top of the file (or simply above the code which depends on that).
The require-package and maybe-require-package are defined in a custom local file called init-elpa.el
Add (require 'init-elpa) to the file (I'm assuming it provides the init-elpa feature).
which is require'd by the init.el file
This is fine -- require does nothing if the library in question has already been loaded. Even when there's an overarching init file loading other files, it's sensible for each file to require the things it needs (unless there are circular dependencies).
The black variable warning is the most "intricate": I guess it's caused by the fact that the reformatter package isn't included because maybe-require-package isn't included as well.
I'm guessing that reformatter-define is a macro and that the symbol black is not actually used as a variable. When only macros are required, one would typically (eval-when-compile (require 'reformatter)) but judging by the name maybe-require-package it's intended that reformatter might not be loadable at all. If that's all accurate, you can use this wrapper to cope with the false-positive:
(with-suppressed-warnings ((free-vars black))
...)
See C-hig (elisp)Compiler Errors for further information on handling byte-compilation warnings and errors.
64-bit Windows 7
Clozure Common Lisp Version 1.9 WindowsX8632
Emacs 24.3.1
Slime changelog date 2014-06-17
I have an example .lisp file which starts out as follows:
(ql:quickload 'qt)
(in-package "QT")
The rest of the program shows a dialog box.
When I run this from the command line, wx86cl -load helloqt.lisp it seems to work fine.
When I run this from Emacs Slime (C-x C-k) it says there is no package "QT".
However if I first evaluate the first line individually (C-x C-e) then I can compile the whole thing and it works, modulo the normal issues of trying to run a QT thread from within Slime on Windows.
How do I make it so I can compile/run the file from emacs without having to manually evaluate the first line first?
Also, why doesn't (in-package ...) change the current package in the Slime session? I have to change it manually if I want to interact with the package contents.
When you compile the file as a whole, it is first read as a whole. At that time, none of it has yet been evaluated, so the package QT is not defined yet.
You can either use eval-when to evaluate something at an earlier time, or use a system definition facility (ASDF is predominant nowadays) to load your system in the right order.
Eval-when:
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload '#:qt))
(in-package #:qt)
Note that you usually should not muck around in library packages but define your own, fresh package to hold your code:
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload '#:qt))
(defpackage #:qt-example
(:use #:qt))
(in-package #:qt-example)
;; your code here
(In case you are wondering, defpackage, defun, defclass etc. are specially designed macros that expand to a form inside such an eval-when.)
This is sometimes OK for little one-off scripts. For systems of any noteworthy size, especially as soon as they have more than one source file, use ASDF:
;;;; qt-example.asd
(in-package #:cl-user)
(asdf:defsystem #:qt-experiments
:description "Some experiments with QT."
:serial t
:components ((:file "package")
(:file "qt-example"))
:depends-on (#:qt))
;;;; package.lisp
(defpackage #:qt-example
(:use #:qt))
;;;; qt-example.lisp
(in-package #:qt-example)
ASDF comes with most open-source Common Lisp implementations. You might need to set up the ASDF registry. I like to have one or two base directories for all my local projects, so that I can just put the following into ~/.config/common-lisp/source-registry.conf:
(:source-registry
(:tree (:home "devel"))
(:tree (:home "src"))
:inherit-configuration)
Then ASDF finds all systems defined below those directories. In SLIME, you can just use ,load-system or ,open-system from the REPL with the system name to load it, resp. open all files in it, optionally loading it.
When compiling a single toplevel form (using C-c C-c) from a file, SLIME looks backward from there for an in-package form to find out what package it should assume. Conventionally, you should only have a single in-package form per file, at its top.
A commonly useful shortcut is C-c ~ in Lisp source files, which switches the REPL to the directory of the file and the effective package at point.
A little hard to find, but there is slime-repl-set-package:
(defun slime-connected-hook-switch-to-stumpwm-package ()
(slime-repl-set-package "STUMPWM"))
(add-hook #'slime-editing-mode-hook
#'slime-connected-hook-switch-to-stumpwm-package)
I am trying to program GNU Emacs 23 to issue require commands lazily, on demand, instead of up front in my .emacs file. If I wanted to delay the execution of a load command, I could use autoload. But require and load take different sorts of arguments.
Is there a predefined function that does for require the same job that autoload does for load? And if not, what tools would people recommend that I use to roll my own?
There is not difference between require and load with regards to autoload. require is just a frontend to load, which more or less comes down to:
(defun require (feature &optional filename noerror)
(unless (featurep feature)
(let ((filename (or filename (symbol-name feature))))
(load filename noerror))))
As you can see, the symbol name given to require is equal to the filename given to load. As a matter of fact, the first (require 'foo) evaluated in an Emacs session is equivalent to (load "foo").
Thus, you can just use (auto-load 'foo-function "foo") for foo-function from the library foo, that you can load with (require 'foo).
One more answer to help clarify (this was a little verbose for a comment):
autoload says "if this function isn't already defined, then load this file (if and when the function is called)."
require says "if this library isn't already loaded, then load this file (immediately)."
Note in particular that you don't need to use require to load a library; that's simply the way you ensure that you don't load it again (assuming you don't want to do that). The (provide 'FEATURE) expression in the library will be evaluated no matter how the library was loaded, which lets any future require know that it doesn't need to do anything.
It's a similar situation for autoload -- if the file has already been loaded (and therefore the function in question properly defined), then the autoload no longer has any effect.
What kind of "demand" do you have in mind for your "on demand"?
If a given command or other function needs (or soft-needs) a given library, then that function itself can use (require 'foo) or (require 'foo nil t). The library will be loaded on demand from that function.
Consider also whether you might need to load the file more than once, i.e., reload it in some situations, whether or not it has already been loaded.
For #2, for instance, my code that uses a library of Lisp macros, icicles-mac.el does not just use require, because I want to make sure that if a user gets a new version of that library (e.g., downloads a new source version and byte-compiles it) then that new version is used whenever s?he byte-compiles another library that needs it. (This is important -- when a library of macros changes, other libraries that use those macros generally need to be recompiled after loading the new macros file.) For that, instead of just (require 'icicles-mac) I use this:
(eval-when-compile
(or (condition-case nil
(load-library "icicles-mac") ; Use load-library to ensure latest .elc.
(error nil))
(require 'icicles-mac))) ; Require, so can load separately if not on `load-path'.
I want to load my file named "my-c-setup.el" when the c-mode is loading. So, I'm using the function "autoload".
With my python setup, it works well :
lang.el
(autoload 'python-mode "my-python-setup" "" t)
my-python-setup.el
(require 'python)
; ...
I'm trying to do the same with the c-mode, but i does not work :
lang.el
(autoload 'c-mode "my-c-setup" "" t)
my-c-setup.el
(setq c-basic-offset 4)
; ...
When I try to open a file in c-mode (test.c for example), I have the following error :
File mode specification error: (error "Autoloading failed to define function c-mode")
Autoload is not what you're looking for. What it does is simply load some code the first time it is needed, which is a handy way to extend Emacs' functionality while still keeping the start-up time low.
To solve your problem, we gotta think about what you really want to do: do you simply want some of your code to be loaded at some point, or do you want buffer-local customizations for ever buffer that is in c-mode?
If you simply want Emacs to load your code at start-up, either put your code directly into your .emacs file or use load-file or require instead of autoload:
load-file simply takes a file name, loads the lisp code in that file and evaluates it. So if your code is in a file named "/path/to/my-c-setup.el", you could put the following line in your .emacs, and the code will be loaded on every start-up:
(load-file "/path/to/my-c-setup.el")
Perhaps you don't want to give the absolute path name for every file you load. In that case, you could use the function load-library instead which is similar to load-file but tries to find the given filename in any of the directories stored in the variable load-path:
(add-to-list 'load-path "/path/to")
(load-library "my-c-setup.el")
The advantage is that you have to do the add-to-list part only once, and all subsequent calls to load-library will be able to find code in that directory.
An alternative way is the provide/require mechanism: you can make your .el-file "provide" some feature by putting a (provide 'feature) call in it, e.g.
(provide 'my-c-mode-customizations)
Then put an according (require 'feature) in your .emacs file, and your code will be loaded as well:
(require 'my-c-mode-customizations)
However, if you want your code only be loaded when c-mode is activated on a buffer, the way to achieve that is through Emacs' Hook mechanism:
A hook is a variable where you can
store a function or functions to be
called on a particular occasion by an
existing program.
Most major modes provide a customizable hook variable to which you can add functions that will be called whenever the major mode is invoked. For instance, c-mode provides c-mode-hook. In order for your own customizations to be called whenever c-mode is turned on for a buffer, put them in a function, say, my-c-mode-customizations and add the following line to your .emacs file:
(add-hook 'c-mode-hook 'my-c-mode-customizations)
Of course, you still need autoload for Emacs to actually find the definition of that function.
Lisp's autoload does not call a function when a file is loaded but tells lisp that the function is available and that the given file provides it. Whenever someone calls the (not yet defined) function, the file is loaded.
I think that c-mode is already defined and thus fails to re-register.
Autoload doesn't do what you think it does.
http://www.gnu.org/software/emacs/elisp/html_node/Autoload.html
What you probably want are mode-hooks or eval-after-load.
See eval-after-load vs. mode hook for the difference between the two.
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.