---
title: Token Efficient Language
date: 2026-04-20
updated: 2026-09-07
excerpt: Writing C in fewer tokens with a compact syntax and a transpiler.
---

TEL, short for Token Efficient Language, is a compact syntax for writing C with LLMs. A transpiler turns it back into standard C. Our hello-world example uses about 70% fewer tokens in TEL. The code is on [GitHub](https://github.com/BautistaPessagno/TEL).

My friends and I used to joke about ways to use fewer tokens, especially after Claude's usage limits got tighter. We'd seen [Caveman Claude](https://github.com/juliusbrussee/caveman), which makes Claude talk like a caveman to cut down on words.

The idea made us laugh: "why waste tokens with lot words when few words do trick". But it only shortens natural language responses. A loop like `for (int i = 0; i < n; i++)` still has the same syntax, however briefly Claude writes its prose.

So [@rodrihern\_](https://x.com/rodrihern_), [@LolooMendez](https://x.com/LolooMendez), [@pascalordanoo](https://x.com/pascalordanoo), and I started working on TEL.

## So what the f\*ck is TEL?

The idea is a one-to-one mapping between C and TEL, with the same program behavior in either form. The LLM reads and writes TEL, and the transpiler produces C. We want developers to be able to read TEL too.

C is our starting point. We'd like to support Java, TypeScript, React projects, and Rust later.

## Why bother?

LLMs consume tokens when they read code and when they generate it. A compact representation lets you fit more code in the context window. Generating fewer output tokens can also reduce costs and response time.

## How it works

- Statements end with newlines, so TEL drops the semicolons.
- Indentation defines blocks instead of `{ }`.
- Keywords get shorter forms. TEL uses `fn` for function declarations, `ret` for `return`, `w` for `while`, `sw` for `switch`, `?` for `if`, `td` for `typedef`, and `str` for `struct`.
- The common loop `for (int i = 0; i < n; i++)` becomes `fd i 0 n`.
- The transpiler adds includes it can infer. Calling `printf` adds `<stdio.h>`; using `malloc` adds `<stdlib.h>`.
- Types get shorthands. `unsigned long int` becomes `uli`, `unsigned int` becomes `uint`, and `void` becomes `v`.
- If a function's last expression matches its return type, TEL treats it as the return value.

## Show me the numbers

Here's hello world in both forms:

```c
// C: 27 tokens, 99 characters
#include <stdio.h>

int main(int argc, char * argv[]) {
    printf("hola mundo");

    return 0;
}
```

```c
// TEL: 8 tokens, 29 characters
main
    printf("hola mundo")
```

In this example, the token count falls from 27 to 8, about 70%. The character count falls from 99 to 29, about 71%. Savings vary with the code:

| Construct | C | TEL | Saved |
| --- | --- | --- | --- |
| Hello world | 27 tokens | 8 tokens | 70% |
| Function with a `for` loop | 45 tokens | 32 tokens | 29% |
| `struct` definition with `typedef` | 26 tokens | 21 tokens | 19% |
| Five `#include` directives | 26 tokens | 16 tokens | 38% |

## Where we want to go

We want to try a workflow where the codebase stays in TEL and LLMs read and write it in that format. The build step would transpile it to C. That would let us fit more code in the context window without changing the algorithms.

---

*Built by Bautista Pessagno, Rodrigo Hernandez, Lorenzo Méndez, and Pascal Ordano. 2026.*
