コンテンツにスキップ

jv Beginner Tutorial

English | 日本語

Complete guide to get started with jv [/jawa/] in 30 minutes! If you know Java, you can immediately experience the charm of jv!

🎯 What You'll Learn

  • ✅ Installing jv (5 minutes)
  • ✅ Creating your first jv project (5 minutes)
  • ✅ Experiencing the difference from Java (10 minutes)
  • ✅ Trying jv's distinctive features (10 minutes)

📋 Requirements

  • Java 21 or higher - To run the Java code generated by jv (Java 25 recommended)
  • Basic Java knowledge - Understanding of classes, methods, variables
  • Command line operations - Basic terminal usage

⚡ Step 1: Install jv (5 minutes)

macOS/Linux:

# One-liner installation!
curl -L https://github.com/project-jvlang/jv-lang/releases/latest/download/install.sh | sh

Windows:

# Run in PowerShell
iex ((New-Object System.Net.WebClient).DownloadString('https://github.com/project-jvlang/jv-lang/releases/latest/download/install.ps1'))

🛠️ Other Installation Methods

For Rust developers:

cargo install jv-cli

Manual installation: 1. Download OS-specific binary from GitHub Releases 2. Add executable to PATH

✅ Verify Installation

jv --version
# → jv 1.0.0

jv doctor
# → Environment check will run
cd jv-lang

Build the compiler

cargo build --release

The jv binary will be at target/release/jv

./target/release/jv --help

### Verify Installation

```bash
jv version
# Output: jv 0.1.0 - Java Sugar Language compiler

Your First jv Program

1. Initialize a Project

mkdir my-jv-project
cd my-jv-project
jv init

This creates:

my-jv-project/
├── jv.toml          # Project configuration
└── src/
    └── main.jv      # Main source file

2. Write Some Code

Edit src/main.jv:

fun main() {
    // Basic string interpolation
    val name = "jv"
    println("Hello, ${name}! 🌟")

    // Whitespace-separated arrays
    val numbers = [1 2 3 4 5]
    val doubled = numbers.map { it * 2 }
    println("Original: $numbers")
    println("Doubled: $doubled")

    // when expressions (unified conditionals)
    val result = when {
        numbers.size > 3 -> "Large array"
        numbers.isEmpty() -> "Empty array"
        else -> "Small array"
    }
    println("Array size: $result")

    // Range syntax and for loops (unified loops)
    for (i in 0..5) {  // 0..5 = 0 to 4 (exclusive)
        print("$i ")
    }
    println()

    for (i in 0..=5) {  // 0..=5 = 0 to 5 (inclusive)
        print("$i ")
    }
    println()

    // Unit system - Currency
    val price = 100.USD
    val euroPrice = price.to(EUR)  // Automatic exchange rate conversion
    println("Price: $price = $euroPrice")

    // Unit system - Temperature
    val celsius = 25.°C
    val fahrenheit = celsius.to(°F)  // 25°C = 77°F
    println("Temperature: $celsius = $fahrenheit")

    // Unit system - Physical units
    val distance = 100.m  // meters
    val time = 2.s        // seconds
    val velocity = distance / time  // → 50m/s (automatic unit inference)
    println("Velocity: $velocity")

    // Destructuring assignment
    val (x, y, z) = [10, 20, 30]
    println("x=$x, y=$y, z=$z")

    val person = { "name": "Alice", "age": 30 }
    val { name, age } = person
    println("Name: $name, Age: $age")

    // JSON with comments and POJO generation
    val config = {
      "app": {
        "name": "jv-demo",           // Application name
        "version": "1.0.0",          // Version
        "features": ["units", "destructuring", "json"]  // Feature list
      }
    }
    println("Config: $config")

    // Extended numeric types
    val bigNumber = 123456789123456789n  // BigInt
    val precise = 3.141592653589793d     // BigDecimal
    val complex = 3 + 4im                // Complex
    val rational = 1//3                  // Rational

    println("Big number: $bigNumber")
    println("Precise PI: $precise")
    println("Complex: $complex")
    println("Rational: $rational (${rational.toDouble()})")
}

3. Build and Run

# Build the project (generates Java code and compiles)
jv build

# Run the compiled program
jv run

Output:

Hello, jv!
Original: [1, 2, 3, 4, 5]
Doubled: [2, 4, 6, 8, 10]

Understanding Key Features

Unified Conditionals: when Expressions Only

jv uses when expressions for all conditionals. There is no traditional if statement.

// when expression with value
val status = when (code) {
    200 -> "OK"
    404 -> "Not Found"
    else -> "Error"
}

// Condition-based when
val message = when {
    score >= 90 -> "Excellent"
    score >= 70 -> "Good"
    else -> "Keep trying"
}

Unified Loops: for Statements Only

jv uses for statements for all loops. There are no while or do-while loops.

// Range iteration
for (i in 0..10) {     // 0 to 9 (10 is exclusive)
    println(i)
}

for (i in 0..=10) {    // 0 to 10 (10 is inclusive)
    println(i)
}

// Collection iteration
for (item in items) {
    println(item)
}

// Infinite loop
for (;;) {
    if (condition) break
}

Universal Unit System

jv natively supports various units including currency, temperature, and physical units.

// Currency conversion
val dollars = 100.USD
val euros = dollars.to(EUR)

// Temperature conversion
val celsius = 25.°C
val fahrenheit = celsius.to(°F)
val kelvin = celsius.to(K)

// Physical calculations
val distance = 100.m
val time = 5.s
val speed = distance / time  // Automatically m/s

// Date calculations
val today = Date.now()
val tomorrow = today + 1.day
val nextWeek = today + 1.week

Destructuring Assignment

Easily extract values from arrays and objects.

// Array destructuring
val (a, b, c) = [1, 2, 3]

// Object destructuring
val user = { "name": "Alice", "age": 30 }
val { name, age } = user

// Destructuring in function parameters
fun printPerson({ name, age }: Person) {
    println("$name is $age years old")
}

JSON with Comments & POJO Generation

jv natively supports JSON with comments.

val config = {
  "server": {
    "host": "localhost",  // Server host
    "port": 8080,         // Port number
    "ssl": true           // Enable SSL
  },
  "features": ["auth", "api", "websocket"]
}

// Auto-generate type-safe POJOs from JSON
@GeneratePOJO
val schema = {
  "name": "User",
  "fields": {
    "id": "Long",
    "name": "String",
    "email": "String"
  }
}
// This generates a User class

Understanding the Build Process

When you run jv build, the following happens:

  1. Lexing: jv source is tokenized
  2. Parsing: Tokens are parsed into an Abstract Syntax Tree (AST)
  3. IR Transformation: AST is converted to Intermediate Representation (IR)
  4. Java Generation: IR is transformed into readable Java 25 (or Java 21 compatible) source code
  5. Java Compilation: Generated Java is compiled with javac

You can specify the Java target version with the --target flag:

# Target Java 25 (default)
jv build

# Java 21 compatibility mode
jv build --target 21

You can see the generated Java code in the out/ directory:

# View generated Java
cat out/Main.java

Example Generated Java Code

jv generates readable, idiomatic Java 25 code:

public class Main {
    public static void main(String[] args) {
        // Basic string interpolation
        final var name = "jv";
        System.out.println("Hello, " + name + "! 🌟");

        // Whitespace-separated arrays → List.of()
        final var numbers = List.of(1, 2, 3, 4, 5);
        final var doubled = numbers.stream()
            .map(it -> it * 2)
            .toList();
        System.out.println("Original: " + numbers);
        System.out.println("Doubled: " + doubled);

        // when expression → Java 25 switch expression
        final var result = switch (true) {
            case numbers.size() > 3 -> "Large array";
            case numbers.isEmpty() -> "Empty array";
            default -> "Small array";
        };
        System.out.println("Array size: " + result);

        // Ranges and for loops → Enhanced for loop
        for (int i = 0; i < 5; i++) {
            System.out.print(i + " ");
        }
        System.out.println();

        // Unit system → Quantity type library
        final var price = new USD(100);
        final var euroPrice = price.convertTo(EUR.class);
        System.out.println("Price: " + price + " = " + euroPrice);

        final var celsius = new Celsius(25);
        final var fahrenheit = celsius.convertTo(Fahrenheit.class);
        System.out.println("Temperature: " + celsius + " = " + fahrenheit);

        final var distance = new Meters(100);
        final var time = new Seconds(2);
        final var velocity = distance.divide(time);
        System.out.println("Velocity: " + velocity);

        // Destructuring → Individual variable declarations
        final var x = 10;
        final var y = 20;
        final var z = 30;
        System.out.println("x=" + x + ", y=" + y + ", z=" + z);

        // JSON with comments → Map.of() (comments removed)
        final var config = Map.of(
            "app", Map.of(
                "name", "jv-demo",
                "version", "1.0.0",
                "features", List.of("units", "destructuring", "json")
            )
        );
        System.out.println("Config: " + config);

        // Extended numeric types
        final var bigNumber = new BigInteger("123456789123456789");
        final var precise = new BigDecimal("3.141592653589793");
        final var complex = new Complex<>(3.0, 4.0);
        final var rational = new Rational<>(1, 3);

        System.out.println("Big number: " + bigNumber);
        System.out.println("Precise PI: " + precise);
        System.out.println("Complex: " + complex);
        System.out.println("Rational: " + rational + " (" + rational.toDouble() + ")");
    }
}

Exploring Advanced Features

Data Processing Pipelines

Use jv's pipeline operator for concise data processing:

val results = data
    |> filter { it.isValid() }
    |> map { it.transform() }
    |> sortBy { it.priority }
    |> take(10)

Physics Calculations with Units

fun calculateKineticEnergy(mass: kg, velocity: m/s): J {
    return 0.5 * mass * velocity.pow(2)  // E = (1/2)mv²
}

fun calculateForce(mass: kg, acceleration: m/s²): N {
    return mass * acceleration  // F = ma
}

// Real-world usage
val carMass = 1500.kg
val carSpeed = 30.m/s
val energy = calculateKineticEnergy(carMass, carSpeed)
println("Kinetic energy: $energy")  // 675000.0 J

Complex Numbers and Advanced Math

fun complexMath() {
    val z1 = 3 + 4im
    val z2 = 1 - 2im
    val product = z1 * z2                    // Complex multiplication
    val magnitude = (z1 * z1.conjugate()).sqrt()  // Magnitude
    val phase = z1.arg()                      // Phase angle

    println("Product: $product")
    println("Magnitude: $magnitude")
    println("Phase: ${phase} radians")

    // Rational number arithmetic
    val rational1 = 1//3
    val rational2 = 2//5
    val sum = rational1 + rational2  // 11//15 (automatically reduced)
    println("1/3 + 2/5 = $sum")
}

DSL Embedding Examples

SQL Queries:

fun getActiveUsers(): List<User> {
    return database.query(```sql
        SELECT id, name, email FROM users
        WHERE active = true
        ORDER BY name
    ```)
}

Business Rules:

val discountRules = ```drools
rule "Premium Discount"
when
    $customer: Customer(isPremium == true)
    $order: Order(amount > 1000)
then
    $order.applyDiscount(0.15);
end

Next Steps

Congratulations! You've learned the basics of jv. To continue your learning journey:

Key Features to Explore

  • when expressions - All patterns of unified conditionals
  • for loops - Using ranges, collections, and infinite loops
  • Unit system - Complete guide to currency, temperature, and physical units
  • Destructuring - Using it in function parameters and complex data structures
  • JSON POJO generation - Auto-generating type-safe data classes
  • DSL embedding - Integrating SQL and business rules

Getting Help