# What changed in 0.13

> Calling C (FFI), GPU loops, .NET API shapes, NuGet distribution, class discovery, refinements, named tuples, owned collections, and the tooling that ships with them.

Canonical: https://alice-lang.org/documentation/reference/whats-new-0-13/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

Alice 0.13 makes Alice code work with the rest of the .NET ecosystem in both directions. C functions can be called
without glue code, `gpu for` loops run on the graphics card, Alice libraries expose the API shapes C# and F# expect
(events, delegates, iterators, `naming = "dotnet"`), and Alice packages are published on NuGet. Most existing code
compiles unchanged. The behavior changes to check are listed first. The full list is in the
[changelog](https://github.com/alicelanguage/alice/blob/main/CHANGELOG.md).

## Behavior changes

| Change                                                                                                                                                                         | What to do                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `[runtime] gc = "auto"` is the default. The build selects server GC (DATAS) when the program forks or runs parallel loops, and workstation GC otherwise.                       | Nothing for most programs. Set `gc = "workstation"` for a short-lived CLI that must start fastest, or `gc = "server"` to force a mode. See [GC modes](https://alice-lang.org/documentation/guides/max-performance.md#choose-the-collector-for-the-workload). |
| An assignment inside a branch of a block assigns the enclosing method's variable, as in Ruby. Before, `best = v if v > best` inside a block declared a new block-local `best`. | Check blocks that assign to a name from the enclosing method.                                                                                                                                                                                                |
| Conditions use Ruby truthiness: `if s`, `unless t`, `while q`, `s ? a : b` and `!s` on a nullable value are nil checks.                                                        | Code that used to fail with "expected Bool" now compiles.                                                                                                                                                                                                    |

## Calling C

`lib` and `fun` call C with no glue code. The full table of what crosses the boundary is in
[calling C](https://alice-lang.org/documentation/advanced/ffi.md).

```alice
@[Link("libc.so.6")]
lib LibC
  fun strlen(s : String) : UInt64
  fun getenv(name : String) : String?
  fun qsort(base : Array(Int32), n : UInt64, size : UInt64, cmp : Callback(Pointer(Int32), Pointer(Int32), Int32)) : Void
end
```

- `String` parameters are UTF-8 on a stack buffer, with no allocation. An embedded NUL raises instead of truncating.
- `String?` results are borrowed and never freed; a NULL pointer is `nil`.
- `out` and `ref` parameters pass a pointer to the caller's variable, so C out-parameters need no `unsafe`.
- A `Callback(...)` parameter takes a lambda literal, lifted to a static C function: no delegate and no allocation.
- `Pointer(T)` is only allowed inside `unsafe ... end` or an `unsafe def`.
- Every import is blittable behind an inlined wrapper, so NativeAOT has no marshalling stubs to precompile.

## GPU loops

`gpu for` compiles the loop body to an ILGPU kernel and runs it on the preferred device (CUDA, OpenCL, or ILGPU's
CPU accelerator). The guide is [GPU loops](https://alice-lang.org/documentation/guides/gpu.md).

```alice
def total(xs : Array(Int64)) : Int64
  t = 0_i64
  gpu for i in 0...xs.size
    t += xs[i] * 2_i64
  end
  t
end
```

- Reductions: `t += e` into an outer `Int32`, `Int64`, `Float32` or `Float64` is an atomic add on the device.
- `gpu ... end` regions keep the arrays of their loops on the device: each is uploaded once, written arrays are copied
  back at `end`, and a CPU read inside the region is a compile error. In a 51-launch run over 1M floats the region
  took 29 ms against 132 ms with a transfer per launch.
- Admission uses the same independence proof as `par for`, plus GPU rules. Each rejection names its cause.
- `ALICE_GPU=cpu` forces ILGPU's CPU accelerator, which gives the same results on machines without a GPU.

## .NET interop

- **Events, delegates and default interface methods.** `event clicked : EventHandler` is raised with
  `clicked&.Invoke(self, args)`; `delegate Op(a : Int32, b : Int32) : Int32` declares a delegate type; an interface
  `def` with a body is a default implementation. See [classes](https://alice-lang.org/documentation/language/classes.md).
- **Iterators.** A method returning `IEnumerable(T)`, `IEnumerator(T)` or `IAsyncEnumerable(T)` with no block parameter
  is lazy: `yield x` is `yield return`. See [methods](https://alice-lang.org/documentation/language/methods.md).
- **Method references.** `->sq`, `->sq(Int32)`, `->shape.area` and `->Geometry.dist` pass a method as a block, a `Func`
  or any delegate. See [blocks](https://alice-lang.org/documentation/language/blocks.md).
- **Source generators.** Roslyn source generators run on Alice code. `partial def` declares a body-less method that a
  generator completes, for `[GeneratedRegex]` and `[LibraryImport]`; `[JsonSerializable]` contexts give reflection-free
  JSON. See [.NET and NuGet](https://alice-lang.org/documentation/guides/dotnet.md).
- **Entity Framework Core and Avalonia.** Both run from Alice. A `DbContext` subclass runs LINQ queries that EF translates
  to SQL, and an `.axaml` window can take its code-behind in Alice. Extension methods from any referenced assembly are
  callable without parentheses (`query.ToQueryString`).
- **Alice spellings for .NET members.** `sw.elapsed.total_milliseconds`, `sb.append_line(x)`, `d.contains_key?(k)` and
  `dir.exists?` map to the .NET names on instances as they already did on statics. A Prelude method of the same name
  still wins where it fits.
- **Parameter attributes on records.** `record Span(start : Int32, @[JsonPropertyName("end")] stop : Int32)` puts the
  attribute on the generated property, where serializers read it.
- **`await using`** awaits `DisposeAsync` at `end`, for EF Core contexts and async streams.
- **`lock obj ... end`** is C#'s `lock`, for .NET APIs that need Monitor locking. Writes inside are still race-checked.
  Shared Alice data still uses `Mutex(T)`. See [mutexes and atomics](https://alice-lang.org/documentation/concurrency/synchronization.md).

## Language

- **Named tuples.** `{name: "ada", age: 36}` is a C# named tuple with no allocation, read as `t.name` or `t[:name]`. The
  type `{min: Int32, max: Int32}` names one. Hashes keep `=>`. See [tuples](https://alice-lang.org/documentation/language/tuples.md).
- **Assignment as a condition.** `if user = find(id)` and `while line = reader.ReadLine` assign before the test.
  Flow narrowing reads a nullable number as its value inside `if n` and after a guard clause.
- **Class discovery.** `Controller.subclasses`, `Controller.descendants` and `ObjectSpace.each_object(typeof(Controller))`
  list the program's own classes, which is what a plugin or framework needs. Enumerating live objects is not offered.
- **Refinements.** `refine String do ... end` inside a module is visible only in files that write `using <module>`.
  See [modules](https://alice-lang.org/documentation/language/modules.md).
- **Lambdas as blocks.** `xs.sum(&->sq)` and `xs.select(&->(x : Int32) { x.even? })` are inlined into the loop like a
  literal block.
- **Safe call.** `x.try &.m(args)` is the safe call `x&.m(args)`.
- **Multi-line blocks in parentheses.** `Task.Run(->() {` followed by statements on separate lines parses.
- **Nullable generic arguments.** `Dictionary(String, String?)` and `List(String?)` keep their nullable annotations.
- **Native callbacks and `out`/`ref`.** See [calling C](https://alice-lang.org/documentation/advanced/ffi.md).

## Ownership and performance

- **Owned lists and hashes.** A local `List(T)` or `Dictionary(K, V)` that never escapes is rented from a per-thread
  pool and released at its last use, with its grown storage kept. Element types are not limited to numbers, and
  `Clear` on release drops element references, so the pool keeps nothing alive. Storing, capturing, or passing a
  collection to .NET keeps it on the GC. See [ownership](https://alice-lang.org/documentation/advanced/ownership.md).
- **Presized collections.** `xs = List(T).new` followed by a counted loop that adds once per iteration is sized to the
  trip count first. `SoA` stores gain `reserve(n)`.
- **Three forks.** `trib(n - 1) + trib(n - 2) + trib(n - 3)` forks all three calls. A forking method also gets a
  serial clone, so the calls below the fork depth cost what plain recursion costs. See
  [fork/join](https://alice-lang.org/documentation/concurrency/fork-join.md).
- **Iterators on spans.** `Span(T)` and `ReadOnlySpan(T)` take `each`, `sum`, `count` and the other inlined iterators.
- **Returned collections.** An owned list that a method returns moves out to the caller unreleased.

## Tools and distribution

- **NuGet.** `Alice.Sdk` is an MSBuild SDK that includes the compiler, so `<Project Sdk="Alice.Sdk/0.13.0">` compiles
  `.al` files in a project with nothing else installed. `Alice.Cli` installs `alice` with
  `dotnet tool install -g Alice.Cli`, and `Alice.Runtime` is packable for C# hosts. See [the SDK](https://alice-lang.org/documentation/tools/sdk.md).
- **`alice pack` and `alice publish`.** Libraries and .NET tools ship as NuGet packages. `[package]` takes `id`,
  `description`, `authors`, `license`, `repository`, `homepage`, `tags` and more, and bad ids fail before packing.
  `kind = "tool"` with `command` packs a tool. See [publishing](https://alice-lang.org/documentation/guides/publishing.md) and the
  [manifest](https://alice-lang.org/documentation/tools/manifest.md).
- **`alice new`.** `alice new name --tool` creates a .NET tool package. `alice new name --lib` writes a description and
  `naming = "dotnet"`, so the library is ready for `alice publish`.
- **`naming = "dotnet"`.** A library's public members compile to .NET names: `total_area` becomes `TotalArea`, and
  `empty?` becomes `IsEmpty`. F# and C# callers see a conventional API. Alice code keeps Alice names.
- **Incremental builds.** `alice gen` runs only when a source, a reference, the compiler or the project changed. A
  no-op `alice build` takes 1.0 s instead of 2.35 s.
- **Language server.** Find references and rename work across the project. Matches come from the lexer and resolve to
  the symbol under the cursor, so `Square#area` renames without touching `Invoice#area`. See [editor setup](https://alice-lang.org/documentation/tools/editors.md).
- **`alice build --native`** keeps the directory layout of the entry file, so multi-file programs with relative
  `require` paths build natively.
- **`alice prove`** skips nested directories that have their own `alice.toml`.
- **`alice fmt`** indents `using` and `await using` blocks, interface default methods and `unsafe def`.

## Production readiness

The [production](https://alice-lang.org/documentation/reference/production.md) page lists what 0.13 is ready for, the test behind each claim,
recommended `alice.toml` settings per workload, and what is not ready yet.

## Continue reading

- Previous: [MSBuild integration](https://alice-lang.org/documentation/tools/sdk.md)
- Next: [Diagnostic reference](https://alice-lang.org/documentation/reference/diagnostics.md)
