Questions about built-in functions

  1. Why are there so “many” built-in function? @sin, @cos, etc look like ordinary library function.

  2. Mixing of name conventions. Most of built-in functions are using camel case.
    Besides this, there are @memcpy, @Frame, @This, @TypeOf. I am
    surprised to find both @frame and @Frame.

1 Like
  1. Built-in functions cannot be implemented in pure zig. @sin and @cos can be written in library, as std.math does, the reason for a built-in is they could use a hardware instruction for the calculation if available.

  2. This conforms to zig’s style guide, builtins that returns a type should be in TitleCase, otherwise should be in camelCase.

1 Like
  1. Library function can’t use hardware instructions?

  2. Some counter examples of the naming guide.

    • @memcpy

    • @cImport(expression) type

    • @import(comptime path: []u8) type

1 Like

@sin and @cos map directly to compiler-rt’s sincos, which will use whatever instructions the cpu has to offer. However, the cpu either might not have any instructions for such a case, or you might not have compiler-rt (in which case it won’t find sincos).

Ideally the optimizer would be able to turn std.math.sin and std.math.cos into @sin and @cos when it can.

I think the current goal is to get rid of the @sin and @cos builtins when such case is possible

2 Likes

@sin, etc, reminds me of the standard procedures and functions in Pascal, :slight_smile:

I have just taken a look into std.math. It is quite different from what I had assumed.
I think there would be many versions of sin for different CPUs with polynomial
fitting as a fallback method.

The standard library isn’t supposed to make assumptions about platform or cpu so that it can work everywhere. That means that all of std.math needs to be implemented entirely in zig with no calls to builtin magic (which is why std.math.sin is not just a call to @sin)

I like this approach, built-in functions cannot be implemented in “user-space”, and rely on the compiler;

It becomes very clear for functions such @addWithOverflow for example, but sometimes it’s not so clear like @sin and @cos … Maybe some builtins could be replaced in favor of user-space, for example, moving @fieldParentPtr in std.meta

IMHO, these built-in functions (@sin, @addWithOverflow, etc) should be made like “normal” library function, as C compilers (intrinsic function) .

Only a small set of functions which obviously need compiler magic (@Type, etc) should be listed in Builtin-Functions section. Or, I am afraid that we are going to see an explosion in this section in the near future, which will scare new learners.

This disadvantage of this approach of “intrinsic functions” is now the builtin functions are in the same namespace as user symbols. By requiring a @ for builtin functions, the language is free to add new functions knowing that it won’t break user code that was already using that symbol. This namespacing is a very refreshing feature for Zig coming from other languages like D that didn’t do that, and have kind of painted themeselves into a corner when it comes to adding/removing builtins.

The other benfit of using @ for builtins is it immediately tells you where the function comes from. In fact, so long as you don’t use usingnamespace, Zig is really the only language I can think of where you can tell where every symbol that you use comes from just by looking at the file. This is a huge benefit when it comes to code maintenance, which Zig prioritizes over making it easier to “write” code.

1 Like

Suppose someday, CPU introduces hardware support for hypot. A new @hypot is added into built-in function. Code need to be updated to enjoy the benefits. But, if it is just a “normal” library function, all we need to do is recompiling the code.

Yeah that’s one of the benefits of library abstraction.

Additionally, “no std” scenario is a first-class citizen … so you don’t need any library to use built-in functions.

1 Like

100% agree on the huge benefit of clearly identifying and isolating builtins into their own namespace via the @ prefix. I think the poster child for what can go wrong when you don’t do this is the story of _Bool in C.

1 Like

Get prepared for the 1000th @ function in the Builtin-Functions section. :grinning: