Imports

Let's unravel the art of importing files and libraries in FatScript! Why? Well, because in this language you can import whenever your heart desires, simply by using a left arrow <-.

Dot syntax

To use imports with dot syntax, project files and folders should neither start with a digit nor contain symbols.

you can force any path you like by using literal paths

Named import

To import files, use the .fat extension for filenames (or no extension at all), but omit the extension in the import statement. Here's an example:

ref <- filename

if both x and x.fat files exist, the latter takes precedence

For importing files from folders:

ref1 <- folder.filename
ref2 <- folder.subfolder.filename

To import all files from a folder, leverage the dot-underscore syntax:

lib <- folder._

Please note: only files immediately inside the folder are included using the above syntax. To include files from subfolders, explicitly mention them. Additionally, a "_.fat" file (or "_" file) inside a folder can override the dot-underscore import behavior.

Element access

Once imported, access elements using dot syntax:

ref1.element1

Element extraction

To extract specific elements from a named import or to avoid prepending the module name every time (e.g., lib.foo), employ destructuring assignment:

{ foo, bar } = lib

Visibility

Named imports are resolved at the global scope, irrespective of where they are declared. This means even if you declare a named import inside a function or a local scope, it will be globally accessible.

Local import

To import within the current scope, use:

_ <- filename

Local imports, unlike named imports, dump the file content directly into the current scope. Thus, an imported method can be invoked as baz(arg) rather than ref.baz(arg).

While local imports are best suited for importing types into the global scope, they should be used with caution when importing library content. Overusing local imports can lead to namespace pollution, which can make it more challenging to follow the code, because it becomes less apparent where the methods come from.

Selective local import

You also can discard elements from a local import by using destructuring assignment:

{ foo } = { _ <- lib }

the point is to avoid namespace pollution, as all the contents will be processed

Literal paths

With literal paths, you may use any filename or extension. However, note that those imports are not evaluated during bundling, but at runtime. Here's an example:

ref <- '_folder/2nd-source.other'

You can also use smart texts as literal paths:

base = 'folder'
file = 'source.xyz'
ref <- '{base}/{file}'

Since FatScript alternatively accepts JSON-like syntax you may even load a JSON file directly as an import:

json <- 'sample/data.json'

however possible, it is more advisable to use file.read and then recode.fromJSON

Keep in mind that literal paths can make your code more complex, and those imports can only be dynamically resolved, so use them sparingly.

Import policy

FatScript utilizes an "import once" strategy with an in-scope flag mechanism, automatically bypassing files that have already been imported.

Imports are generally resource-efficient. However, local imports within method bodies should be avoided as they are re-evaluated with each invocation, potentially causing memory retention.

This behavior is not classified as a bug per se, but rather a consequence of design choices in FatScript's garbage collection (GC) system. The GC's optimizations exclude nodes directly derived from source code, allowing them to evade standard mark-and-sweep procedures. As a result, local imports within methods miss out on deduplication, causing their nodes to remain resident until the program's end:

myMethod = -> {
  _ <- lib  # potential memory leak
  ...
}

Here are some strategies to address this issue:

  • Relocate the import statement to the outer scope.
  • Opt for a named import as an alternative.
  • Reorganize the 'lib' structure to export a method.

results matching ""

    No results matching ""