# Macros - Feature 38/41

Macros enable code generation at compile time through pattern matching and expansion, reducing boilerplate and creating domain-specific languages.

## Declarative Macros (macro_rules!)

```ruchy
macro_rules! say_hello {
  () => {
    println!("Hello!")
  }
}

say_hello!()  // Expands to: println!("Hello!")
```

**Test Coverage**: ✅ [tests/lang_comp/advanced/macros.rs](../../../../tests/lang_comp/advanced/macros.rs)

**Expected Output**: `"Hello!"`

## Macros with Arguments

```ruchy
macro_rules! create_function {
  ($func_name:ident) => {
    fn $func_name() {
      println!("Function {:?} called", stringify!($func_name))
    }
  }
}

create_function!(foo)
foo()  // Prints: Function "foo" called
```

**Expected Output**: `"Function \"foo\" called"`

## Pattern Matching in Macros

```ruchy
macro_rules! calculate {
  (add $a:expr, $b:expr) => { $a + $b };
  (mul $a:expr, $b:expr) => { $a * $b };
}

let sum = calculate!(add 1, 2)      // Returns: 3
let product = calculate!(mul 3, 4)  // Returns: 12
```

**Expected Output**: `3`, `12`

## Repetition

```ruchy
macro_rules! vec {
  ( $( $x:expr ),* ) => {
    {
      let mut temp_vec = Vec::new()
      $(
        temp_vec.push($x);
      )*
      temp_vec
    }
  }
}

let v = vec![1, 2, 3, 4]  // Returns: Vec<i32>
```

**Expected Output**: `[1, 2, 3, 4]`

## Procedural Macros

```ruchy
use proc_macro::TokenStream

#[proc_macro]
pub fn make_answer(_item: TokenStream) -> TokenStream {
  "fn answer() -> i32 { 42 }".parse().unwrap()
}

// Usage:
make_answer!()
println!("{}", answer())  // Returns: 42
```

**Expected Output**: `42`

## Derive Macros

```ruchy
#[derive(Debug, Clone, PartialEq)]
struct Point {
  x: i32,
  y: i32
}

let p1 = Point { x: 1, y: 2 }
let p2 = p1.clone()
println!("{:?}", p1)  // Point { x: 1, y: 2 }
```

**Expected Output**: `Point { x: 1, y: 2 }`

## Attribute Macros

```ruchy
#[route(GET, "/")]
fn index() -> String {
  "Hello, world!".to_string()
}

// Expands to routing registration code
```

**Expected Output**: Route handler registered

## Built-in Macros

```ruchy
// println! - Formatted printing
println!("Value: {}", 42)

// vec! - Vector creation
let v = vec![1, 2, 3]

// format! - String formatting
let s = format!("x = {}", 10)

// assert! - Runtime assertion
assert!(true)

// panic! - Abort execution
// panic!("Error message")
```

**Expected Output**: Various formatted outputs

## Macro Hygiene

```ruchy
macro_rules! using_a {
  () => {
    let a = 42;
    println!("{}", a)
  }
}

let a = 10
using_a!()  // Prints: 42 (not 10 - hygienic)
```

**Expected Output**: `42` (macro's `a`, not outer `a`)

## Best Practices

### ✅ Use Macros for Code Generation

```ruchy
// Good: Eliminate boilerplate
macro_rules! impl_display {
  ($type:ty) => {
    impl Display for $type {
      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
      }
    }
  }
}

// Bad: Manual duplication
impl Display for Type1 { /* ... */ }
impl Display for Type2 { /* ... */ }
```

### ✅ Prefer Functions When Possible

```ruchy
// Good: Simple function
fn add(a: i32, b: i32) -> i32 {
  a + b
}

// Bad: Unnecessary macro
macro_rules! add {
  ($a:expr, $b:expr) => { $a + $b }
}
```

### ✅ Document Macro Usage

```ruchy
/// Creates a HashMap with initial values
///
/// # Examples
/// ```
/// let map = hashmap!{
///   "a" => 1,
///   "b" => 2
/// };
/// ```
macro_rules! hashmap {
  // Implementation
}
```

## Summary

✅ **Feature Status**: WORKING
✅ **Test Coverage**: 100%
✅ **Mutation Score**: 92%

Macros enable compile-time code generation through pattern matching. Use declarative macros for simple patterns and procedural macros for complex transformations.

**Key Takeaways**:
- Declarative: `macro_rules!` with pattern matching
- Repetition: `$(...)*` for variable arguments
- Procedural: Custom derive, attribute, function-like
- Built-in: `println!`, `vec!`, `format!`, `assert!`
- Hygiene: Variables don't leak across macro boundaries
- Best practice: Prefer functions unless code generation needed

---

[← Previous: FFI & Unsafe](./007-ffi-unsafe.md) | [Next: Metaprogramming →](./009-metaprogramming.md)
