Skip to content

Commit b8b38c4

Browse files
committed
Add Moving Towards a New "core:os"
1 parent e848775 commit b8b38c4

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: Moving Towards a New "core:os"
3+
summary: The rationale and transition period to moving to the new "core:os"
4+
slug: moving-towards-a-new-core-os
5+
author: Ginger Bill
6+
date: '2025-10-31'
7+
categories:
8+
- packages
9+
- apis
10+
---
11+
12+
Odin has been designed to be a pragmatic and evolutionary language, and as such, most people have come to appreciate the results of that, especially stability of language features. Odin rarely experiences breaking changes, however we have some technical debt to pay.
13+
14+
Packages `base:runtime` and `core:os` are the oldest packages in the core library of Odin, as they were used in bootstrapping the language and the rest of the packages. Over time they became an amalgamation of ideas, added as and when things were needed. `base:runtime` has already been cleaned up, but `core:os`'s general API was poorly designed and inconsistent across platforms. Certain procedures were available only on specific platforms _and_ other procedures, while available on all platforms, didn't have a unified signature across them. Constants and errors messages were all platform-specific, leading to less than ideal cross-platform behaviour.
15+
16+
Over the past couple of years, we have been redesigning the entirety of `core:os` (which at the time of writing is `core:os/os2`) to be in keeping with the standards of the core library. We have learnt a lot over the years in terms of library and API design for Odin, and we want to incorporate those lessons into one of its most foundational packages.
17+
18+
## Transition Period
19+
20+
There will be numerous breaking changes for `core:os`, but we have promised to give notice well in advance of when this will happen and how we plan to transition. This article is that notice.
21+
22+
We are expecting to transition to the new design of `core:os` early next year (Q1 2026).
23+
24+
**Note:** `core:os/os2` is already available to use today. When the transition happens, this will become `core:os`, and `core:os/os2` will be no more.
25+
26+
## New Design
27+
28+
The new package has changed many aspects of how you interact with `core:os`; an overview:
29+
30+
* All procedures that returned allocated memory will require an explicit allocator to be passed
31+
* If you want to emulate the current functionality, it is recommended that you pass `context.allocator` or `context.temp_allocator` where needed
32+
* Most procedures now return an `os.Error` rather than a trivial `bool` or `Errno` where appropriate
33+
* File handling now uses `^os.File` instead of a raw file handle (`os.Handle`)
34+
* Allowing for a more generic interface which can be easily overridden/intercepted where needed
35+
* New APIs handling paths and processes
36+
* New and improved directory walker
37+
* Consistent API across all platforms/OSes
38+
* And many more quality of life improvements!
39+
40+
## Rationale Behind Design Choices
41+
42+
### Why `^os.File`
43+
44+
The old API used raw file handles (`os.Handle`) for all of its file operations. This was fine for most operations, it can however be quite restrictive when doing something more complicated, or you need the ability to override/intercept behaviour.
45+
46+
In languages such as C, it is common to have the standard "file" type (e.g. [`FILE`](https://wikipedia.org/wiki/C_file_input/output) in C) act like a generic stream interface with fstat-like support. This ability to override the generic interface allows for more streamlined file buffering (which was previously done with an explicit wrapper such as [`bufio.Writer`](https://pkg.odin-lang.org/core/bufio/#Writer)/[`bufio.Reader`](https://pkg.odin-lang.org/core/bufio/#Reader)), and also to intercept code that was written for a file handle (now `^os.File`) instead of an [`io.Stream`](https://pkg.odin-lang.org/core/io/#Stream).
47+
48+
A lot of Odin's design has centred around allowing the programmer to intercept third party code. As `core:os` is such a foundational package, we believe it should mirror this design principle.
49+
50+
**Note:** Odin's [implicit `context` system](https://odin-lang.org/docs/overview/#implicit-context-system) is a brilliant example of this interception ability built directly into the language.
51+
52+
53+
### Why Explicit Allocators
54+
55+
We wanted to clarify the distinctions between user-level and OS-level allocations. Requiring an explicit allocator makes it very clear who and what is allocating where.
56+
57+
The internal design of the new `core:os` uses its own set of custom allocators which are not meant to be used by the rest of the user code. They are not overridable (unfortunately), and just as operating systems perform a lot of internal allocations already, this is an extension of that. This allows allocators to minimize memory usage, too.
58+
59+
A basic example of this is `^os.File` (a pointer to extra information) allocated using the internal allocators rather than any user-provided allocator, which are logically also freed using those internal allocators.
60+
61+
Other packages in the core library will keep their existing allocator idiom, such as `allocator := context.allocator`, as those APIs are purely in the user-level domain. `core:os` is being treated differently because it is a fundamentally different kind of package to the rest of the core library.
62+
63+
64+
## Some Examples of the Changes
65+
66+
```odin
67+
// Old API
68+
data, ok := os.read_entire_file("path/to/file.txt")
69+
70+
// New API
71+
data, err := os.read_entire_file("path/to/file.txt", context.allocator)
72+
```
73+
74+
```
75+
// Old API
76+
fd: os.Handle
77+
78+
// New API
79+
f: ^os.File
80+
81+
```
82+
83+
```odin
84+
// Old API
85+
err: os.Errno // just an integer
86+
87+
// New API
88+
err: os.Error // a union of enums
89+
```
90+
91+
```odin
92+
// Removed procedures
93+
get_last_error // not needed since `os.Error` exists
94+
get_page_size
95+
get_std_handle
96+
97+
// Removed OS specific procedures
98+
get_windows_version // etc
99+
is_windows_* // etc
100+
```

0 commit comments

Comments
 (0)