← back

Coming from Java

The same static typing and explicit visibility you already work with, without a VM underneath. Tape compiles to one native binary — nothing to install on the target, no warmup, no collector to tune.

classes & interfaces

Java

class, extends, implements. Behavior arrives through the hierarchy.

Tape

struct holds the data, fn Type.method(*self) adds the behavior, and nothing inherits. Components compose through slot and event. Polymorphism is structural — *component[...] accepts any component whose dispatch signatures match, with no implements clause to write.

generics

Java

List<T>, bounded wildcards, and erasure that leaves the type gone by runtime.

Tape

No generics, ever. @tape fn gen_map(K: type, V: type) executes at compile time and emits a concrete Map_i64_string with unboxed storage. The specialization is ordinary tape code you can read.

exceptions

Java

Checked and unchecked exceptions, try/catch/finally, and unwinding you cannot see at the call site.

Tape

T or E puts the failure in the signature, where E is an enum you define carrying a value and a description. or return propagates, or { } handles, defer replaces finally.

runtime & deployment

Java

JVM, JAR, classpath, JIT warmup, and collector flags to tune per workload.

Tape

One binary out of tape build. No VM at runtime and no forced GC — in t1 the compiler inserts string cleanup at scope exit, and the rest is explicit.

what stays the same

  • - Static types, checked before anything runs
  • - pub is your public — everything else stays module-private
  • - Exhaustive match over tagged unions, the way sealed types work
  • - Enums carry a value and a description string
  • - One command from source to a runnable artifact