Use vs Import vs Require vs Require-extension in Chicken Scheme - scheme

I'm a little hazy on the differences between (use) and (import) in Chicken. Similarly, how do (load), (require) and (require-extension) differ?
These things don't seem to be mentioned much on the website.

Load and require are purely run-time, procedural actions. Load accepts a string argument and loads the file with that name (which can be source or compiled code) into the running Scheme, so that whatever it defines becomes available. Require does the same thing, but checks if the file has already been loaded by seeing if provide has been called on the same name (typically by the file as it is loaded). They are relatively rare in Scheme programming, corresponding to plug-ins in other languages, where code unknown at compile time needs to be loaded. See the manual page for unit eval for more details.
Import is concerned with modules rather than files. It looks for the named module, which must have already been loaded (but see below for Chicken 5), and makes the names exported from that module visible in the current context. In order to successfully import a module, there must be an import library for it. It is syntax, so the module name must appear explicitly in the call and cannot be computed at run time. See the manual page on modules for more details.
Require-library does the Right Thing to load code. If the code is already part of the running Scheme, either because it is built into Chicken, it does nothing. Otherwise it will load a core library unit if there is one, or will call require as a last resort. At compile time, it does analogous things to make sure that the environment will be correct at run time. See the "Non-standard macros and special forms" page in the manual for more details.
Use does a require-library followed by an import on the same name. It is the most common way to add functionality to your Chicken program. However, we write (import scheme) and (import chicken) because the functionality of these modules is already loaded. Require-extension is an exact synonym for use, provided for SRFI 55 compatibility. In R7RS mode, import is also a synonym for use.
Update for Chicken 5
Use has been removed from the language, and import now does what use used to do: it loads (if necessary) and then imports. Require-extension is consequently now a synonym for import.
In addition, Chicken-specific procedures and macros have been broken into modules with names like (chicken base) and (chicken bitwise).

Related

Can R7RS-small implementations allow only one define-library per file?

Are compliant R7RS-small implementations allowed to impose a restriction on the number of define-library per file? Some R7RS-small implementations such as Guile 3.0.7 only allow one define-library per file. Is this a deviation from the standard, or is it allowed by R7RS-small?
In R7RS define-library is just a form, similar to library in R6RS. I don't see any allowances in either case that conforming implementations may constrain a file to contain only one such form.
But the Guile documentation has something to say on the matter. In 7.7 R7RS Support:
Happily, the syntax for R7RS modules was chosen to be compatible with R6RS, and so Guileā€™s documentation there applies.
In 7.7.1 Incompatibilities with the R7RS:
As the R7RS is a much less ambitious standard than the R6RS (see Guile and Scheme), it is very easy for Guile to support. As such, Guile is a fully conforming implementation of R7RS, with the exception of the occasional bug and a couple of unimplemented features....
Then in 7.6.1 Incompatibilities with the R6RS
Multiple library forms in one file are not yet supported. This is because the expansion of library sets the current module, but does not restore it. This is a bug.
Yes, I think they can (and, perhaps, should).
If you look at the formal syntax & semantics in r7rs.pdf then
A program is one or more import declarations followed by one or more commands or definitions. Commands and definitions don't include define-library.
A library is exactly one define-library form.
So from that you can conclude that a program doesn't include define-library forms, and a library includes exactly one such form.
Now that document doesn't say how all this maps into files at all, so it's up to the implementation to define that. I think it would be perfectly possible for an implementation to say that the mapping of files to library files should be 1-1, so any given library file contains exactly one library. It would also be possible to have files which contained mixtures of a program and one or more libraries, of course.
In the case where libraries are in their own files (which is obviously the more interesting case in terms of allowing reuse) something has to turn a library name into a file. And that would make it reasonably natural to put exactly one library in each file.
If it was me, I'd allow files which contain a mixture of a program and one or more libraries directly present, but for files which were just libraries I'd allow just one in each file.

What is a library unit in Chicken Scheme?

The terms "unit" and "library unit" are used in many places on the web site, but I failed to find documentation or even definitions of these terms. The only description that I found is in "User's Manual/Supported language/Declarations/(unit|uses)". Also there is an example in "User's Manual/Using the compiler/An example with multiple files". As you can see, very scarce.
If I ever get a response, the next question is how are "units" related to modules described in "User's Manual/Supported language/Modules"? I suppose that "units" somehow relate to compilation, while modules relate to Scheme value names.
Unit is short for "unit of compilation", which is basically a compiled library. If you look at the source code for CHICKEN, you'll notice that each unit from the manual corresponds (roughly) to a source file. Each source file is compiled separately into a .o file, and these units are all linked together into libchicken.so/libchicken.a.
This terminology is not very relevant anymore, except when you're linking statically. Then you need (declare (uses ...)), which refers to the unit name. This is needed, because the toplevel of the particular unit needs to run before the toplevels that depend upon it, so that any definitions are loaded.
In modern code you'll typically use only modules, but that means your code won't be statically linkable. We know this is confusing, which is why we're attempting to make static linking with modules easier with CHICKEN 5, and reducing the need to know about units.

How to compile multiple Chicken Scheme files?

I need to compile a Chicken Scheme project containing multiple source files, but I'm getting errors.
According to the manual and this SO answer, I need to put (declare)s in my sources. Why the compiler can't just see that I'm importing the other source is beyond me, but meh.
The problem is, even if I put the (declare)s in, the compiler complains about the (import)s and (use)s.
infinity.filesystem.scm:
(use bindings filepath posix)
(declare (uses infinity.general.scm))
(load-relative "infinity.general.scm")
(module infinity.filesystem (with-open-file make-absolute-path with-temporary-directory with-chdir)
(import scheme filepath posix infinity.general)
(begin-for-syntax
(use bindings chicken)
(import infinity.general))
...etc...
infinity.general.scm:
(declare (unit infinity.general.scm))
(require-extension srfi-1 srfi-13 format data-structures ansi-escape-sequences basic-sequences)
(module infinity.general (bind+ format-ansi repeat-string join-strings pop-chars! inc! dec!
take* drop* take-right* drop-right* ends-with? take-where)
(import scheme chicken srfi-1 srfi-13 data-structures ansi-escape-sequences basic-sequences bindings ports format)
...etc...
Command:
$ csc -uses bindings.o -uses infinity.general.o -c infinity.filesystem.scm -o infinity.filesystem.o
Compiler says:
Syntax error (import): cannot import from undefined module
and
unbound variable: use
If I just remove the import and use declarations for "infinity.general", the file compiles. However, I have two problems with this:
Will the resulting .o file actually work, in the absence of import and use clauses? Or will it complain about missing code at runtime?
csi requires that my code contains (import) and (use) declarations, whereas csc requires that it does not. I, however, require that my code works in both csi and csc!
How can I solve this, please?
Why the compiler can't just see that I'm importing the other source is beyond me, but meh.
Declares are used to determine dependencies: the compiler needs to know in what order (and if at all) to invoke a particular toplevel, to ensure the right code is initialized before any of the globals from that unit can be used. When everything is being compiled separately, the compiler wouldn't know when to insert calls to toplevels. The -uses switch you pass to csc is redundant: csc -uses foo is equivalent to putting (declare (uses foo)) in the source code. Passing -uses foo.o doesn't do anything with the file foo.o as far as I can tell.
In your code snippet, you're using load, which is not the correct way to include code at compile-time: load will read and evaluate the target file at run time. Instead, you should omit the load completely: the declare already takes care of the dependency; you just need to link them together.
Also, it's not very common to use filenames as module/unit names, though it should work.
If I just remove the import and use declarations for "infinity.general", the file compiles. However, I have two problems with this:
1) Will the resulting .o file actually work, in the absence of import and use clauses? Or will it complain about missing code at runtime?
You'll need to keep the import expressions, or the program shouldn't compile. If it does compile, there's something strange going on. You don't need use when you link everything together statically. If you're using dynamic linking, you will get a runtime error.
The error you get about unbound variable: use is because you're using use in a begin-for-syntax block. You'll probably just need to (import-for-syntax chicken), as per your other SO question.
2) csi requires that my code contains (import) and (use) declarations, whereas csc requires that it does not. I, however, require that my code works in both csi and csc!
It looks like you're approaching this too quickly: You are writing a complete program and at the same time trying to make it run compiled and interpreted, without first building an understanding of how the system works.
At this point, it's probably a good idea to experiment first with a tiny project consisting of two files. Then you can figure out how to compile an executable that works from code that also works in the interpreter. Then, use this knowledge to build the actual program. If at any point something breaks, you can always go back to the minimal case and figure out what you're doing differently.
This will also help in getting support, as you would be able to present a complete, but minimal set of files, and people will be able to tell you much quicker where you went wrong, or whether you've found a bug.

#ifndef in Common Lisp

In C, to make sure we don't re-include headers that are included we use the following structure:
#ifndef UTILS
#define UTILS
#include "my_utils.h"
#endif
I've broken my Lisp program into separate files; multiple files sometimes use the same file (e.g., my_utilities is used by multiple files). When I run the program, I get warnings that I am redefining things (calling load of the same file multiple times).
This would be fixed by doing something similar to #ifndef in C. What is the Common Lisp equivalent or standard method of doing this?
I am fairly new to Lisp. Let me know if there are best practices (perhaps, a different method of structuring my programs?) that I am missing.
The question you asked
The direct analogue of preprocessor conditions like #if in C is the
#+ read-time conditionalization facility.
The question you wanted to ask
To avoid multiple loading of a file, you can either use the standard
(but deprecated)
provide/require facility,
or an add-on system like ASDF.
For Common Lisp applications and libraries it is preferred to use a system management tool. Like ASDF or whatever your implementation may provide. A system is a collection of files with dependencies and various actions (load, compile, ...).
You can always check the state of the runtime and do something.
Example:
(unless (fboundp 'foobar)
(require "foo")
(load "bar"))
(unless (find-package 'foobar)
(require "foo")
(load "bar"))
PROVIDE and REQUIRE are built-in functions for exactly that. If you require a module it will be loaded, unless already provided. Unfortunately this functionality is underspecified in the standard, but implementations may provide useful functionality.
Common Lisp runtimes have a list of features on the list *features*. You can use that to advertise and check functionality.
Example:
In your library:
(push :cool-new-graphics-library cl:*features*)
In your application code:
(when (member :cool-new-graphics-library cl:*features*)
(funcall (find-symbol "DRAW-SPACE-SHIP" "CNGL")
:death-star))
Common Lisp provides a way to conditionalize that a read time. The following code will only be read when the :cool-new-graphics-library feature is present, and thus it only then will be executed later:
#+cool-new-graphics-library(cngl:draw-space-ship :death-star)
Common Lisp also allows you to express some logic:
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
Note that you can force Lisp to execute code at compile-time:
(eval-when (:load-toplevel :compile-toplevel :execute)
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
)
For this to work the EVAL-WHEN has to be at the toplevel in a file. That means it will not work deep in nested forms. It does work inside a toplevel PROGN,LOCALLY, MACROLET and SYMBOL-MACROLET, though.
Thus EVAL-WHEN allows you to run code which is part of the file which is currently compiled. This code than can look for loaded systems, provided modules, available functions, and more.

Load a mathematica package from within a package

I have more or less the following setting. In ~/path/to/my/packages I have two packages package1.m and package2.m. Each package's outline is, for example, the following:
BeginPackage["package1`"]
Unprotect##Names["package1`*"];
ClearAll##Names["package1`*"];
Begin["`Private`"]
vecNorm[vec_?VectorQ]:=Module[{},Return[Sqrt[vec.vec]]];
End[]
Protect##Names["package1`*"];
EndPackage[]
Now, my problem is that I want to use vecNorm defined in package1.m in package2.m. How can I load (safely) package1 from within package2?
At the moment, I load manually both packages as follows:
SetDirectory[StringJoin[NotebookDirectory[], "packages"]];
Needs["package1`"]
Needs["package2`"]
from a notebook saved in ~/path/to/my. I want to load manually only package2 which in turn will load automatically and safely package1. In general I want a solution which changes as little as possible paths etc. of mathematica. What should be the best practice to accomplish this?
PS: By safely I mean that in the future, when I'll define package3 which will be using vecNorm as well and will be loading package1 as well no conflicts will happen.
There are two generally recommended ways to load a package. One is so-called public import, and in your setting it will be done as
BeginPackage["package2`",{"package1`"}]
(* Usage messages etc *)
Begin["`Private`"]
(* code here *)
End[]
EndPackage[]
Here, you indicate the context name of the package you want to load, in the list which is a second optional argument to BeginPackage. This way of importing is called public because the loaded package will remain on the $ContextPath after your main package is loaded, and will thus be publicly available.
The second method is called private import, and is schematically done as
BeginPackage["package2`"]
(* Usage messages etc *)
Begin["`Private`"]
Needs["package1`"]
(* code here *)
End[]
EndPackage[]
In this method, your loaded second package will only be available to the package that loads it (with Needs), thus private import.
Which way you need will depend on the situation. I try to make all my imports private unless I have to make them public. For debugging, however, it may be handy to first make a public import, since then you can play with the second package directly at the top-level.
As for the safety, you can load a package by any number of packages, and this will be safe. When you load several packages into the same context simultaneously, this will be safe as long as those packages don't have public symbols with the same short name. Otherwise, you will run into what is called a shadowing problem, but it is best to make the effort needed to avoid that (it is always possible).

Resources