examples/gallery/08-ffi.hero
Use C libraries for features beyond the language basics.
- 49 lines
- uses C:
math.h stdio.h
extern declares calls to C libraries for maths, files, network connections and databases. The clang compiler checks those declarations against the library’s header, the file that describes its functions and types. It reports incompatible types before the program runs.
Run it
These files introduce the language one feature at a time. This page shows the program and not a result, because no test compares their output byte for byte yet.
The program
## Everything else comes from C
#
# There is no standard library, permanently. Maths beyond arithmetic,
# files, sockets, databases: they arrive through `extern`, and clang checks
# every declaration against the real header — a wrong type here is a
# compile error, not a crash at runtime.
#
# A group names the header its signatures come from. That is not decoration:
# the header is what clang checks against, and without one a declaration
# would be verified by nothing at all.
extern "math.h" link "m"
function sqrt(x: f64) -> f64
function pow(base: f64, exponent: f64) -> f64
function floor(x: f64) -> f64
# `cstr` is a C string and `ptr` an opaque pointer. Neither is a `str`:
# the boundary is visible in the type. A second group, because this one
# comes from a different header — and on macOS neither needs `link`, since
# libm and libc are already there.
extern "stdio.h"
function puts(s: cstr) -> i64
# The hypotenuse, in the language's own arithmetic plus one C call.
#
# Both sides are `f64`, so §4.9 makes the names mandatory at the call site. C's
# numeric APIs are where same-typed parameters cluster — `pow(base:, exponent:)`
# is the same shape — so this is where the rule is felt most and where argument
# inversion would be silent without it.
function hypotenuse(a: f64, b: f64) -> f64
return sqrt(a * a + b * b)
# No implicit conversions: an `i64` becomes an `f64` because you said so.
function diagonal_of(width: i64, height: i64) -> f64
return hypotenuse(a: to_f64(width), b: to_f64(height))
# `pow` is C's, `floor` is C's, and the rounding is yours.
function rounded_power(base: f64, exponent: f64) -> i64
return to_i64(floor(pow(base: base, exponent: exponent))).must()
test "the C library does the maths"
assert hypotenuse(a: 3.0, b: 4.0) == 5.0
assert rounded_power(base: 2.0, exponent: 10.0) == 1024
function main()
print(
"the 16:9 diagonal of a 1920-wide screen: ",
diagonal_of(width: 1920, height: 1080)
)
fingerprint sha256 1c123e67ca74 · 1 file · index.json
Next: 09-holes. All the examples. ← Previous: 07-strings
Run one yourself: the four commands. Learn the language, or read the full specification in one file.