Skip to content

Target Languages

temper build translates to many target programming languages via Backends (Backend.kt) that each embed knowledge about one target language. Each backend is responsible for:

  • converting Temper syntax trees to target language syntax trees, and
  • creating source files and source maps under the temper.out directory, and
  • connecting to language specific tools to

    • post-process the source files, and
    • run the translated tests and collect results, and
    • bundle them into publishable archives.

The Backend IDs noted below may be used with the -b flag (aka --backend) to the temper command line tool to build, run, or test using specific backends. See temper help for more information on -b.

Target Language List

C# Backend

BackendID: csharp

Translates Temper to C# source.

Targets .NET 6.0, although .NET Framework 4.8 might be supported in the future.

To get started with this backend, see the tutorial.

Translation notes

Temper function types, such as fn (Int): Int are translated into either Func delegates for most return types or Action delegates for Void return type. These have an upper limit of 16 parameters, which isn't accounted for in the current translation. In the future, if demand arises, Temper likely will generate new delegate types in generated libraries for larger numbers of parameters.

Temper nullable types, such as A | Null translate into either nullable value types or nullable reference types in C#. Nullable reference types apply only to newer versions of C#, so potential .NET Framework 4.8 support would need to represent these as ordinary reference types.

For clearer representation of intention, Temper collection types translate into .NET generic interfaces, including "ReadOnly" variations as appropriate. For example, Temper Listed<T> and List<T> both translate to IReadOnlyList<T>, whereas ListBuilder<T> translates to IList<T>. Similar rules apply to Temper Mapped types and .NET Dictionary types, with the additional matter that maps created in Temper always maintain insertion order. Use of these interfaces in .NET is complicated by the fact that Ilist doesn't subtype IReadOnlyList, even though standard .NET List subtypes both. Similar issues apply to Dictionary types. To improve ergonomics, usage of Temper Listed generate overloads that accept any of List, IList, or IReadOnlyList. Again, Temper generates similar overloads for Temper Mapped and .NET Dictionary types.

Each Temper library is translated into a .NET project/assembly, and Temper module is translated into a .NET namespace. Files for each subnamespace are produced in respective output subdirectories. Each type defined in Temper is translated to C# in separate file. Top-level Temper modules contents are produced in a "Global" C# static class for the namespace.

The Temper logging console translates in C# to the Microsoft.Extensions.Logging framework, at least for modern .NET usage. This framework typically initializes loggers via dependency injection (DI), which isn't supported for static classes and static initialization. Because of this, and to simplify general libraries that aren't built on DI, Temper instead generates static methods for initializing an ILogger instance for the output library. In the absence of any such configuration, generated libraries fall back to using System.Diagnostics.Trace.

Tooling notes

A csproj file is automatically created for each Temper library such that each builds to a separate .NET assembly.

The only .NET library naming configuration available today for config.temper.md is csharpRootNamespace. If specified, this string is configured as the root namespace for the output project as well as the name of the .NET assembly and the presumed NuGet package ID. More fine-grained configuration might be provided in the future. Microsoft has some advice for namespace selection.

Temper test blocks are translated to use the MSTest framework. A test class is generated for each Temper module, and each test block becomes a test method. Temper automatically provides infrastructure for soft assertions within tests.

Java Backend

BackendID: java

Translates Temper to Java source and later to JARs.

Targets Java 17.

To get started with this backend, see the tutorial.

There is also a Java 8 backend that produces similar output but which does not depend on newer Java runtime library features. Except where specified in the Java8 backend documentation, the notes here also apply to that backend.

Translation notes

TODO: Explain how Temper function types translate to Java SMI types.

TODO: Explain how nullable types are translated

TODO: Explain how Temper types translate to primitive or boxed types.

TODO: Explain overload generation for optional arguments.

TODO: Explain how Temper source files are split into Java files.

TODO: Explain how console.log connects.

Tooling notes

TODO: Explain how to pick a Java package for a library and Maven identifiers.

TODO: Explain how Temper tests correspond to JUnit and the version of JUnit we require

TODO: Explain the generated POM and JAR metadata.

TODO: Generating multi-version JARs is something we plan to do.

Java 8 Backend

BackendID: java8

Translates Temper to Java 8 source, and later to JARs for compatibility with older Java Virtual Machines (JVMs).

Except where noted here, the documentation for the main Java backend also applies to this legacy, Java 8 backend.

Targets Java 8.

JavaScript Backend

Backend ID: js

Translates Temper to JavaScript with types in documentation comments for compatibility with TypeScript.

Targets ES2018 / ECMA-262, 9th edition.

To get started with this backend, see the tutorial.

Translation notes

Temper [interface type declarations] are translated to names in JavaScript that work with JavaScript's instanceof operator. Your JavaScript code may use InterfaceType.implementedBy to create JavaScript classes that implement Temper interfaces.

The temper.out/js output directory will contain a source map for each generated JavaScript source file so that, in a JS debugger, you can see the corresponding Temper code.

Tooling notes

Temper's JavaScript backend translates tests to Mocha tests and generates a package.json file so that running npm test from the command line will run the translated tests for a Temper built JavaScript library.

Python Backend

Backend ID: py

Translates Temper to Python3 with types and builtin mypy integration which helps numerics heavy code perform much better than Python without type optimizations applied.

Targets Python 3.8. For best support, use CPython.

To get started with this backend, see the tutorial.

Translation notes

Temper's Void type translates to a return value of Python None.

Temper default expressions are evaluated as needed, so do not suffer the singly evaluated default expression pitfall.

Named arguments are translated to named arguments in Python, but TODO: we need to remove numeric suffixes.