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 null
able 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 class
es 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.