The Ring

1. What Does the Ring Do?

The Ring is a code extractor that enables you to write a Shen program and extract from it all and only the code from the Shen kernel necessary to run it and translate that code to the object code of your language of choice (Common Lisp, Javascript, Python etc.). This means that you do not need to carry out 20,000 lines of object code merely to run 100 lines of Shen. The Ring works by mapping your code to Kλ, the functional 'assembly language' of Shen and then uses the backend (the compiler from Kλ to the object language) to generate the object language code. Also included are auxiliary object code files needed to run your code.

The Ring uses transitivity tables to compute call relations within the kernel and these tables are downloaded with the plugin.

2. Invoking the Ring

If the file(s) you want to extract is in a directory (say) C:Foo/mystuff then you probably want to cd your home directory to that directory using (cd "C:Foo/mystuff/"). In that way the Ring will dump all the extracted files into that directory. If you use the full path name then you'll get the extracted code from your program files in the directory the files are in and the kernel code in the home directory.

The top level command is
ring followed a series of keyword and values as follows:

keyword value
-files evaluates to a list of strings that denote the files that contain your source code
-license (optional) evaluates to a string denoting the license that you wish to place on your code
-platform (optional) evaluates to a string denoting the object level code you want generated
-notypes (optional) either true or false, defaults to true, type theories are ignored (see below)
-total (optional) either true or false, defaults to true, partial functions are autocompleted (see below)

(e.g. (ring -files ["mycoolapp.shen"] -license "All my stuff").

By default, if you fail to give a license then you get no license on the code; if you don't give a platform then the code generated is Kλ. You'll find the object level code for your programs in files of the form <name>.<extension> where <name> is the name of a source file and <extension> is a function of the platform (e.g kl for Kλ). Currently the only extensions you can enter for platform are "kl" and "sbcl". The kernel code you need to run your application is dumped in a file kernel.<extension>.* This code is referred to here as the tail of the application.

3. The Footprint File

One very useful file footprint is the footprint file that is generated along with the object code which provides an outline of the footprint of your appl. The file provides a list of pairs of the form (@p <symbol> <number>) where <symbol> is the name of an application function and <number> is the size in K of the tail that this function directly pulls in. This is often highly useful, because you'll see right away where your code is pulling in tail. The next section gives some tips on reducing tail.

4. Reducing the Tail

Some tips for you.

1. Avoid partial functions.

When you enter a partial function into Shen, it is closed off by the Shen compiler which inserts a call to the trace package if the function receives an argument outside its domain. This inserted code will bring in code from the trace package. -total set to true will replace these calls by simple error messages that do not pull in tail. But be active in closing off these partial functions with meaningful error messages of your own.

2. Avoid including type theories ....

Type theories bring in a lot of code; thousands of lines - because they are compiled using Shen Prolog and parsed in Shen-YACC. So straight away you have a big overhead. Do you need those theories? Probably not, because the purpose of having them is to guarantee your program is type secure. But you've already done that in Shen - right? So why carry this stuff around? The -notypes option when set to true just ignores type definitions.

3. .... or dynamic appeals to the type checker.

It may be that you are at some point using input+ to dynamically type check input. If so, see if you cannot use some other device. For example (input+ string) is more economically replaced by a simple string test on user input if all you want them to do is enter a string. Retaining input+ means that you have to carry the whole typechecker into your application - which you don't want to do. Also see the remarks in 4. below.

3. Avoid eval.

eval brings in a big tail - over 250K of code - because it essentially embodies the very heart of Shen. eval can invoke everything. Using eval in an application is generally not good practice. Why? Well first eval has no type (unless you are very clever and devise your own type theory) and second it is really quite inefficient. So try not to rely on it.

4. Use low level input operations if possible.

read and input (also input+, lineread, read-file etc) are all high-level input functions; they suck in a lot of code - over 250K - because they pull in the reader. Devise your own light weight reader operations out of read-byte. For instance if you just want to read a person's name, then a simple loop with read-byte and n->string exiting with a string will do the job. read-byte is super-light.

Output operations are not heavy because they are macro driven and are replaced by low level code at compile time. If your code uses output or error, you'll have little tail from this.

5. Beware of relying on macros in your driver functions

Your driver functions are the functions the user invokes to call up your application; they are generally external to the package you are working in. Using macros internally to a package in your application is no problem because Shen will just compile them out, but if you are using them in a driver function then you have a problem because they will not work for the user outside Shen. Macros depend on the intervention of the Shen reader and if you include that you are going to need much of the kernel.

* Note: as of August 2017; only "kl" is working. The system is experimental and is under continuous development.

What Does the Ring Do?

Invoking the Ring

The Footprint File

Reducing the Tail