APITrace

Trace

The call stack of the running program, for logging and diagnostics.

A compiled program knows which Fango functions are executing and the source line each one is at, the same information a crash report prints. capture returns it as ordinary values; render prints it the way a crash report does. Frames follow the generated code rather than the source text: a small pure function the compiler inlined has no frame of its own, a self tail call appears once however deep the recursion, and a Go closure a short lambda becomes shares its enclosing statement’s line. The interpreter keeps the same stack, so the REPL and compile-time evaluation report the same frames.

Frame

type Frame =    { function : String    , file : String    , line : Int    }Source

One entry of a captured call stack.

Fields

function

function : StringSource

The executing function, qualified by its module: Main.divide, Main.compute (lambda) for a function literal inside compute, Main.outer.inner for a local function, Show (List a).show for an instance method, or native Console.Write for a Go sidecar.

file

file : StringSource

The source file as diagnostics name it: the entry’s root-relative path, Sub/Mod.fango, or a bundled module’s logical path.

line

line : IntSource

The line of the call expression being executed.

Instances:

Eq Frame
Show Frame

capture

capture : () -> List FrameSource

The calling function’s stack, innermost first: the first frame is the function that called capture, at the line of that call. Capturing is not referentially transparent, since the result describes the caller, but it performs no effect and may be called anywhere.

import List
import Trace

List.length (Trace.capture ()) >= 0

render

render : List Frame -> StringSource

Renders frames one per line, innermost first, as a crash report prints them: at Main.divide (Main.fango:12), with a trailing newline after each frame and nothing for an empty list.

import Trace

Trace.render [ { function = "Main.divide", file = "Main.fango", line = 12 } ] == "  at Main.divide (Main.fango:12)\n"
Trace.render [] == ""