Skip to main content

Syntax Comparison

This page provides side-by-side syntax comparisons between Oxide, Rust, and Kotlin. Oxide aims to provide a familiar syntax for developers coming from Kotlin and Swift while transpiling to standard Rust.

Variable Declarations

FeatureOxideRustKotlin
Immutablelet x = 10let x = 10;val x = 10
Mutablevar x = 10let mut x = 10;var x = 10
Type annotationlet x: Int = 10let x: isize = 10;val x: Int = 10
Constantconst MAX: Int = 100const MAX: isize = 100;const val MAX = 100

Code Examples

// Oxide
let name = "Alice"
var count = 0
count++
// Rust
let name = "Alice";
let mut count = 0;
count += 1;
// Kotlin
val name = "Alice"
var count = 0
count++

Null Safety

FeatureOxideRustKotlin
Nullable typeT?Option<T>T?
Null literalnullNonenull
Safe callx?.method()x.as_ref().map(|v| v.method())x?.method()
Null coalescex ?? defaultx.unwrap_or(default)x ?: default
Force unwrapx!!x.unwrap()x!!
Null checkif x != null { }if let Some(x) = x { }if (x != null) { }

Code Examples

// Oxide
let name: String? = fetchName()
let length = name?.length ?? 0
let forced = name!!
// Rust
let name: Option<String> = fetch_name();
let length = name.as_ref().map(|n| n.len()).unwrap_or(0);
let forced = name.unwrap();
// Kotlin
val name: String? = fetchName()
val length = name?.length ?: 0
val forced = name!!

Functions

FeatureOxideRustKotlin
Basic functionfn add(a: Int, b: Int): Int { }fn add(a: isize, b: isize) -> isize { }fun add(a: Int, b: Int): Int { }
Expression bodyfn add(a: Int, b: Int): Int { a + b }fn add(a: isize, b: isize) -> isize { a + b }fun add(a: Int, b: Int) = a + b
Default paramsfn greet(name: String = "World")N/A (use Option)fun greet(name: String = "World")
Async functionasync fn fetch(): Stringasync fn fetch() -> Stringsuspend fun fetch(): String

Code Examples

// Oxide
fn greet(name: String = "World"): String {
return "Hello, $name!"
}

async fn fetchUser(id: Int): User {
let data = await api.get(id)
return User.from(data)
}
// Rust
fn greet(name: Option<&str>) -> String {
let name = name.unwrap_or("World");
format!("Hello, {}!", name)
}

async fn fetch_user(id: isize) -> User {
let data = api.get(id).await;
User::from(data)
}
// Kotlin
fun greet(name: String = "World"): String {
return "Hello, $name!"
}

suspend fun fetchUser(id: Int): User {
val data = api.get(id)
return User.from(data)
}

Closures

FeatureOxideRustKotlin
Basic closure{ x -> x * 2 }|x| x * 2{ x -> x * 2 }
Implicit param{ it * 2 }N/A{ it * 2 }
Trailing lambdalist.map { it * 2 }list.iter().map(|x| x * 2)list.map { it * 2 }
Capture by valuecapture { x -> use(x) }move |x| use(x)N/A (automatic)

Code Examples

// Oxide
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.iter().map { it * 2 }.toArray()
let sum = numbers.iter().fold(0) { acc, x -> acc + x }
// Rust
let numbers = vec![1, 2, 3, 4, 5];
let doubled: Vec<_> = numbers.iter().map(|x| x * 2).collect();
let sum = numbers.iter().fold(0, |acc, x| acc + x);
// Kotlin
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }
val sum = numbers.fold(0) { acc, x -> acc + x }

Pattern Matching

FeatureOxideRustKotlin
Match expressionmatch value { }match value { }when (value) { }
Match arm1 -> "one"1 => "one",1 -> "one"
Default caseelse -> "other"_ => "other",else -> "other"
Null patternnull -> "none"None => "none",null -> "none"
Type checkif x is String { }if let Some(s) = x.downcast_ref::<String>() { }if (x is String) { }
Pattern bindingif x is Some(value) { }if let Some(value) = x { }if (x is Some) { val value = x.value }

Code Examples

// Oxide
let result = match status {
Status.active -> "Running"
Status.error(msg) -> "Error: $msg"
null -> "Unknown"
else -> "Other"
}

if user is Admin(level) {
println!("Admin level: $level")
}
// Rust
let result = match status {
Status::Active => "Running",
Status::Error(msg) => format!("Error: {}", msg),
None => "Unknown",
_ => "Other",
};

if let Some(Admin { level }) = user {
println!("Admin level: {}", level);
}
// Kotlin
val result = when (status) {
Status.ACTIVE -> "Running"
is Status.Error -> "Error: ${status.msg}"
null -> "Unknown"
else -> "Other"
}

if (user is Admin) {
println!("Admin level: ${user.level}")
}

Async/Await

FeatureOxideRustKotlin
Async functionasync fn fetch()async fn fetch()suspend fun fetch()
Awaitawait exprexpr.awaitDirect call
Async blockasync { ... }async { ... }async { ... }
Task spawnTask { ... }tokio::spawn(async { ... })launch { ... }
Concurrentasync let a = f1()tokio::join!(f1(), f2())async { f1() }
Timeoutwithin(5.seconds) { }tokio::time::timeout(Duration::from_secs(5), ...)withTimeout(5000) { }

Code Examples

// Oxide
async fn fetchAll(): [User] {
async let users = fetchUsers()
async let posts = fetchPosts()

let (u, p) = await (users, posts)

return within(5.seconds) {
await processData(u, p)
}
}
// Rust
async fn fetch_all() -> Vec<User> {
let (users, posts) = tokio::join!(
fetch_users(),
fetch_posts()
);

tokio::time::timeout(
Duration::from_secs(5),
process_data(users, posts)
).await;
}
// Kotlin
suspend fun fetchAll(): List<User> {
val users = async { fetchUsers() }
val posts = async { fetchPosts() }

val (u, p) = users.await() to posts.await()

return withTimeout(5000) {
processData(u, p)
}
}

Generics

FeatureOxideRustKotlin
Generic functionfn <T> identity(x: T): Tfn identity<T>(x: T) -> Tfun <T> identity(x: T): T
Generic structstruct Box<T>(value: T)struct Box<T> { value: T }class Box<T>(val value: T)
Type boundfn <T: Clone> dup(x: T)fn dup<T: Clone>(x: T)fun <T: Cloneable> dup(x: T)
Where clausewhere T: Displaywhere T: Displaywhere T: Display
Opaque typefn get(): some Iteratorfn get() -> impl IteratorN/A

Code Examples

// Oxide
fn <T: Clone> duplicate(item: T): (T, T) {
return (item.clone(), item)
}

struct Container<T>(value: T)

extension <T> Container<T> {
fn get(): &T = &self.value
}
// Rust
fn duplicate<T: Clone>(item: T) -> (T, T) {
(item.clone(), item)
}

struct Container<T> {
value: T,
}

impl<T> Container<T> {
fn get(&self) -> &T {
&self.value
}
}
// Kotlin
fun <T: Cloneable> duplicate(item: T): Pair<T, T> {
return item.clone() to item
}

class Container<T>(val value: T) {
fun get(): T = value
}

Traits and Extensions

FeatureOxideRustKotlin
Trait definitiontrait Drawable { }trait Drawable { }interface Drawable { }
Trait implextension Point: Drawable { }impl Drawable for Point { }class Point : Drawable { }
Inherent implextension Point { }impl Point { }(methods in class)
Extension functionextension String { fn double() }N/A (use trait)fun String.double()

Code Examples

// Oxide
trait Drawable {
fn draw()
fn area(): Float64
}

extension Circle: Drawable {
fn draw() {
println!("Drawing circle")
}

fn area(): Float64 = 3.14159 * self.radius * self.radius
}

// Rust
trait Drawable {
fn draw(&self);
fn area(&self) -> f64;
}

impl Drawable for Circle {
fn draw(&self) {
println!("Drawing circle");
}

fn area(&self) -> f64 {
3.14159 * self.radius * self.radius
}
}

impl Circle {
fn new(radius: f64) -> Circle {
Circle { radius }
}
}
// Kotlin
interface Drawable {
fun draw()
fun area(): Double
}

class Circle(val radius: Double) : Drawable {
override fun draw() {
println!("Drawing circle")
}

override fun area() = 3.14159 * radius * radius

companion object {
fun new(radius: Double) = Circle(radius)
}
}

Visibility Modifiers

FeatureOxideRustKotlin
Publicpublic fn foo()pub fn foo()public fun foo() (default)
Privateprivate fn foo() or defaultfn foo() (default)private fun foo()
Crate-wideinternal fn foo()pub(crate) fn foo()internal fun foo()
Module parentprotected fn foo()pub(super) fn foo()protected fun foo()

Error Handling

FeatureOxideRustKotlin
Throwing functionfn parse() throws: Intfn parse() -> Result<isize, Error>fun parse(): Int (throws)
Try expressiontry parse()parse()?try { parse() }
Try or nulltry? parse()parse().ok()runCatching { parse() }.getOrNull()
Do-catchdo { } catch e { }match result { Ok(v) => ..., Err(e) => ... }try { } catch (e: Exception) { }

Code Examples

// Oxide
fn parseInt(s: String) throws: Int {
if s.isEmpty() {
throw ParseError("Empty string")
}
return s.parse().unwrap()
}

fn main() {
do {
let n = try parseInt("42")
println!("Parsed: $n")
} catch e {
println!("Error: $e")
}

// Or use try? for optional result
let maybe = try? parseInt("invalid")
}
// Rust
fn parse_int(s: &str) -> Result<i32, ParseError> {
if s.is_empty() {
return Err(ParseError::new("Empty string"));
}
s.parse().map_err(|_| ParseError::new("Invalid"))
}

fn main() {
match parse_int("42") {
Ok(n) => println!("Parsed: {}", n),
Err(e) => println!("Error: {}", e),
}

// Or use .ok() for optional result
let maybe = parse_int("invalid").ok();
}

String Interpolation

FeatureOxideRustKotlin
Simple"Hello, $name"format!("Hello, {}", name)"Hello, $name"
Expression"Sum: ${a + b}"format!("Sum: {}", a + b)"Sum: ${a + b}"
Debug format"Debug: #value"format!("Debug: {:?}", value)N/A
Multi-line$$"""..."""r#"..."#"""..."""

Code Examples

// Oxide
let name = "World"
let greeting = "Hello, $name!"
let math = "Result: ${2 + 2}"
let debug = "Value: #someStruct"
// Rust
let name = "World";
let greeting = format!("Hello, {}!", name);
let math = format!("Result: {}", 2 + 2);
let debug = format!("Value: {:?}", some_struct);
// Kotlin
val name = "World"
val greeting = "Hello, $name!"
val math = "Result: ${2 + 2}"