# The not keyword

**URL:** <https://ziggit.dev/t/the-not-keyword/6587>\
**Category:** Brainstorming\
**Tags:** language\
**Created:** [October 29, 2024, 2:04pm UTC](https://ziggit.dev/t/the-not-keyword/6587 "2024-10-29T14:04:18Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [October 29, 2024, 2:04pm UTC](https://ziggit.dev/t/the-not-keyword/6587/1 "2024-10-29T14:04:18Z")

</div>

When I started programming in Pascal 500 years ago and switched to other languages I always missed the ‘not’ keyword.  
Now I see in Zig to my surprise the `and` / `or` keywords.  
I would really love to see my `not` back in Zig.  
_However_: in Pascal / Delphi the `not/and/or` are used for both bitwise operations and booleans, which can be confusing.

The `!` is so narrow that it can be easily missed, when scanning code.  
A `not` would be fantastic.

How do you fellow programmers think about this?

---

<div class="post-metadata">

**Author:** ![n0s4](https://ziggit.dev/user_avatar/ziggit.dev/n0s4/32/2227_2.png) [@n0s4](https://ziggit.dev/u/n0s4)\
**Post date:** [October 29, 2024, 2:15pm UTC](https://ziggit.dev/t/the-not-keyword/6587/2 "2024-10-29T14:15:45Z")

</div>

Andrew already rejected this: ["Not" instead of "!" · Issue #6625 · ziglang/zig · GitHub](https://github.com/ziglang/zig/issues/6625#issuecomment-706830879).

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [October 29, 2024, 2:20pm UTC](https://ziggit.dev/t/the-not-keyword/6587/3 "2024-10-29T14:20:02Z")

</div>

Hahah ok I will read. He should have rejected `and/or` then as well 🙂

---

<div class="post-metadata">

**Author:** ![Dok8tavo](https://ziggit.dev/user_avatar/ziggit.dev/dok8tavo/32/707_2.png) [@Dok8tavo](https://ziggit.dev/u/Dok8tavo)\
**Post date:** [October 29, 2024, 4:32pm UTC](https://ziggit.dev/t/the-not-keyword/6587/4 "2024-10-29T16:32:34Z")

</div>

Imo `and/or` have a good reason not be operator: they have an impact on the control flow. If the left side of an `or` expression is `true`, the right side won’t to be evaluated, same when the left side of an `and` expression is `false`.

This isn’t the case for the `!` operator.

---

<div class="post-metadata">

**Author:** ![chrboesch](https://ziggit.dev/user_avatar/ziggit.dev/chrboesch/32/438_2.png) [@chrboesch](https://ziggit.dev/u/chrboesch)\
**Post date:** [October 29, 2024, 4:59pm UTC](https://ziggit.dev/t/the-not-keyword/6587/5 "2024-10-29T16:59:26Z")

</div>

And you should also read this: [require parentheses sometimes to disambiguate confusing operator precedence · Issue #114 · ziglang/zig · GitHub](https://github.com/ziglang/zig/issues/114#issuecomment-302235077)

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [October 29, 2024, 5:16pm UTC](https://ziggit.dev/t/the-not-keyword/6587/6 "2024-10-29T17:16:37Z")

</div>

Ah interesting. I will read.  
I will miss my beloved not forever.

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [October 30, 2024, 8:09am UTC](https://ziggit.dev/t/the-not-keyword/6587/7 "2024-10-30T08:09:08Z")

</div>

Sidenote:  
When I was reading this topic, just for a moment I struggled to remember what operator Zig is actually using for the “boolean not”. The reason being that I instinctively try to avoid it in order to simplify logic. Since “boolean not” is a logical operation that can be removed without introducing any other logical operations, removing it saves every reader from tracking that redundant negation, meaning it improves readability.

There’re two obvious ways of eliminating it:

1. Rename boolean variables

```zig
var is_false = false;
while (!is_false) {
    ...
}

```

Becomes:

```zig
var is_true = true;
while (is_true) {
    ...
}

```

1. Apply “[De Morgan’s laws](https://en.wikipedia.org/wiki/De_Morgan%27s_laws)”

```zig
if (!(a >= b and c >= d)) {
    ...
}

```

Becomes:

```zig
if (a < b or c < d) {
    ...
}

```

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [October 30, 2024, 9:29am UTC](https://ziggit.dev/t/the-not-keyword/6587/8 "2024-10-30T09:29:07Z")

</div>

I never use what I call “The Back and Forth Bouncing Booleans” which attacks my brain.

And yes this is a good example! (including the crazy ! for not, who on earth invented that…).

```zig
if (!(a >= b and c >= d))

```

For my (C#) work I sometimes use:

```zig
if (MyLookupFunction(args) == false) // this
if (!MyLookupFunction(args)) // instead of this

```

EDIT: chat gpt answer to who is guilty

> The choice of `!` for “not” is rooted in early programming languages and mathematics, where brevity was essential due to limited screen space and memory. This notation likely traces back to **BCPL** (the precursor to C) and **ALGOL**. Ken Thompson and Dennis Ritchie, while developing C, adopted `!` as a logical NOT operator, making it standard for languages that followed.
> 
> The irony is real, though—`!` is indeed narrow and easy to miss, especially given its significance in logical expressions. Unfortunately, by now, it’s deeply embedded in programming conventions.

Sometimes we are just stuck in reality 🙂

---

<div class="post-metadata">

**Author:** ![dude\_the\_builder](https://ziggit.dev/user_avatar/ziggit.dev/dude_the_builder/32/557_2.png) [@dude\_the\_builder](https://ziggit.dev/u/dude_the_builder)\
**Post date:** [October 30, 2024, 12:36pm UTC](https://ziggit.dev/t/the-not-keyword/6587/9 "2024-10-30T12:36:54Z")

</div>

It ain’t pretty, but it works 😹

```zig
const std = @import("std");

inline fn not(b: bool) bool {
    return !b;
}

pub fn main() !void {
    if (not(3 > 4)) {
        std.debug.print("{}\n", .{not(3 > 4)});
    }
}

```

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [October 30, 2024, 12:38pm UTC](https://ziggit.dev/t/the-not-keyword/6587/10 "2024-10-30T12:38:01Z")

</div>

You just invented a new keyword.

---

<div class="post-metadata">

**Author:** ![FObersteiner](https://ziggit.dev/user_avatar/ziggit.dev/fobersteiner/32/1177_2.png) [@FObersteiner](https://ziggit.dev/u/FObersteiner)\
**Post date:** [October 30, 2024, 1:44pm UTC](https://ziggit.dev/t/the-not-keyword/6587/11 "2024-10-30T13:44:50Z")

</div>

never saw it like this before, if there is no `not` keyword but only `!`,

```zig
pub fn main() !void {

```

is a bit strange; the function does not return `not void` …

---

<div class="post-metadata">

**Author:** ![chrboesch](https://ziggit.dev/user_avatar/ziggit.dev/chrboesch/32/438_2.png) [@chrboesch](https://ziggit.dev/u/chrboesch)\
**Post date:** [October 30, 2024, 2:39pm UTC](https://ziggit.dev/t/the-not-keyword/6587/12 "2024-10-30T14:39:43Z")

</div>

> [@ericlang](#):
>
> `if (MyLookupFunction(args) == false) // this`

This is much easier to read.
