Bundles
A bundle is a stateless entity that holds types, constants, and pure helper functions. Bundles let tasks and networks share definitions without coupling their behaviour.
package com.neosyn.sha256;
bundle SHACommon {
typedef u6 addr_t;
u9 HASH_SIZE = 256;
u32 Ch(u32 x, u32 y, u32 z) {
return (x & y) ^ (~x & z);
}
u32 Maj(u32 x, u32 y, u32 z) {
return (x & y) ^ (x & z) ^ (y & z);
}
}A bundle has no ports, no state variables, and no setup or
loop. Every function it declares is implicitly const - the
keyword is optional.
Referencing a bundle
There are three ways to use a bundle's members from another entity. Pick the shortest one that doesn't cause name conflicts.
Import everything, refer by short name:
import com.neosyn.sha256.SHACommon.*;
// addr_t, HASH_SIZE, Ch(), Maj() are now in scopeImport the bundle, refer by qualified name:
import com.neosyn.sha256.SHACommon;
// SHACommon.addr_t, SHACommon.Ch(), …Refer by fully qualified name, no import:
com.neosyn.sha256.SHACommon.addr_tWildcard imports are convenient but can cause collisions when two bundles export the same name. Qualified imports avoid that.
What goes in a bundle
| Kind | Allowed | Notes |
|---|---|---|
typedef | Yes | Shared type aliases |
| Constant | Yes | Compile-time values |
struct | Yes | Shared record types |
enum | Yes | Literals are always written Mode.RUN, never bare |
| Function | Yes | Implicitly const |
| State variable | No | Bundles are stateless |
| Port | No | Bundles have no interface |
setup / loop | No | Bundles have no behaviour |
If a bundle needs state or behaviour, it should be a task instead.
Declarations at file scope
When the definitions are used by only one file, writing a whole
bundle for them is ceremony. Since v2.9.6 you can declare
const, typedef, struct and enum directly in the file,
above the first entity:
package com.neosyn.fir;
const u8 TAPS = 8;
typedef u16 acc_t;
task Fir {
sync { in u8 x; out acc_t y; }
// TAPS and acc_t are in scope here, unqualified
}These become an unnamed bundle that the file imports for you, so you refer to them by short name with no import line and no qualifier.
Two rules follow from that:
- They must sit above the first
task,networkorbundle, after any imports. A declaration below the first entity is a syntax error. - A file gets one such group. Declarations cannot be interleaved between entities.
File-scope declarations are private to their file. Other files cannot import them, so anything shared belongs in a named bundle.