From d4b92d96ada452162c54f3b897856b5f3de340c7 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Mon, 6 Oct 2014 11:08:47 -0400 Subject: [PATCH] packages.md --- functions.md | 4 +++ packages.md | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 packages.md diff --git a/functions.md b/functions.md index e3f064e..574222b 100644 --- a/functions.md +++ b/functions.md @@ -80,3 +80,7 @@ of using it. `+` is a variadic function in this example: (: fmt.Println (avg 1 2 3 4 5)) ``` + +## Tail-recursion + +TODO diff --git a/packages.md b/packages.md new file mode 100644 index 0000000..245462f --- /dev/null +++ b/packages.md @@ -0,0 +1,95 @@ +# 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.