Call function in another lisp file

两盒软妹~` 提交于 2019-12-02 18:01:51

问题


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!


回答1:


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.

  1. Create directory where ASDF looks for files.
  2. 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.




回答2:


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.




回答3:


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*))


来源:https://stackoverflow.com/questions/19731546/call-function-in-another-lisp-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!