SkillAgentSearch skills...

Jet

Jet is a simple OOP, dynamically typed, functional language that runs on the Erlang virtual machine (BEAM). Jet's syntax is Ruby-like syntax.

Install / Use

/learn @i2y/Jet
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<img src="https://github.com/i2y/jet/raw/master/jet_logo.png" width="300px"/>

Jet is a dynamically typed, OOP-functional language that runs on the Erlang virtual machine (BEAM). Its syntax and object model are influenced by Ruby and Reia.

Language Features

Types

# Numbers
49        # integer
4.9       # float

# Booleans
true
false

# Atoms
:foo

# Lists
list = [2, 3, 4]
[1, *list]             # => [1, 2, 3, 4]
[head, *rest] = list   # head => 2, rest => [3, 4]

# Tuples
{1, 2, 3}

# Maps
dict = {name: "jet", version: 2}
dict.get(:name, "?")  # => "jet"

# Strings (charlists)
"Hello"

# Binaries
<<1, 2, 3>>
<<"abc">>

# Anonymous functions
add = {|x, y| x + y}
add.(3, 4)  # => 7

multiply = do |x, y|
  x * y
end

Variable Rebinding

# x = x + 1 just works — the compiler generates fresh BEAM variables
total = 0
total = total + 10
total = total + 20
total  # => 30

Classes & Immutable State

@attr reads and writes instance state. Each mutation returns a new object — the original is unchanged. The compiler automatically returns self at the end of initialize.

# Point.jet — standalone class (no module wrapper needed)
class Point
  def initialize(x, y)
    @x = x
    @y = y
  end

  def move(dx, dy)
    @x = @x + dx
    @y = @y + dy
    self
  end

  def x()  @x  end
  def y()  @y  end
end

p = Point.new(0, 0)
p2 = p.move(3, 4)
# p is unchanged — each mutation returns a new object

Mixins — Composition over Inheritance

class Stack
  include Enumerable

  def initialize()
    @items = []
  end

  def push(item)
    @items = [item, *@items]
    self
  end

  def reduce(acc, func)
    lists::foldl({|item, a| func.(a, item)}, acc, @items)
  end
end

s = Stack.new().push(10).push(20).push(30)
s.map {|n| n * 2}                 # => [60, 40, 20]
s.reduce(0) {|acc, n| acc + n}    # => 60

Actors

The actor keyword creates a process-backed class (OTP gen_server). expose declares its public interface. Actor state uses the process dictionary, so methods don't need to return self.

actor ChatRoom
  expose post(user, text), recent(n), count()

  def initialize(name)
    @name = name
    @messages = []
  end

  def post(user, text)
    @messages = [{user, text}, *@messages]
    :ok
  end

  def recent(n)
    lists::sublist(@messages, n)
  end

  def count()
    erlang::length(@messages)
  end

  def on_terminate(reason)
    puts("Room closing: ~p", [reason])
  end
end

room = ChatRoom.spawn("general")
room.post("alice", "Hello!")
room.count()  # => 1

# Async & cast
future = room.async().count()
future.await()        # => 1
room.cast().post("bob", "Fire and forget")

# Timers & raw messages
room ! {:custom, "message"}     # send raw message (handled by on_message)
send_after(1000, room, :ping)   # delayed message

# Monitoring
monitor(room)  # receive {:DOWN, ref, :process, pid, reason} on exit

Effect Declarations (needs / platform)

module Greeter
  needs Console

  def self.greet(name)
    Console::puts("Hello, " ++ name ++ "!")
  end
end

# Provide concrete implementations via platform blocks
platform Production
  provide Console with StandardConsole
end

Pattern Matching

match {x, y}
  case {0, 0}
    "origin"
  case {0, _}
    "on Y axis"
  case {x, y} if x == y
    "on diagonal"
  case _
    "somewhere else"
end

Erlang Interop

# Call any Erlang/OTP module with :: syntax
node = erlang::node()
timer::sleep(1000)
lists::sort([3, 1, 2])  # => [1, 2, 3]

Higher-Order Functions

nums = [5, 3, 8, 1, 9]

nums.map {|n| n * 2}             # => [10, 6, 16, 2, 18]
nums.select {|n| n > 4}          # => [5, 8, 9]
nums.reduce(0) {|acc, n| acc + n}  # => 26

3.times do |i|
  puts("tick ~p", [i])
end

Requirements

  • Erlang/OTP >= 26.0
  • Gleam >= 1.0

Installation

$ git clone https://github.com/i2y/jet.git
$ cd jet
$ gleam build
$ gleam export erlang-shipment && escript build_escript.erl
$ ./jet --help

Usage

Compiling a single file

$ ./jet Foo.jet

Compiling and executing

$ ./jet -r Foo::bar Foo.jet

Building a project

$ ./jet build src/

Building an escript (standalone executable)

Bundle all .beam files into a single executable. Requires Erlang on the target machine.

$ ./jet escript MyApp src/
$ ./myapp

Building an OTP release

Generate a release directory with bin/ launcher and ebin/ beams.

$ ./jet release MyApp src/
$ ./_release/bin/myapp

Entry point convention: jet escript and jet release call Module::main(). Define def self.main() in your app module.

Running tests

$ gleam test
View on GitHub
GitHub Stars26
CategoryDevelopment
Updated25d ago
Forks2

Languages

Gleam

Security Score

95/100

Audited on Mar 16, 2026

No findings