Smaller Io interface (Io-core)

According to the standard library documentation, the current Io interface contains the following:

  • file system
  • networking
  • processes
  • time and sleeping
  • randomness
  • async, await, concurrent, and cancel
  • concurrent queues
  • wait groups and select
  • mutexes, futexes, events, and conditions
  • memory mapped files

A lot of this stuff is completely unavailable in certain environments such as in embedded systems, so attempting to use the Io interface yields a lot of wasted memory, which can be very important in memory constrained environments such as embedded systems.

Perhaps it’s time for Zig to consider an smaller Io interface (Io-core) in the standard library that still supports async and concurrency, but doesn’t have stuff like filesystems which require an entire operating system.

1 Like

I suspect what is considered as core has as many opinions as there are potential users. Good luck reaching a consensus :blush:

Getting rid of the os-dependent filesystem stuff alone from the Io interface already gets rid of 54 function pointers, which is more than half of the function pointers in the current Io interface. That and removing whatever other os-dependent stuff can result in the Io-core. Ideally Io-core would support anything that could be done with Rust core or Rust core+alloc.

Just wait a few releases. Restricted function pointers will essentially turn this into static dispatch, so code can be eliminated from the binary. And the cost of indirect calls is gone.

7 Likes

There are several topics where the same issue already discussed
You are not alone

I believe the answer to that problem is

  1. Io.Operation where some operations are grouped together in one function (à la “ioctl” )

  2. Restricted function pointer which is complicated name to detect that there is only one Io implem in your program, so all Io function call are static dispatched (not sure how it removes the vtable?)

But curious which platform are you targeting ?

Zig’s goal is optimal code generation across all environments, including embedded. Solutions which split the std lib (like rust’s no_std) are sub optimal. The compiler knows where the dead code is, and it’s reasonable to expect a compiler to be able to delete it. We should be more imaginative and not be beholden to status quo of embedded being annoying AF to work on.

2 Likes