C△ provides two output functions through plstd: printd for type-aware single-value printing that automatically detects what you’re passing, and printfs for formatted output that supports both {expr} f-string interpolation and classic %-style format specifiers. Both functions write directly to standard output and work seamlessly across x86_64 Linux and ARM64 macOS.
printd — Type-aware Print
printd accepts a single value of any supported type and prints it without requiring a format string. Pass it an int, a string, a float, a char — it figures out the right representation automatically.
printd(42); // prints: 42
printd("hello"); // prints: hello
printd(3.14); // prints: 3.14
printd('A'); // prints: A
printd works with all of the following types:
| Type | Example | Output |
|---|
int | printd(100) | 100 |
float / double | printd(2.718) | 2.718000 |
char | printd('Z') | Z |
string | printd("hi") | hi |
auto | auto x = 7; printd(x) | 7 |
printd appends a newline (\n) after every value it prints. If you need fine-grained control over spacing and newlines, use printfs instead.
printfs is not implemented yet. No printfs.plib ships in the plstd/ folder in the GitHub, and printfs is not bundled inside printd.plib or any other plstd module. Calls to printfs(...) will fail to resolve at link time. The documentation below describes the designed behavior; the function does not exist in the current compiler. As a workaround, use printd for output, or fall back to C’s printf via raw C interop. Tracked in Compiler Status.
printfs is the workhorse for structured output. It accepts a format string followed by any number of arguments, and supports two interpolation styles you can mix freely in the same call: {expr} f-string placeholders and %-style specifiers.
string name = "world";
int x = 42;
printfs("Hello, {name}!\n"); // Hello, world!
printfs("x = %d\n", x); // x = 42
printfs("{x} squared = {x*x}\n"); // 42 squared = 1764
F-string braces evaluate arbitrary C△ expressions inline — you can perform arithmetic, call functions, or reference any in-scope variable directly inside {}.
Use these %-style specifiers in printfs format strings when you prefer explicit type control over f-string interpolation.
| Specifier | Type |
|---|
%d | int |
%ld | long |
%lld | long long |
%u | unsigned |
%o | octal |
%x / %X | hex (lowercase/uppercase) |
%p | pointer |
%f | float / double |
%s | string / char* |
%c | char |
%k | auto (dynamic type resolved at runtime) |
The %k specifier is unique to C△ — use it when you have an auto variable and want printfs to resolve and print the underlying type at runtime.
auto val = 99;
printfs("val is: %k\n", val); // val is: 99
Choosing Between printd and printfs
Reach for printd when you want to quickly inspect a single value during development, no format string needed, just drop in the variable. Switch to printfs when you’re building real output: labelled values, multi-variable lines, or anything that benefits from a template string. F-string syntax ({expr}) keeps those format strings readable without the verbosity of positional % specifiers.
// Quick debug inspection — use printd
int result = compute();
printd(result);
// Structured output — use printfs
printfs("compute() returned %d after {iterations} iterations\n", result);
Importing Output Functions
Both printd and printfs are part of plstd. Because the compiler auto-imports what you use, explicit imports are optional — but adding them makes your dependencies visible at a glance.
// Import all of plstd (includes printd and printfs)
using <plstd>;
// Import only what you need
using printd from <plstd>;
using printfs from <plstd>;