Skip to content

Creating Seed Systems

phantomics edited this page May 8, 2018 · 3 revisions

In this section, we'll delve into .seed files, which serve as the foundation for all Seed systems. The .seed file in a given Seed project does everything that the .asd file does in ASDF packages, along with implementing the input and output processes that define how a Seed system works. In other words, the .seed file format expresses a superset of the functions accessed through the .asd format.

The format in brief

This is the basic format of the .seed file:

(sprout :demo :system (:description "This is the system package's title."
                                    :author "Somebody" :license "MIT") 
	:package ((:use :common-lisp)(:export))
        :branches nil)

Each .seed file contains an invocation of the (sprout) macro. The first argument is the name of the system, :demo in this case, followed by a list of parameters. The :system parameter defines the ASDF package that this system expressed. The contents of this system are used (along with some other sources of information) to populate the .asd file in the system's home directory, thus providing for the system to be packaged, built and run via ASDF.

The :package parameter defines the content of the package.lisp file in the system's home directory, which defines the package via the (defpackage) macro. The compiler literally connects 'defpackage to the beginning of the expression to create the package.lisp file.

The :branches parameter is where it gets interesting. The example above contains a nil value for branches, resulting in a Seed system that's impossible to interact with. That's not very interesting, so let's go into greater depth.

Specifying the stage

:branches ((stage (in (set-time))
                  (out (set-type :stage)
                       (display-params (:primary (:first :second))
                                       (:adjunct (:clipboard :history)))
                       (codec))))

The :branches parameter is first and foremost a list of the branches present in a system. A branch is one of the channels through which input and output flow to and from a Seed system. The stage branch, specified above, is the foundation for the other branches in the system. The stage defines a Seed system's basic user interface.

In the case above, the stage is defined as containing two primary displays, one for the :first branch and one for the :second branch, and two adjunct displays, one for the :clipboard branch and one for the :history branch.

The primary displays in a system are the main data displays that a user may interact with. They usually appear as large interactive areas on the screen. The adjunct displays refer to smaller interactive areas used to display information that doesn't need to be as detailed as what's shown in the primary displays. For instance, you could say that in a word processor the main text pane is a "primary display," while the control banks and menu items above and below it are the "adjunct displays."

###Dataflow concepts

The Seed system specification is a kind of dataflow language. That means that each statement operates on data received from the previous statement (for the most part). This is different from typical Lisp code. For instance, say that you've created two lisp functions, called (gimme-a-5) and (multiply-that-by-6). When you run the function (gimme-a-5) it returns the value 5. When you run the function (multiply-that-by-6 3) you get 18. The (multiply-that-by-6) function can't work without a number passed to it. Now let's say you execute the following code:

(gimme-a-5)
(now-multiply-that-by-6)

In a regular Lisp environment, this will result in an error. But within the :branches (sprout) macro, you would receive a result of 30. Now, that presumed that (gimme-a-5) and (now-multiply-that-by-6) are defined as Seed system media, but we'll get into the implications of that later. The important thing to understand is that every expression you see in the :branches parameter operates on the output of the previous expression, or at least it has the potential to.

Let's look at that stage system spec one more time:

:branches ((stage (in (set-time))
                  (out (set-type :stage)
                       (display-params (:primary (:first :second))
                                       (:adjunct (:clipboard :history)))
                       (codec))))

What's happening here is that first the type of the system output is specified (a :stage system). Then, the display parameters for the system are set. When evaluated, this macro produces a Lisp code expression that defines how the user interface is made up. Finally, the (codec) expression is evaluated. The (codec) macro expands to a function that converts the Lisp code received in the previous expression into a JSON format that can be expressed by the end user's Web browser.

Clone this wiki locally