What is the convention for Racket filename extensions? - racket

.rkt is the conventional file extension for 'regular' Racket source code. In the documentation, I also see .rktl and .rkts being used. What are .rktl and .rkts used for, and are there any more Racket filename extensions I am not aware of?

The .rkt file extension is generally used for files that represent modules. These normally have a #lang .... line at the top, or sometimes (module ....). They can be imported as modules with require.
The .rktl and .rkts file extensions are used for files meant to be loaded at the top-level that aren't modules. They don't necessarily have a #lang .... line at the top, and must be loaded in some external environment with load instead of imported with require. These usually have a more "dynamic" feel to them, and they're used more often with scripts that use mutation of variables across multiple files. This is not the "encouraged" style in Racket.
The .rktd file extension is used for files that just have data encoded as s-expressions, not code. These files should not be required or loaded (they should not be executed as code). However, other programs use them to store data on the file system using write, and to read the data later using read. Its purpose is the same as a .sexp file or a .json file, just pure data.

Related

How to import files relative to main file, instead of current directory? ((Chez) Scheme)

For example, in my main.scm file I have (load "util.scm"). util.scm is a file in the same folder as main.scm. Both files are located in ~/documents/myproject/.
Now when I'm in this directory, and I run $ chez-scheme main.scm everything works fine. However, if I'm in my home directory and run $chez-scheme documents/myproject/main.scm it complains, not being able to find the file util.scm. I suppose this is the case because the current directory was my relevant home directory, and as such util.scm is indeed not there, it is actually in documents/myproject/. That being said, I'm used (in other languages) to the functionality of looking these paths up relative to the file containing the instruction to import, and I'd like to have that here as well. I've tried prefixing it by ./ or defining the file as a libary and doing (import (util)) but none of it works outside of documents/myproject/. Is there any way to get this to work as I intend it to?
I assume this is Chez-Scheme-specific. If not I'd prefer an answer that is implementation-neutral.
load is kind of awkward in R5RS since the report states that system interfaces are off topic in the report, but they include load which is a half hearted solution. The report does not say if the load is relative to the current directory or the file the load form originates from so in order to be portable I guess you are required to run your script from the current directory and have your loaded file relative to both.
Since Chez Scheme implements R6RS load is not really the right form to use. R6RS removed load in favor of libraries. You should make your file a library and consult how to install it. In some systems that is just placing the files in the right path, adding library location in configuration or running install script. How one uses the library is the same in all implementations, by using import.
According to Chez documentation you can pass --libdirs to it to give it one or more paths to consider for loading libraries. You can see the paths it scans by evaluating (library-directories)
There are several different ways to accomplish what (I think) you are trying to do, but eventually they all boil down to letting Chez know where to look for things. When given relative paths, include and load use the source-directories parameter to search for the requested file. Libraries have their path automatically prepended to source-directories while they are being loaded or compiled, so if your main.scm were a library definition then it would find util.scm as you expect.
However, it sounds like main.scm isn't a library, it's a top-level program. Unfortunately, Chez doesn't have a command line option to set the source-directories like it does for library directories. That leaves you with a bit less flexibility. Any of the following will work:
Make util.scm a library and invoke Chez with the --libdirs option to let it know where to look for libraries.
Set source-directories and load main.scm from inside the REPL rather than from the command line.
Write a wrapper shell script that does the above by echoing the commands into scheme so you don't have to type it yourself. (Only suitable if you don't also need to then type into the scheme session).
Write a wrapper shell script that cds into your project directory before running scheme (and presumably cds back to the original directory when it's done).

Convenient way to start a custom OCaml toplevel in Emacs with tuareg

If I start a custom toplevel in Emacs/tuareg with the tuareg-run-caml function, I need to give the path to the toplevel and the various -I options it requires to find the CMI files. This typing is tedious, is there a more convenient way to start a custom toplevel?
One approach is to add a .ocamlinit in the project directory that uses #directory to add whatever paths are necessary to the toplevel. You can also use this to install printers, add shorter names for commonly used modules, run test code, etc.
Note that you probably want that project specific .ocamlinit to execute ~/.ocamlinit, since things like opam tend to put bits and pieces in there. It might look something like this:
#use "/home/foo/.ocamlinit"
#directory "_build"
open Printf
module V = VeryLongModuleName
Note that #use expects a hard-coded path. This unfortunately interferes with distributing the file.
I further automate this by having an emacs command to start a toplevel that searches the current directory for a file called *.top to execute, falling back to ocaml if none is found. As ocamlbuild provides a fairly simple method of building these files, this avoids much of the tedium of getting a project loaded into a useable toplevel.

Joining files in Coffescript

I am currently looking to use RequireJS to ensure modularity in the front end side of my project written in Coffeescript. Is there a way to use "import" directives in coffeescript so that you could recursive compile a large number of ".coffee" files into a single ".js" file - and potentially minify it too. I know there is a "join" argument you can pass to the coffeescript compiler, but it would be really useful to just reference files from one to another.
Secondly, it should be able to do this compilation really fast, so that the filewatcher can immediately change the entire output .js file every time any file (out of hundreds of files) was changed.
In addition, if it provided inbuilt minification/obfuscation that would be GREAT!

How to run a LISP program

Does the LISP program need to be in the same folder as the LISP compiler or can I call it from anywhere?
The basic operation is to call load with a pathname.
(load #p"/home/user710086/foo.lisp")
Then, you may need to run whatever "main" function is supplied by that file.
The location can also be in the current directory, which is, of course, platform dependent. The current directory usually has nothing to do with the directory the Lisp executable resided in, but is the directory of the shell you called it from. I do not know what the current directory is in Windows when you click on something, but I would guess that it is some home-directory-surrogate.
There are several things that may wrap around that basic operation. Usually, code is organized into an ASDF system, and has defined one or more packages. You would then add the .asd file to asdf:*asdf-registry* and then load the package with
(asdf:load-sys 'foo)
This would load all files defined in the .asd file in a calculated order, thus providing you with the system's functionality.

What is the difference between require and load in common lisp?

I'm going through Practical Common Lisp, I'm almost finished, and one question that has not been answered for me so far (or maybe I just missed it) is the difference between "require" and "load".
So what is the difference?
Thanks.
require is used for modules, which can each consist of one or many files.
load is used to load an arbitrary single file.
The require function tests whether a
module is already present (using a
case-sensitive comparison); if the
module is not present, require
proceeds to load the appropriate file
or set of files. The pathname
argument, if present, is a single
pathname or a list of pathnames whose
files are to be loaded in order, left
to right. If the pathname argument is
nil or is not provided, the system
will attempt to determine, in some
system-dependent manner, which files
to load. This will typically involve
some central registry of module names
and the associated file lists.
Source: http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node119.html
The load function loads the file named by
filename into the Lisp environment. It
is assumed that a text (character
file) can be automatically
distinguished from an object (binary)
file by some appropriate
implementation-dependent means,
possibly by the file type. The
defaults for filename are taken from
the variable
default-pathname-defaults. If the filename (after the merging in of the
defaults) does not explicitly specify
a type, and both text and object types
of the file are available in the file
system, load should try to select the
more appropriate file by some
implementation-dependent means.
Source: http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node217.html
The difference is that (require) loads a module if it has not been loaded already; (load) loads a file.