Я інколи кажу, що C++ — це хороша мова з поганими дефолтами. Маю на увазі, що мова дуже потужна і дозволяє робити купу всього, але програміста при цьому примушує тримати купу деталей в голові, щоб не схибити десь.
Нюанс полягає в тому, що мови з хорошими дефолтами я поки не бачив, хоч деякі з них намагаються виправити бодай якусь маленьку проблему, що вже непогано. Як в тому ж #Rust зробили, щоб всі «змінні» стандартно були константами. Воно ж і логічно, ні? Як часто вам насправді треба мати мутабельні змінні? З поточними практиками — дуже рідко, бо через вплив ФП ви найімовірніше просто позначаєте якесь проміжне immutable значення окремим імʼям. Але в C++ для оголошення константи програмісти мусять окрему роботу виконати — написати
Або додали ось в C++11 атрибути, зокрема🤯 «Навіщо?» — спитаєте ви. Я теж не одразу второпав.
Є у вас, наприклад, так званий mutex guard — така штука, яка локає мьютекс при створенні та автоматом анлокає його при виході зі скоупу (при знищенні). Як
Річ у тім, що можна хибно написати ось такий код, і компілятор вам жодного слова не скаже:
Короч, як ви вже здогадалися, щоб уникнути останньої проблеми, можна позначити конструктор як
Логічно? «Логічно»!😅 Але чому це не стандартна поведінка? Ніхто того не зна. Як часто ви пишете функції, які повертають значення, яке можна ігнорувати? Нащо тоді вони його повертають? А як часто ви пишете класи, екземпляри яких ніяк не використовуються? Чисто заради сайд-ефектів чи що?
У #Nim теж так подумали й зробили всі значення non-discardable, причому компілятор одразу помилку пише, а не попередження:
І щоб виправити це, треба буквально сказати йому, що значення вам не потрібне:
Круто, еге ж?
Вирішив пошукати, в яких ще імперативних мовах таке є, і виявилося, що в жодній! #Zig та #Swift нібито попередження видають, але це не точно. А ще в #Rust є схожий пропоузал. Чому ніхто цього не робить? Є ідеї? )
Нюанс полягає в тому, що мови з хорошими дефолтами я поки не бачив, хоч деякі з них намагаються виправити бодай якусь маленьку проблему, що вже непогано. Як в тому ж #Rust зробили, щоб всі «змінні» стандартно були константами. Воно ж і логічно, ні? Як часто вам насправді треба мати мутабельні змінні? З поточними практиками — дуже рідко, бо через вплив ФП ви найімовірніше просто позначаєте якесь проміжне immutable значення окремим імʼям. Але в C++ для оголошення константи програмісти мусять окрему роботу виконати — написати
const
. Легко забути та скіпнути? Легко.Або додали ось в C++11 атрибути, зокрема
[[nodiscard]]
в C++17. Якщо функцію таким позначити, то компілятор «заохочується» 😆 видати попередження, що треба щось зробити зі значенням, що повертається. І як виявилося, подібним атрибутом можна позначити конструктор Є у вас, наприклад, так званий mutex guard — така штука, яка локає мьютекс при створенні та автоматом анлокає його при виході зі скоупу (при знищенні). Як
std::lock_guard
, ага. Використовується наступним чином:{
const mega_guard lock{mutex};
// ...
}
Річ у тім, що можна хибно написати ось такий код, і компілятор вам жодного слова не скаже:
{
mega_guard{mutex}; // не lvalue, тож одразу знищується, звільняючи мьютекс
// ...
}
Короч, як ви вже здогадалися, щоб уникнути останньої проблеми, можна позначити конструктор як
[[nodiscard]]
:class mega_guard {
public:
[[nodiscard]] explicit mega_guard(mutex &);
// ...
};
Логічно? «Логічно»!
У #Nim теж так подумали й зробили всі значення non-discardable, причому компілятор одразу помилку пише, а не попередження:
proc sum(x, y: int): int =
result = x + y
sum(3, 4) # Error: expression 'sum(3, 4)' is of type 'int' and has to be discarded
І щоб виправити це, треба буквально сказати йому, що значення вам не потрібне:
discard sum(3, 4)
Круто, еге ж?
Вирішив пошукати, в яких ще імперативних мовах таке є, і виявилося, що в жодній! #Zig та #Swift нібито попередження видають, але це не точно. А ще в #Rust є схожий пропоузал. Чому ніхто цього не робить? Є ідеї? )
Please open Telegram to view this post
VIEW IN TELEGRAM