ktm v0.28.3

The language

Everything ktm has, one topic per chapter, each with many small programs you can run. Read them in order the first time; later, use them as a reference.

  1. 1A first programWhat a ktm source file looks like, where a program starts, how it prints, how it ends, and the ways to build and run it.
  2. 2Types and valuesThe built-in types, their sizes and limits, how values convert from one type to another, and how to write numbers, characters and text in source code.
  3. 3VariablesDeclaring local and global variables, the zero they start with, letting the compiler pick the type, static locals, constants, and where a name is visible.
  4. 4OperatorsArithmetic, bit operations, assignment, comparisons and logic, ktm's chained comparisons, sizeof and typeof, casts, and the order operators apply in.
  5. 5Control flowif and else, the three loops, the range-based for, break and continue, and goto. switch has its own chapter.
  6. 6switchswitch picks one of several branches by a value. It looks like C's, with four differences: cases don't fall through into each other, a case can be a range, you can switch on text, and an explicit fallthrough is there for the rare case you want it.
  7. 7FunctionsDefining and calling functions, how arguments and results are passed, prototypes, default arguments, parameters that know where they were called from, recursion, and how your names stay apart from the libraries'. Variable arguments, overloading, function pointers and methods have chapters of their own.
  8. 8PointersA pointer holds the address of a value. This chapter covers taking addresses, reading and writing through pointers, pointers to structs, null, pointer arithmetic, and the conversions between pointer types. For a pointer that knows its length, see Arrays and slices.
  9. 9MemoryWhere values live, how to allocate memory that outlives a function, how to give it back, and the habits that keep a program free of leaks. ktm has no garbage collector: memory you allocate is yours until you free it.
  10. 10Arrays and slicesA fixed-size array holds its elements in place. A slice T[] is a pointer and a length: a view of some Ts that knows how many there are, and checks every index. This chapter covers both, how they convert into each other, and when to use which.
  11. 11Stringsktm has three ways to hold text. A String is text you own: it grows and you free it. A u8[] is a view of text someone else owns: what functions take to read text. A u8 * is a C string, for C functions. This chapter covers all three and how they convert.
  12. 12Structs and unionsA struct groups several values under one name; a union lets several fields share the same memory. This chapter covers declaring structs, initialising them, how they are copied, how they nest, how they are laid out in memory, declaring them ahead, and unions, named and anonymous. Methods on structs have their own chapter, Methods.
  13. 13MethodsA method is a function that belongs to a struct: it is named Type.name, written outside the struct, and called on a value with value.name(...). A struct can also extend one other struct and get its fields and methods. This chapter covers defining and calling methods, self, the conventions for making and freeing values, inheritance, hiding a method, and why there is no virtual dispatch (and what to do instead). ktm has no classes and no constructors: a struct is data, and its methods are functions.
  14. 14EnumsAn enum is a set of named integer constants of its own type. Its members are always written with the enum's name in front, Color.red, so two enums can have members of the same name. This chapter covers declaring enums, their values and underlying type, using members as constants, flags, conversions to and from integers, switching on an enum, names at run time, and enums as error codes.
  15. 15Errorsktm reports errors with exceptions: throw stops what is running and jumps to the nearest try that encloses it, any number of calls up, where catch handles the error. This chapter covers the Error struct, throwing, catching, error codes, rethrowing, what happens on the way up, errors the library throws, @caller parameters for saying where a problem is, and the report an uncaught error prints.
  16. 16defer and scopeddefer runs a statement when its block is left, however it is left: the end of the block, a return, a break, or an error passing through. scoped in front of a declaration frees the variable the same way. Both keep the clean-up next to the code that needs it, so it can't be forgotten on one of the ways out. This chapter covers defer, the order defers run in, what they see, and scoped.
  17. 17GenericsFunctions, structs and methods can take type parameters: one definition, written once, used with many types. Each use is compiled for its types, producing the same code you would write by hand, with no void * and no casts. This chapter covers generic functions, how the types are worked out at a call, generic structs and their methods, methods with type parameters of their own, generic bases, the library's generic containers, and the errors generics give.
  18. 18OverloadingSeveral functions can share one name when their parameter types differ. A call picks the one its arguments fit best, at compile time. This chapter covers declaring overloads, how a call chooses, integer literals and casts, enums, defaults and ties, taking the address of an overload, overloaded methods, and the errors.
  19. 19Variable argumentsA function can take any number of extra arguments after its fixed ones. Inside the function they are a slice, with no va_list to walk. There are three kinds: typed extras (T ...name), extras of any type (any ...name) and untyped 64-bit slots for format functions (...name). This chapter covers each, passing extras on to another function, and C's own ....
  20. 20Function pointersA function pointer holds the address of a function, so the function to call can be chosen at run time, stored in a table or a struct, and passed to other functions. Its type is written fn(parameter types) return type. This chapter covers the type, taking addresses and calling through pointers, passing and returning functions, tables of them, pointers in structs, pointers to function pointers, callbacks with context, and which conversions work.
  21. 21Type aliasestype Name = T; gives a type a second name. The alias is the type itself, not a new one: the two are interchangeable everywhere. This chapter covers declaring aliases, naming long types with them, what "the same type" means, aliases of arrays and generic instances, and aliases in modules.
  22. 22Modules and packagesA module is a directory of .ktm files with a name. A program imports it and uses the names the module marks pub, with the module's name in front: geo.area(5). A package is a module that lives in its own git repository and is imported by its path, as in Go. This chapter covers writing a module, what is visible where, methods and private fields across modules, imports and how modules are found, start-up order, the prelude, packages with ktm.mod, ktm get, and the prebuilt package cache.
  23. 23AttributesAn attribute is a word starting with @, written before a struct, a field or a parameter. It asks the compiler to write code for the declaration, or tells a library how to treat it. This chapter covers where attributes go, @json and @yaml and the methods they generate, the field attributes @key, @skip and @omitEmpty, the settings attributes @env and @required, the validation rules @min, @max, @email, @url and @oneOf, @caller on parameters, seeing the generated code, and reading attributes through reflection.
  24. 24ReflectionReflection lets a program look at its own types while it runs: a struct's fields and where they are, an enum's members and their names, a value's type. The reflect module provides it. This chapter covers describing a type with reflect.typeOf, what a reflect.Type holds, handling a value of any type with reflect.of, reading and writing fields by name, enum names, attributes, and how the library builds on it.
  25. 25The preprocessorThe preprocessor runs before the compiler proper: it defines named values with #define, keeps or drops code with #if, pastes files in with #include, and links C libraries with #link. It is C's preprocessor, simplified: a macro names one value, and there are no function-like macros. This chapter covers #define, how a macro's value is evaluated, conditional compilation, macros from the command line, the predefined macros, #include and #link.
  26. 26Calling Cktm calls C functions directly: declare one with extern "c" and call it, with no wrapper and no cost beyond a normal call. Most of the C library is already declared in the libc module. This chapter covers the libc module, declaring C functions and data, how C types are written in ktm, C structs, passing ktm functions to C as callbacks, linking other C libraries, and how ktm's names stay apart from C's.
  27. 27Threads and threadlocalA ktm program can run several threads at once, each with its own stack, all sharing the program's globals and heap. The thread module starts them and gives them locks to take turns with; the language adds threadlocal, a global with one copy per thread. This chapter covers starting threads, errors in them, sharing data safely, threadlocal, many threads at once (WaitGroup, each, channels, pools), coroutines in brief, and C's threads.
  28. 28Inline assemblyAn asm { } block holds machine instructions, assembled by ktm itself for x86_64 or arm64. The routines it defines are called from ktm like any function. This chapter covers writing asm routines, binding them to ktm prototypes with _extern, how arguments and results travel, labels and loops, a function whose whole body is assembly, writing instructions as raw bytes, supporting both processors, and the errors.
  29. 29Safety and debuggingktm is a systems language: it has pointers and manual memory, and a program can still go wrong in the ways C programs do. What it adds is help in finding out where. This chapter covers the checks ktm makes while a program runs (bounds checks, zeroed locals), the reports a failing program prints (uncaught errors and crashes), finding memory bugs with -Memsafe, looking at what the compiler made of a program, and using a native debugger.