23: Modules, overloaded functions and generic functions
E2301
No .ss file for an import. import name looks for name.ss next to the importing file, then in each folder of the Python path.
import attentoin
Check the name, or put the folder that has the file on the Python path. See Importing other files.
E2302
Files that import each other. A file can’t import itself, directly or through other files: each file is checked with what it imports, so a cycle has nowhere to start.
$ cat a.ss
import b
$ cat b.ss
import a
$ shapescript check a.ss
error[E2302]: `b.ss` imports this file back
= note: the files import each other: a.ss -> b.ss -> a.ss
Move what both need into a third file that both import. See Importing other files.
E2303
An imported file has errors. A file is checked with the files it imports, and an error in one of them is reported at the import that leads to it, with its errors as notes.
$ cat broken.ss
fn f(x: [n]) -> [n] = y
$ cat main.ss
import broken
$ shapescript check main.ss
error[E2303]: `broken.ss` has an error
= note: broken.ss:1:23: error[E0301]: unknown name `y`
Fix the imported file; shapescript check on it shows the errors in full. See Importing other files.
E2304
A name an imported file doesn’t declare. std.name must be declared at the top level of the file imported as std.
import shapescript.std.fit as std
fn f(x: [n]) -> [n] = std.nothing(x)
Check the spelling, and that the declaration is in that file, not in one it imports: a file’s own imports aren’t part of its names. See Importing other files.
E2305
Standalone build of a file with imports. A --standalone module needs only torch, but it would import the other files through the shapescript package’s import hook.
$ cat main.ss
import shapescript.std.fit as std
$ shapescript build --standalone --devices cpu main.ss
error[E2305]: a standalone build can't import other `.ss` files
Build without --standalone, or put what you import into the file. See Importing other files.
E2306
An import or generic function where it can’t be used. Importing other .ss files, and calling generic functions, work in files, not in notebook cells; a program on several devices can’t import them yet, since each device’s worker runs only the file’s own code; an exported program can’t call another file’s functions; and an imported file can’t declare other devices than the file importing it.
%%shapescript
import layers
error[E2306]: `import` of a `.ss` file can't be used here
Put what you import into the cell or the file. See Importing other files.
E2307
Functions of the same name for the same model. Functions may share a name only when each takes a different model as its first parameter, since a call picks one by its first argument’s model.
dim D = 4
model A:
param w: [D] = zeros
fn forward(m: A, x: [D]) -> [D] = x * m.w
fn forward(m: A, x: [D]) -> [D] = x + m.w
Rename one of them. A function whose first parameter isn’t a model, and a generic function, can’t share their names. See Overloaded functions.
E2308
No function of that name for the argument’s model. Each function of the name takes a model first, and none takes the first argument’s.
dim D = 4
model A:
param w: [D] = zeros
model B:
param v: [D] = zeros
model Z:
param z: [D] = zeros
fn forward(m: A, x: [D]) -> [D] = x * m.w
fn forward(m: B, x: [D]) -> [D] = x + m.v
fn f(z: Z, x: [D]) -> [D] = forward(z, x)
Declare a forward for Z, in this file or in the one that declares Z. See Overloaded functions.
E2309
Misused type variable. A type variable of a generic function can’t also name an axis of its signature, and it must be used by a parameter, since calls work it out from their arguments.
dim D = 4
fn f(m: M, x: [M D]) -> [D] = x[0]
Use another letter for the axis, or a name, such as n. See Generic functions.
E2310
Arguments disagree about a type variable. Each type variable stands for one type in a call, worked out from the arguments: two arguments that make it different types, or no argument that says what it is, are an error.
dim D = 4
model A:
param w: [D] = zeros
model B:
param v: [D] = zeros
fn same(a: M, b: M) -> [D] = zeros_like(a)
fn f(a: A, b: B) -> [D] = same(a, b)
Pass values of the same type, or give the function two type variables, as fn same(a: M, b: N). A value from Python has no ShapeScript type to give. See Generic functions.
E2311
A generic function needs a function the model doesn’t have. A generic function’s instance for a model calls a function on it that isn’t declared for that model, in the generic function’s file or the model’s. The error is at the call to the generic function, and names where it uses the function.
import shapescript.std.fit as std
dim D = 4
model Plain:
param w: [D] = zeros
data Ex:
x: [D]
fn train(mut m: Plain, data: Dataset[Ex], sink: LogSink, mode: Mode):
std.fit(mut m, data, sink, 1, 8, 0.1, mode)
error[E2311]: `fit` with M = Plain, E = Ex needs a function `loss` that takes `Plain` first
= note: `train_step` uses it at <shapescript>/std/fit.ss:29:27, called by `run` …
Declare it, here fn loss(m: Plain, batch: [b] Ex, mode: Mode) -> [], next to the model. See Generic functions.
E2312
A generic function doesn’t check with these types. Checking the instance of a generic function for the types of a call found an error. The error is at the call, with the error in the generic function as a note.
dim D = 4
model A:
param w: [D] = zeros
fn loss(m: A) -> [D] = m.w
fn grad_of(m: M) -> Grad[M]:
l, g = value_and_grad(loss, m)
return g
fn f(m: A) -> Grad[A] = grad_of(m)
Here loss for A doesn’t give a [], so it can’t be differentiated. Change the function for the type, or call the generic function with another. See Generic functions.
E2313
Generic functions call each other too deeply. Each level of generic functions that call others for new types makes a round of new instances, and there may be 16.
dim D = 4
model A:
param w: [D] = zeros
fn g1(m: M) -> [D] = g2(m)
fn g2(m: M) -> [D] = g3(m)
fn g3(m: M) -> [D] = g4(m)
fn g4(m: M) -> [D] = g5(m)
fn g5(m: M) -> [D] = g6(m)
fn g6(m: M) -> [D] = g7(m)
fn g7(m: M) -> [D] = g8(m)
fn g8(m: M) -> [D] = g9(m)
fn g9(m: M) -> [D] = g10(m)
fn g10(m: M) -> [D] = g11(m)
fn g11(m: M) -> [D] = g12(m)
fn g12(m: M) -> [D] = g13(m)
fn g13(m: M) -> [D] = g14(m)
fn g14(m: M) -> [D] = g15(m)
fn g15(m: M) -> [D] = g16(m)
fn g16(m: M) -> [D] = g17(m)
fn g17(m: M) -> [D] = g18(m)
fn g18(m: M) -> [D] = m.w
fn f(a: A) -> [D] = g1(a)
Make the chain shorter, or make some of its functions take the concrete type. See Generic functions.