# Coming from Python — The Complete Migration Guide

U compiles your code to native binaries and WebAssembly. Everything Python's ecosystem does through separate libraries (numpy, pandas, polars, matplotlib, torch), U does through its type system and modifier annotations. No FFI, no C extensions, no pip install — one language, one compiler.

## Quick Reference

### Python → U Type Mapping

| Python | U | Notes |
|--------|---|-------|
| `int` | `I` | 32-bit integer (64-bit: `Q`) |
| `float` | `N` | 64-bit double |
| `str` | `S` | Immutable string |
| `bool` | `B` | `true` / `false` |
| `list[int]` | `[I]` | Typed list |
| `dict[str, int]` | `{S: I}` | Typed map |
| `None` | `none` | — |
| `tuple` | `(I, S, N)` | Fixed-size tuple |
| `Optional[int]` | `I +N` | Nullable via `+N` modifier |
| `bytes` | `[Q8]` | Byte array |

### Python → U Syntax Mapping

| Python | U | What it means |
|--------|---|---------------|
| `def greet(name):` | `f greet(name: S) -> S` | Functions start with `f` |
| `class Dog:` | `d Dog` | Data types start with `d` |
| `if x > 0:` | `xx > 0 &` | Guard: condition + `&` |
| `return x` | `r => xx` | Return |
| `for x in items:` | `items.on(xx => ...)` | Iteration via `.on()` |
| `lambda x: x*2` | `xx => xx * 2` | Lambda |
| `try/except` | `x/!` | Error types (compile-time) |
| `async def` | `f +A name()` | Async via `+A` modifier |
| `x = 5` | `xx: I +M = 5` | Variables need 2+ char names |
| `print(x)` | `print(xx)` | Same — compiles to native I/O |

## Data Science Migration

### numpy → Typed Lists + Tensor

| numpy | U | Status |
|-------|---|--------|
| `np.array([1,2,3])` | `[1, 2, 3]` | ✅ Typed list, compiled |
| `np.zeros((3,3))` | `Tensor.zeros([3, 3])` | ✅ In runtime |
| `np.ones((3,))` | `Tensor.ones([3])` | ✅ In runtime |
| `a + b` (element-wise) | `Tensor.add(aa, bb)` | ✅ Element-wise ops |
| `a * b` | `Tensor.mul(aa, bb)` | ✅ Element-wise |
| `a @ b` (matmul) | `Tensor.matmul(aa, bb)` | ✅ Matrix multiply |
| `a.sum()` | `Tensor.sum(aa)` | ✅ Reduction |
| `a.mean()` | `Tensor.mean(aa)` | ✅ Reduction |
| `a.reshape(2,3)` | `Tensor.reshape(aa, [2, 3])` | ✅ Zero-copy view |
| `a.T` | `Tensor.transpose(aa)` | ✅ Transpose |
| `np.dot(a, b)` | `Tensor.dot(aa, bb)` | ✅ Dot product |
| `np.linalg.norm(a)` | `Tensor.norm(aa)` | ✅ L2 norm |
| `np.arange(0, 10, 2)` | `Tensor.arange(0, 10, 2)` | ✅ Range tensor |
| `a[0:3]` | `Tensor.slice(aa, 0, 0, 3)` | 🔜 Coming |
| `np.concatenate` | — | 🔜 Coming |
| `np.random.randn(3,3)` | — | 🔜 Coming |
| GPU acceleration | `Tensor.add(aa, bb) +V` | ✅ Modifier → WGSL shader |

**The `+V` advantage:** numpy calls into C/Fortran via FFI. U compiles the operation directly. Add `+V` and the compiler emits a GPU compute shader — no CUDA toolkit, no separate library.

### pandas/polars → Dataframe

| pandas/polars | U | Status |
|---------------|---|--------|
| `pd.read_csv("f.csv")` | `Dataframe.from_csv("f.csv") +A` | ✅ (sync: `from_csv_string`) |
| `df.head(5)` | `df.head(5)` | ✅ |
| `df.sort_values("col")` | `df.sort("col", false)` | ✅ |
| `df[["a","b"]]` | `df.select(["a", "b"])` | ✅ |
| `df[df["age"] > 30]` | `df.filter_mask(df.get_column("age").gt_I(30))` | ✅ |
| `df["col"].sum()` | `df.get_column("col").sum_I()` | ✅ |
| `df["col"].mean()` | `df.get_column("col").mean()` | ✅ |
| `df["col"].max()` | `df.get_column("col").max_I()` | ✅ |
| `df.assign(bonus=...)` | `df.with_column("bonus", col)` | ✅ |
| `df.groupby("col").agg(...)` | `df.groupby(["col"]).agg(...)` | 🔜 Coming |
| `df.merge(other, on="id")` | `df.join(other, "id", "inner")` | 🔜 Coming |
| `df.to_csv("out.csv")` | `df.to_csv("out.csv") +A` | 🔜 Coming |
| `print(df)` | `print(df)` | ✅ Box-drawing table |
| Lazy evaluation | `+W` modifier | ✅ Spec'd, runtime 🔜 |
| GPU columns | `+V` on column ops | ✅ Spec'd, WGSL 🔜 |

**Why U beats polars:** Polars is Rust compiled to a Python extension. U compiles the entire pipeline — filter, select, sort — to one native binary or WASM module. The compiler sees the full chain and can fuse operations, push predicates down, and emit a single GPU kernel instead of three separate passes.

### matplotlib/seaborn → REPL Charts

| matplotlib | U REPL | Status |
|------------|--------|--------|
| `plt.bar(data)` | `plot([1,2,3,4])` | ✅ Inline SVG bar chart |
| `plt.plot(data)` | `linechart([1,2,3,4])` | ✅ Inline SVG line chart |
| `plt.show()` | Auto-renders in REPL | ✅ |
| `df.plot()` | `print(df)` → styled table | ✅ |
| 3D plots | — | 🔜 Coming |
| Heatmaps | — | 🔜 Coming |

### torch/tensorflow → Tensor + `+V`

| PyTorch | U | Status |
|---------|---|--------|
| `torch.tensor([1,2,3])` | `Tensor.from_data([1,2,3], [3])` | ✅ |
| `torch.zeros(3,3)` | `Tensor.zeros([3, 3])` | ✅ |
| `x + y` | `Tensor.add(xx, yy)` | ✅ |
| `x @ y` | `Tensor.matmul(xx, yy)` | ✅ |
| `x.sum()` | `Tensor.sum(xx)` | ✅ |
| `.to("cuda")` | `+R(GPU)` | ✅ Spec'd |
| Autograd | `+R` on Tree → MVCC diff | 🔧 Designable |
| `nn.Linear` | — | 🔜 Future |

**Automatic differentiation in U:** U's Tree type has `.diff()` which computes structural diffs between immutable snapshots. Combined with `+R` (refcounted immutable data) and the compiler's ability to see the full computation graph, autograd is a natural extension: each operation records its Tree diff, and backward passes `.diff()` through the recorded chain. This is not implemented yet, but the primitives (`Tree.diff`, `+R`, `+V`) are all in place.

### scipy → Built-in Math

| scipy | U | Status |
|-------|---|--------|
| `math.sqrt(x)` | `sqrt(xx)` | ✅ Built-in |
| `math.abs(x)` | `abs(xx)` | ✅ Built-in |
| `math.floor(x)` | `floor(xx)` | ✅ Built-in |
| `math.ceil(x)` | `ceil(xx)` | ✅ Built-in |
| `math.sin(x)` | `sin(xx)` | ✅ Built-in |
| `math.cos(x)` | `cos(xx)` | ✅ Built-in |
| `math.log(x)` | `ln(xx)` | ✅ Built-in |
| `math.exp(x)` | `exp(xx)` | ✅ Built-in |
| `scipy.optimize` | — | 🔜 Future |
| `scipy.integrate` | — | 🔜 Future |

## Side-by-Side Examples

### 1. Fibonacci

```python
# Python
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)
print(fib(10))  # 55
```

```
// U
f fib(nn: I) -> I
    nn <= 1 & r => nn
    r => fib(nn - 1) + fib(nn - 2)
f main()
    print(fib(10))  // 55
```

### 2. Data Analysis

```python
# Python (pandas)
import pandas as pd
df = pd.read_csv("data.csv")
young = df[df["age"] < 30]
avg = young["salary"].mean()
print(f"Average salary under 30: {avg}")
```

```
// U
f main()
    df = Dataframe.from_csv("data.csv") +A
    young = df.filter_mask(df.get_column("age").lt_I(30))
    avg = young.get_column("salary").mean()
    print(avg)
```

### 3. Matrix Multiply

```python
# Python (numpy)
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
c = a @ b
print(c)  # [[19,22],[43,50]]
```

```
// U — compiles to native, add +V for GPU
f main()
    aa = Tensor.from_data([1,2,3,4], [2, 2])
    bb = Tensor.from_data([5,6,7,8], [2, 2])
    cc = Tensor.matmul(aa, bb)
    print(cc)  // Tensor(shape=[2,2], data=[[19, 22], [43, 50]])
```

### 4. Struct / Class

```python
# Python
class Dog:
    def __init__(self, name, age=0):
        self.name = name
        self.age = age

d = Dog("Buddy", 3)
print(d.name)  # Buddy
```

```
// U — prints as JSON via __pack__
d Dog
    name: S = "Rex"
    age: I +M = 0
f main()
    dd = Dog("Buddy")
    dd.age = 3
    print(dd)  // {"name":"Buddy","age":3}
```

## The Modifier System — U's Superpower

Python needs separate libraries for each execution strategy. U uses annotations:

| What you want | Python | U |
|---------------|--------|---|
| Mutable variable | Default | `+M` |
| Nullable value | `Optional[T]` | `+N` |
| Heap allocation | Default | `+R` (refcounted) |
| Async function | `async def` | `f +A name()` |
| GPU execution | `cupy` / `torch.cuda` | `+V` |
| Lazy evaluation | `polars.LazyFrame` | `+W` |
| GPU-resident data | `.to("cuda")` | `+R(GPU)` |

**One language, one compiler.** No `pip install`, no version conflicts, no FFI overhead. Your code compiles to a native binary or a WebAssembly module that runs in any browser.

## What's Ready Now

- ✅ REPL with inline charts (`plot()`, `linechart()`)
- ✅ Integers, floats, booleans (true/false), strings
- ✅ Functions, recursion, guards
- ✅ Data types with `__pack__` → JSON printing
- ✅ Dataframe: from_csv, head, sort, select, filter, column aggregation
- ✅ Tensor: element-wise ops, matmul, reductions, reshape
- ✅ Compiles to WASM — runs in the browser playground
- ✅ Compiles to native C — full performance

## What's Coming

- 🔜 `+V` GPU kernel emission for column and tensor ops
- 🔜 `Dataframe` backtick template with `__validate__` compile-time optimization
- 🔜 GroupBy, Join, window functions
- 🔜 String concat in WASM (works in native)
- 🔜 Autograd via Tree.diff + computation graph recording
- 🔜 3D visualization in REPL
