ginger/docs/packages.md
2014-10-06 17:44:07 -04:00

2.9 KiB

Packages

Ginger packages follow many of the same packaging rules as go packages. This stems from ginger compiling down to go and needing to inter-op with go packages.

As discussed in the compilation doc, packages are defined as follows:

(. package "github.com/mediocregopher/awesome"

    (. def AwesomeThing "totally")

    (. defn AwesomeFunction []
        (: rand))
)

This expression does not have to appear in a particular folder heirarchy, and multiple packages can appear in a single file. A package's definition can be split up into multiple package statements across different files. This is discussed more in the compilation doc.

Variable/Function naming

Variables and functions follow the go rule of upper camel casing for public variables/functions and lower cammel casing for private variables/functions. This rule is enforced by the go compiler for both go packages and translated ginger packages.

Private

A private variable/function can only be referenced from within a package. If a package is split into multiple parts across a project a private variable/function defined in one part can be used in another part.

Public

A public variable/function can be used within a package without any extra embelishment (in the above example, (: AwesomeFunction) could simply be called from within the package.

Outside of a package can be used as follows:

(. package "show-and-tell"

    (. defn main []
        (: fmt.Println
            (: github.com/mediocregopher/awesome.AwesomeFunction)))
)

show-and-tell.main uses both the Println function from the fmt package and the AwesomeFunction function from the github.com/mediocregopher/awesome package. This syntax is rather cumbersome, however, and can be shortcutted using the alias function in a package

(. package "show-and-tell"

    (. alias "github.com/mediocregopher/awesome" "aw")

    (. defn main []
        (: fmt.Println
            (: aw.AwesomeFunction)))

Like go, aliasing a package to "." imports it directly:

(. package "show-and-tell"

    (. alias "github.com/mediocregopher/awesome" ".")

    (. defn main []
        (: fmt.Println
            (: AwesomeFunction)))

Aliasing a package requires that you use it in the package you've aliased it in, unless you alias to "_".

Idiomatic package usage

While it is not a requirement that your package namespaces follow the directory heierarchy they show (in fact, you could have an entire project, with multiple packages, all within a giant flat file), it's definitely recommended that you do. It will make the code much easier to create a mental map of for newcomers to it.

Circular dependencies

Go enforces that a package may not have circular dependencies. That is, packageA may not import packageB while packageB also imports packageA. Ginger will also, be way of being translated to go, also enforce this rule.