I created a module (game.rkt) in Racket in which there is my game logic; in this file I define several variables, functions, threads...
I need to embed that module inside another one (gui.rkt) and start the game (game.rkt) from gui.rkt.
How do I do that?
gui.rkt: You need to provide the definitions you want other modules to be able to use. Definitions aren't visible outside the module, by default. If you've defined functions foo and bar that you want to provide: (provide foo bar).
game.rkt: (require "gui.rkt").
This assumes files are in the same directory.
For more details see the Guide sections about require and provide. Both have a number of options -- Racket's module system is one of its strongest features -- but the simple case is simple.
Related
The Racket docs indicate that Racket has separate forms for: require, load, include, and import. Many other languages only contain one of these and are generally used synonymously (although obviously with language specific differences such as #include in C, and import in Java).
Since Racket has all four of these, what is the difference between each one and which should I be using in general? Also if each has a specific use, when should I use an alternative type? Also, this question seems to indicate that require (paired with provide) is preferred, why?
1. Require
You are correct, the default one you want is almost always require (paired with a provide). These two forms go hand in hand with Racket's modules and allows you to more easily determine what variables should be scoped in which files. For example, the following file defines three variables, but only exports 2.
#lang racket ; a.rkt
(provide b c)
(define a 1)
(define b 2)
(define c 3)
As per the Racket style guide, the provide should ideally be the first form in your file after the #lang so that you can easily tell what a module provides. There are a few cases where this isn't possible, but you probably won't encounter those until you start making your own Racket libraries you intend for public distribution. Personally, I still put a file's require before its provide, but I do sometimes get flack for it.
In a repl, or another module, you can now require this file and see the variables it provides.
Welcome to Racket v6.12.
> (require "a.rkt")
> c
3
> b
2
> a
; a: undefined;
; cannot reference undefined identifier
; [,bt for context]
There are ways to get around this, but this serves as a way for a module to communicate what its explicit exports are.
2. Load
This is a more dynamic variant of require. In general you should not use it, and instead use dynamic-require when you need to load a module dynamically. In this case, load is effectively a primitive that require uses behind the scenes. If you are explicitly looking to emulate the top level however (which, to be clear, you almost never do), then load is a fine option. Although in those rare cases, I would still direct you to the racket/load language. Which interacts exactly as if each form was entered into the repl directly.
#lang racket/load
(define x 5)
(displayln x) ; => prints 5
(define x 6)
(displayln x) ; => prints 6
3. Include
Include is similar to #include in C. There are even fewer cases where you should use it. The include form grabs the s-expression syntax of the given path, and puts it directly in the file where the include form was. At first, this can appear as a nice solution to allow you to split up a single module into multiple files, or to have a module 'piece' you want to put in multiple files. There are however better ways to do both of those things without using include, that also don't come with the confusing side effects you get with include.1 One thing to remember if you still insist on using import, is that the file you are importing probably shouldn't have a #lang line unless you are explicitly wanting to embed a submodule. (In which case you will also need to have a require form in addition to the include).
4. Import
Finally, import is not actually a core part of Racket, but is part of its unit system. Units are similar in some ways to modules, but allow for circular dependencies (unit A can depend on Unit B while Unit B depends on Unit A). They have fallen out of favor in recent years due to the syntactic overhead they have.
Also unlike the other forms import (and additionally export), take signatures, and relies on an external linker to decide which actual units should get linked together. Units are themselves a complex topic and deserve their own question on how to create and link them.
Conclusion (tldr)
TLDR; Use require and provide. They are the best supported and easiest to understand. The other forms do have their uses, but should be thought of 'advanced uses' only.
1These side effects are the same as you would expect for #include in C. Such as order being important, and also with expressions getting intermixed in very unpredictable ways.
I want to keep a list of required modules of a particular module (let's say the current-module).
I feel like there are some other options (such as parsing the module?) that could be tried, but I started playing with the idea of shadowing (require) and adding the required items to a hash-table with the module-name. The problem is I cannot figure how to write a syntax definition for it.
Although not working, a function definition equivalent would be like below:
(define require-list (make-hash))
(define require
(lambda vals
; add vals to hash-table with key (current-namespace)
(let ([cn (current-namespace)])
(hash-set! require-list cn
(append vals (hash-ref require-list cn))))
(require vals)))
.. it seems the last line call should be modified to call the original (require) as well?
A correct version or a pointer to how to do it, or any other way of achieving the original goal highly appreciated.
If you just want to get a list of imports for a particular module, there is a convenient built-in called module->imports that will do what you want. It will return a mapping between phase levels and module imports—phase levels higher than 0 indicate imports used at compile-time for use in macro expansion.
> (require racket/async-channel)
> (module->imports 'racket/async-channel)
'((0
#<module-path-index:(racket/base)>
#<module-path-index:(racket/contract/base)>
#<module-path-index:(racket/contract/combinator)>
#<module-path-index:(racket/generic)>))
Note that the module in question must be included into the current namespace in order for module->imports to work, which require or dynamic-require will both do.
This will inspect the information known by the compiler, so it will find all static imports for a particular module. However, the caveats about dynamic requires mentioned by John Clements still apply: those can be dynamically performed at runtime and therefore will not be detected by module->imports.
Short short version:
Have you tried turning on the module browser?
Short version:
You're going to need a macro for this, and
It's not going to be a complete solution
The existing require is not a function; it's a language form, implemented as a macro. This is because the compiler needs to collect the same information you do, and therefore the required modules must be known at compile time.
The right way to do this--as you suggest--is definitely to leverage the existing parsing. If you expand the module and then walk the resulting tree, you should be able to find
everything you need. The tree will be extremely large, but will contain (many instances of) a relatively small number of primitives, so writing this traversal shouldn't be too hard. There will however be a lot of fiddling involved in setting up namespace anchors etc. in order to get the expansion to happen in the first place.
Regarding your original idea: you can definitely create a macro that shadows require. You're going to want to define it in another file and rename it on the way out so that your macro can refer to the original require. Also, the require form has a bunch of interesting subforms, and coming up with a macro that tries to handle all of these subforms will be tricky. If you're looking at writing a macro, though, you're already thinking about an 80% solution, so maybe this won't bother you.
Finally: there are forms that perform dynamic module evaluation, and so you can't ever know for sure all of the modules that might be required, though you could potentially annotate these forms (or maybe shadow the dynamic module-loading function) to see these as they happen.
Also, it's worth mentioning that you may get more precise answers on the Racket mailing list.
This is I suspect, a matter of style and/or personal taste but I thought I'd ask anyway.
I have been in the habit of defining packages thus:
(defpackage :wibble
(:use :cl :drakma)
(:export :main))
Once I have executed IN-PACKAGE (:wibble, in this case), I can then use the symbols in DRAKMA unadorned:
(http-request ...
Then I recently read that seasoned Lisp hackers would rather not :use but:
(drakma:http-request ...
Just wondered what the consensus of opinion was on here and whether there were any pros or cons (not that type of CONS :) ) either way?
Cheers,
Peter
When you use a package, there are a couple subtle ways things might go wrong if the used package changes.
First, the package might export more symbols in the future. If, for example, the package exports a new symbol library:rhombus and you're already using that myapp::rhombus to name something, you are suddenly using the inherited symbol, with all possible attachments (e.g. classes, defuns, macros, etc), with sometimes strange results. If you use qualified symbol names, you will not get any more or any less than the symbols you want.
Second, the package might stop exporting symbols in the future. So if, for example, library:with-rhombus disappears, your call to (with-rhombus (42 42 42) ...) will suddenly get an error for an invalid function call (42 ...) rather than something that points directly to the source of the problem, the "missing" symbol. If you use qualified symbol names, you will get an error along the lines of Symbol WITH-RHOMBUS is not exported from the LIBRARY package which is clearer.
Importing symbols (with :import-from or :shadowing-import-from or import) is not without its own trouble. Importing works on any symbol, regardless of whether it's external or not. So it could be the case that the symbol is now library::rhombus, i.e. not intended for public consumption any more, but importing will still work with no errors.
Which option you use depends on your comfort level with the source package. Do you control it, and you will not make any conflicting changes without thorough testing? Go ahead and import or use to your heart's content. Otherwise, be careful about checking for unintended side-effects as library package interfaces change.
This is more a style issue, so it's impossible to categorize it in black and white, but here are the pros and cons:
Using package-qualified symbols.
Avoids symbol conflicts.
Allows to clearly distinguish foreign symbols.
Allows to easily search, replace, copy,... uses of a certain symbol from the external library (for refactoring, extracting the code to some other place etc.)
Makes code uglier, but only when library names are too long. (For example, I add a nickname re to cl-pprce, and now the code using it is even better, than w/o qualification: think re:scan)
Importing the whole package
Basically, the opposite of the previous case. But I tend to use it with utility libraries, because using qualified names often beats their whole purpose of making code more concise and clear :)
:import-from package symbol
This is one option you've forgotten to mention. I think it may be useful, when you use one or too very distinct symbols from a certain package very frequently. It also allows to import unexported symbols.
Good answers so far.
Another view is that a package and its symbols make up a language. If you think a symbol should be a part of this language, then you should make it available without the need to qualify it with another package - when programming in this language.
For example in the CLIM implementation there is a CLIM-LISP package which sets up the implementation language. It is a variant of the COMMON-LISP package. Then there are packages like CLIM-SYS (resources, processes, locks, ...), CLIM-UTILS (various utilities and extensions of Common Lisp) and CLIM itself. Now in a new package SILICA (an abstract window system) these four packages are used. The implementation of Silica thus is implemented in a language which is built as a union of two languages (the Common Lisp variant CLIM-LISP and the UI commands of CLIM) plus two utility packages which extend CLIM-LISP with some facilities.
In above example it makes sense to use the packages, since they are extending each other to form a new language and the implementation in that new package makes heavy use of those.
If you had a package which needs conflicting packages, then it would not make sense to use them. For example a package could use drawing commands tailored to a GUI and for Postscript output. They would have similar names. Using them both would lead to conflicts. You also want to make clear in the source code for the human reader from where these symbols are coming. Is it a line-drawing command from a postscript or a GTK+ library? Would be great if you can find it out easily - even though the function names are the same.
As a rule of thumb, I :use packages that extend the general language, but use qualified symbols for packages that have some special application. For example, I'd always :use alexandria, but refer fully qualified to symbols from Hunchentoot. When in doubt, I use qualified names.
I wrote two functions in two separated files, assumed to be file A.lisp and B.lisp, where both files have some main program code for test and A.lisp would call the function in B.lisp. This means using the load method directly in A.lisp would execute the main code in B.lisp, which is not supposed to happen. And these files are, in my opinion, too small to be considered using something like package.
Is there anything like Python's if __name__ == "__main__": stuff in Common Lisp? Top-level code that's wrapped inside this condition will only be executed if the current file is the main module, i.e. the running program, but not if it's imported as a library.
Packages are only namespaces for symbols. They don't say anything about loading or compiling code.
Common Lisp does not have the idea of a library, module or even something like a 'main' module/routine in its ANSI Common Lisp standard. The standard defines two routines PROVIDEand REQUIRE. But those are not very well specified.
Most applications and libraries use a 'system' tool to structure, specify, compile and load code.
There is a 'free' one called ASDF. 'Another System Definition Facility'. For most types of applications a tool like ASDF is useful. For primitive applications you can write your own tools using standard functions like COMPILE-FILEand LOAD.
Nick Levine wrote a tutorial for ASDF (part of his abandoned Lisp book project): Systems.
Several Lisp implementations have more extensive facilities to create applications (for example Mac OS X applications written with Clozure Common Lisp).
The if __name__ == "__main__": idiom is very specific to Python, and even some people in the Python community consider using it for test code bad style.
With Common Lisp's high emphasis on interactive development in the REPL, it would actually be a disadvantage to have to reload the whole file each time you want to run the tests. Just put the tests into a function definition instead of the top level, it works and is more convenient.
Top level forms are evaluated.
You could define a main function as in the following example, and you could call that function whatever you like:
a.lisp:
(defun main ()
...)
b.lisp:
(load "a.lisp")
(main)
I don't really know how it works in Python but it looks like a file is
a module, and two files are two distinct modules. This not the case in
Common Lisp. If you don't define any package, when you load a file,
all definitions will be available in the current package (CL-USER is
the default). It's more like if you've pasted your code into the REPL.
But packages aren't really hard to use.
in A.lisp:
(defpackage foo
(:use #:cl)
(:export main))
(in-package :foo)
(defun main ()
(do-some-stuff)
(baz:main some-args))
in B.lisp:
(defpackage baz
(:use #:cl)
(:export main))
(in-package :baz)
(defun main (some-args)
(do-some-stuff))
You could read
The Complete Idiot's Guide to Common Lisp Packages
and
PCL chapter on packages.
The example below is given in Paul Grahams ANSI Common Lisp as an example of doing encapsulation:
(defpackage "CTR"
(:use "COMMON-LISP")
(:export "COUNTER" "INCREMENT" "CLEAR"))
(in-package ctr)
;function definitions here
However in Peter Seibels Practical Common Lisp, link here, he says:
Because packages are used by the reader, a package must be defined
before you can LOAD or COMPILE-FILE a file that contains an IN-PACKAGE
expression switching to that package. Packages also must be defined
before other DEFPACKAGE forms can refer to them...
The best first step toward making sure packages exist when they need
to is to put all your DEFPACKAGEs in files separate from the code that
needs to be read in those packages
So he recommends creating two files for every package, one for the defpackage and one for the code. The files containing defpackages should start with (in-package "COMMON-LISP-USER").
To me it seems like putting the defpackage in the same file, before the in-package and code, is a good way to ensure that the package is defined before used. So the first method, collecting everything into one file seems easier. Are there any problems with using this method for package creation?
I think that using a separate file for defpackage is a good habit
because:
You don't « pollute » your files with defpackage.
It makes it easier to find the exported/shadowed/... symbols, you
know you just have to look at package.lisp.
You don't have to worry about the order when you use ASDF.
(defsystem :your-system
:components ((:file "package")
... the rest ...))`
Peter Seibel says so ;)
EDIT:
I forgot to mention quickproject which facilitates the creation of
new CL projects.
REPL> (quickproject:make-project "~/src/lisp/my-wonderful-project/"
:depends-on '(drakma cl-ppcre local-time))`
This command will create a directory "~/src/lisp/my-wonderful-project/"
and the following files:
package.lisp
my-wonderful-project.asd (filled)
my-wonderful-project.lisp
README.txt
And thus, I think it's good to use the same convention.
I tend to use multiple source code files, a single "packages.lisp" file and a singe "project.asd" system definition file for most of my projects. If the project requires multiple packages, they're all defined in "packages.lisp", with the relevant exports in place exported.
There is this reason for putting DEFPACKAGE in its own file: if you have a large package, then you might have several groups of related functions, and you might want to have separate source files per function group. Then all the source files would have their own IN-PACKAGE at the top, but they would all "share" the external DEFPACKAGE. Then as long as you get the DEFPACKAGE loaded first, it doesn't matter the order you load the other source files.
An example I'm currently working on has multiple classes in the package, and the source files are broken up to be per class, each having a class definition and the related generic function and method definitions.