Skip to content

Imports & libraries

An import should answer a simple question: which reviewed implementation does this name mean? D/BASIC offers two honest answers—bake the source into the program, or bind an exact compiled library.

A dotted module name

An import occupies its own source line:

IMPORT dworks.widgets

Module names are ASCII case-insensitive dotted identifier segments. The example maps the public name dworks.widgets to the governed dworks/widgets.bas library.

dworks.* and gx are protected standard module names. A project cannot shadow either with a same-named local file.

Baked imports

IMPORT dworks.widgets BAKED

BAKED expands the library's source before normal parsing and produces one self-contained .dbc program. Use the word explicitly for a protected D/Works module:

IMPORT dworks.widgets BAKED

Use it when:

  • one portable file is more valuable than sharing storage;
  • the program and library are being developed together;
  • no installation step should be required; or
  • the destination runner does not maintain a shared library store.

Expansion is deterministic, depth-first, and once per canonical file. A library may import another library; cycles refuse instead of recursing forever.

Shared imports

IMPORT dworks.widgets SHARED

SHARED compiles the program against a .dbl artifact and records an exact dependency:

  • library identity and version;
  • exported name and ordinal;
  • argument and result signature;
  • class shape when an exported class is used; and
  • SHA-256 digest of the artifact bytes.

At load time, the runner binds those exact bytes. An absent, changed, or incompatible library refuses by name before the program begins. It never quietly bakes a different copy and calls that close enough.

Use it when many programs share a substantial stable library or when a D/OS package installs the dependency alongside its consumers.

Every import is baked by default, including protected modules. Choose SHARED explicitly when a matching installed artifact is part of the program's delivery contract:

IMPORT dworks.widgets SHARED

The default is deliberately simple: source comes with the program unless you name an exact shared artifact. One program may bake a changing helper and share a stable installed D/Works or GX library, but SHARED is always written where that dependency matters.

Baked and shared are delivery choices

The BASIC meaning is the same:

DIM Save AS WorksButton
Save = NEW WorksButton("save", "Save")

With a baked import, the implementation body lives in the program image. With a shared import, a call can cross into the installed library image. The optimizer keeps only dependencies the program actually reaches; merely offering a shared library does not force an unused pin into the image.

Project-local modules

For a non-dworks.* name, resolution begins below the entry source file's project root:

my-project/
├── main.bas
└── model/
    └── invoice.bas
' main.bas
IMPORT model.invoice

Path separators, absolute paths, .. traversal, and disguised escapes are refused. A source import is a module name, not ambient filesystem authority.

A library cannot become a second application

Imported source may define:

  • constants and declarations;
  • TYPE records;
  • classes;
  • procedures and member bodies; and
  • its own nested imports.

It may not define a second top-level executable entry, WINDOW SUB lifecycle, ON KEY, ON POINTER, WINDOW ACCEPTS, or ON DROP face. The application owns its one entry and event surface.

That rule is what lets dworks.widgets remain a toolkit rather than a hidden window manager.

Standard libraries

Module Purpose
dworks.widgets themes, damage, controls, menus, and local UI events
dworks.document_media bounded document tables, images, and local transfer staging
dworks.network HTTP helpers, capability/status models, and owning asynchronous sessions
dworks.files typed mount, directory, bounded file-I/O, and file-edit helpers
dworks.data typed fixed-array wrappers for DATA read, browse, write, and artifact flows
dworks.sha256 canonical COMPUTE.SHA256 wrapper
dworks.sha256_oracle deliberately slow all-BASIC conformance oracle
dworks.drag typed drag-session carrier helpers
dworks.interchange application interchange helpers
dworks.dwrite_dobj d/Write DOBJ shapes and operations
dworks.dwr1 DWR1 document carriers
dworks.write_artifacts document artifact workflows and receipts
dworks.calc_model d/Calc model components
dworks.calc_view d/Calc view helpers
gx the GX game engine; its currently admitted core covers caller-owned scenes, entities, tiles, cameras, collision, and animation

These are source-facing libraries. Importing one supplies declarations and implementations; it does not create a host capability. For example, IMPORT dworks.data does not mount storage, and IMPORT gx does not create a graphics or audio route. The runner must still offer the rows a wrapper or application requests.

Build a library artifact

The desktop toolchain can publish a compiled D/BASIC library:

dbasic build-library library.bas -o library.dbl \
  --name example.library --version 1.0.0.0 --id 42

A .dbl is self-describing DBC with an export table and no application face. Publisher identity and version are build inputs; they are not magic constants a library source can claim about itself.

Import safety limits

The source assembler enforces finite work:

  • no more than 128 distinct modules;
  • no more than 1 MiB of expanded source;
  • one expansion per canonical file;
  • no cycles;
  • no escape from the project source root; and
  • no imported application faces.

These are useful diagnostics, not arbitrary inconvenience. A build should not depend on an unbounded include graph or whichever file happened to exist outside the project today.

What D/BASIC does not mean by import

IMPORT is not:

  • C #include with textual macros;
  • a runtime request for an unchecked source path;
  • a DLL search by a convenient filename;
  • a target-specific plugin loader; or
  • a way to smuggle another application entry into the program.

The compiler knows the source or the exact artifact. The emitted image records the resulting contract.

Library design advice

  • Export concepts, not target adapters.
  • Keep WINDOW and input faces in the application.
  • Put typed carrier packing behind small procedures.
  • Keep mutable session state in application-owned objects, not module globals shared by every consumer.
  • Give public operations stable names and explicit argument modes.
  • Test both BAKED and SHARED delivery for a library meant to support both.

Next: Compiler & Optimizer →