1

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!

4 Answers 4

5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

For very simple systems (load "filename") is enough
Thank you very much for this huge answer! I am not sure where I have to add the .sbclrc file. I think that I do not have such a big system. WHere do I have to write exactly ths (load "filename.lisp") and how can I call the function of the other file? So How can I do, what I was asking?
@IsaMunich: LOAD would go in the file you want to bring the other functions in to. .sbclrc goes in your ~ directory on OSX and Linux; it's a bit trickier on Windows (Use Linux if you can :) )
1

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.

Comments

0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.