Language Features
Ziv is designed to provide a robust set of features that make it easy to write code that is both efficient and easy to read. This document provides an overview of the language features that Ziv provides.
Table of Contents
- Simple and Readable Syntax
- Strong Static Typing with Type Inference
- Pattern Matching
- Modularity
- Concurrency and Parallelism
- Functional Programming
- Error Handling
- Generics
- Object-Oriented Programming
- Metaprogramming
- Interoperability
- Testing Support
- Asynchronous Programming
- Advanced Features
Simple and Readable Syntax
Ziv emphasizes readability and simplicity, making it easy to write and understand code. The syntax is clean and minimalistic, reducing the likelihood of errors and enhancing the readability of the code.
Example:
fn greet(name: string) -> void:
print("Hello, " + name + "!")
if name == "Alice":
print("You are awesome!")
else:
print("Nice to meet you!")
greet("Alice")
Strong Static Typing with Type Inference
Ziv has a robust static type system that catches errors at compile time. It also supports type inference, allowing you to omit explicit type declarations when unnecessary.
Example:
# Explicit typing
let age: int = 25
name: string = "Alice"
# Inferred typing
let age = 25 # Inferred as int
# Compile-time error example
age = "Alice"
Pattern Matching
Ziv provides powerful pattern matching capabilities that allow you to match values against patterns and extract data from them.
Example:
fn is_even(n: int) -> bool:
when n:
0 => true
1 => false
_ => is_even(n - 2)
Modularity
Ziv supports modularity through the use of modules, allowing you to organize your code into reusable components.
Example:
# math.ziv
module math
fn add(a: int, b: int) -> int:
return a + b
fn subtract(a: int, b: int) -> int:
return a - b
end module
# main.ziv
import math
fn main() -> void:
result: int = math.add(10, 5)
print(result)
Concurrency and Parallelism
Ziv provides built-in support for concurrency and parallelism, allowing you to write code that can run concurrently and in parallel.
-
Concurrency: Ziv supports lightweight threads that can run concurrently when spawned.
fn task(id: int) -> void: print("Task " + id + " started") fn main() -> void: spawn(task, 1) # Start task 1 spawn(task, 2) # Start task 2
-
Parallelism: Ziv supports parallelism through the use of the
parallel
keyword, allowing you to execute code in parallel.fn task(id: int) -> void: print("Task " + id + " started") fn main() -> void: # Start task 1 and task 2 in parallel parallel: task(1) task(2)
Functional Programming
Ziv supports functional programming paradigms, including first-class functions, higher-order functions, lambdas, recursion, closures, and immutability.
Example:
-
First-Class Function
# First-class function fn greet(name: string) -> void: print("Hello, " + name + "!") fn main() -> void: f: (string) -> void = greet f("Alice") # Output: Hello, Alice!
-
Higher-Order Function
# Higher-order function fn apply(f: (int) -> int, x: int) -> int: return f(x) fn square(x: int) -> int: return x * x fn main() -> void: result: int = apply(square, 5) print(result) # Output: 25
-
Lambda Expression
# Lambda expression fn main() -> void: result: int = apply(|x| x * x, 5) print(result) # Output: 25
-
Immutability
# Immutable data structure !my_list: list[int] = [1, 2, 3] fn main() -> void: print(my_list) # Output: [1, 2, 3] my_list[0] = 4 # This will cause a compile-time error
-
Monads
# Monad using >> operator fn add_one(x: int) -> int: return x + 1 fn multiply_by_two(x: int) -> int : return x * 2 fn main() -> void: result: int = 1 >> add_one >> multiply_by_two print(result) # Output: 4
-
Arrow Functions
# Arrow function fn main() -> void: f: (int) -> int = |x| x * x result: int = f(5) print(result) # Output: 25
-
Currying
# Currying fn add(a: int, b: int) -> int: return a + b fn main() -> void: add_five: (int) -> int = add(5) result: int = add_five(10) print(result) # Output: 15
-
Partial Application
# Partial application fn add(a: int, b: int) -> int: return a + b fn main() -> void: add_five: (int) -> int = add(5, _) # Partial application result: int = add_five(10) print(result) # Output: 15
-
Map, Filter, Reduce
# Map, filter, reduce numbers: list[int] = [1, 2, 3, 4, 5] # Map doubled: list[int] = map(numbers, |x| x * 2) print(doubled) # Output: [2, 4, 6, 8, 10] # Filter evens: list[int] = filter(numbers, |x| x % 2 == 0) print(evens) # Output: [2, 4] # Reduce sum: int = reduce(numbers, 0, |acc, x| acc + x) print(sum) # Output: 15
-
Lazy Evaluation
# Lazy evaluation fn main() -> void: # infinite list of numbers numbers: list[int] = lazy: for i in 0.. : yield i # take first 5 numbers for n in take(numbers, 5): print(n)
Error Handling
Ziv provides robust error handling mechanisms that allow you to handle errors gracefully and recover from them.
Example:
fn divide(a: int, b: int) -> int:
if b == 0:
error("Division by zero")
return a / b
fn main() -> void:
result: int = divide(10, 0)
Generics
Ziv supports generics, allowing you to write code that is generic over types.
Example:
fn swap<T>(a: T, b: T) -> (T, T):
return (b, a)
fn main() -> void:
result: (int, int) = swap(10, 20)
print(result)
Object-Oriented Programming
Ziv supports object-oriented programming features, such as classes, inheritance, and encapsulation.
Example:
-
Class Definition
# Define a class with private, public, and protected members class BankAccount: public owner: string protected balance: float private account_number: string # Constructor fn init(account_number: string, owner: string): self.account_number = account_number self.owner = owner self.balance = 0.0 # Destructor fn deinit() -> void: print("Account " + self.account_number + " closed") public fn deposit(amount: float): self.balance += amount # Methods are public by default fn withdraw(amount: float): self.balance -= amount protected fn get_balance() -> float: return self.balance private fn get_account_number() -> string: return self.account_number
-
Inheritance and Protected Access
# Inheritance class SavingsAccount(BankAccount): public interest_rate: float fn init(account_number: string, owner: string, interest_rate: float): parent.init(account_number, owner) self.interest_rate = interest_rate public fn calculate_interest() -> float: return self.get_balance() * self.interest_rate
-
Instance Creation and Method Invocation
# Instance creation and method invocation fn main() -> void: account: SavingsAccount = SavingsAccount("12345", "Alice", 0.05) account.deposit(1000.0) interest: float = account.calculate_interest() print(interest) # Output: 50.0
-
Polymorphism
# Base Class class Animal: public fn speak() -> string: return "Animal speaks" # Derived Class class Dog(Animal): public fn speak() -> string: return "Dog barks" # Another Derived Class class Cat(Animal): public fn speak() -> string: return "Cat meows" fn main() -> void: dog: Animal = Dog() cat: Animal = Cat() print(dog.speak()) # Output: Dog barks print(cat.speak()) # Output: Cat meows
-
Abstract Classes
# Abstract Class abstract class Shape: public abstract fn area() -> float # Concrete Class class Circle(Shape): public radius: float fn init(radius: float): self.radius = radius # Implement abstract method public fn area() -> float: return 3.14 * self.radius * self.radius
-
Interfaces
# Interface interface Printable: public fn print() -> void # Class implementing the interface class Document(Printable): public fn print(): print("Document printed")
-
Static Members
# Static Members class Counter: public static count: int = 0 public static fn increment(): Counter.count += 1 public static fn get_count() -> int: return Counter.count fn main(): Counter.increment() Counter.increment() count: int = Counter.get_count() print(count) # Output: 2
-
Operator Overloading
# Operator Overloading class Vector: public x: float public y: float fn init(x: float, y: float): self.x = x self.y = y public fn +(other: Vector) -> Vector: return Vector(self.x + other.x, self.y + other.y)
Metaprogramming
Ziv provides metaprogramming capabilities that allow you to generate code at compile time.
Example:
macro repeat(n: int, body: block):
for i in 0..n :
body
fn main():
repeat(5):
print("Hello")
Interoperability
Ziv provides seamless interoperability with other languages, allowing you to call functions written in other languages from Ziv code.
Example:
# Import a C function
extern fn c_function() -> int
fn main() -> void:
result: int = c_function()
print(result)
Testing Support
Ziv has built-in support for testing, enabling you to write and execute test cases directly in your code.
Example:
# This function adds two numbers
fn add(a: int, b: int) -> int:
return a + b
# Test cases
test "Addition" :
assert(add(1, 2) == 3)
assert(add(0, 0) == 0)
Asynchronous Programming
Ziv provides built-in support for asynchronous programming, allowing you to write asynchronous code easily and efficiently.
Example:
async fn fetch_data(url: string) -> string;
response: string = await http.get(url)
return response
Advanced Features
Ziv provides a range of advanced features, such as decorators, and more, that allow you to write powerful and expressive code.
-
Decorators:
Ziv supports decorators, which are functions that modify the behavior of other functions or methods.
# Decorators @log fn add(a: int, b: int) -> int: return a + b fn main(): result: int = add(1, 2) print(result) # Output: 3
-
Class Decorators:
Ziv also supports class decorators, which are functions that modify the behavior of classes.
# Class Decorators fn singleton(cls: class) -> class: instance: cls = null fn get_instance() -> cls: if instance == null: instance = new cls() return instance return cls @singleton class Database: fn init(): print("Database initialized") fn main() -> void: db1: Database = Database.get_instance() db2: Database = Database.get_instance() print(db1 == db2) # Output: true
-
Module Versioning:
Ziv supports module versioning, allowing you to specify the version of a module that your code depends on.
# math.ziv module math version "1.0.0" fn add(a: int, b: int) -> int: return a + b end module
# main.ziv import math version "1.0.0" fn main(): result: int = math.add(10, 5) print(result)
-
Type Aliases:
Ziv supports type aliases, allowing you to define custom names for existing types.
# Type Aliases type Point = (int, int) fn distance(p1: Point, p2: Point) -> float: x1, y1 = p1 x2, y2 = p2 return sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
-
Import Aliases:
Ziv supports import aliases, allowing you to import modules with custom names.
# Import Aliases import math as m fn main(): result: int = m.add(10, 5) print(result)``