Skip to content
FutureBlitz

    Install

    Modules and packages, 2 of 6

    Modules and Import

    Import std's modules and folders, give a module a short name with As, and take only some names with From.

    What you’ll build

    A short program that summarizes a list of temperature readings with std’s statistics, keeps the recent ones on a stack, and cleans up a line of text with a regular expression. Each part uses a different form of Import, and you’ll see what the compiler says when one is missing.

    Every name needs its Import

    A module is named by its path, with dots between folders and without .fb: std’s file std/math/stats.fb is the module std.math.stats. Nothing of std’s is there without an Import, not even Print, which is in std.core. This program has no Import line:

    Print("hello")
    $ fb run main.fb
       Compiling main.fb
    main.fb:1:1: error: 'Print' is in std.core, which this file doesn't import
      |
    1 | Print("hello")
      | ^^^^^
    error: couldn't build main.fb because of 1 error

    So nearly every file starts with Import std.core. The language’s own features need no Import, though std’s code carries them out: strings, ==, For ... In, Throw and Catch, and a {key: value} Map literal all work in a file that imports nothing. Naming Map or another of std’s types, or calling one of its functions, needs the Import. Import lines come first in a file, before any other line of code.

    A module or a folder

    Import names a module, or a folder of modules, which brings in each module directly in it. std.collections is a folder whose files declare Stack, Queue, Set, and the rest, and std.collections.stack is one of them.

    Import std.core
    Import std.collections.stack
    
    Local readings = [18.5, 21.0, 19.5, 23.0]
    Local recent = Stack<Float>()
    For r In readings
        recent.Push(r)
    End For
    Print("latest: {recent.Pop() ?? 0}")
    Output
    latest: 23

    Leave the Import out, and the error says where Stack is:

    Import std.core
    
    Local recent = Stack<Float>()
    recent.Push(18.5)
    Print(recent.Count)
    $ fb run main.fb
       Compiling main.fb
    main.fb:3:16: error: 'Stack' is in std.collections, which this file doesn't import
      |
    3 | Local recent = Stack<Float>()
      |                ^^^^^^^^^^^^
    error: couldn't build main.fb because of 1 error

    A short name with As

    Import X As Name brings a module’s names in only through Name. It keeps a module’s names apart from your own, and makes clear where each one comes from.

    Import std.core
    Import std.math.stats As Stats
    
    Local readings = [18.5, 21.0, 19.5, 23.0]
    Print("mean {Stats.Mean(readings)}, median {Stats.Median(readings)}")
    Output
    mean 20.5, median 20.25

    With As, the names aren’t there without it. A bare Mean(readings) is an error that says how the file imports it. It names the folder, std.math, where the module is:

    Import std.core
    Import std.math.stats As Stats
    
    Local readings = [18.5, 21.0, 19.5, 23.0]
    Print(Mean(readings))
    $ fb run main.fb
       Compiling main.fb
    main.fb:5:7: error: 'Mean' is in std.math, which this file imports as Stats, so it's Stats.Mean
      |
    5 | Print(Mean(readings))
      |       ^^^^
    error: couldn't build main.fb because of 1 error

    Only some names with From

    From X Import A, B brings in only the names it lists, without a qualifier.

    Import std.core
    From std.text.regex Import Regex, RegexError
    
    Try
        Local number = Regex("[0-9]+")
        Print(number.Replace("room 101, floor 3", "#"))
    Catch e As RegexError
        PrintError(e.Message)
    End Try
    Output
    room #, floor #

    Every other name of std.text.regex stays out. Using one, like its Match Class, is an error that says the From line doesn’t name it.

    All of them together

    A file mixes the forms freely, one per line:

    Import std.core
    Import std.collections.stack
    Import std.math.stats As Stats
    From std.text.regex Import Regex, RegexError
    
    Local readings = [18.5, 21.0, 19.5, 23.0]
    Print("mean {Stats.Mean(readings)}, median {Stats.Median(readings)}")
    
    Local recent = Stack<Float>()
    For r In readings
        recent.Push(r)
    End For
    Print("latest: {recent.Pop() ?? 0}")
    
    Try
        Local number = Regex("[0-9]+")
        Print(number.Replace("room 101, floor 3", "#"))
    Catch e As RegexError
        PrintError(e.Message)
    End Try
    Output
    mean 20.5, median 20.25
    latest: 23
    room #, floor #

    A plain Import also brings the names in under the module’s last name, so after Import std.collections, collections.Stack is the same type as Stack. Two modules can import each other, and the compiler sorts out the order.

    What you learned

    • A module is named by its path, as std.math.stats is std/math/stats.fb, and a folder’s name imports each of its modules.
    • Every name of std’s needs an Import, std.core’s too.
    • Import X As Name gives a module’s names only through Name.
    • From X Import A, B brings in only the names it lists.
    • The compiler’s error for a missing name says where the name is and how the file imports it.

    Report an issue with this page or with FutureBlitz on GitHub.