ООП мертве? Як парадигми програмування воюють зі складністю

Програмісти сперечаються роками: процедурне програмування чи об’єктно-орієнтоване? Чи, може, функціональне? Ці парадигми формують не лише синтаксис коду, а спосіб мислення. Холівари виникають не тому, що хтось неправий — а тому, що різні підходи пристосовані до різних задач.

«Об’єктно-орієнтоване програмування — надзвичайно погана ідея, яка могла з’явитися лише в Каліфорнії» — Едсгер В. Дейкстра
«Ця парадигма [ООП] тісно відображає структуру систем „реального світу“, а отже, добре підходить для моделювання складних систем зі складною поведінкою» — Ніклаус Вірт

Двоє легендарних комп’ютерних вчених — і настільки протилежні думки. Хто має рацію? Щоб зрозуміти, треба поринути в історію — від машинного коду до мультипарадигмальних мов програмування.

Парадигма програмування — це спосіб мислення і написання програм, який визначає, як будуються програми та як вирішуються задачі.

Різні парадигми пропонують різні підходи — наприклад, писати програму як набір інструкцій (процедурна)*, як взаємодію об’єктів (об’єктно-орієнтована) або як обчислення через функції (функціональна).

Від перфокарт до спагеті-коду

Початок програмування був суворим. У 1940–1950-х роках програмісти буквально писали нулями та одиницями.

Налагодження програми могло зайняти дні. Наприклад, пошук помилки в програмі ENIAC вимагав перевірки тисяч фізичних з’єднань.

Асемблер трохи полегшив справу, дозволивши записувати інструкції в більш-менш зрозумілій формі (MOV AX, BX). Але писати навіть просту програму на кілька сотень інструкцій — це був виклик. Також потрібно було розуміння низькорівневої архітектури комп’ютера і апаратних обмежень.

У 1960-х з’явились мови високого рівня: BASIC, FORTRAN. Вони дали можливість писати зрозуміліше, але не набагато краще. Програми стали схожі на клубок GOTO: з переходами туди-сюди, з неможливістю зрозуміти, що викликається і коли. Це і був справжній «спагеті-код».

10 INPUT "Enter a number"; A
20 IF A = 0 THEN GOTO 100
30 PRINT "Not zero"
40 GOTO 10
100 PRINT "Goodbye"

Цей підхід працював, поки програміст міг тримати всю програму в голові. Але як тільки об’єм коду виростав — його переставали розуміти навіть автори. Крім того, треба врахувати, що і сучасні можливості типу окремих файлів і функцій на той час були доступні далеко не завжди.

Структурне програмування: перша революція

У 1968 році Едсгер Дейкстра опублікував статтю «Go To Statement Considered Harmful», яка стала переломним моментом в історії програмування. Він стверджував, що GOTO — це «отрута» для програми: вона руйнує передбачуваність і контроль потоку.

Рішенням стало структурне програмування: використання конструкцій if, while, for, блоків і вкладених структур. Завдяки цьому програма почала нагадувати дерево з чіткими гілками, а не хаотичний клубок стрибків від одного рядка коду до іншого.

Коли до цього підходу додалася можливість групувати логіку у вигляді процедур і функцій, з’явився процедурний стиль програмування. Він дозволяв організовувати код у зрозумілі блоки з назвами, які можна багаторазово викликати, що стало серйозним поштовхом у розвитку складніших програмних систем.

Мова C стала ідеальним інструментом для цього підходу. Вона дозволила створювати функції, модулі, маніпулювати пам’яттю, при цьому залишаючись максимально близькою до заліза.

«C — химерна, недосконала, але надзвичайно успішна» — Деніс Річі

UNIX написали на C — і це був доказ: можна створити повноцінну операційну систему, використовуючи даний підхід. Проте коли виникла потреба створювати програмні системи для автоматизації процесів у різних сферах діяльності людини, стало зрозуміло, що потрібен інший інструмент, який би дозволив простіше створювати моделі реального світу та повторно використовувати написаний код.

До речі, в тому самому 1968 році виник термін «криза програмного забезпечення», пов’язаний зі збільшенням продуктивності комп’ютерів і складністю проблем, що вони можуть вирішувати.

Основні проблеми пов’язані з «кризою програмного забезпечення»: проєкти перевищували бюджети в рази, не встигали в терміни, а якість була незадовільною. Причина — старі методи не масштабувалися. Ті самі проблеми будуть виникати і далі, стимулюючи використання нових підходів.

ООП: моделюємо світ об’єктами

Процедурний підхід добре працював для системного програмування, але в 1980-1990-х роках характер задач змінився. Бізнес почав вимагати автоматизації складних процесів — банківських систем, управління запасами, моделювання реальних об’єктів.

Використання послідовності дій для їх опису виявилось занадто складним. Найголовнішою проблемою стало дублювання логіки, яке призводило до збільшення кодової бази та ускладнення самого коду через велику кількість перевірок різноманітних умов. Потрібен був новий рівень абстракції.

З’явились Simula, Smalltalk, C++, Java. І з ними — об’єктно-орієнтоване програмування. Клас, об’єкт, наслідування, інкапсуляція — нова мова для моделювання реального світу.

«Об’єктно-орієнтоване програмування, яким воно з’явилося в Simula 67, дозволяє будувати структуру програмного забезпечення на основі структур реального світу та надає програмістам потужний спосіб спростити проєктування і створення складних програм» — Девід Ґелернтер

Книга Граді Буча з об’єктно-орієнтованого проєктування починається з пояснення проблеми складності і того, що ООП — це інструмент для її подолання.

«Основне завдання інженерії програмного забезпечення — це керування складністю. Складність програмних систем часто перевищує складність апаратного забезпечення, на якому вони працюють. ... Мета об’єктно-орієнтованої розробки полягає в подоланні притаманної ПЗ складності шляхом поділу її на керовані частини» — Граді Буч, Об’єктно-орієнтований аналіз та проєктування з прикладами застосування

ООП дозволяє створити програму, яка не просто виконує інструкції, а поводиться як взаємодіючі сутності. Наприклад, банківська система — це рахунки, клієнти, транзакції. Вони мають стан і поведінку. Саме це дозволяє ООП: будувати масштабовані, підтримувані системи. Проте мислити послідовністю команд при описі конкретної задачі для людини простіше. Для комп’ютера більш природно виконувати готову послідовність команд, а не створювати її спочатку з опису класів.

Саме тому продуктивність застосунків C++ була нижчою при використанні складних абстракцій і віртуальних викликах за звичайний C. Тим не менш це була плата за вищу продуктивність програмістів.

Ви не любите ООП?

«Ви не любите котів? Ви просто не вмієте їх готувати» — невідомий автор

Це ж можна сказати про об’єктно-орієнтоване програмування. За великим рахунком ООП просто інший підхід до структурування коду, він вимагає від програміста більш глибокого аналізу та напруження на етапі проєктування.

Зазвичай у коді, побудованому на основі вдало спроєктованих класів (ООП), ви побачите набагато менше конструкцій if, ніж у коді, написаному в процедурному стилі, який робить те саме. Це можна пояснити тим, що вибір послідовності інструкцій робиться в момент створення об’єкта, тоді як у процедурному підході перевірки умов зустрічаються безпосередньо під час виконання алгоритму. Імовірність зустріти дублювання логіки в процедурному коді також вища. При цьому мова не лише про copy-paste, а й про частини коду, які можуть бути написані по-різному, але з точки зору бізнес-логіки виконувати одну й ту саму функцію.

Водночас багато хто пише процедурний код під виглядом ООП. В цьому випадку ви побачите анемічну модель предметної галузі, часте використання сетерів/гетерів, класи без методів, або класи з тільки з методами без властивостей та велику кількість final.

Важливо розуміти, що не потрібно намагатись будь-яку задачу вирішити за допомогою ООП. Наприклад, алгоритм сортування.

З іншого боку, якщо у вас складна предметна галузь з широким набором сценаріїв, використання набору вдало спроєктованих класів може суттєво полегшити вам життя, зменшивши кількість і складність коду.

Проте справа не лише в синтаксисі — змінюється сам принцип розробки. ООП вимагає аналітичного мислення, і без нього дуже важко створити справді гарний код.

DDD, коли ООП вже не вистачає

На початку 2000-х років із появою хмарних платформ та зростанням вимог до масштабованості стало очевидно: навіть об’єктно-орієнтованого підходу інколи недостатньо для управління складністю великих систем.

У цей час набирає популярності Domain-Driven Design (DDD) — підхід, запропонований Ерiком Евансом. Його ключова ідея — розбивати складні предметні області на менші ізольовані частини (обмежені контексти) й описувати їх за допомогою єдиної мови (Ubiquitous Language), зрозумілої і для розробників, і для експертів домену.

DDD став не лише технічною практикою, а й способом організації співпраці між бізнесом і розробкою. Моделі створюються не ізольовано програмістами, а в діалозі з експертами предметної галузі. Це дозволяє мінімізувати розрив між кодом і реальною логікою бізнесу.

Технічно DDD добре поєднується з ООП: агрегати, сутності, об’єкти-значення та сервіси природно реалізуються через класи й об’єктні відносини. Проте DDD виходить за межі ООП — він задає методологію побудови архітектури, яка з часом еволювала в мікросервісні підходи та сучасні розподілені системи.

«Складності не слід уникати; нею слід управляти» — Ерік Еванс

Таким чином DDD став ще одним етапом у боротьбі зі складністю: якщо структурне програмування приборкало хаос коду, а ООП допомогло моделювати реальні об’єкти, то DDD дозволив масштабувати ці моделі на рівень цілих доменів і великих організацій.

Несподіваний поворот: Go — мінімалізм від Google

Проте складність притаманна не тільки задачам, але й інструментам. Як відповідь на ускладнення стандартів розповсюджених мов у 2009-му Google випускає Golang: без наслідування, без класів, без шаблонів, з мінімальним набором конструкцій. Але при цьому дуже швидку.

«Менше — це експоненційно більше» — Роб Пайк

Go — це експеримент з управління складністю через спрощення. Замість додавання нових можливостей Go прибрав те, що вважав зайвим. В противагу Java чи C++ Go суттєво простіший.

«Go було створено простим, щоб уникнути тієї складності, яку ми бачили в інших мовах, особливо в тих, що надихнули нас, як-от C++ та Java» — Роберт Ґріземер

Go не підтримує ООП із наслідуванням класів, але містить деякі базові об’єктно-орієнтовані інструменти — інкапсуляцію, інтерфейси та методи. Замість наслідування Go використовує композицію, а поліморфізм досягається через інтерфейси. Це дозволяє писати код без надлишкової складності класичних ООП-мов.

Go дозволяє структурувати код через прості структури та методи. Проте має менші можливості по моделюванню складних предметних галузей. Go — радше процедурна мова і це плата за високу продуктивність коду.

З іншого боку, оскільки велика кількість програмістів пишуть процедурний код, не використовуючи об’єктно-орієнтовані можливості, то і при переході на Go не відчують дискомфорту від їх відсутності.

А що з іншими парадигмами?

Теоретичні основи функціонального програмування виникли ще до появи комп’ютерів — у 1930-х роках було сформульовано лямбда-числення, яке згодом лягло в основу функціональної парадигми.

Оскільки ця парадигма має чіткий математичний базис, мови на зразок Haskell дають змогу виявляти багато помилок ще на етапі компіляції, зокрема типові невідповідності чи суперечності в структурі програми.

Проте кількість задач, які зручно вирішувати в рамках функціональної парадигми, значно менша у порівнянні з іншими. Про це свідчить статистика використання мов програмування.

Найбільш розповсюджений представник декларативного програмування — SQL. В розробці програм він має скоріше допоміжну функцію для отримання даних з БД і недооцінений великою кількістю розробників.

Не раз доводилось зустрічати випадки, коли розробник вибирає масив даних з БД і починає обробляти цей масив в коді замість того, щоб отримати бажаний результат за допомогою SQL-запита. Програма стає як менш зрозумілою, так і менш продуктивною. Проте це тема для іншої розмови.

Загалом декларативні парадигми не можуть повністю закрити поширені класи задач, тому і маємо «протистояння» підходів, які найчастіше використовуються: процедурного та об’єктно-орієнтованого.

Існують і інші парадигми, але вони менш розповсюджені і тому ми не будемо їх розглядати.

Мультипарадигмальність: нова норма

Сучасні мови програмування вже давно перестали бути «чистими» представниками лише однієї парадигми. Вони еволюціонували, інтегруючи у себе найкращі підходи з різних стилів програмування — процедурного, об’єктно-орієнтованого, функціонального та навіть декларативного (наприклад, у вигляді анотацій). Це дозволяє розробникам обирати найзручніший стиль для вирішення конкретної задачі, не обмежуючи себе рамками однієї парадигми.

Python — яскравий приклад мультипарадигмової мови. Він однаково добре підходить і для написання простих скриптів у процедурному стилі, і для побудови великих систем з використанням ООП, і для функціонального програмування завдяки підтримці вищих функцій, лямбд і генераторів.

Java — колись майже синонім класичного ООП, поступово відкрився для інших підходів: у сучасних версіях з’явилися лямбда-вирази, стріми, функціональні інтерфейси, що значно розширило інструментарій розробника.

JavaScript та PHP теж починали як прості скриптові мови, але сьогодні підтримують і ООП (класи, наслідування, інтерфейси), і функціональний стиль (callback-функції, map/reduce/filter), і навіть елементи реактивного та асинхронного програмування.

Мультипарадигмальність стала стандартом для нових мов і майбутнє програмування — за гнучкістю й здатністю поєднувати різні ідеї в одному рішенні. Саме тому вибір мови дедалі частіше визначається не її «чистотою», а зручністю поєднання різних підходів для розв’язання реальних задач.

Коли яку парадигму обирати

Функціональне програмування:
— Задачі без стану: трансформації, фільтрація, агрегація.
— Паралельні обчислення без загальнодоступних даних.
Де використовується: обробка потоків даних, компілятори, математичні обчислення.

ООП:
— Моделювання складних доменів з багатьма сутностями.
— Довготривалий стан та складна поведінка об’єктів.
Де використовується: enterprise-системи, ігрові рушії, симулятори.

Процедурне:
— Чітка послідовність операцій, мінімум абстракцій.
— Критична продуктивність, системний рівень.
Де використовується: ядра ОС, драйвери, вбудовані системи.

Декларативне:
— Опис бажаного результату, а не способу його досягнення.
— Складні запити та трансформації даних.
Де використовується: бази даних (SQL), конфігурації (YAML/JSON), веброзмітка (HTML/CSS).

Важливо: більшість сучасних проєктів комбінує підходи. Вибір залежить від конкретної частини системи, а не від проєкту загалом.

Ключові висновки

Розвиток парадигм та мов програмування — це еволюція, направлена на управління складністю, пов’язаною зі збільшенням масштабу задач.

Це відповідь на проблеми, з якими вже не справлялись старі підходи. GOTO не справлявся з тисячами рядків коду, процедури — з мільйонами, ООП — з розподіленими системами.

Не існує універсальної мови чи парадигми. Важливо вміти обирати інструмент залежно від контексту.

ООП не мертве. Процедурний стиль — не пережиток. Функціональне програмування — не панацея.

Проблема часто в тому, що ми користуємось молотком там, де потрібна викрутка.

Водночас парадигми програмування можна розглядати як інший вимір мислення, у якому розробник рухається, створюючи програмний продукт. І що важливо — для цього не обов’язково змінювати мову програмування. Знання та комбінування парадигм відкриває більше свободи й можливостей у написанні коду. Це дозволяє адаптуватися до задач різного рівня складності, створювати гнучкіші архітектури й зрештою писати якісніше програмне забезпечення.

Навчіться думати в різних парадигмах — і холівари втратять сенс.

Примітка. Коректніше вживати термін «імперативна парадигма» замість «процедурна», адже саме імперативний підхід охоплює базові принципи управління станом програми через послідовні інструкції. Проте серед програмістів частіше йде мова про процедури та функції, адже знайомство з цим стилем відбувалося переважно через мови на кшталт C, де акцент робився саме на процедурному програмуванні.

Література та посилання

Ілюстрації Юлії Дмитракович

👍ПодобаєтьсяСподобалось14
До обраногоВ обраному10
LinkedIn

Найкращі коментарі пропустити

ООП мертва? Ні, автор інфором, а загаловок клікбейт.

Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Чи необхідна заміна деталей у зношеному обладнанні? Так.
Тому що перестане працювати? Не завжди. Іноді тому, що може вибухнути під час експлуатації.
Питання: чи легасі код може вибухнути під час експлуатації?
Друге питання: чи можно дивитися на код, у якому є легасі, як на код, вартість якого завищена?
Третє питання: а взагалі — код амортизують?
P.S.
Якщо амортизують, то код це капітал.

Код це точно капітал. Бо інтелектуальна власність.

проскролив коментарі і зрозумів що це те саме що і на цьому відео з редіта))
www.reddit.com/...​cv0/linux_users_when_the

Важливо зазначити, що техніки ООП що реалізовано в ООП-мовах є обмежуючі та розширюючі.
— абстракція
— приховування
— інкапсуляція
— наслідування
це обмежуючі.
— поліморфізм — розширююча.
Частіше за все задачею технік ООП через фічі мови є ОБМЕЖИТИ дизайн. Із цього треба виходити.

Частіше за все задачею технік ООП через фічі мови є ОБМЕЖИТИ дизайн. Із цього треба виходити.

По факту да. А цель упростить за счет стандартизации инструментов. Так же как и стандарт на размер гаечных ключей.

шо, опять? Ви ще згадайте про Delphi, UML, CMS, шо програмувати більше не потрібно, воно само і т.п.

Авторе, а як ви так прямо через абзац скаканули з функціонального на декларативне програмування?
Чи ви вважаєте, що це одне й те саме?

Ну і статистика використання мов говорить багато про що. Але виводити з неї напряму кількість задач які зручно вирішувати з допомогою ФП — ну дещо (сильно) притягнуто за вуха.

У статті ці підходи стоять поруч не тому, що вони однакові, а тому, що це різні способи мислення при розв’язанні задач — виражені у формі функцій, конфігурацій чи SQL-запитів.
Функціональний і декларативний підходи мають різну природу, але обидва можуть використовуватись для розв’язання конкретних задач, тому логічно розглядати їх поруч у контексті еволюції підходів до програмування.

Щодо статистики використання мов. Деякі мови програмування зручніші для певних парадигм, тож я допускаю що популярність мов відображає популярність відповідних способів мислення.

Мій особистий досвід, звісно, не статистика, але здебільшого бачу імперативний стиль, далі — об’єктний, а функціональні чи декларативні елементи застосовуються точково для окремих задач.

Якщо у вас є об’єктивніші джерела чи дослідження — з цікавістю почитаю.

ООП — теж доцільно використовувати для окремих задач, але це не ставить його на одну поліцю з SQL :).
FP так саме як і ООП — використовується для плюс мінус тих самих задач. Питання розповсюдженості ООП — то розпіареність і уявна «простота» порявнюючи з FP. Але ця простота — за рахунок того що власне ООП забезпечує набагато нижчий рівень абстракції, то стартувати можна дійсно швидше. Питання тільки в тому, що якщо домен більш менш складний — то для того щоб вийшло щось більш-менш mainainable — все одно потрібно буде застосовувати абстракції, які потрібно буде вивчати. І цих абстракції «з коробки» в ООП якось небагато.

Про те і мова, ці обмеження виключно на рівні уявлень окремої людини. Навчитесь думати по різному, у вас буде більше можливостей в рамках наявних інструментів. Ось наприклад, github.com/cedardb/DOOMQL — DOOM на SQL :)

ммм, пахне 90ми, С/С++ за 24 часа і отето вот всьо:)
Якщо чесно, ооп не має чіткого визначення. Принаймні я його так і не знайшов.
Також додам, всі думають, що ооп це інкапсуляція, наслідування і поліморфізм, але виявляється, що це візітор, декоратор, фабрика і стратегія. І це правильно, бо насправді має значення не те, що собою являє об’єкт, а те як і з чим його комбінувати.

Якщо чесно, ооп не має чіткого визначення.

+100500, тепер на додачу до визначень за Кеєм, Бучем, Маєром та іншими (Страутрп та Барбара Лісков ще теоретизували) треба додати ще одне від Павла Лущика:

але виявляється, що це візітор, декоратор, фабрика і стратегія

візітор паттерн то «лише вивернуте наізнаку наслідування» ))

Й далі треба «розкомувати» в напрямку «Експрешен проблем» (в чудовій статті від Eli Bendersky)

а «декоратор», «фабрика» і «стратегія» такі як в «класичній» книжчі GoF, то лише воркераунди довкола того, що в 1994 в «мейнстрімних» мовах не було «функцій першого класу»))

Чи значить то, що «декоратор», «фабрику» і «стратегію» не треба називати «своїми іменами» — ні.
Най й далі будуть «декоратор», «фабрика» і «стратегія»
тільки реалізовувати через "ламбду"/"делегат"/"кложур"/std::function<>/Function<>/Action<>, а не методами з минулого століття))

+100500, тепер на додачу до визначень за Кеєм, Бучем, Маєром та іншими (Страутрп та Барбара Лісков ще теоретизували) треба додати ще одне від Павла Лущика:

Добавь еще от меня определение. ООП это парадигма мышления в терминах классов и объектов. Остальное прикрученные фишки их несть числа.)

ну короче в хацкелі є класи. щодо об’єктів не впевнений, але instance присутній:)

Як доречі ваша машина Кузьміна поживає?

Погоджуюсь, для того щоб щось моделювати — потрібно щоб то чим моделюєш мало якісь властивості, які можна співставити з властивостями того що моделюєш. А «інкапсуляція, наслідування, поліморфізм» — самі по собі не мають майже ніяких властивостей та не слідують ніяким формальним законам. Тобто реалізовано там може бути абсолютно що завгодно, воно може бути неконсистентне з точки зору логіки.
Патерни ООП — теж не дуже допомагають, бо теж не мають формального опису. Хочаб в стилі «якщо зробите те те і те і переконаєтесь що в вашій реалізації нема того і того — то це реалізація visitor, decorator, whatever патерна. І тоді з цього слідує те, те і те». Єдине що декларується — щось типу в таких-то випадках можна використати патерн А, а в таких то Б. А що з цього слідує? А нічого. Ну можливо у вас код стане простішим, але це не точно.
Тобто, за великим рахунком, все ООП — це така собі реалізація модулів. Бо глобальний стан і контекст — погано, давайте запхаємо його по коміркам. І це потрібно. В деяких випадках. Але казати що це якась фундаментальні основи якими можна підперти все... Та камон — це набір якихось ремісницьких прийомів, типу цвіх — забиваємо, шуруп вкручуємо, дивись не переплутай.

ООП це реально найкраще , що було придумано. Це універсальний метод якщо проєкт це щось більше ніж скрипт на одну команду

Саме тому в ядрі Linux немає жодного натяку на ООП. ;)

Це універсальний метод

Універсальний не дорівнює ідеальний. Це скоріше щось опосередковане.

Саме тому в ядрі Linux немає жодного натяку на ООП. ;)

І довго цей міф буде розповсюджуватись?
Обʼєкти — є. Наслідування інтерфейсів реалізаціями — є. Віртуальні функції — є. Вже достатньо.
Нема наслідування реалізації і обмежень видимости при інкапсуляції. Ну так і без них нормальне ООП.
Ви спробуйте якось заглянути в сорці...

Тоді визначення ООП це одна єдина фіча: вказівник на функцію. І воно було ще в Unix 50 років тому. А визначення ООП зводиться до все гарне проти всього поганого: якщо щось має успіх, там обов’язково можна знайти елемент ООП.
Якщо читати Греді Буча, то наслідування реалізації він вважав обов’язковою ключовою рисою. Без неї не ООП за його визначенням. Причому саме реалізації, не просто інтерфейсів.
Але йдуть роки, зараз наслідування реалізації вважається чи не антипаттерном (composition over inheritance), а ООП начебто нікуди не поділось.

Тоді визначення ООП це одна єдина фіча: вказівник на функцію.

На яку з? Я цього не зрозумів. Якщо мова про факт виклику віртуальної функції через вказівник, може бути інший варіант. Я бачив ООП з віртуальними функціями на bash, коли виклик йшов по імені. Але навіть це не однозначна ознака.

Якщо читати Греді Буча, то наслідування реалізації він вважав обов’язковою ключовою рисою.

Є визначення за Граді Бучем.
Є за Аланом Кеєм.
Є ще за кимось.
Варіант Буча зрозумілий, але він занадто орієнтований на конкретний стиль. Я підтримую цей стиль (і вважаю спроби його заборонити, як в Go, марними), але і те, як роблять те ж ООП в інтерфейсі ядра, теж має право на існування.

До речі, я взагалі вкрай мало чую про Граді Буча після ≈2005 року. Якось його наробки вийшли з масової уваги.

І довго цей міф буде розповсюджуватись?

Дуже просте запитання. Два.

  1. На якій мові написане ядро Linux?
  2. Чи є в цій мові обовʼязкові атрибути ООП мови, на кшталт декларації класів?
Обʼєкти — є.

Якщо ми будемо будь-які структури називати обʼєктами, то можемо легко упоротися та дійти до висновку, що HTML — це ООП мова програмування.

Вже достатньо.

Ніт.

Ви спробуйте якось заглянути в сорці...

Є купа підходів в не-ООП мовах програмування, які можуть вважатися за такими, що схожі на класичні ООП-шні. Але тоді можна так само сказати, що ООП це трохи ускладнена процедурщина.

Чи є в цій мові обовʼязкові атрибути ООП мови, на кшталт декларації класів?

Нема. Що далі? Якщо ви вважаєте, що від цього в ядрі нема ООП, ви помилились.

Дуже просте запитання. Два.

Які не мають жодного відношення до дійсности.

то можемо легко упоротися та дійти до висновку, що HTML — це ООП мова програмування.

Програмування — ні. бо нема коду. Опису — коли будуть довільні теги і атрибути. Тобто HTML — ще ні, XML — да.

Ви впали в демагогію, значить, аргументи кінчаються.

Є купа підходів в не-ООП мовах програмування, які можуть вважатися за такими, що схожі на класичні ООП-шні.

Важливо не яка мова, а як написана програма. Мова тут може дуже допомагати, частково допомагати, хоча б не заважати, частково заважати, сильно заважати.
C частково заважає, але все одно писати на ньому в ООП можна і часто де треба.

Для порівняння: на JavaScript писали задовго до класів в ООП стилі навіть з реальною інкапсуляцією (чого C не дає).

Але тоді можна так само сказати, що ООП це трохи ускладнена процедурщина.

В мінімальних формах так і є. В серйозних розділення на сутності, привʼязка коду і даних до них, барʼєри доступу до не-свого (інкапсуляція), інші ідейні компоненти ООП переводять на новий якісний рівень, після якого «процедурщина» стає абсолютно неадекватним означенням.

Які не мають жодного відношення до дійсности.

Чому це? Ще й як мають.

Програмування — ні. бо нема коду.

В сучасних браузерах HTML є нічим іншим ніж кодом. Тоді на будь-яку трансльовану мову можна сказати, що там немає коду. Просте запитання, чим якийсь відрізняється від HTTP колу з наступним парсингом даних та ствтренням пари сотен інстансів класів? Нічим. Це макрофукнція, навіть параметризована.

Важливо не яка мова, а як написана програма.

Важливо не як написана програма, а які сутностями, абстракціями та їхньою взаємодією оперував розробник під час її написання. І тут виникає наступне запитання. Мова програмування не дозволяє робити інкапсуляцію. Але я прийняв рішення використовувати щось схоже на це в своєму коді. Чи значить, що я пишу в ООП стилі? Я так не вважаю. Тому що тоді ніякого ООП стиля не існує. Це лише мікс з інших підходів, які зʼявилися набагато раніше.

Для порівняння: на JavaScript писали задовго до класів в ООП стилі навіть з реальною інкапсуляцією (чого C не дає).

Що таке ООП стиль? Які його основні ознаки? Ми ж дорослі хлопчики, мусимо чітко визначати сутності перед тим, як про щось сперечатися, щоб потім не було, що один про сіно, а інший про солому...

В серйозних розділення на сутності

Сутності — це віртуальна річ. Структура даних плюс пара процедур, які забезпечують додавання, зміну та видалення, можна вважати класом. Інкапсуляція — це лише домовленість, що без дозволу лізти куди не треба не варто. Але, в ООП мовах програмування ці правила внесені в синтаксис самої мови та трохи контролюються компілятором чи інтерпретатором. Але це ніяк не робить інкапсуляцію унікальною властивістю виключно ООП підходу. Її можна легко зробити й в процедурному підході (правда не на рівні синтаксису)

після якого «процедурщина» стає абсолютно неадекватним означенням.

Ок, давай дамо визначення процедурному стилю програмування тоді.

В сучасних браузерах HTML є нічим іншим ніж кодом. Тоді на будь-яку трансльовану мову можна сказати, що там немає коду. Просте запитання, чим якийсь відрізняється від HTTP колу з наступним парсингом даних та ствтренням пари сотен інстансів класів? Нічим. Це макрофукнція, навіть параметризована.

ем... а відколи це в чистому HTML можна знодувати якийсь «інпут» так, щоб та вся машинерія наявними засобами «обчислила» аутпут? Те, що бравзер юзає якіто ООП структури й код ніразу не значить, що ми змогли б йому підіпхати такий HTML який заставив би бравзер робити якісь задані нами обсислення...

вірніше — а відколи це HTML Тюрінг компліт? Мова про чистий HTML, як на ньому «описати обчислення», й порахувати умовний факторіал, чи роздрукувати числа Фіборачі, не вхардкоджуючи їхні значення?

ось sed «раптом» Тюрінг компліт, ну чи там C++ темплейти, ага..., чи навіть Conway’s Game of Life...
А на HTML як зробити то?

ем... а відколи це в чистому HTML можна знодувати якийсь «інпут» так, щоб та вся машинерія наявними засобами «обчислила» аутпут?

Ви хочете обмежити мову таким чином, щоб обовʼязково натягнути сову на глобус. Але текст будь-якої програми нічим не відрізняється від HTML. Тобто, при наявності спеціального транслятора можна HTML перетворювати на мову програмування. Саме так я роблю у власному фреймворку. Я тупо «програмую» на HTML. В мене є , . Чим не мова програмування? ;)

що ми змогли б йому підіпхати такий HTML який заставив би бравзер робити якісь задані нами обсислення...

Які саме обчислення ви маєте на увазі?

Але текст будь-якої програми нічим не відрізняється від HTML

що значить «нічим не вдрізніється»?

Звісно що можна розглядати теги як «виклики процедур» й «таке саме» можна було б зробити на «справжній мові» (тій, що «Тюрінг компліт», ага),
А от навпаки, на HTML запрограмувати «бабл сорт» не вийде, бо нема рекурсії/циклів/галуження...

(тут би згодилося «наукове визначення» для «Тюрінг компліт», але воно ще менш зрозуміле ніж «побутово/інтуітивне»)

Які саме обчислення ви маєте на увазі?

таке, щоб реалізовуло якийсь алгоритм, що за інпутами «обчислює» аутпути (й без CSS ага)

як HTML порахувати факторіал для довільного числа, чи там числа Фібоначчі?
не обов’язково прямим текстом/числом у вікні бровзера, най (хоча б) пропертями тегів, кольорами бекграудна, координатами елементів... їхньою кількістю

як HTML порахувати факторіал для довільного числа, чи там числа Фібоначчі?

Я вже казав, вам ніхто не заважає зробити свій транспайлер з однієї мови на іншу. Тобто, візуально це буде все той самий HTML, але під капотом буде кипіти робота.

А от навпаки, на HTML запрограмувати «бабл сорт» не вийде, бо нема рекурсії/циклів/галуження...
<foreach from="arr" item="a">
<value>a * 10</value
</foreach>
Ось така конструкція використовується в моєму фреймворку.
Ось така конструкція використовується в моєму фреймворку.

нє нє, «ета другоє»,
треба щоб «штатний», «рідний» HTML виконувався самим штатним бравзером, без JS/CSS, плагінів та допилів...

А якщо фреймворк інтерпретує HTML, то це вже «нето» ))

(десь тут поруч XSLT та решта штук...)

Ви коли востаннє спеку HTML дивилися? Вона повна різними JS інтерфейсами, як то LocalStorage, або різного типу воркерів.

Вона повна різними JS інтерфейсами, як то LocalStorage, або різного типу воркерів.

ну але ж сам HTML не може до неї звернутися, ага...

<foreach from="arr" item="a">

без прикрученої збоку додаткової ЖС машинерії — не робе

Без інтерпретатора або компілятора ваш код теж нічого не робе. То знайдіть мені хоча б одну відмінність від мого коду та вашого. ;)

Звичайно, але тоді треба так і написати
-> «новий інтерпретатор/компілятор/фреймворк від Олександра Шпака перетворює HTML конструкції на виконуваний код» (бо, без отого самого «інтерпретатора» на стандартному бравзері, без тих доліпок, що їх задизайнив Олександр Шпак виконати кастомні конструкції придумані Олександром Шпаком не вийде))

Це ж комон сенс, без компілятора або інтерпретатора ваш код — лише текстові файли. ;)

Це ж комон сенс, без компілятора або інтерпретатора ваш код — лише текстові файли. ;

Звичайно, ну от до сих пір HTML не мав такого «компілятора або інтерпретатора» (всякі примочки типу Vue та їхні «трюки» не рахуємо), тому стандартний HTML бравзером «виконуватися» в плані «Тюрінг комплітнес» ніяк не міг...

Тепер ми встановили, що той пан написав якуто «примочку» (фреймворк) й тепер може виконуватися за спеціально придуманими тим паном тегами. Це прекрасно :)

стандартний HTML

Ось тут криється нюансик. Якщо взяти якийсь HTML 4.x, то так. Але HTML 5 вже розширив свою зону «відповідальності» також на JS, та ще й продовжує додавати різні нові API. Використання цих API в JS є нічим іним як використанням HTML :D Хоча це й звучить дивакувато.

Але HTML 5 вже розширив свою зону «відповідальності» також на JS

ну але без ЖС він «сам по собі» ніяк виконуватися не зможе))

та ще й продовжує додавати різні нові API. Використання цих API в JS є нічим іним як використанням HTML :D Хоча це й звучить дивакувато.

ну але реалізувати тільки HTML тегами цикли/функції/кондішени/рукурсую не вийде, доки ми не додамо ЖС примочки від того пана...

тобто мова на HTML тагах без ЖС не є «Тюрінг компліт», ну ніяк не натягти сову на глобус...

а от вже ЮHTML + CSS «при певних умовах» вже «Тюрінг компліт» навіть без JS хоча й така «комплітнес», як приклади там, воно й виглядає доволі юзлесс як й всі решта «брейнфаків»))

(десь тут поруч XSLT та решта штук...)

Off topic. За XSLT я б окремий котел в аду поставив... Хоча XPath та XQuery — янгольські технології!

Вначале мой язык был теговый. Позже до меня дошло что теги совершенно лишнее. Никакого смысла в них нет с точки зрения синтаксиса. Все прекрасно транслируется и без них.

Теги дають певну перевагу. Це DOM та купа методів по роботі з ним. Замість того, щоб писати синтаксичний аналізатор, який жере дофігаліард ресурсів, теги можна перебрати рекурсивно та дешево, а половину роботи взагалі зроблять розробники браузерів за тебе, оптимізуючи код браузера та пришвидшуючи стандартні функції.

За 10 років мій код став працювати швидше без жодного капіталовкладення з мого боку. Гарно ж!

Теги дають певну перевагу. Це DOM та купа методів по роботі з ним. Замість того, щоб писати синтаксичний аналізатор, який жере дофігаліард ресурсів, теги можна перебрати рекурсивно та дешево, а половину роботи взагалі зроблять розробники браузерів за тебе, оптимізуючи код браузера та пришвидшуючи стандартні функції.

То це той пан перевинайшов XSLT Lisp, тілки не на «S-Expressions» а на HTML тегах, й з АПІшкою готовенького DOM замість ліспівських car/cdr

Лінк на новий фреймворк «в студію»!

Я стару версію зніс, працюю над документацією до другої версії зараз, як буде реліз — сповіщу.

в не-ООП мовах програмування

що таке «не-ООП мови» програмування? це ж лише ті, на яких оте саме ООП просто робити незручно... але «програмувати в стилі ООП» з «інкапсуляцією» (через неймінг конвеншени), «наслідуванням» (наприклад включення структуток), «поліморфізмом» (так так, через поінтери на функції й заповнення вручну структурок «аля VMT») можна не лише на «няшній Сшці», а й на асемблері, й навіть на бінарних кодах вкодовуючи зміщення полів вручну...

Також й після компіляції <тут_ваша_улюблена_ООП_мова> в «бінарник», оте «правильне ООП з уоюбленої ООП мови» воно нікуди не зникає, й далі продовжує юзатися як запускається та аплікуха...

що таке «не-ООП мови» програмування?

Будь-яка мова програмування, яка за замовчуванням не оперує обʼєктами, класами, не має синтаксичного цукру для поліморфізму, наслідування та інших атрибутів ООП.
Якщо упоротися, то ніякого ООП не існує. Процесор гадки не має про жодну з високорівневих концепцій, тупо виконує код за інструкціями, які розуміє, щось там в памʼять зберігає, читає. Обʼєкти? Змінні? Перший раз чую. Для якогось там ALU навіть немає різниці, звідкіля дані взялися, з кеша чи памʼяті.

Будь-яка мова програмування, яка за замовчуванням не оперує обʼєктами, класами, не має синтаксичного цукру для поліморфізму, наслідування та інших атрибутів ООП.

а що ООП існує тільки в «синтаксичному цукрі»?
а відкомпільована програма вона вже не викликає методів через VMT?
поки ми юзаємо «COM об’єкти» на С++ то вони є об’єктами, а коли ми їх створюємо з DLL то вже нє?

Якщо упоротися, то ніякого ООП не існує. Процесор гадки не має про жодну з високорівневих концепцій, тупо виконує код за інструкціями, які розуміє, щось там в памʼять зберігає, читає. Обʼєкти? Змінні? Перший раз чую. Для якогось там ALU навіть немає різниці, звідкіля дані взялися, з кеша чи памʼяті.

«Процесор гадки не має», «. Для якогось там ALU навіть немає різниці», бо воно не має свідомості))

А ООП можна вкодовувати хоч на C, хоч на асемблері, а хоч й машинними кодами))

а що ООП існує тільки в «синтаксичному цукрі»?

А що, є бодай один CPU, який розуміє класи та іншу оту всю «магію» ООП?

а відкомпільована програма вона вже не викликає методів через VMT?

Що таке метод? Яка інструкція за нього відповідальна?

А ООП можна вкодовувати хоч на C, хоч на асемблері, а хоч й машинними кодами))

Можна. Тільки відрізнити ООП від не-ООП буде доволі важко. Візміть будь-яку програму та спробуйте по її бінарнику дізнатися, в якому стилі там її вкодували.

А що, є бодай один CPU, який розуміє класи та іншу оту всю «магію» ООП?

та вони навіть процедур процедурного не розуміють, коли оте от

BX LR
Що таке метод? Яка інструкція за нього відповідальна?

і не треба ніяких інструкція для метода))

Можна. Тільки відрізнити ООП від не-ООП буде доволі важко. Візміть будь-яку програму та спробуйте по її бінарнику дізнатися, в якому стилі там її вкодували.

Ну можна ж робити «ООП» на асемблері, отож, якщо дизасебмлювати, то це з буде ООП тільки зі зміщеннями замість назв полів чи віртуальних функцій))

А якщо мова за умовний .NET то воно взагалі декомпілюється офігенно))

>Процесор гадки не має про жодну з високорівневих концепцій
iAPX 432

треба йти навпаки,
там де

BX LR
замість ret, то, що, отже ніяких «процедур» не існує? процедурного програмування не існує? ))

та нє, пан Шпак про це ж і пише. ніби на рівні асм немає ніяких процедур і тим більше об’єктів. хоча він напевно не здогадується, що фактично асм формує монаду стану ліл.
доречі, я колись розмірковувам про цей лінк реджістер. можна вважати, що будь який call це такий собі goto з параметром. у конкретно call цей параметр адреса повернення. але є два але. 1. ця адреса може бути не обов’язково адресою наступної інструкції. 2. це може бути не адреса взагалі. цікаво було б знайти в літературі, чи має це якесь використання.

ніби на рівні асм немає ніяких процедур і тим більше об’єктів

Які інструкції за це відповідають?

ой, ну всьо. ну наприклад усі. процессор інкапсулює регістри і інтерфейс до памп’яті, інструкції — методи. кожен наступний процесор насідує попередній. проци різних виробників поліморфні.

процессор інкапсулює регістри і інтерфейс до памп’яті, інструкції — методи. кожен наступний процесор насідує попередній. проци різних виробників поліморфні.

Оно то так. Есть только один нюанс. Распределение регистров (если процессор с регистрами) происходит на уровне транслятора подразумевая что процессор единственный.

і інтерфейс до памп’яті

Який такий інтерфейс? З точки зору процесора інтерфейс це шина, що Infinity Fabric, що QPI.

інструкції — методи

А чому не функції, команди, процедури? Як ви так хитро визначили, що це саме методи?

кожен наступний процесор насідує попередній

Вибачте, це взагалі якась маячня. Набір інструкцій може залишитися без змін, бути розширеним або зменшеним від покоління до покоління. Різні процесори можуть підтримувати різні набори інструкцій, навіть різні ядра в рамках одного кристала можуть мати різну підтримку.

проци різних виробників поліморфні.

Ага, якийсь ARM та x86. Або RISC-V.

>З точки зору процесора інтерфейс це шина, що Infinity Fabric, що QPI.
правильно. абстракція. інтерфейс з методами прочитатиї/записати
>А чому не функції, команди, процедури? Як ви так хитро визначили, що це саме методи?
тому що інструкції оперують внутнішнім станом процесора.
метод до речі по суті фукція, у який є схований параметр.
>Ага, якийсь ARM та x86. Або RISC-V.
ні. i3 і щось від амд. два проца, але з т.з. коду — однаковий. поліморфізм.

інтерфейс з методами прочитатиї/записати

а выполнить? шина команд же...

В шині немає команд чи даних. Там все дані.

Команди будуть на вході в декодер, прийдуть з L0 instruction cache в більшості архітектур.

В шині немає команд чи даних. Там все дані.

Спорить не люблю. Тем более, теоретически в архитектуре фон Неймана оно так объявлено. Только практически оно не так. У большинства как раз шина команд отдельно от шин данных.

Про яку саме шину йде мова?

clk : in std_logic;
rst : in std_logic;
r : in std_logic;
w : in std_logic;
addr : in std_logic_vector(31 downto 0);
datai : in std_logic_vector(31 downto 0);
datao : out std_logic_vector(31 downto 0);
ready : out std_logic;
не тут команди?

Я уже понял что здесь продвинутые программисты. Чисто для подумать оператор Go to addr читает или записывает в ячейку addr ?

правильно. абстракція. інтерфейс з методами прочитатиї/записати

Ви не можете керувати цими «абстракціями» від слова зовсім. Там немає звичного вам «записати» чи «прочитати». Є сигнал такту, під час цього в шину може бути щось записано або прочитано з неї в залежності від того, кому призначений адресат та що зараз знаходиться в шині в кожного з адресатів. В кільцевих шинах дані передаються кожен такт від одного адресату до іншого по колу.

тому що інструкції оперують внутнішнім станом процесора.

Яким саме? Які стани процесора вам відомі?

ні. i3 і щось від амд. два проца, але з т.з. коду — однаковий. поліморфізм.

О, почалися умови висуватися. Ви в курсі, що сучасні компілятори створюють при певних параметрах компіляції декілька реалізацій коду для різних архітектур в одному бінарнику? Полуморфізм якийсь...

>Там немає звичного вам «записати» чи «прочитати».
mov reg, mem, mov mem, reg. ld st для ріск. це і є записати прочитати. у мене зараза на другому моніторі vivado відкритий з проектом для zynq. у мене є сумніви, що ви мені щось нове розкажете про шини.
>Які стани процесора вам відомі?
один 32 бітний регістр має 2**32 станів.
> Ви в курсі
в курсі. але яке це має відношення до того, що два процесора різних виробників можуть реалізувати один іса?

Вибачте, до чого тут ШИНА чи ІНТЕРФЕЙС CPU? Ви розумієте, що той перелік команд, що ви навели, не стосуєтся взагалі цих двох термінів, що я наводив раніше (IF та QPI).

у мене є сумніви, що ви мені щось нове розкажете про шини.

Ви взагалі про архітектуру CPU гадки не маєте, бо ви дивитеся виключно в код. Шина процесора обслуговує комунікацію між ядрами, контроллером памʼяті, періферією, забезпечує кеш-когерентність. Коли ви в коді даєте команду прочитати щось з комірки памʼяті, то CPU може не робити цієї дії взагалі, бо дані вже є в шині. Читання з шини при деяких реалізаціях взагалі запис. Тобто шина вивантажує дані в кеш CPU, а не ядро «читає» щось.

один 32 бітний регістр має 2**32 станів.

Яке примітивне розуміння побудови CPU...

в курсі. але яке це має відношення до того, що два процесора різних виробників можуть реалізувати один іса?

Можуть. Але чи однакові реалізації? Для вашого спрощеного випадку це дійсно так і є. На практиці кожна архітектура має власні особливості, наприклад в одній команда множення двох 64-бітних FP чисел займає 18 тактів, а в іншій — лише 12. Або дозволяється робити два складання 32 бітних INT за такт.

Аргументи закінчилися? Не дивно.

аргументи про що? що саме ви намагаєтеся довести?

Цікаве звірятко. Але, чи є там хоч щось про ООП? Чи про функціональне програмування?

глянь даташит, там нічого крім ооп немає. наміть gc прикрутили.

Що саме ви називаєте там ООП?

це не я називаю. це його розробники так стверджують. сперечайтеся з ними будь ласка.

9.2 Segments and Objects

The concepts of object-based computing are deeply imbedded in the Intel 432. All system resources are represented as objects; for example, a processor object maintains the state of each GDP or IP in the system. Each processor object then contains a queue of process objects, which represent work to be scheduled and executed. All objects are addressed through capabilities which, on the Intel 432, are called access descriptors (ADS). (The vendor’s terminology is used in this chapter for compatibility with Intel literature. The notation “AD” is used throughout for “capability.”)

At the lowest level, objects are composed of memory segments, and a memory segment is the most fundamental object (called a generic object on the Intel 432).

Навіть в документі вони просто хайпають на назвах. Під капотом там все ті ж сегменти памʼяті, розділення даних та інструкцій, черги, шини. Але баззвордів на кшталт object-based computing — маса.

кекл. так можна довести все для всього. наприклад:
в спп під капотом plain old data з вказівниками на якісь шмати коду, які щось роблять. ооп там лише баззворд и профанація. ніякого ооп в спп немає.

Саме тому я постійно прошу дати визначення ООП, щоб не було різночитання. Поки що я чув одне від Андрія Севастʼянова. Ви або даєте власне, або погоджуєтеся з наведеним ним.

що таке «не-ООП мови» програмування?

Мені подобається ситуація, яка була наприкинці 90-х, тоді все було просто. Було три кита ООП: інкапсуляція, наслідування, поліморфізм. Мова вважалася ООП, якщо дозволяла описувати класи (сукупність полів та методів), дозволяла обмежувати видімість в середині класа (інкапсуляція), дозволяла наслідуватися від класів (наслідування), дозволяла перевизначати функції у класі (поліморфізм). Таким чином C++, Delphi, Java це ООП мови, Сі не ООП.

Сучасне визначення ООП розмите до беззмістовності, по суті є вказівних на функцію, є ООП. Haskell раптово теж стає ООП, бо є датакласи. Тому я його просто не сприймаю.

наприкинці 90-х

то часи OLE та ActiveX... навіть для Сшки існували інструкції як проімітувати COM об’єкти, то це ж таки було ООП, хіба ні?

Таким чином C++, Delphi, Java це ООП мови, Сі не ООП.

C++, Delphi, Java то мови на яких зручно робити ООП
на Сі — незручно, але то не значить, що «неможливо»

Сучасне визначення ООП розмите до беззмістовності

+100500

COM скоріше бінарний інтерфейс для взаємодії між різними мовами. А так знову, наслідування немає.

так наслідування, воно ж «за Бучем», а тепер мода на «агрегація замість наслідування»...
але навіть «тоді» всі оті COM, OLE, ActiveX (а також всяке CORBA) то для тих, хто цим займався було «Тру ООП» в його найдосконаліцій формі...

(Оффтоп: найкращою з всього була можливість заюзати веббразвер контрол... то було чудовим способом «зачитерити» й оминути весь мазохізм MFC/ та тих всіх «челенджів» гуі програмінга під вінду, й так як M$ всюди пхала IE, то цей трюк всюди працював, й не треба було разом з аплкухою тягти за собою цілий веббравзер у вигляді електрону)

M$ всюди пхала IE, то цей трюк всюди працював, й не треба було разом з аплкухою тягти за собою цілий веббравзер у вигляді електрону)

точно, перспектива тягати за собою цілий віндоус замість браузера — вигладала би чудово)

ну сьогодні по факту кожен чатік якраз й тягне за собою браузер у вигляді «електрону»...

а «тоді» можна було юзати штатний IE, який в тій вінді вже був готовенький, й то все виглядало наче «нативна аплікуха»))

...для Лінуха в «той час» робити «кросплатформенні аплікухи» ще було не настільки «модно»...

а щодо необхідності «щось тягти з собою» насправді навіть під Лінухами це є досі проблемою, бо інакше навіщо було винаходити appimage/flatpack/б-гомерзький snap?

Я, звісно, всіма руками й ногами за flatpack))

а «тоді» можна було юзати штатний IE ... у вінді

Ща, штатний.. IE.. хфантастика...

Для гарантування секюрності, рантайм, сумісності та якої-небудь версіон-фічастості — наймовірніше запускали би у віртуалці віндовс-у-віндовс.

Як бонус — кросплатформено, та крім того підтримка та розвиток суміжних галузей по виробництву пам’яті та проців.
Суцільні профіти.. майже з усіх аспектів, тому агреговано і без варіантів — булоб тільки віндос-у-віндос рішення.

навіщо було винаходити ... flatpack/snap?

Гарантований рантайм, плюс зновуж додаткова секюрність, крос-використання, та більш легке рішення ніж замотані в докер. Перспектива — в рамках immutable os використання в store стайл. Одним словом з усіма pros and cons ознайомтесь архітектурно нп з андроїд.

Для гарантування секюрності, рантайм, та якої-небудь версіон-фічастості наймовірніше

про що той пан пише? про які такі сценарії?

я описую цілком собі реальний й впроваджений кейс, де тула юзала штатний IE через «веббравзерконтрол» станом на «майже 20років тому» й «все працювало» не лише на XP а й навіть на «Вісті»))

й то все до всіх отих електронів та реакт нейтівів :)

й ніяких «віртуалці віндовс-у-віндовс»...
мало того «сторінки» та «картинки» були зашиті прямо в тулу як «ресурси» й до них можна було звертатися прямо з сторінок як res://чототам (так званий «res:// Protocol»).

й то все працювало «з коробки» без ніяких «контейнерів» та «віртуалок», й IE не треба було пакувати разом в інсталер! :)

«відкрив Америку» що таке було можливо ще тоді?

а ще ж були «HTA аплікації», що запускалися з кліка, й могли юзати new ActiveXObject й «розгортатися» в файлову систему, дьоргати DLLки, ага... тобто існував не тільки мазохізм MFC/ATL/WTL а й цілком собі інший світ альтернативних солюшенів, що часом були й зручніші (хоч й не дуже відомі/популярні)...

А ще можна було юзати готовий скріптінг, той, що вбудований у вінду, бо cscript/wscript — теж присутні разом з віндою «з коробки», ага, й через ActiveXObject -> IDispatch інтергруватися з C++ними лібами...

не має прямого відношення до розвитку описаних вище рішень, одним словом — дос юзери напевно зацікавляться умовним «iєбравзерконтрол»)

Скоріше та концепція ООП провалилася. Але, щоб вийти зі скрутного становища, вирішили змінити визначення, та ще й так, щоб взагалі було незрозуміло що воно таке: додали ще абстракцію, що взагалі балабольство.

яка концепція? та, що COM? чи та що «за Бучем»?

COM «провалився», бо його частвково поховав .NET
(а частково й те, що «канонічний» COM був також наповнений бойлерплейтом)

А «за Бучем» й досі живе, наслідування реалізації не зникло, його в різній мірі й далі юзають, й не всюди воно «аж таке шкідливо»...

Я не про COM, я більше про наслідування реалізації. Так, його юзають, але не так активно, і не крізь.

звичайно, бо нема «срібної кулі», «універсального рецепту» і тд... то все «ООП», «ФП» воно не «одне vs інше» і не «проти процедурного», а скорше «набір прийомчиків», які можна використати залежно від ситуації, а от «відчути ситуацію» то вже більше «мистецтво» ніж «наука»...

так, саме тому в ядрі kobject усюди ліл.
також рекомендую вам глянути на file_operations struct, що це якщо не то, що в джаві називають інтерфейс

Інтерфейс є ознакою ООП?

У часи Греді Буча мова вважалася ООП, якщо дозволяла описувати класи (сукупність полів та методів), дозволяла обмежувати видімість в середині класа (інкапсуляція), дозволяла наслідуватися від класів (наслідування), дозволяла перевизначати методи у наслідниках (поліморфізм). Три кити ООП.

struct A_private {
  int a;
  int b;
};

struct A_public {
  unsigned char its_no_yours[sizeof(int)*2];
};

void A_method(struct A_public *x) {
  ((struct A_private *)x) -> a++;
}

struct B {
  struct A_public base;
  int c;
};

struct B *create_b(int a, int b) {
  struct B *ret = malloc(sizeof(struct B));
  ((struct A_private *)(&ret->base))->a = 2;
  ((struct A_private *)(&ret->base))->b = 3;
  ret->c = 4;
  return ret;
}
звісно, я так не писав, не пишу і не буду, і не рекомендую, але згідно визначення С — об’єктно орієнтовна мова.
є доречі pdf про те, як на С реалізувати все, що є в с++.
те, що ядро в дечому об’єктно орієнтовне я читав в книжці. щось типу internals of linux kernel чи якось так.

не відносно oop, якщо не дуже старостильно демонструвати то для читабельності щось типу
struct B re = { .base.a = a, .base.b = b, .c = c };
return memdup(&re, sizeof(re)); // memdup поза стд

згідно визначення С — об’єктно орієнтовна мова.
є доречі pdf про те, як на С реалізувати все, що є в с++.

Є неявне визначення, що мова вважається об’єктно-орієнтованою, якщо вона підтримує ключові принципи ООП (інкапсуляцію, наслідування, поліморфізм) на рівні самої мови, а не лише через патерни чи ручну емуляцію. Тому С не є ООП-мовою за дизайном, навіть якщо можна реалізувати схожі конструкції засобами мови.

А lisp — значить не ООП мова, якщо воно там реалізовано через multiple dispatch.
І чи гірший ad-hock поліморфізм реалізований через тайпкласи, нід реалізований через наслідування?
Чи можна щось більш розповсюджене взяти — той самий JS з їх prototype based ООП — воно достатньо відрізняється від того що в C++ чи Java.

Так, справедливо, межа між «об’єктно-орієнтованою» і «не об’єктно-орієнтованою» мовою не завжди однозначна.
Lisp із CLOS справді має об’єктну модель із multiple dispatch, а JavaScript — прототипне ООП. Але обидві мови вбудовано підтримують об’єктність як частину своєї семантики. Тобто це не «емуляція патернами», а механізм, передбачений дизайном мови.
У випадку ж C — мова сама по собі не має понять класу, об’єкта чи поліморфного виклику. Усе це можна імітувати через структури, вказівники на функції тощо, але це вже користувацька надбудова, а не властивість самої мови.
Тож питання не в тому, який саме вид поліморфізму (через наслідування, тайпкласи чи multiple dispatch), а в тому, чи є він складовою семантики мови, чи його треба реалізовувати вручну.

Це швидше емуляція ООП, я згоден, написано в ООП стилі. В принципі, на будь якій мові можна написати інтерпретатор іншої та писати в такому стиль. Асемблер взагалі і ООП, і функціональна, бо все скомпілюється в машинні коди.

Але в данному разі ми не використовуємо конструкції мови задля цього, а просто знаходимо хаки. Писати так незручно, так ніхто не пише.

Це швидше емуляція ООП, я згоден, написано в ООП стилі. В принципі, на будь якій мові можна написати інтерпретатор іншої та писати в такому стиль.
...
Писати так незручно...

звичайно що емуляція, ну але ж вся «комп’ютерна наука» й є про емуляцію/симуляцію, як один «обчислювач» виразити через інший «обчислювач» й в такий спосіб довести їхню «еквівалентність», й то ніразу не про «зручності юза»...

з різним ступенем мазохізма «ООП like» можна юзати в будь де!

... так ніхто не пише.

Чому ж не пише? пишуть, й вважають то «тру ООП», оце от все як приклад Course Shows How OOP Works Under the Hood та Application Note Object-Oriented Programming in C.

Й купа людей на різних проектах роками бавиться в «таке» ООП з отим розрекламованим qp фреймворком саме в його Сшній «іпостасі», й вважають саме це «тру істинно правильним» підходом для свого проекту, замість юзати нормальну ООП мову де все було б готовеньке й непотрібно було б отого мазохізму з бойлерплейтом VMTшок вручну через VPTR

як приклад Course Shows How OOP Works Under the Hood

Курси до чистий маркетинг для новачків, макуха.

звичайно що емуляція, ну але ж вся «комп’ютерна наука» й є про емуляцію/симуляцію, як один «обчислювач» виразити через інший «обчислювач» й в такий спосіб довести їхню «еквівалентність», й то ніразу не про «зручності юза»

Ну.. не вся, бо таких обчислювачів небагато, довести еквівалентність не складно. Але то не програмування, то математика. А для програмування достатоньо практичного підходу: наскільки це важко, наскільки так роблять.

Курси до чистий маркетинг для новачків, макуха.

Не важливо, головне що qp обирають менеджери, великі компанії, платять гроші за додаткові фішки/тули...
Навіть якщо в Сшному варіанті таке «ООП» та ще й з «проджект спесіфіками» то «каст на касті, кастом поганяє», й вжагалі жахливо незручно, але зато всі при роботі, всім є що робити, готовне продовжувати надувати щоки як все «по бест практісес»

А для програмування достатоньо практичного підходу: наскільки це важко, наскільки так роблять.

от я ж кажу qp фреймворк по факту — важко, але продовжують робити, й бізнес квітне в усіх))

спочатку дайте визначення ооп

будь-яке визначення OOP призводило до незгоди ким-небудь з тим визначенням, по ідеї настав час обговорювати вже саму парадигму парадигмування у програмуванні)

одним словом, «філософія — не наука» © викладач філософії у моєму вузі

з точки зору дослідження краще тоді:
метафізика — не [і далі по тексту]

Про логiчне програмування (Prolog, Mercury) начебто забули

І краще було б і не згадувати;\
Майже єдиний варіант Prolog, що вижив, зветься make. Інші опинились не потрібні. Де їх пробували вводити (наприклад, оцінки комітів в Gerrit), реакція 90+% користувачів була «викиньте каку і дайте щось процедурне».

З точки зору теорії, я згоден, воно цікаво — дає деяке логічне замкнення. Але йому краще б там і залишатись.

в цілому згоден. додам, що перші версії vm для erlang були на пролог. десь у 80х

Хмм.

> Коли до цього підходу додалася можливість групувати логіку у вигляді процедур і функцій, з’явився процедурний стиль програмування.

Процедурний стиль був значно раніше структурного. Років так на 10. До часів S/360 він вже був «загальним місцем».

Структурний стиль має причину не просто в якійсь відмові від GOTO. Відмова була потрібна для автоматизованої верифікації коду. Писати структурно можна було і на Fortran IV. І більшість вже так робила. Але, коли переходи не визначені явними відповідними словами для програми-аналізатора — для того рівня вирахувати, що тут цикл, а тут ранній вихід, було просто неможливо — рівень заліза не дозволяв. Приклад на малюнку це підкреслює, там проста зрозуміла логіка, тільки без відступів:) Я бачив і реальні плетінки, ось там було тяжко.

(Схожим чином, LISP був розроблений вперше в 1958-му, але залізо, на якому було б вигідно його запускати, зʼявилось тільки в 1970-х. І ще можна прикладів набрати.)

Це тільки в процесі впровадження усвідомили, що воно ще й дає, у більшости випадків, полегшення читання коду — і тоді структурний стиль почав входити в навчання.

І згадувати C у звʼязку зі структурним програмуванням недоречно, бо C ніяк його не форсував. Ба більше, тільки подивитись на Duffʼs device достатньо, щоб зрозуміти, що все там не так ;\

Є два різних ООП: активних обʼєктів (Simula, Smalltalk, в «емуляції» будь-яка система на акторах, наприклад, Erlang) і пасивних обʼєктів (C, C++, Java, C#, Python, JavaScript, тисячи їх). Коли волають що «Алан Кей писав зовсім про інше», змішують, навмисно чи ні, ці два типи.

> Замість наслідування Go використовує композицію, а поліморфізм досягається через інтерфейси. Це дозволяє писати код без надлишкової складності класичних ООП-мов.

Це можна було робити і на класичних ООП мовах, хоч на C++. Просто не створювати високі ієрархії наслідування. Я був на проектах, де їх не було, бо не було причини — і був на таких, де без багаторівневого наслідування можна було вішатись від складности. Штучна заборона наслідування реалізації — не краща ідея на рівні мови, мʼяко кажучи.

Ну і, по відгукам тих, хто пише на Go, щільність copy-paste там — в реальних галерно-корпоративних проектах — просто зашкалює. Тобто краще не стало.

З загальним висновком статті — принципово згоден на 101%. Не треба все лікувати молотком:)

Дякую за змістовний і детальний коментар!

Коли я говорю про історію парадигм чи технологій, то маю на увазі не момент їхньої появи, а момент поширення — коли ідея стала масовою.
Аналогічно з книгодрукуванням: можливість друкувати існувала задовго до Гутенберга, але саме його верстат започаткував епоху широкого використання друку, тому від нього й ведемо відлік.

Щодо процедурного програмування — згоден, сама ідея з’явилася раніше. Мова C лише зробила її більш практичною та зручною для масового використання. GOTO ніхто й сьогодні не забороняє, але його застосування — радше ознака поганого стилю, ніж інженерної необхідності.

Стосовно ООП — тут справді холіварна тема. Особисто я орієнтуюсь на поширене трактування ООП у сучасних мовах, де головний акцент — на наслідуванні як інструменті повторного використання коду. У цьому сенсі розробників можна умовно поділити на тих, хто вміє ефективно працювати з наслідуванням, і тих, хто його хейтить.

Щодо Go — повністю погоджуюсь: відсутність наслідування справді призводить до дублювання логіки.

Коли ми говоримо про технології, не можна відривати їх від людського фактору. Популярність часто визначає не лише технічна доцільність, а й маркетинг.
Достатньо згадати, що компанія Sun Microsystems витратила близько 500 мільйонів доларів на просування Java у перші роки її існування.

Загалом, стаття не про процедури чи класи, скільки про те, що, навчившись мислити по-різному й розуміти різні варіанти розв’язання задач, розробник отримує змогу вибирати найбільш оптимальний підхід у конкретній ситуації, незалежно від мови програмування.

Стосовно ООП — тут справді холіварна тема. Особисто я орієнтуюсь на поширене трактування ООП у сучасних мовах, де головний акцент — на наслідуванні як інструменті повторного використання коду.

Это все следствие более глубоких причин. Дело в том, что все естественные языки (индоевропейской группы) объектные. И наше мышление отсюда тоже объектное. Все остальное детские болезни ООП.

Киньте пожалуйста ссылку на то, где можно почитать про такую классификацию естественных языков. о гипотезе лингвистической относительности я знаю, а вот классификации обьектные, ... (какие еще?) не встречал.

сори. Не могу скинуть. Вся моя библиотека пропала после оккупации. Но, на память не жалуюсь. В семью индоевропейских языков входит большинство языков см. Здесьhttps://www.google.com/search?q=%D1%8F%D0%B7%D1%8B%D0%BA%D0%B8+%D0%B8%D0%BD%D0%B4%D0%BE%D0%B5%D0%B2%D1%80%D0%BE%D0%BF%D0%B5%D0%B9%D1%81%D0%BA%D0%BE%D0%B9+%D1%81%D0%B5%D0%BC%D1%8C%D0%B8&sca_esv=2e0bf73006d1ba9f&sxsrf=AE3TifMmtnoeNGToSr2xBXIP-y2D3qQ-rA%3A1760004104773&source=hp&ei=CIjnaM7sLLXAwPAPwP7r2AI&iflsig=AOw8s4IAAAAAaOeWGKh-UHzeFFAfFy2Wh-1Z754nSkgx&oq=%D1%8F%D0%B7%D1%8B%D0%BA%D0%B8+%D0%B8%D0%BD%D0%B4%D0%BE&gs_lp=Egdnd3Mtd2l6IhPRj9C30YvQutC4INC40L3QtNC-KgIIATIFEAAYgAQyBRAAGIAEMgUQABiABDIGEAAYFhgeMgYQABgWGB4yBhAAGBYYHjIGEAAYFhgeMgYQABgWGB4yBhAAGBYYHjIGEAAYFhgeSPa3AVCYC1jFZHAEeACQAQCYAY8BoAGMC6oBAzQuObgBAcgBAPgBAZgCEaACtgyoAgrCAg0QIxiABBgnGIoFGOoCwgIHECMYJxjqAsICDRAuGIAEGCcYigUY6gLCAgUQLhiABMICChAAGIAEGEYY-QHCAgwQABiABBgKGEYY-QHCAgcQABiABBgKwgIHEC4YgAQYCsICCBAAGIAEGKIEwgISEAAYgAQYsQMYgwEYDRhGGPkBwgIKEAAYgAQYsQMYDcICBxAAGIAEGA3CAgcQLhiABBgNwgIIEAAYgAQYywGYAwfxBaI4Wkeqm0eGkgcENC4xM6AH6H2yBwQwLjEzuAeODMIHBzAuMS44LjjIB4cB&sclient=gws-wiz. К не объектным языкам относятся языки индейцев.
Этой темой занимался когда начинал работать над созданием своего языка. Много литературы тогда прочитал. Это было лет 20 назад. Просто поверь. Или по гугли.

К не объектным языкам относятся языки индейцев.

Языки индейцев очень разные. Но то, что вы говорите, это скорее всего инкорпорирующие языки, в которых в одном предложении могут смешиваться части разных слов.
При этом там всё равно стандартная тройка subject, verb, object в каком-то выбранном порядке из множества возможных, только их обозначить бывает сложновато.
И не надо идти за океан, французский можно с хорошим основанием признать таким же инкорпорирующим.

Ещё вы могли прочитать про строй языка (в английском alignment). И тоже незачем гоняться за индейцами, ранний общеиндоевропейский был языком активного строя (active-stative alignment), наследие этого до сих пор можно разглядеть в некоторых фичах языков. Но в любом строе есть формы для агента, пациента, презента и прочих компонентов высказывания, только группируются они по-разному и с разными ограничениями.

Но то, что вы говорите, это скорее всего инкорпорирующие языки, в которых в одном предложении могут смешиваться части разных слов.

Я сказал то, что сказал. Не больше

— Маэстро, какие ваши творческие планы?
— Ну, я положил на музыку...
— В самом деле? Жаль, очень жаль...

Могу примеры привести. В английском перед объектом предлог The, перед классом a. В фразе каждый мужчина должен построить дом... Дом это класс.. А вот я живу в доме за углом, слово дом это объект. Сколько не говори «мед» во рту слаще не станет.. Здесь мед просто лексема.

В английском перед объектом предлог The, перед классом a.

Тогда далеко не все индоевропейские языки обладают таким различием.
В украинском вообще нет аналога артиклей на уровне грамматики. В русском есть только в диалектах и в рудиментах типа различения кратких и полных прилагательных. Считать в «Одну простую сказку, а может и не сказку...» «одну» за недооформленный неопределённый артикль — это банальность, но требования грамматики здесь нет.

Не надо спорить со мной. Мне это не интересно. Объектность не в артиклях. В определении места, времени и тп. Вот здесь подробнее.. cyberleninka.ru/...​tnost-i-logichnost/viewer

В украинском вообще нет аналога артиклей на уровне грамматики.

Чому це немає?

There is a book on the table: Ось моя кімната, ось мій стіл. На столі лежить книга. (ніколи у цьому контексті не скажеш книга лежить на столі)
There is the book on a table: Де є книга? Книга лежить на столі (на запитання про конкретну книгу ти ніколи не скажеш на столі лежить книга)

Ти природньо ставиш визначене на початок, невизначене у кінець.

(ніколи у цьому контексті не скажеш книга лежить на столі)

Якщо мова з самого початку йшла про цю книгу, то її поставлять на перше місце.

Ти природньо ставиш визначене на початок, невизначене у кінець.

І це не артиклі як частини мови або члени речення. Це саме порядок слів. Ця манера іде ще з загальної індоєвропейської, де теж артиклів не було (і взагалі як для нас була дуже дивна, там складних конструкцій, по типу object clause, в реченні взагалі не могло бути, слова в реченні були всі незалежні і розташовувались в порядку зменшення значення в висловлюванні... але це окрема тема).
І тут не визначене/невизначене. Тут є типовий порядок і нетиповий. Те, що ви сказали про «невизначене», це те, що пікреслюється як нова або принципова інформація. Підкреслення може бути зроблено зміною порядку, а може і інтонацією («Я те́бе кохаю» і «те́бе я кохаю», «я́ тебе кохаю» і «тебе я́ кохаю»). Не можна тут спрощувати.

Англійська майже не має зараз вільного порядку слів і таких інтонацій, і вони компенсують або довгими описами («Thatʼs me who loves you!»), або артиклями. (І не тільки вона, артиклі це типова риса десятків мов.)

Це знову диспут що є аналогом. В українській визначене/невизначене визначається порядком слів. А в англійській артиклями. Як на мене це аналоги, бо виконують одну функцію.

Мова C лише зробила її більш практичною та зручною для масового використання. GOTO ніхто й сьогодні не забороняє, але його застосування — радше ознака поганого стилю, ніж інженерної необхідності.

так, goto зазвичай легко розкручуються та замінюються в коді використанням інших конструкцій, що не скажеш те саме відносно longjmp який іноді використовують — чим у такому випадку пропонуєте його обходити конструктивно в сі?

longjmp який іноді використовують

де крiм драйверiв якихось?

В драйверах як раз longjmp використати складно. Це аналог виключення, але в драйвері зазвичай обмежений стек контексту, багато використання ресурсів (спінлоки, дескриптори, ...). Не кажучи про те, що через непередбачуваний стек викликів у kernel space маємо panic.

longjmp використовують скоріше в процесах з великою складною обробкою, щоб вийти у разі фатальної помилки: парсери/інтерпретатори (синтаксичні помилки), обробка медіа (пошкодження потоку), взагалі коли нам треба швидко вийти із глибокої рекурсії, де повернення кодів помилок через кожен рівень занадто громіздке.

нiколи не бачив якщо чесно.
Довге простирадло з попередженнями у доках так, запам’яталось)

Lua, ldo.c

Взагалі, оскільки перший С++ був транслятором до Сі, то дуже ймовірно, що виключення спеціально проєктувалися з можливостю реалізувати їх через longjmp. Кажуть що були компілятори під ARM, які так й робили. Звісно що зараз прийшли більш оптимальні методи.

А в сі паттерн такий

struct context {
    jmp_buf env;
    FILE *file;
    void *buffer;
};

if (setjmp(ctx.env) == 0) {
    process_something(&ctx);
} else {
    cleanup_context(&ctx); // close file, dealloc buffer, ...
}

Через longjmp завжди можна терміново вийти з process_something

А в сі паттерн такий

не зовсім такий, і не єдиний такий,
та й зовсім не катить якщо «по дорозі назад» треба робити клінапи ресурсам...

але головна «сумлька» полягає якраз в тому, що часом й далі майже отак буквально й пишуть (й навіть імітують «ексепшени» де «інформація для розкрутки» сториться в подобі «стеку» застореного в TLS, й ті ексепшени скачуть через стекфрейми окремих функцій, й то все загорнуте в пекельні макро, щоб виглядало «майже як С++»)...

інша (й, тоді вже значно краща від тих велосипедів) ідіома з goto Cleanup; де мітка в кінці процедури, й тоді еррор коди між функціями! й тоді в логи можна писати коди помилок не лише в місці виникнення помилки, й потім й де зловив, а й «по дорозі назад», й часом такий маразматично-параноїдальний підхід рятує при аналізі злих багів, коли проміжні стани мають значення))

грубо кажучи (не порушуючи NDA)

result_t якато_апішка(...){
    result_t res = ...;
    ... щось робимо

    res = якато_апішка(...);
    if( is_error_code(res) ){
        logger("все пропало на такомуто етапі", res);
        goto Cleanup;
        //а "return res" НЕ КАТИТЬ
        //бо треба поклінапити й решту ресурсів
    }
    ...

Cleanup: 
    if( такийто ресурс був засетаплений ){
        поклінапити той ресурс
    }
    ... і тд для всіх решти ресурсів
    return res;
}
Можна позбутися кондішеналів if( такийто ресурс був засетаплений ) якщо Cleanup міток зробити багато, й туди скачуть залежно від того, до яких ресурсів вже встигли дійти, тобто мітки в зворотньому порядку від порядку алокування ресурсів й далі руцями вкодовувати все приблизно то само, що робить компілятор для RAII...

...
або забити на «няшну Сшечку» й в «умовному С++» юзати готовий RAII + саморобний Maybe або ж std::optional/std::variant/std::expected/щось_типу_того ага... (й всі Пайтони та C# з їхніми with/using для RAII теж прокатять))

...
або й «забити ще більше», й якщо платформа дозволяє а libstdc++ не муляє, то й юзати звичайні C++ ексепшени (звісно з обов’язковим RAII, от чим С++ не вгодив, то відсутністю defer, й необхідністю або обгортати кожне унікальне гівнеце в клас, або ж юзати саморобний макрос defer, Boost.ScopeExit й подібне)...

... і тут бац, ми повернулися «на круги своя» до варіанту «майже як з longjmp» але тепер весь «пекельний бойлерплейт» не «руцями», а компілятором.

на що насправді треба вважати: не лише C++ні ексепшени не можуть перетинати меж бірарних модулів (втім, трюки з longjmp — також не можуть, бо ж «хз» як ми потрапили до цього коллбеку, який хоче longjmp «хзкуди» чераз коллстек в якому, в загальному випадку, «хзщо» перед ним, й не факт чи той коллбек взагалі з викликаний з того ж потоку, який робив setjmp для того jmp_buf куди ми скачемо... которше варіантів спагетті комбінаторного вибуху «як можна натупити з саморобними ексепшенами» — море)

в абсолютній більшості випадків які зустрічалися goto cleanup забирається якщо причесати той код, тобто опціональний у використанні на полякати піпл не знайомих з умовним «фортран» стайл)

в такій «абсолютній більшості» й longjmp тим більше непотрібен))

(він має своє місце тільки там, де пекельні трюки в стилі «корутин через longjmp», що, втім, також є непортабельно/UB)

то інша тема по якій вже проїхалися вище, та десь доволі рідко кимось може і використовуються в зовсім інших патернах ніж звичні «пекельні трюки goto cleanup», тобто не перегоутушнюйте — бо то пишуть що некращий стайл)

проїхалися вище

нижче)) вже дочитав й туди...

в загальному погоджуся з дописами шановного добродія Valentin Nechayev :)

проїхалися вище

нижче)) вже дочитав й туди...

просторово-часовий релятивізм комент-сприйняття)

Те що залишилося ще відкритим і неузгодженим з попередніх серій) — хто що вкладає в OOP чи розуміє під тим, тобто питання не стилістики а скоріш мабуть термінології десь

тобто питання не стилістики а скоріш мабуть термінології десь

ось на цьому якраз й не буде досягнено згоди, чи то «три кита ООП» має бути, чи двоє (без наслідування) чи четверо (з абстракцією, яка ніби й так була «само собою зрозуміло»)...

... а потім хтось прийде й скаже «то все неправильно, бо головне — месіджі!»))

на цьому якраз й не буде досягнено згоди

це не самоціль, принаймні видно що існує деяка суттєва різниця та можна побачити у чому саме

Ок, треба так писати. І що? Особливо зараз, просто попроси LLM написати код звільнення ресурсів у разі помилки, чи перевірити правильність. Так, я би не відмовився від синтаксичного цукру. Але написання простирадла не займає багато часу і в принципі помилитися там важко. Тому чесно, я не бачу приводу тут сильно сумувати.

Перевага longjmp скоріше у тому, що ти не будеш його плодити на кожен чих.

Особливо зараз, просто попроси LLM написати код звільнення ресурсів у разі помилки, чи перевірити правильність.

саме так, й...
...щоразу просити LLM то все перевірити кожен раз, коли дивишся на зміни, замість того щоб покладатися на гарантоване RAII від умовних C++/Rust (чи Python/C# з їхніми with/using)

Але написання простирадла не займає багато часу і в принципі помилитися там важко.

«простирадло» замилює око, за ним губляться суттєві деталі, воно стає «візуальним шумом» крізь який можна пропустити щось суттєве...
(навіть для LLMки воно «збільшує розмір вікна»)

Перевага longjmp скоріше у тому, що ти не будеш його плодити на кожен чих.

нє нє, нема переваг, бо «наступна напряму безпосередньо викликана функція» що «сьогодні працює тут і зараз», вона вже «завтра» стане коллбеком, який викликається «невідомо де» за опосередкуванням 100500 «лєвих» АПІшок, й взагалі з іншого сріда... бо проект мейнтейнить 100500людей, й нівкого нема часу, щоб вникнути в усі подробиці під час рів’ю...

навіть для LLMки воно «збільшує розмір вікна»

вважаєте що першим під ші роздачу попаде більш вискорівневе програмування (нп починаючи з веб-програмування)? — бо з ним легше чи менш ресурсозатратно можливо

не ставлю прогнозів щодо ШІ... прогнозування справа невдячна (якщо тільки не працювати "гадалкою«/шарлатаном в «шоу екстрасенсів»)).

та й поняття «низькорівневе програмування» дуже умовне, бо цілком собі можна юзати той же (умовно) С++ на «контролерах» (умовна Ардуінка та С++ вже згадувалася не раз), й писати в регістри напряму (достаньо «низькорівнево»?) вперемішку з RAII та... темплейтами, й навіть для ламбд місце знайдеться, хоч й нема std::function))

заб’ємо на хвилинку на ШІ-шне «вікно» й лишишо тільки людське (ШІ «в теорії» можна «прокачувати» як завгодно, а от чєловєкі, навіть з «ноотропами» й на «амфетамінках», все одно так революційно своє «вікно» не прокачають). «відділити зерна від полови» — нетривіальна задача... й коли ШІшачка виплюнула 100500 «чогось», то бажано хоч приблизно розуміти про що мова, навіть якщо людина не править код й тільки потім заставляє ШІ писати тести до набрєдогенерованого (на практиці — править і код і тести).

Тобто всякий одноманітний бойлерплейт — полюбе навантаження на найслабшу ланку (чєловєків), полюбе то когнітивне сміття, крізь яке треба пробиратися, бути уважним, помічати те що треба, пам’ятати що було на попередніх екранах, коли проскролив... коротше всі оті «когнітивні челенджі» — адський мазохізм, якщо є спосіб це обійти, й вирішувати більш цікаві есеншал задачки, най краще вони будуть «челенджом», а не бойлерплейт!

Цей комент не виглядає як бачення (не про погоду ж цікаво запитувати) на доволі пряме — по чому саме можливо першим пройдеться ші. Так у чого шансів більш попасти під ші каток — веб-програмування чи низькорівневе щось якщо брати в цілому? З мого бачення схоже що першим буде саме високорівневе програмування (можливо і з інших причин — нп більш актуально чи більший профіт)

ще раз, не знаю що таке «вискорівневе програмування» в контексті до даного питання, бо маніпулювати «високорівневими абстракціями» можна «де завгодно» (так само, як й де завгодно можна «бойлерплейтити»)

першим «під каток» піде якраз те програмування, для якого більше відкритого матеріалу...

й, насправді нас ще чекає «велика криза ШІ» коли ШІ почне вчитися на тому, що набрєдогенерував сам ШІ...

(щось таке було з гугльтранслейтом, що вчився на перекладених статтях, а з певного моменту почав вчитися на статтях перекладених ним самим й здурів... втім якось ту проблему таки порішали)

окей, зайдемо з іншого боку) — від точки зору з

точно легше ніж в Сішному світі

— чи з ші можливо будуть кращі результати (з human точки зору) у тому що і для людини легше?

— чи з ші можливо будуть кращі результати (з human точки зору) у тому що і для людини легше?

в ШІ будуть кращі результати в тому, де в ШІ буде більше простору для навчання,
там де в нього є більше «навчальних послідовностей»))
тобто в популярних, й повторюваних галузях (там, де більша можливість підмітити ймовірнісні закономірності на основі наявних даних)...
тут «кращі результати ШІ порівнянно з результатами ШІ», ага))

в чоловєків з ШІ будуть кращі результати в тому, де «те_що_перечислено_вище» * (умовно помножене на) «де в чєловєків буде більше можливостей пояснити ШІ, що, власне треба від нього добути» * (умовно помножене на) «здатність чєловєків проаналізувати якість наданих AI-шечкою результатів»...

про те, які результати в ШІ без чєловєків порівнянно з чєловєками й на думку чєловєків, то треба щоб інші чєловєкі оцінювали їх й ми попадаємо в галузь філософії вибору критеріїв кращості...

я не зустрічав робіт (не достатньо шукав), які б доводили, що в людини «свідомість» та «неперервність» її мислення були б еквівалентними способам «мислення» LLMки.

чи зможе ШІ уеквівалентнитися людині й видати ті ж/чи кращі результати, що й людина, знаючи «весь контекст» відомий людини, й чи буде аутпут LLM в такому випадку еквівалентний/гірший (з точки зорі людини)/кращий людському (не в плані швидкості/кількості, а в плані якості) — хз...

очікувано, що якщо більшість чєловєків «тупить» й породжує дурню, то й ШІ, навчаючись на таких «тупняках» повторюватиме за ними. наскільки вийде його «замодерувати» щоб з 90фігових та 10хороших (за якими критеріями? ггг) він обрав саме 10хороших — хз (й ще дуже залежить від того, хто «модерує» таке навчання)

...Короттше ми йдемо й глибокий оффтоп філософії, я не маю відповіді ))

здатність чєловєків проаналізувати

оптимізм в купі з

якщо більшість чєловєків «тупить»

песимізмом дорівнює

глибокий оффтоп філософії, не маю відповіді)

:)

замість того щоб покладатися на гарантоване RAII

З мого досвіду на ці граблі я наступав частіше ніж в Сі, бо воно приховане та часто неочікуване. Варіант golang з defer мені подобається більше.

«простирадло» замилює око, за ним губляться суттєві деталі,

Ок, тебе тратує, зрозумів. Мене анітрохи. Які деталі губляться?

З мого досвіду на ці граблі я наступав частіше ніж в Сі, бо воно приховане та часто неочікуване. Варіант golang з defer мені подобається більше.

що саме приховане та неочікуване?
те, що при виході з скоупу об’єкт згине «сам собою», й перед тим викличеться його «деструктор»?

Ок, тебе тратує, зрозумів. Мене анітрохи.

про смаки не сперечаються))

Які деталі губляться?

ті, що не «бойлерплейт», а, власне есеншал для вирішення задачі :)

що саме приховане та неочікуване?

Приховані виклики конструкторів та деструкторів. Ти не розумієш, чи взагалі там щось викликається. Інколи треба йти по всій ієрархії. А головне, що ти можеш просто не подумати, що там ще щось може бути, що тобі не треба.

власне есеншал для вирішення задачі

Ну.. коли працюєш з хитрим API, то власне задача нічого не наплутати у цьому API. Тому для мене зручно, коли воно все поруч, я не розмазано по класам.

Приховані виклики конструкторів та деструкторів. Ти не розумієш, чи взагалі там щось викликається. Інколи треба йти по всій ієрархії. А головне, що ти можеш просто не подумати, що там ще щось може бути, що тобі не треба.

Ем... а чому це вони «приховані»? Ctrl+Click та й все писутнє!
Умовне

{
    Чототам назваІнстанса{параметри конструктора};
    ...
    назваІнстанса.назваМетода(...);
    ...
}
нічим не гірше (навіть краще) за
{
     Чототам назваІнстанса;
     Чототам_ctor(&назваІнстанса, параметри конструктора);
     ...
     Чототам_назваМетода_(&назваІнстанса, ...);
     ...
     Чототам_dtor(&назваІнстанса)
}
бо (на мою думку/смак, а про смаки не сперечаються) в Сшному варіанті купа способів натупити, походити по граблях, забувши щось зробити з того «простого й одноманітного бойлерплейту» (й, як показує практика — туплять, й туплять не в таких «простих видимих кейсах», а десь там «в глибині» забувши в Чототам_dtor викликати БазаДоЧототам_dtor або викликавши не той _dtor, або ще якісь тупняки, бо варіантів натупити — вагон комбнаторного вибуху по всій ієрархії, наприклад присвоїти неті методи в закопіпейстчену VMTшку, чи забути їх присвоїти і тд...
через велетеньку кількість «точок можливого затупу» ймовірність «туплення» багатократно зростає, навіть якщо кожна з тих «точок» вважається «настільки простою, що затупити малоймовірно»)...
Інколи треба йти по всій ієрархії. А головне, що ти можеш просто не подумати, що там ще щось може бути, що тобі не треба.

Ем... ну так само ж треба йти по ієрархії з Чототам_ctor, БазаДоЧототам_ctor, БазаДоБазиЧототам_ctor, нє?

Або взагалі «композиція замість наслідування», так «модніше»))

А в ідельному світі взагалі не треба йти по ієрархії далі й заглядати всередиру, бо до першого ж конструктора повинен бути доксіджен з описом (в реальному надаль, нетак, бо деякі особи спецом не пишуть доків, адже «коде смел, все має бути зрозуміле з коду, бла-бла-бла», а по факту ніразу незрозуміло, що він там мав на увазі, й скільки повнен «жити» той об’єкт, хто чим овнерить й коли то все треба очищати, бо цього просто не написано в коментарях...)

Ну... коли працюєш з хитрим API, то власне задача нічого не наплутати у цьому API. Тому для мене зручно, коли воно все поруч, я не розмазано по класам.

Так і не треба розмазувати, ніхто ж не заставляє робити 100500базових класів, то не питання Сшка vs мови з підтримкою RAII, то питання «Деякі з стилів ООП» супроти «інших стилів (необов’язково/не) ООП» ))

в Сшному варіанті.. ctor.. dtor..

щось наплутано, в сі не оперують термінологією ctor dtor

в сі не оперують термінологією ctor dtor

Ем...ще й як «оперують»!!!
Ще й вважають то і є «тру ООП»!
Є «семінари, тренінги, курси»: Course Shows How OOP Works Under the Hood та інструкцій типу Application Note Object-Oriented Programming in C.

Й «то все» в деякому «ембедді», в певних колах, вважається зашибісь як круто, аби ж тільки не юзати «підхід Ардуінки», а щоб тільки повкодовувати оте все бойлерплейт руцями!

тру ООП

у світі багато чудернацького, для когось що плюси що сі, для когось що java що javascript, ...

Одним словом

в певних колах
Одним словом
в певних колах

звичайно, тільки для тих «в певних колах» навпаки існує лише їхній «ООП всесвіт», вони не знають ні про оті всі ваші реакти, ні про нетбінси, ні про svelte ні про vue, й всяких «Angular» то взагалі «якась лєва дичина»...

й для них навпаки все оте про JS, фронтенди/бекенди то «певні кола»...

а «справжній девелопмент» з «справжнім ООП» й щоб «індастріал грейд перевірені солюшени (типу qp)» то все «тру» буквально для тих штук, які заливаються прошивками на девайси, керують процесами і тд...

знову «відкрив Америку»?

ні про оті всі ваші реакти, ні про нетбінси, ні про svelte ну про vue... й для них навпаки все оте про JS

хтось цікавиться, хтось ні

хтось цікавиться, хтось ні

неважно, ми ж тут про розуміння ООП говоримо,
от я ж й кажу, що «розуміння ООП» в цілих індустріях може бути буквально ось таким, як вже згадане «індастріал грейд перевірений солюшен qp»... є й інші «індастріал грейд перевірені солюшени» різного ступеня пропрієтарності...

є й фрішні, й умовний
gtk_widget_destroy
то й є самий справжній «деструктор» в таких термінологіях для одного з способів «ООП в C» який прийнято в GObject))

Хтось пише _destroy хтось пише _dtor ще хтось навіть так й пише _dectructor «шаблончик» для «емуляції ООП» всюди приблизно то само, різниця в деталях (що мужуть бути доволі суттєві, якщо натупити), а найгадіше, то коли ті всі «стилі емуляції ООП» завдяки поєднанню фреймворків на ліб всі вперемішку на одному проекті!

поєднанню фреймворків та ліб, всі вперемішку на

python чи javascript стайл?

який Пайтон? все на Cішці))

Просто окрім qp з його «ООП підходом» є ще велика ліба комунікації від замовника, що слідує своїм «умовностям» для «ООП в С», й є ще бібліотека «ембеддед графіки» де також свої «правила» на «ООП в С» (й де навіть ресурси йміджіі також С-шкою). Тому треба пам’ятати не тільки де _ctor де _init, а й де _create а й всю решту умовностей, які для кожного з «ООП підходів» унікальні...

А місце для Пайтона, то тільки автоматом конвертувати малюночки від дизайнерів в .с шні файли, ось такий він «ембед»))

Ем... а чому це вони «приховані»? Ctrl+Click та й все писутнє!

І де клікнути, щоб побачити які деструктори будуть викликані по виходу з блока? На кожну обʼяву не наконтролклікаєшься.

Про ctor/dtor навіщо? Просто я не бачу сенсу обгортувати handle у клас лише для того, щоб автоматично викликати деструктор. Бо відразу виникнуть питання копіювання, dup, ... Я хочу це бачити та контролювати ручками.

І де клікнути, щоб побачити які деструктори будуть викликані по виходу з блока? На кожну обʼяву не наконтролклікаєшься.

По класові на оголошення айтемів, на вході в блок))

Про ctor/dtor навіщо? Просто я не бачу сенсу обгортувати handle у клас лише для того, щоб автоматично викликати деструктор. Бо відразу виникнуть питання копіювання, dup, ...

Для хендлів роблять готові обгорточки, або й on_scope_exit макро, й то не найбільша проблема, з хендлами як правило ніяких проблем))

Я хочу це бачити та контролювати ручками.

Проблема з «ООП на Сшці» ніразу не в хендлах файлів,
проблема в власне «об’єктах» для «логіки програми», там де «ієрархіями класів» намагаються «замоделювати», й з певного моменту вже ніхто не розуміє в тих «спагетті об’єктів» що з чим взаємодіє, й скільки часу то «живе»...

Ті об’єкти мають «поля», деякі з полів — хендли, деякі — пойнтери «кудись», деякі з поінетрів є «овнящими», а деякі то просто «лінки»... а ще «мутувати» той стейт можна тільки зпід мютекса (або ж лише як відповідь на «месідж» що прийшов в «наш» срід) + купа інших «контекстів», месіджі що продовжують йти до об’єкта після того як він «згинув» й решта приколів...
(тобто реальна система зовсім не така, як її придумали «на папірчику», особливо якщо команда росте й початкові «високі ідеї» розмиваються), кототше в результаті «нето», вічно данглінг пойнтери, щось не заініціалізовано, неті месіджі нету, нета обробляються, сегфолт, таггед юніон юзається неправильно, й пішло поїхало...

І взагалі все

юзається неправильно, й пішло поїхало...

в python чи в javascript?

в python чи в javascript?

так ми ж про Cішечку, там, де «все руцями», нє?

неважно, ми ж тут про розуміння ООП говоримо, от я ж й кажу
юзається неправильно, й пішло поїхало
в python чи в javascript?

якщо це якби натяк, що «в ооп все неправильно взагалі й тому ті ж самі проблеми ООП в ЖС/Пайтон»,

нє-нє, в ЖС/Пайтоні хоча б, є гарбіч колектор,
а саме головне вони раняться на машинах з «дофіга пам’яті» де оті меморі ліки «менш помітні» порівнянно з тим, що й так жере сама платформа, якщо порівнювати з ресурсами ембеддед девайсу на якому «ООП на Сшечці»...

а ще «там» на традиційних ЖС/Пайтон платформах неможливо звертатися до «пам’яті» через данглінг пойнтер, та ще й так, що він може жити в девайсі дні, тижні й «нічого не стається», пам’ять пишеться, читається, й «все добре», а потім вивалиться в зовсім іншому місці, й пів року досліджувати «багу Гейзенберга»...

не вийде звертатися до юніона не по тих полях, що відповідають тегові, не вийде вказати sizeof «нетої структурки» при memcpy, й не вийде закастити поінтер до іншої «нетої структурки», й лазити по її полях так, що попервах «нічого не ламається», й бага з покоцаною пам’яттю потім вилазить в зовсім іншому місці...

коротше «все нето» — «ООП на Сшечці» (особливо в великих командах) — г@вно))

Й саме тому я за насадження Rust силою на «ембеддед» проектах.... й саме тому (на мою думку) Лінус робить все правильно, коли «ламає через коліно» всю оту «стару гвардію», саме так))

(а взагалі, прошу пана написати прямим текстом, що він там «має на увазі», ми не на «уроці літератури» де «що мав на увазі автор»)

саме тому я за насадження

і тоді логічним булоб трохи в майбутньому за ші, який за всіх і вся розбереться, ні?

ми не на «уроці літератури»

а на доу

і трохи в майбутньому за ші мабуть, який за всіх і вся розбереться?

не розбереться, але «за ШІ» так))

а на доу

і що?

я достатньо «родкрив тему» чи є ще якісь питання (прямим текстом)?

не розбереться, але «за ШІ»

Це більш цікаво, а чомуб йому тоді не розібратися (десь в доволі недалекій перспективі) там де менша ймовірність помилитися, нп починаючи з веб-програмування. Чи тут такий логічний різонінг думаєте не спрацює?

ми пішли по колу починаючи з «прогнози — невдячна справа...» й далі за текстом

пішли по колу починаючи з
прогнози — невдячна справа

пропоную різний різонінг, може з кола виведе

Для хендлів роблять готові обгорточки, або й on_scope_exit макро, й то не найбільша проблема, з хендлами як правило ніяких проблем))

Я ж й кажу, що для сішного коду виглядає норм і goto cleanup.

Проблема з «ООП на Сшці» ніразу не в хендлах файлів,
проблема в власне «об’єктах» для «логіки програми», там де «ієрархіями класів» намагаються «замоделювати», й з певного моменту вже ніхто не розуміє в тих «спагетті об’єктів» що з чим взаємодіє, й скільки часу то «живе»...

Ну... якби на розуміли, то Linux ніколи не був би доведений до розуму. Є багато складних проєктів, які досить якісні. Що скільки живе зазвичай зрозуміло, бо в принципі ти знаєш коли воно стане непотрібне — коли викличуть fclose.

Я ж й кажу, що для сішного коду виглядає норм і goto cleanup.

Тільки якщо той хендл не мембер структурки з «кучою всього» яку «хз хто» має звільнити, «хз коли» й «хз» які з тих полів маємо прибити/поклоузити «ми», а які «хтось»))

Ну... якби на розуміли, то Linux ніколи не був би доведений до розуму. Є багато складних проєктів, які досить якісні.

так він і не доведений, якщо зважати на іхні ж «срачі», зокрема й щодо Rust, бо ніхто не знає який там має бути меморі овнершип (але, звісно, то безмірно краще ніж 20років тому))

Що скільки живе зазвичай зрозуміло, бо в принципі ти знаєш коли воно стане непотрібне — коли викличуть fclose.

(f)close викличуть «тут» чи «там»? а як взагалі знати момент «непотрібності» якщо воно юзається в різних місцях...

Це якщо я злосним кодстаном й скурпульозним рів’ю не дам нікому копіювати хендли «кудись», десь їх сторити й множити без dup/DuplicateHandle (або, якщо в мене обгорточка буде тільки «мувабл» але не копіабл)... і не тільки хендли, а й решту...
Коротше то питання «дисципліни» на яку всі по мірі розростання проекту «ложили», тобто «нето», «не працює»...
Отож най вже краще мова/компілятор за тим всім слідкує, а не «чєловєкі».

«Отож най вже краще м̶о̶в̶а̶/̶к̶о̶м̶п̶і̶л̶я̶т̶о̶р̶ ші-пілятор за тим всім слідкує, а не чєловєкі»

відклавши в бік питання якості/результатів на сьогоднішньому рівні, по суті відношення не зміниться, тобто — виглядає таксамо, чи не так?

ші-пілятор за тим всім слідкує

наразі не слідкує))
бо якраз

відклавши в бік питання якості/результатів на сьогоднішньому рівні

...
хоча ідея Spec-driven development доволі хороша, може хоч таким чином заставимо людей писати коментарі/документацію :D

я так зрозумів

наразі

по суті якби так, хоча насьогодні ще явно далеко до того — тому ні)

нічого не зрозумів але дуже цікаво то все вже злісний оффтоп))

не так щоб зовсім, з часом будуть суперечки про щось інше, онтологічним парадигмуванням OOP може ШІ і не стане заморочуватися (тобто можна дивитися з цього ракурсу)

хоча ідея Spec-driven development доволі хороша

Чесно, це перше що приходить до розуму. І так й писали в 60-ті та 70-ті. Проблема скоріше у тому, що текст на мові програмування це і є сама точна специфікація. А усе інше страждає: то щось не врахує, то неоднозначно.

текст на мові програмування це і є сама точна специфікація

А отут якраз посперечаюся, бо, без відповідного коментаря зробуити за кодом «ментальне зусилля» й зрозуміти чи то «баблсорт» чи таки щось інше — займає час...

Іншими словами коли девелопер прочитав працю якогось ученого і реалізував в коді (не вказавши лінк на джерело ідей), то той код ніфіга не еквівалентний науковій праці з якої він зроблений з точки зору сприйняття людиною...

Для того, між іншим, Дональд Кнут й придумав свій «Літерейт програмінг», звідти й усі доксіджени, ЖС доки, Сфінкси, ЕмКадокси та решта...

Для всіх готовеньких ліб/вреймворків всі читають готову документацію, замість читати сорси...
Але в той же час чомусь розраховують, що власне написане ними буде «і так понятно»...

Але в той же час чомусь розраховують, що власне написане ними буде «і так понятно»...

Так отож. Особливо коли код описує щось принциво нове або не звичне до пересічного розробника. Дока дуже сильно допомагає, а дока з ютюбчиком та прикладами — ще краще.

Для того, між іншим, Дональд Кнут й придумав свій «Літерейт програмінг», звідти й усі доксіджени, ЖС доки, Сфінкси, ЕмКадокси та решта...

Здається мені, що ти пишеш про те, про що ніколи не пробував. tangle, weave хоч раз запускав?
Literate programming немає нічого спільного з доксідженами і т. п.

По-перше, його можна розглядати як мову програмування. Дійсно, подивимося сюди, це pdf який отриманий з сорцевого коду TeX: tex.pdf

Наприклад, пункт 4:

@p @t\4@>@<Compiler directives@>@/
program TEX; {all file names are defined dynamically}
label @<Labels in the outer block@>@/
const @<Constants in the outer block@>@/
mtype @<Types in the outer block@>@/
var @<Global variables@>@/
@#
procedure initialize; {this procedure gets things started properly}
  var @<Local variables for initialization@>@/
  begin @<Initialize whatever \TeX\ might access@>@;
  end;@#
@t\4@>@<Basic printing procedures@>@/
@t\4@>@<Error handling procedures@>@/

Виникає питання, чи це схоже не Pascal? У цілому це виглядає більше як варіант M4 :-) Так, потім ти можеш розширювати плейсхолдери, ...

Literate programming це не документація, де скоріше розповідь, як писалася програма. Крок за кроком. Документація же містить все що завгодно, окрім цього. Більше того, часто це просто переказ сирцевого коду.

Здається мені, що ти пишеш про те, про що ніколи не пробував. tangle, weave хоч раз запускав?

звісно що я не запускав «класичних тулів» Кнута, і навіть не вмію ЛаТеХом))

Але ідея логічно обгрунтувати історію «нафіга оце, як ми сюди прийшли», вона чудесна, й доксіджен, окрім власне доків, чудово катить ))

Literate programming це не документація, де скоріше розповідь, як писалася програма. Крок за кроком.

саме так, саме так! я хочу бачити «звідки то взалося» й «нафіга воно мені»... код повинен проситися «не викидай мене, я потрібен для того й того»...

А не оце от все, що робиться щось «нужноє, полєзноє, важноє», тільки ж хз н@хр*на воно тут в цьому проекті? Як воно мапується на рівкваєрменти/дизайн...

На «серйозних проектах» це називається «трейсабіліті», для того буває навіть спеціальний формат коментарів... а ще реки, й айтеми дизайну мають унікальні ІДшки й їх треба в коді вказувати, щоб потім можна було змапувати що звідки взялося, й чого так, а не інакше... а (для контрасту) на г@внопроектах автори навіть не сподоблюються в назві чейнджліста вказати джира айтем, тому навіть з історії GIT незрозуміло що й звідки взялося, чи можна переробити/модифікувати оцю незрозумілу байду, чи краще присобачити костиль збоку (звісно в «ідеальному світі» на «незрозумілу байду» ще й повинен бути юніт тест, та ще й також з посиланнями на ІДшки реків/дизайну)

Документація же містить все що завгодно, окрім цього. Більше того, часто це просто переказ сирцевого коду.

нє, нє... не переказ сирцевого коду, а щоб навівши на виклик функції я отримав короткий хінт, що вона робить... якщо я хочу зробити (умовно) HTTP ріквест до сайту, то мені глибоко байдуже які там TLS, SSL, й всі оті низькорівневі деталі (доти, доки ліба не заматюкається на помилки з сертифікатом)), що в що загнорнуто, й як воно ходить через сокети і тд...
Я хочу побачити живий приклад, ось це те, що я маю на увазі під документацією тобто така «підказка» прочитавши яку я одразу розумію як то юзати (так, це скорше юзер гайд, якщо використовувати іншу термінологію, але їх ніхто не пише, то яке краще місце для такої підказки, як не доксіджен поруч?)...

саме так, саме так! я хочу бачити «звідки то взалося» й «нафіга воно мені»...

Проблема що для цього треба мати хист до графоманства. Можливо зараз при допомозі LLM, але... Оособисто я коли пробував literate programming, то більшість часу витрачав не на написання коду, а на те як уникнути тавтології, як виразити свої думки, як це сказати, ... Ти б вже давно написав код, а там сидиш на параграфом тексту та робиш там зміни.

а щоб навівши на виклик функції я отримав короткий хінт, що вона робить...

Я працюю в vim і такі хінти у мене не налаштовані. Не заважає ніяк, ти або бачиш з назви та контексту, а якщо є сумніми, то пʼять хвлин подивитися, переконатися плюс отримаєш додаткову інфу. Не кажучи про те, що такі хінти є тільки в ширвжиткових лібах.

Я хочу побачити живий приклад, ось це те, що я маю на увазі під документацією тобто така «підказка» прочитавши яку я одразу розумію як то юзати

stackoverflow або LLM дає те саме, а проблеми починаються в нюансах. Ще раз, це написання коду, а це займає у мене 5-10% часу, тому немає різниці як. Але у складних випадках документація просто не може все охопити.

всі читають готову документацію

це якщо щось не працює, якщо працює то щось є дуже великі сумніви що її хтось читає)

це якщо щось не працює, якщо працює то щось є дуже великі сумніви що її хтось читає)

а як першопочатково взнати «як воно працює»?

я не хочу читати сорси requests.get й розбиратися з тим всім до глибини ОС викликів/особливостей алгоритмів шифрування...

й, чесно, я ніколи не робив Ctrl+Click по requests.get
але ось
requests.readthedocs.io/...​uickstart/#make-a-request

хіба ж це не прекрасно? ))

а як першопочатково взнати «як воно працює»?

спробувати?) тобто не знаю, то був просто як цікавий факт, пліз не сприймайте як пропозицію не читати доки

p.s. яка претензія зустрічається до документації — що то буває малоінформативна-машинна дока яка згенерована або написана для галочки

pps. з наведеною вами — виглядає доволі інформативний quickstart як там і зазначено

спробувати?) тобто не знаю, то був просто як цікавий факт, пліз не сприймайте як пропозицію не читати доки

ну мені просто влом перебирати варіанти...
я хочу готовий юз й знати готові граблі одразу...

а не взнати після експериментів, що, виявляється, АПІшка не threadsafe й треба було щось там залокати (звісно, в конкретному прикладі нічого локати не треба, але в загальному буває люди місяцями юзають апішку неправильно, «а потім виявилося» що треба було такіто прекондішени й воно «працювало» чисто випадково))

Ну блін, на трансформаторній будці ж чогось пишуть «не залазь — в’бє», чи «не вмикати, працюють люди» на рубільніках, замість запропонувати самосу залізти й дослідити самостійно де там висока напруга...

на трансформаторній будці ж чогось пишуть

скоріш аналогія на «make all warnings into errors» при компиляції (-Wall -Werror)

скоріш аналогія на «make all warnings into errors» при компиляції (-Wall -Werror)

нє нє, мова саме про те, щоб взнати про «граблі» в «коробочці» не розкриваючи коробочку.

взнати про те, що «щось там» треба було засетапити перед викликом АПІшки треба не постфактум після місяців юзу, а при перегляді сигнатури в доксіджені над нею))

ну але, звісно, якби горе автори сподобилися б зробити рантайм асерт на «байду вже було засетаплено», то не було б й граблів так довго, бо їх знайшли б при першому виклику))

а не взнати після експериментів, що, виявляється, АПІшка не threadsafe й треба було щось там залокати

Ну... у більшості випадків або зрозуміло з контексту, або клієнт працює з одного потока. Але... Подивися сирцевий код... Чи запитай LLM.

або зрозуміло з контексту

якого такого «контексту»? нема «контексту» на першому рівні, й на другому/третьому нема, бо воно лише в одній з опосередковано заюзаних АПІшок вилізло, й «обдарованому» сценарії... щоразу перебрати цей комбінароний вибух практично неможливо (нагадую мова про Cшку та структури даних з поінтерами й індірект викликами)

або клієнт працює з одного потока

Так, це була класна ідея: кожен об’єкт зі свого потока й оперує лише своїми даними, які йому передали у вигляді месіджів, в теорії це дуже круто, а на практиці руйнується одразу, якщо тільки в одній з тімів вирішили передавати чергами щось складніше ніж просто дані, й тоді геніальна ідея множиться на нуль.

Але... Подивися сирцевий код... Чи запитай LLM

таке працює тільки якщо обмежити рівні індірекшена, глибину вкладеності викликів, володіння об’єктами... тд...
коротше умовний Лінус повинен сидіти, й обкладати всіх матом, як тільки якийсь оверкомплікейшен!
А бо ж... ми знову «винаходимо» Rust...

PS. якщо що, то в кейсі «Лінус vs г@внофункція make_u32_from_two_u16» я, звісно, на боці Лінуса по всіх пунктах))

повинен сидіти, й обкладати всіх матом, як тільки якийсь оверкомплікейшен! А бо ж... ми знову «винаходимо» Rust...

Оверкомплікейшен підтримки та розробки з раст? Наймовірніше буде якийсь свій заморожений раст з bigtech поставкою розробників, в іншому випадку завдяки відсутності стандартизації та занадто сподівань/надій на мовні засоби замість відлагодженої workflow з тестуванням — можна швидко отримати щось подібне до відомого кейсу bcachefs tools в debian.

Оверкомплікейшен підтримки та розробки з раст?

Оверкомплікейшен всього проекту... згадувана make_u32_from_two_u16 то чиста Сшечка))
Просто саме на Rust дуже дуже акцентують увагу... воно звучить по новому...

А «maintainer burnout» помножене на «токсичність» Лінуса (та й решти мейнтейнерів) — відома річ...

Питання більше до психології: все це «тримається» завдяки «токчичним практикам» наведення порядків, чи всупереч?

Який там відсоток внесків від людей що працюють на корпорації, й отримують за те зарплату від корпорацій?
То може не так все й просто й райдужно з «найкращою системою в світі»... та й зробити форк, й послати «корпорації» разом з растом може хто завгодно, втім не дуже видно охочих...

Наймовірніше буде якийсь свій заморожений раст з bigtech поставкою розробників

саме так, саме так, воно сформується в щось більш стабільне, й саме за бабло корпорацій.

в іншому випадку завдяки відсутності стандартизації та занадто сподівань/надій на мовні засоби замість відлагодженої workflow з тестуванням

та не «замість» а «на додачу»)) ну й так, меморі баги, вони аж занадто анноїнг... хто покоцав цю структурку? трюк з датабрейкпоінтом робе тільки якщо бага репродюситься, проїходити всі оті стадії, переважно за чужою «творчістю» навіть для того, хто «вміє» — нецікавий й нетворчий процес...

все це «тримається» завдяки «токчичним практикам» наведення порядків, чи всупереч?

і тримається непогано схоже, незалежно від прив’язуваня до «завдяки чи всупереч» ракурсу)

послати «корпорації» разом з растом може хто завгодно

навіщо?

саме так, саме так, воно сформується в щось більш стабільне

Тільки за. Колись доволі давно (як і все що новеньке з’являється у широкому розповсюдженні) трохи покрутив і вирішив залишити поки допиляють до стандартизації. Тому чомуб не почекати ще того

«на додачу»
Отож най вже краще мова/компілятор за тим всім слідкує, а не «чєловєкі».

От якби це було безкоштовно, то нема питань. Але... на практиці це приводить до того, що ти розкручуєш С++ код, щоб зрозуміти що там як відбувається. Бо абстракції текуть. Це причина чому люди навіть зараз обирають Сі а не C++ та Rust. І оскільки вони створюють досить стабільні складні системи, то не можна вважати їх дебілами.

Але... на практиці це приводить до того, що ти розкручуєш С++ код, щоб зрозуміти що там як відбувається.

На Сшці так само «розкручуєш», бо шукаєш всі юзеджі отого поінтера й намагаєшся зрозуміти коли ж він там видаляється й там правильно чи неправильно?

Бо абстракції текуть. Це причина чому люди навіть зараз обирають Сі а не C++ та Rust.

Не знаю, чи саме це причина, бо срачі довкола Расту були довкола інших речей, а не «текучих абстракцій»... отож ми не вгадаємо, не придумаємо тут мотивацію замість оригінальних учасників того «срачу» (та й хз що там вони насправді в себе в голові думали)...

А взагалі, які ще «абстрації» й куди вони «течуть»?

Якщо я заборонив копіювання своєї структури даних =delete
то куди «втіче» та абстракція?
Якщо я дозволив лише переміщувати (але не копіювати/клонувати) свою структурку, то поки вона «подорожує» я точно знаю що то, звідки я копіюю інстанс вже «почищено», й якщо я запхав мою структурку в чергу, то вже на «цьому» боці нічого не треба «очищати» й овнером стане той, хто витягне структурку на «тому» боці...

Якщо ж мова про відомий «The Law of Leaky Abstractions» від Джоеля, то так само «за Джоелем» течуть й Сшні абстракції, особливо якщо згідно з
www.state-machine.com/...​-oop-works-under-the-hood
та
www.state-machine.com/...​oc/AN_Simple_OOP_in_C.pdf
жахливий ООП гавновреймворк на Сшці, хоча спочатку все ніби класно, але потім каст на касті кастом поганяє...

люди навіть зараз обирають Сі а не C++ та Rust. І оскільки вони створюють досить стабільні складні системи, то не можна вважати їх дебілами.

А хто казав до вони «дебіли» (якщо не рахувати змісту гнівних постів самого «токсичного» Лінуса, коли він періодично обкладає когось «дуже нехорошими словами» за занадто пізній коміт)?

Автори Лінукса дуже уважні люди, з високим ступенем концентрації уваги, вмінням розвязування складних завдань, трекання багатьох речей одночасно, нетривіальними ментальними здібномстями...

Легко таких набрати в тім? Ніразу не легко!
А багато задоволення всією тімою шукати «багу Гейзенберга» бо хтось проявив неуважність?
Задоволення від такого отримують хіба що клінічні мазохісти... а саме головне такі пошуки (часом по пів року, відкладаючи реліз) баги, якої можна було уникнути засобами мови, вони ніразу не додають value до кінцевого продукту...

... до речі, й сам Linux Kernel, навіть написаний на Ciшечці це ж також «абстракція», нє? То, отже «The Law of Leaky Abstractions» аплікабл й до нього))

На Сшці так само «розкручуєш», бо шукаєш всі юзеджі отого поінтера й намагаєшся зрозуміти коли ж він там видаляється й там правильно чи неправильно?

Для мене це простіше, ніж коли ця логіка десь схована в неявних операціях.

А взагалі, які ще «абстрації» й куди вони «течуть»?
Якщо я заборонив копіювання своєї структури даних =delete
то куди «втіче» та абстракція?

Тому що інколи треба скопіювати. А от абстракція це забороняє. Але я про інше.

Візьмемо практичний приклад: socket. Є високий рівень на кшталт asyncio. А от популярної легкої надбудови я не знаю, використовують чисте сішне API без обгорторк. Ніякого class Socket. А раз це не набуло популярності за 30 років, то значить там є свої граблі, тобто абстракція протікає, користуватися незручно: більше проблем.

жахливий ООП гавновреймворк на Сшці, хоча спочатку все ніби класно, але потім каст на касті кастом поганяє...

Звісно, тому цей фреймворк і не використовують. Не розумію навіщо на нього взагалі дивитися?

баги, якої можна було уникнути засобами мови, вони ніразу не додають value до кінцевого продукту...

Якби це було безкоштовно, то люди не дурні, давно б почали використовувати. А так засоби мови щось вирішують, а якісь проблеми створюють.

Для мене це простіше, ніж коли ця логіка десь схована в неявних операціях.

вона не схована, все на виду Ctrl+Click (а в ідеальному світі взагалі в реалізацію заглядати не треба, див вище приклад про requests.get... ну чи std::lock_guard теж чудовий приклад)

Тому що інколи треба скопіювати. А от абстракція це забороняє. Але я про інше.

хто сказав? чому забороняє? якщо треба то забиваємо на абстрації, й пишемо великий switch))

Візьмемо практичний приклад: socket. Є високий рівень на кшталт asyncio. А от популярної легкої надбудови я не знаю, використовують чисте сішне API без обгорторк. Ніякого class Socket. А раз це не набуло популярності за 30 років, то значить там є свої граблі, тобто абстракція протікає, користуватися незручно: більше проблем.

і в Пайтоні невже ніхто не пише?

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
    тут працюємо з сокетом

# а тут він вже закрився

а взагалі, нічого не знаю, я бачив й С++ обгорики і довкола сокетів, і довкола хендлів... а зараз якесь посилання на «мальйон мух»...

хіба не прекрасно, якби на додачу до const я міг би заспецифікувати такі речі, як, наприклад uncopyable, щоб мій сокет потім при правках ніхто кудись «не стирив», не засторив (можна ж стирити в будь якій з допоміжних, куди я його запихаю, зробити копію й десь зберігати) де не треба й не поюзав після звільнення, чи навпаки не звільнив до того як я завершу роботу...
Ну тобто щоб його мобна було тільки «позичити» на час виклику функції, але не засторити копію «десь там»?

ну от ми тільки що й винайшли Rust))

Звісно, тому цей фреймворк і не використовують. Не розумію навіщо на нього взагалі дивитися?

на вашому проекті не використовують, на моєму (на багатьох, і тут і за океаном) — використовують...
та то мало не «стандарт галузі»...

Якби це було безкоштовно, то люди не дурні, давно б почали використовувати.

знову «мільйон мух»...
так вже ж використовують в тій чи в іншій формі, RAII, unique_ptr, всякі with пайтона, using С#, try з ресурсами синтаксис Джави...
та й Rust «вже використовують», он Лінус повним ходом пропихає... а хто буде з ним не згоден, того обкладе матами й вижене з проекту примусить піти

і в Пайтоні невже ніхто не пише?

Я не бачив, не кажуми про те, що цей приклад досить умовний. Можливо, якщо тобі треба відкрити сокет, щось надіслати, дочекатися відповіді та закрити, то це працює. І то за рахунок того, що в Python вже реалізовані переключення контексту на інші потоки. Але у випадку реального застосунку socket буде створюватися та закриватися у різних функціях, тому від цього користі мало.

ну от ми тільки що й винайшли Rust))

То й пишіть. Я трохи пробував, як секс у скафандрі, не моє. Для частини задач мені байдуже, чи чи мій застосунок вилетить на unwrap чи буде segfault, але писати довго, муторошно і так в принципі помилки більше в лозіці. Це не кажучи про рефакторінг.

так вже ж використовують в тій чи в іншій формі, RAII, unique_ptr, всякі with пайтона, using С#, try з ресурсами синтаксис Джави...

Хтось використовує, хтось пише на Сі. Для мене щось високорівневе то Python, щось надійне то Haskell, перформанс то Сі.

шукати «багу Гейзенберга» бо хтось проявив неуважність?

скрізь так, виключень де такого не буває напевно ще не існує, з flutter з одним з пакетів буквально недавно щось подібне бачив

а саме головне такі пошуки (часом по пів року, відкладаючи реліз)

щоб далеко не ходити — закомітити «занадто пізній комміт» поза відпрацьованим для того механізмом, включно поза давно узгодженою процедурою тестування та отримати від Лінуса відповідно?)

якої можна було уникнути засобами мови

Якщо загалом брати, то як колись казав один з викладачів в універі «залиште ваші рожеві мрії за дверима заходячи до ...».
Частину можливо уникнути (навіть і значну якогось типу) за рахунок відповідних мовних засобів, але те що буває забувають при тому — який трейдоф, та чи варто того чи ні — буває варто, буває ні. Зазвичай сперечаються за той баланс для якої-небудь конкретики, але останнім часом все частіше зустрічаються доволі яркі випадки крайнощів типу — якщо зібралося, значить і багів неповино бути.

якщо зібралося, значить і багів неповино бути.

Тут треба більш сильний варіант: якщо математично доведено. Але ти спробуй доведи!

Тут треба більш сильний варіант: якщо математично доведено. Але ти спробуй доведи!

так от вже «Rust borrow checker» дещо доводить, отже ми рухаємо «в правильному напрямку»))

Він не доводить логіку, він просто гарантує, що не буде помилок при роботі з памʼяттю. Що більш менш буде гарантувати люба мова з GC. Так, в багатопоточних застосунках гарантій трохи більше, але навіть гарантій вітсутності deadlock немає. А от як довести в Rust що програма не містить багів?

А на Сі з допомогою засобів верифікації я можу це зробити.

Він не доводить логіку, він просто гарантує, що не буде помилок при роботі з памʼяттю. Що більш менш буде гарантувати люба мова з GC.

нє нє, не можна GC, ми ж в «ембедді»... треба щоб всюди «детермінований час» тому ніякого зависання на GC

Так, в багатопоточних застосунках гарантій трохи більше, але навіть гарантій вітсутності deadlock немає.

Звісно, але на деяких проектах, де мютекси/локи/івенти/черги/потоки з іменами, дедлок взагалі не проблема, адже вочдогом ловиться в рантаймі одразу, ще при тестах, й навіть пишеться в трейси хто й з чим напартачив (навіть якщо то рідкісний кейс, що репродюситься тільки «раз на мільйон» в продакшені, то з девайсу можна ті «трейси» добути й заінвестігувати що там нетак)

от як довести в Rust що програма не містить багів?

ніяк, але полюбе Rust — це вже краще за «голу Сшку» (навіть якщо на ту голу Сшку натравлено купу лінтерів, деяких навіть за великі гроші)

та й що значить «не містить багів»? для того потрібні реки/дизайн, бо «баги» то не лише умовний дедлок, а й відповідність «хотілкам» замовника, та ще й формально оформленим, щоб було відносно чого верифікувати (чого, насправді ніколи на 100% не буває навіть на «серйозних проектах»)

А на Сі з допомогою засобів верифікації я можу це зробити.

так, я пам’ятаю в мене десь навіть закладка десь є, на спеціальну обмежену версію С й тулу до неї, придуману якимись ученими, й дивний їхній сайт в стилі початку 2000х...

Але ж на умовному «нашому проекті» того (саме отої математичної тули) не юзають...
Взагалі ні на якому не юзають...
То виходить тула ще більш рідкісна ніж Ada...

Та ще й треба довести замовникам, що тула буде краще за ті валідовані лінтери, які вони юзають (звісно з джастіфікованими ексепшенами... інакше як би вийшло ту всю «кашу» замутити))

Ну тобто тула від вчених й спеціальна обмежена Сшка може й класні, але вони існують в якомусь «іншому світі», там, де не юзають (й навіть ніколи не чули) про «індастріал грейд qp» й всьо решта...

нє нє, не можна GC, ми ж в «ембедді»... треба щоб всюди «детермінований час» тому ніякого зависання на GC

Ну.. по-перше навіть на Haskell писали операційну системи, більше як дослідження того, які проблеми виникають при цьому в чистих функціональних мовах.

По-друге, особисто я не вірю в перспективи Rust в embedded, обмежень більше ніж користі.

вочдогом ловиться в рантаймі одразу

Ну... мінус швидкодія. Знову, ми про embedded та спінлоки? І знову ж, це не гарантія, що їх немає. Це означає, що їх не піймали.

ніяк, але полюбе Rust — це вже краще за «голу Сшку» (навіть якщо на ту голу Сшку натравлено купу лінтерів, деяких навіть за великі гроші)

Це раз, є верифікатори. Тобто математичний доказ, що програма працює правильно, виконує специфікацію, не містить UB. Цим Rust краще? Зайві обмеження.

та й що значить «не містить багів»? для того потрібні реки/дизайн, бо «баги» то не лише умовний дедлок, а й відповідність «хотілкам» замовника, та ще й формально оформленим, щоб було відносно чого верифікувати

Так, наприклад є формально перевірений компілятор Сі, правда більша частина на OCalm. Можна формалізувати інструкції процесора, можна формалізувати стандарт Сі (простіше ніж Rust), можна довести, до код, який буде згенерований компілятором формально відповідає стандарту.

Є, наприклад, веріфікований менеджер памʼяті з доказом того, що про alloc буде виділений новий фрагмент, а при free він буде звільнений, або буде помилка (до речі зроблений з аналогом FAT, тобто службова інформація про блоки міститься в іншому фрагменті памʼяті, тому якщо ми виходимо за межі, то ми просто залазимо на наступний блок даних, але не торкажмо службові дані.

Ну.. по-перше навіть на Haskell писали операційну системи, більше як дослідження того, які проблеми виникають при цьому в чистих функціональних мовах.

Ну так, ось зараз поекспериментують з Rust, відшліфують, тай «щось буде», не дарма ж корпорації вкладають бабла... й то не одна якась а всі разом...

По-друге, особисто я не вірю в перспективи Rust в embedded, обмежень більше ніж користі.

Наразі звучить як «вкусовщина», бо для мене «примусовий RAII» виглядає навпаки «фічею», такий собі «лоу хенгінг фрут» щоб позбутися задачки «хто покоцав цей байтик в обдарованому сценарії?»

Ну... мінус швидкодія. Знову, ми про embedded та спінлоки? І знову ж, це не гарантія, що їх немає. Це означає, що їх не піймали.

Які спінлоки? Чому «мінус швидкодія»? Вочдог не повинен ранитися «весь час», й не повинен прівентити дедлок, він має його задетектити постфактум... звісно, 100% гарантії нема, але навіть бага «на філді» інвестігується, й легко знаходиться руткоз.

Це раз, є верифікатори. Тобто математичний доказ, що програма працює правильно, виконує специфікацію, не містить UB. Цим Rust краще? Зайві обмеження.

наразі виглідає так, що цим бавиться тільки «академія», й час «великої ідеї» не настав...
Rust краще якраз тим, що корпорації саме тут й побачили «велику ідею» й вкладаються баблом, тобто буде все готовеньке... ну й ті «обмеження» багато людей вважає «фічами», от так само, як й система типів, це ж «обмеження», ну але катить як корисна фішка навіть в Пайтоні тайпанотації, й лише для того, щоб ІДЕшечка підсвітила (не лише, їх в Пайтоні можна витягувати в рантаймі й робити цікаві речі))

Так, наприклад є формально перевірений компілятор Сі, правда більша частина на OCalm.

Тобто все ще дослідницікі проекти, що їх не просуває «жодна велика кантора»

Можна формалізувати інструкції процесора, можна формалізувати стандарт Сі (простіше ніж Rust), можна довести, до код, який буде згенерований компілятором формально відповідає стандарту.

А далі люди повинні засісти й написати рули для ядра Linux?
Чи переписати все по новій, щоб вкластися в те, що підтримує «формально перевірений компілятор Сі, правда більша частина на OCalm»?

Є, наприклад, веріфікований менеджер памʼяті з доказом того, що про alloc буде виділений новий фрагмент, а при free він буде звільнений, або буде помилка (до речі зроблений з аналогом FAT, тобто службова інформація про блоки міститься в іншому фрагменті памʼяті, тому якщо ми виходимо за межі, то ми просто залазимо на наступний блок даних, але не торкажмо службові дані.

Ем... ну так його ж й далі треба буде юзати з тими рулами й їх треба буде писати й далі, за межами менеджера памʼяті...

й, очевидно, що всюди будь яка операція, що «не підкріплена математикою», де не доведено, що вона «математично сейф й відповідає настановам», без того доведення має генерувати помилку на етапі компіляції, нє?

бо якщо писання прекондішенів, поскондішенів та решти «математики» — опційне,
то яка би крута не була реалізація malloc та free але завжди можна буде натупити з данглінг поінтерами й юз афте фрі чи меморі ліками і тд, якщо не примушувати користувача «довести математикою», що він має право ту free зробити саме отут... а ще всюди треба примусово щоразу довести що він не виліз за межі виділеної пам’яті, й не обов’язково послідовним записом, а й «яким попало»...

час «великої ідеї» не настав
корпорації вкладають... й то не одна якась а всі разом...

в тих теоріях малоб бути щось з
— на галерах дуже важко вже стало відслідковувати якість коду, тому треба запроваджувати у себе впершу чергу, та щоб було де набирати людей з відповідними знаннями — просування скрізь. Хоча з іншого боку запитували би — так тодіж як у файрфокс справи з тим йдуть (в якості можливого маркера впровадження).

«доу хенгінг фрут» :)

...дуже важко вже стало відслідковувати якість коду, тому треба просувати у себе в першу чергу, та щоб було де набирати людей з відповідними знаннями....

звичайно, вся проблема в тому, що знайти людину здатну вслідкувати за тою оверкомплікейтед кашою — все важче...
Та й навіть ті, що могли вслідкувати рік тому — вже не стягують))

то не люди «отупіли», то два фактори одночасно
1. Все ускладнилося «до ручки».
2. Відсоток населення, що органічно здатні братися за такі задачі й вирішувати їх якісно (навіть за велике бабло) — обмежений...

І тому все більше розповсюджуються мови програмування де все легше (а часто і зручніше) працювати, з можливо в майбутньому перспективою делегування взагалі в ші?
У такому випадку вектор раст кейсу схоже в протилежному напрямку виглядає.

все легше (а часто і зручніше) працювати

для цього треба ще специфікувати, що таке «легше», «зручніше»...
Комусь типи «незручні», а хтось навпаки в динамічній мові «тайп анотейшени» ліпить...
Хтось хоче спочатку реки (чи спочатку тести), а хтось навпаки, спочатку код... Є лоюди що коментарів пишуть (й в тих коментарях їхні «шпаргалки»)), є що не пишуть, бо ліньки, не вміють (а «зпід палки» виходить «капітанщина», щось юзлесс таке що на от*бить), а є такі, що не пишуть принципово «бо так сказав дядко Боб» (тому часом моя перша їм порада — спалити книжку Стіва Роберта Мартіна, віддати в село бабі на підпалку))

(десь тут можна було б згадати астоср@чі про механіка vs автомат, але це «нете»...)

для цього треба ще специфікувати, що таке «легше», «зручніше»

з онтологічними питаннями просимо звертатися — спершу в секцію парадигмування, потім в секцію суперпозицій :)

зі схильністю до парадигмувань — спершу в секцію парадигмування, потім в секцію раст суперпозиції :)

то вже якась *уйня й неконструктив, як й з тим «диском Ц» в сусідній темі))

Контенту для пошукових запитів ми нагенерили вже достатньо, а за «філософією» — в секцію філософії, за «прогнозами» про «ШІ» в секцію до «ванги» й в «битву екстрасенсів»))

то вже ... неконструктив

Частково погоджусь. Хоча питання чи раст йде разом з загальним розвитком різних мов в сторону спрощення програмування, чи ні — доволі цікаве.

p.s. заапдейтив як з «онтологічними питаннями» відносно — треба ще специфікувати «легше/зручніше»

Ну так, ось зараз поекспериментують з Rust, відшліфують, тай «щось буде», не дарма ж корпорації вкладають бабла... й то не одна якась а всі разом...

Я працював у двох корпораціях, тому фраза «не дарма» звучить досить оптимістично. Для корпорацій цілком типово експериментувати, а якщо експеримент не спрацював, проєкт просто тихо закривають.
Здається, що саме Google зараз найактивніше просуває Rust у Linux kernel. Що, звісно, не гарантує успіху: Google+ , Hangouts, Inbox, Stadia, Glass... теж колись вважалися перспективними.

Наразі звучить як «вкусовщина»

А ти взагалі працював з ядром Linux? Писав драйвера?

«жодна велика кантора»

Так і запишемо, Airbus це шаражкіна контора.

А далі люди повинні засісти й написати рули для ядра Linux?

Ядро Linux так і буде ядром Linux, все зайшло занадто далеко, як на мене. Хоча окремі компоненти верифікувати можна. Ну а так є seL4 формально верифікована ОС, написана на Сі (плюс Haskell). Використовується в авіоніці.

А в Linux широковживана універсальна ОС, де безпека завжди йде в компромісі зі зворотною сумісністю, продуктивністю і новими фічами.

й, очевидно, що всюди будь яка операція, що «не підкріплена математикою»

Зовсім не очевидно, команди процесора описуються формально, тому все на основі можна описати формально.

якщо не примушувати користувача «довести математикою», що він має право ту free зробити саме отут.

Це користувачу вирішувати, чи треба йому верифікація чи не треба.

Здається, що саме Google зараз найактивніше просуває Rust у Linux kernel. Що, звісно, не гарантує успіху: Google+ , Hangouts, Inbox, Stadia, Glass... теж колись вважалися перспективними.

Зате Go живе й квітне, й навіть огидну потворку «Дарт» змогли прилаштувати в Флаттері вже після того, як на початкову ідею «заміни ЖС Дартом»... «поклали болт»... а ТайпСкріпт — дитя M$ теж цілком собі квітне))

А ти взагалі працював з ядром Linux? Писав драйвера?

ми вже про це говорили в іншому чатіку — лінкед лісти, RCU... там же й інший добродій приводив приклади як то все (дуже й «недуже») вирішується в Rust... а я плювався на методи витягувається всієї структурки з лінкедліста за допомогою макросів ()... ну й так, макроси, прості слова, глобальні змінні, DKMS...
... але ж наразі Лінус ще не здався з Растом, отже знає щось більше від нас))

Так і запишемо, Airbus це шаражкіна контора.

Ну ті потужні кантори, що юзають qp фреймворк — ніразу не «шарашкіни»... але як той, хто працював й епізодично ще працює з тим «індастріал грейд», можу відповідально заявити «qp фреймворк в його Сшній інкарнації — г@вно» ))

___
Airbus отже Ada, тут важко сперечатися з потужним «благословенням» від «перевіряючих органів», з іншого боку все якось сумно з продуктивністю, причому щось якось аж «в рази» і навіть гірше за Go...

А в Linux широковживана універсальна ОС, де безпека завжди йде в компромісі зі зворотною сумісністю, продуктивністю і новими фічами.

то за тими ж таблицями benchmarksgame Rust майже на рівні з няшною Cшечкою, отож може прижитися з безпекою та продуктивністю))

Зовсім не очевидно, команди процесора описуються формально, тому все на основі можна описати формально.

Описуються, але ж «далі» теж треба всюди юзати, тобто «без того доведення має генерувати помилку на етапі компіляції» примусово, інакше всі «верифікаці», якщо вони не повні — то «фіговий листочок»...

Це користувачу вирішувати, чи треба йому верифікація чи не треба.

ну так от тут якраз й головні граблі, що «це заскладно доводити що тут free — правильно», «тиждень до релізу», «ліньки», ще щосьтотам...
Тобто якщо верифікація опційна, то її будуть пропускати...

Так само як «забивають» й на решту речей, про що я вже описував вище...

... але ж наразі Лінус ще не здався з Растом, отже знає щось більше від нас))

Лежить окремо в пісочниці, нікому не заважає, гроші приносить.

Описуються, але ж «далі» теж треба всюди юзати, тобто «без того доведення має генерувати помилку на етапі компіляції» примусово, інакше всі «верифікаці», якщо вони не повні — то «фіговий листочок»...

По факту це окремий процесс, якщо брати VST, то ми переводимо текст програми в AST, далі в CoQ формулюємо властивості до проводимо доказ. І так, CoQ поверне помилку. У мене стаття тут в листі очікування про верифікацію.

ну так от тут якраз й головні граблі, що «це заскладно доводити що тут free — правильно», «тиждень до релізу», «ліньки», ще щосьтотам...

Теж саме відноситься і до Rust. Якщо брати авіацію, там не реліз, а сертифікація, DO-178C. Вони просто запитають: так у вас рівень A, показуйте вашу верифікацію. Тому хочеш не хочеш — мусиш.

причому щось якось аж «в рази» і навіть гірше за Go...

Ada працює в сегменті, де безпека важливіше за швидкодію. Знову, тести приховують маленьку деталь: зміна вимог, рефакторінг.

Лежить окремо в пісочниці, нікому не заважає, гроші приносить.

ну срачі ж продовжуються, отже, комусь таки «заважає»...
якби все було «безперспективно» то й навіть не пробували б

По факту це окремий процесс, якщо брати VST, то ми переводимо текст програми в AST, далі в CoQ формулюємо властивості до проводимо доказ. І так, CoQ поверне помилку. У мене стаття тут в листі очікування про верифікацію.

Оце було б цікаво почитати.

Теж саме відноситься і до Rust. Якщо брати авіацію, там не реліз, а сертифікація, DO-178C. Вони просто запитають: так у вас рівень A, показуйте вашу верифікацію. Тому хочеш не хочеш — мусиш.

В авіації, напевно все навпаки з буковками... буковка A чи буковка С «сама страшна»?

Тим не менше ніколи не чув, щоб юзали CoQ навіть для «самої страшної буковки» на тих проектах, про які я чув... Натомість покриття юніт, інтеграційними тестами (з спеціальними тулами, за великі бабки, що міряють покриття, й все має бути зелененьке), код рів’ю, ріск асесменти й мітігейшени... а от щоб «математично доведи тою тулою» — нє такого нема ніде...

Це ж треба було б, перед тим як взагалі почати юзати CoQ, ще й валідувати сам весь отой «процес верифікації за домомогою CoQ» й довести, що він забезпечує «покриття», й «нічого не втіче», й щоб «злі контролюючі організації» то признали взамін... хм, а взамін чого з вищеперечисленого? здається нічого з того вони викинути не погодяться, все одно «хочеш не хочеш — мусиш» робити те все решта, ніякого полегшення...

...та й щось гугль на запит «DO-178C and CoQ» не видає нічого отрім лєвого «Cost of Quality»... Тобто не видно, щоб то було включено в офіційний процес...
Я припускаю, що окрема організація може завалідувати додатковий (до тих що є) процес, але поблажок щодо попередніх їм за то все одно не буде

Ada працює в сегменті, де безпека важливіше за швидкодію. Знову, тести приховують маленьку деталь: зміна вимог, рефакторінг.

Звичайно, ну так Rust же також дає безпеку, нє? Й швидкий, практично, на рівні з Сшкою (не «в рази», а така різниця якась зовсім несуттєва)...

Ну й так, безпека важливіше, але чомусь обирають й «голу Сшку» замість «найбезпечнішої Ada», й навіть без всякого «CoQ», зато з «псевдо ООП фреймвормаки на Cшці»... й то все валідують й успішно пропихають навіть в такі девайси, де можливо «serious injury or death»...

(я веду до того, що Rust би унеможливив всі баги з розряду «хто покоцав цей байтик?», та ще й за сміховинну плату, але натомість й далі Сшка та г@вноімітація для «ООП», спагетті поінтерів, каст на касті кастом поганяє, та решта «приколів»...)

на тих проектах, про які я чув...

У DO-178C прописано таке:

Рівень E (No Effect) — збій ніяк не впливає на безпеку літака; тестування є опціональним.
Рівень D (Minor) — збій призводить до незначних незручностей для екіпажу; вимагаються базові unit-тести та code review.
Рівень C (Major) — збій спричиняє серйозні проблеми, але не становить загрози для життя; необхідне 100% покриття коду, інтеграційні тести та ручне тестування (Manual QA).
Рівень B (Hazardous) — збій може призвести до травм пасажирів або екіпажу; вимагаються статичний аналіз, property-based testing та фаззинг.
Рівень A (Catastrophic) — збій створює пряму загрозу життю або може призвести до авіакатастрофи; обов’язкові формальна верифікація та математичний доказ коректності.

Натомість покриття юніт, інтеграційними тестами (з спеціальними тулами, за великі бабки, що міряють покриття, й все має бути зелененьке), код рів’ю, ріск асесменти й мітігейшени...

Це рівні D та C.

збій створює пряму загрозу життю або може призвести до авіакатастрофи

очевидно, софт рубається на частини, й кожна з них повинна жити в окремому давайсі/адрес спейсі, так же?

бо якщо Рівень A (Catastrophic) живе в одному адрес спейсі з Рівень E (No Effect), то з рівня E ми завжди можемо покоцати байтик рівня A, це ж логічно...

Вірніше, отже, все що живе в одному адрес спейсі з чимось «E», воно, отже таж «E», все вірно?

обов’язкові формальна верифікація та математичний доказ коректності.

Й мова саме (й обов’язково) про «автоматизований» процес, а не про дядечка «рів’ювера», що оформлює свій аналіз формальною докою про те, що й як він верифікував, й ставить підпис?

То CoQ, отже, вже валідували, щоб замінити того дядечка?
Якщо так, то круть, тоді скидаю капелюха))

бо якщо Рівень A (Catastrophic) живе в одному адрес спейсі з Рівень E (No Effect)

То рівень E автоматично стає рівнем A, тому що збій створює загрозу життю, або може призвести до авіакатастрофи. Рівень E це зазвичай допоміжні скрипти, тощо. Makefile наприклад.

То CoQ, отже, вже валідували

Наприклад, в статті, VerificationofType Checking andErasure forCoq,in Coq автори формалізували й частково довели коректність ядра Coq (перевірку типів та ерацію) всередині самого Coq, але через теорему Ґеделя про неповноту повну самодоказову коректність неможливо досягти, тому частина метатеорії лишається як аксіоми.
Так, чисто теоретично є варіанти, що злодій розробник зможе використати критичну помилку щоб скласти формальну верифікацію. Але... код CoQ не виконується, це інструмент типу cmake, відпрацював та видав результат. Якщо припускати злодія розробника у середині, то в принципі в більшості проєктів він зможе закласти міну.

То рівень E автоматично стає рівнем A, тому що збій створює загрозу життю, або може призвести до авіакатастрофи. Рівень E це зазвичай допоміжні скрипти, тощо. Makefile наприклад.

точно, я все переплутав, бо в «нас» навпаки, чим більша буква, тим «зліше» рівень, й інша кількість рівнів северіті, але зміст я зрозумів :)

Отже все, що живе в одному частині з «серйознішим» рівнем, й може «щось якось підгадити зі сторони» то воно також стає «серйозніше» й його також треба покривати, все логічно

Наприклад, в статті, VerificationofType Checking andErasure forCoq,in Coq автори формалізували й частково довели коректність ядра Coq (перевірку типів та ерацію) всередині самого Coq, але через теорему Ґеделя про неповноту повну самодоказову коректність неможливо досягти, тому частина метатеорії лишається як аксіоми.

я трохи не про ту «валідацію», нукові праці можуть писати багато що...

я про те, що умовній організації *** (контролюючий орган в галузі, без якого девайс, з яким можливо «serious injury or death» не піде до юзерів) треба доказати, що дядечка який рів’ювить код й складає формальний документ можна замінити на тулу Coq.

Оце «доказування» (валідація процесу) про що «автоматизоване Coq катить замість алалізу складеного живою людиною» воно вже відбулося у вашій галузі?
(не знаю, як поянити, тобто «у нас» просто наукова стаття з якогото сайту для огранізації *** не прокатить, навіть якщо в тій статті «все правильно»).

Але... код CoQ не виконується, це інструмент типу cmake, відпрацював та видав результат. Якщо припускати злодія розробника у середині, то в принципі в більшості проєктів він зможе закласти міну.

ем... знову, напевно, не вмію поянити... «ми» не можемо використовувати на проекті, в процесі розробки «невалідовані тули», тобто якщо тула «показує покриття зелененьким», то, отже тут тулу також треба «провалідувати» за певною процедурою... й всі CMake й gcc (чи Візуал Студію) також валідують за певною процедурою (то не означає «верифікації» всіх фішок компілятора, а саме офіційне встановлення на придатність до «інтендед юз»)

От власне довкола того й питання: умовно «ваш відповідник нашого контролюючого органу», він не потребує «валідації Coq» в сенсі вказаному вище? Наукової статті з якогото сайту достатньо щоб «покрити» той рікваєрмент для «самого злого класу» й більше не потребувати послуг дядечка, який дивиться код й складає формальний документ?

+ ще, як «заміряти покриття», чи ми справді закрити все прекондішенами й посткондішенами? Тобто мова не про «злодія розробника» а про те, що може наші теореми доводять взагалі «нето» й нетам де треба...
якщо я десь забув написати/неправильно написав кондішени до теореми, що ми «не виліземо за межі масиву», й взагалі забув поставити такий асерт в тому місці, то тула «знайде сама» що я того не зробив? Чи ми знову повернулися до того, що хтось тепер має ще верифікувати наші прекондішени/посткондішени й те все, й чи ми їх вліпили де треба?

також треба «провалідувати» ... Візуал Студію

як і її користувача)

повернулися до того, що хтось тепер має ще верифікувати ... й те все

верифікатора?

верифікатора?

ну так, верифікатор верифікаторів верифікаторів для верифікаторів)) Коротше й тут чєловєкі не зникають, все одно хтось мусить до того дивитися

все одно хтось мусить до того дивитися

на посаду можна запропонувати тещу, має мати досвід верифікацій)

Оце «доказування» (валідація процесу) про що «автоматизоване Coq катить замість алалізу складеного живою людиною» воно вже відбулося у вашій галузі?

Авіація, NASA я думаю так. А там де я працював... Ок, припустимо драйвер відеокарти підвисне. Чи роутер перезавантажиться. Так, неприємно, але... 100% надійності не треба. Тому Сішка, мова скоріше про зручність.

CMake й gcc (чи Візуал Студію) також валідують за певною процедурою

cmake на валідувати не треба, бо йому треба лише раз запустити збірку, у продакшені він не буде. Тобто це рівень A.

gcc це ширвжиток, він не має ніяких safety-критичних сертифікацій. Треба Diab Compiler, ...

й більше не потребувати послуг дядечка, який дивиться код й складає формальний документ?

Ні, без дядечки поки що не вийде, бо регулятори вимагають не тільки математичні докази, а й кваліфіковані toolchain та compliance з процедурними вимогами DO-178C. Але обсяг роботи дядечки суттєво зменшується, formal verification покриває частину того, що раніше доводилося перевіряти вручну.

Тобто мова не про «злодія розробника» а про те, що може наші теореми доводять взагалі «нето» й нетам де треба...

Довести неправильно це можна практично виключити. А от забули додати твердження про швидкодію, чи ліміти пам’яті, от це реальна проблема, бо formal verification доводить тільки те, що явно сформулювали в специфікації. Типу як Boeing 737 MAX: зробили все по специфікації, а не врахували взаємодію MCAS з пілотами.

Авіація, NASA я думаю так. А там де я працював... Ок, припустимо драйвер відеокарти підвисне. Чи роутер перезавантажиться. Так, неприємно, але... 100% надійності не треба.

Ем... тобто всі побудови довкола авіації, то не «інсайди», а скорше «припущення»?

Тому Сішка, мова скоріше про зручність.

Тут, все ж, «вкусовщина», яку ще треба придумати як «міряти об’єктивно», зокрема й про те, за які аспекти зручності мова...

cmake на валідувати не треба, бо йому треба лише раз запустити збірку, у продакшені він не буде. Тобто це рівень A.

ем... напевно знову плутанина з буквами, бо «А» — самий легкий рівень «у нашій галузі», а «у вашій галузі» згідно цитати вище «Рівень A (Catastrophic)»...

Щодо валідації, знову ж таки, напевно залежно від галузі... «у нас» згідно постанов всі тули мають бути валідовані, й навіть вказуються в формальних доках що вносяться в спецільану систему й там трейситься що за домопогою чого створюється...

А от забули додати твердження про швидкодію, чи ліміти пам’яті, от це реальна проблема, бо formal verification доводить тільки те, що явно сформулювали в специфікації.

От я якраз про те, я не ставлю під сумнів тулу логічного виводу (хоча її також «у нас» провалідувати буде треба), а про те, що чєловєкі або нето пропишуть в реках, або ж не покриють все (я щось сумніваюся, що кожен доступ до масиву за індексом прописується окремо)...

... й, все ж, бракує «популярного викладу»... книжка по «веріфаєбл С» якось «не пішла»... магія з аналізом важкодобутого AST в екзотичній мові (що сама написана на екзотичній мові) — «нето», бо видається, що заставити HR знайти відповідних спеціалістів, або ж якось натрейнити їх — фантастика. Це треба щоб політехи/універи готували (там мало який випускник пригадує що таке Lisp, навіть на тих спецільностях, де його «вчать»), коротше задачка на роки й Rust з його популярними туторіалами вже ніразу не виглядає «оверкомплікейтед» порівнянно з навігаціюєю по AST й прувленням, що воно не зробить free двічі, також й в контексті того, що така навігація не скасовує інших активностей))

Ну тобто навіть коли я «здолаю поріг входження» й навіть переконаю начальство що C+Coq (чи + Rocq Prover, це ж так тепер звесться) буде точно ефективніше, ніж С + «оте все що я згадав вище», все одно «не взлетить» з вищеописаних причин

Звичайно, ну так Rust же також дає безпеку, нє?

Жодної безпеки, якщо чесно. Так, він захищає від деяких помилок з пам’яттю, але в коді все одно може бути unwrap, який упаде, вихід за межі масиву, або просто помилка в логіці, наприклад, додав +2 замість +3, або виник нескінчений цикл.

Ну й так, безпека важливіше, але чомусь обирають й «голу Сшку» замість «найбезпечнішої Ada»

З верифікацією. Ada (SPART) має верифіакцію Хоара, але цього недостатньо для списків, наприклад. Для цього є Separation Logic. Сішку обирають за те, що вона проста та стабільна, є верифікований компілятор. Взагалі чим простіше мова програмування, тим простіше компілятор, тим меншу в ноьому багів. Що там зміниться в новому релізі Rust та як воно вплине... Issue #25860 чи MIR оптимізація... Тобто які у нас гарантії, що компілятор генерує правильний код?

скрізь так, виключень де такого не буває напевно ще не існує, з flutter з одним з пакетів буквально недавно щось подібне бачив

Так, але баги «різного порядку»...
Звісно, Rust «не порішає всіх проблем»,
але через деякі можна буде переступити й одразу до «більш есеншал» речей, ніж довго й нудно з дата брейкпоінтами репродюсити хто там рандомо мені коцає байтик в структурці :)

«залиште ваші рожеві мрії за дверима заходячи до ...»

abandon hope, all ye who enter here))

але те що буває забувають при тому — який трейдоф, та чи варто того чи ні — буває варто, буває ні.

benchmarksgame-team.pages.debian.net/...​rksgame/fastest/rust.html

який трейдоф, та чи варто того чи ні — буває варто, буває ні.

часом на трейдоф можна (й варто) просто «забити»))

в тому плані, як вже тут поруч й відмічати, M$ вчинили правильно, коли просто забили на деякі «UB оптимізації» для «обдарованих корнер кейсів тестів з 2% перформанс буст», щоб лишити юзерам більш сподіваний юзерекспірієнс))

часом на трейдоф можна (й варто) просто «забити»))

bon voyage, just smile and wave)
youtu.be/F4tF7e_2Gvw

перформанс буст

Далеко не єдиний фактор з багатьох можливих, і зазвичай не визначальний. Розгляд багатьох агреговано в конкретних випадках — це те що має сенс.

cfront закинули саме через складність реалізації exceptions. там що думаю, що ніяка його версія longjmp не чіпала.

Ну... якщо кожна функція буде приймати додатково параметр контексту, а це порушення ABI. Або потокові змінні, можливо це не сподобалося? Бо не всі компілятори їх підтримують.

не маю інформації. можливо справа була не тільки в цьому, а в самих планах автора. так би мовити бачення еволюції проекта.
для хацкеля теж був hugs, і його теж закинули на якомусь етапі.

Просто немає практичної цінності, як мене. Тому знаходиться невеличка група ентузіастів, яка поступово втрачає ентузіазм.

нiколи не бачив якщо чесно

really? нечасто зараз використовується, але ніколи ...

p.s. з того що точно під рукою майже в усіх — ping (iputils) наприклад, або.. grep по gtk subprojects, etc.

так глибоко не копав, так
зазвичай goto кудись в кiнець, де роблять cleanup

Зараз в сутності взагалі ніде не використовують, там де є exceptions повально перейшли на stack unwinding/SEH. В драйверах та в принципі системному коду, ексепшени під забороною.

В Microsoft C — є. За рахунок SEH як розширення, яке на рівні компілятора підтримано відповідними словами (`__try` і так далі).
І повторюсь, що я б хотів таке бачити всюду, починаючи з Linux, воно в рази зручніше, ніж морочитись з обробниками сигналів і сподіваючись, що longjmp нічого не зламає.

Це не стандарт, не кажучи про те, що Microsoft C не підтримує останні стандарти, просто незрозуміла іграшка. Писати чисто під Windows... На чистому Сі? Збочення.

морочитись з обробниками сигналів

Це інша функція, більше комунікація.

Це не стандарт, не кажучи про те, що Microsoft C не підтримує останні стандарти, просто незрозуміла іграшка.

На жаль, да, інші цього не підтримують.
Але не «іграшка». У MS C є одна колоссальна перевага: він не ганяється за тим, щоб заради 2% в нікому не потрібному синтетичному тесті використати ще десяток UB там, де програмісти найменш цього чекають. Вони навіть SSA ввели тільки у 2015-му.

Це інша функція, більше комунікація.

Не плутайте асинхронні сигнали як SIGTERM з внутрішними синхронними, як SIGSEGV. (Їх взагалі не слід було обʼєднувати в один механізм.)

Зараз в сутності взагалі ніде не використовують

якось незвично бачити комент без історичного ракурсу в часи до і після Клеопатри в рамках сутності аналогій розвитку програмного парадигмування)

так, goto зазвичай легко розкручуються та замінюються в коді використанням інших конструкцій

Не завжди. І не завжди його треба виключати.

що не скажеш те саме відносно longjmp який іноді використовують — чим у такому випадку пропонуєте його обходити конструктивно в сі?

Ось саме тут в юніксах я сумую по SEH. Воно дійсно геніальна ідея, і нормально було б перекласти на нього всю обробку помилок, і мовні засоби обробки винятків теж робити через нього.

Не завжди. І не завжди його треба виключати

а ніхто і не сказав ще завжди-завжди), якщо то не переплетено в рамках дуже довгого полотна (яке само по собі напрошується на декомпозицію принаймні для читабельності) — нагайдайте практичні випадки де з ним в сі

в юніксах я сумую по SEH

якось не задумувався над тим, які трейдофс з тим можливі?

typos в коменті вище: нагадайте випадки використання саме локального «goto» з сі де то має сенс

Глобальна мітка cleanup де очищується все тимчасове, що нароблено в функції. Альтернатива у вигляді дуже уважного контролю, в якому з return треба на що сказати free, де повернути старе значення і все таке, зламається максимум на пʼятому параметрі, почнуть забувати.
(C++ вирішує це через RAII, Go — через defer, в обох випадках рахує дії вже компілятор.)
Розширений приклад: тут.

Вихід з другого і глибше вкладеного циклу, до сих пір в мові нема тегованих циклів і відповідно break/continue по тегу. Звісно, можна нарожати bool-флагів з перевіркою в умові циклу, і ifʼов в тілі, але навіщо?

Глобальна мітка cleanup де очищується все тимчасове, що нароблено в функції

з цим проблем особливо не зустрічав кодуючи щось, та довгі полотна функцій не подобаються бо важко читаються потім навіть самому через деякий час, а якщо без них — то більшість gotos у такому випадку немає необхідності використовувати

Звісно, можна нарожати bool-флагів з перевіркою в умові циклу, і ifʼов в тілі, але навіщо?

Якщо краще потім оптимізується компайлером чи читається в цілому — чомуб і ні, але не наполягатиму особливо на деяких випадках використання. Тому і написав «зазвичай» в початковому коменті відносно оцінювання з точки зору стилістики. Більш цікавий випадок то longjmp.

Якщо краще потім оптимізується компайлером

Ні (або я таких не бачив).

чи читається в цілому

Більшости — ні.

Більш цікавий випадок то longjmp.

А в чому різниця з try-catch?

в чому різниця з try-catch?

Якщо це не конкретизований кусок try{} коду, то по ідеї (imho) логічно повісити обробку нп signal з jump куди треба, що принаймні читається трохи більш інтуїтивно у цьому випадку ніж try what? синтаксис, хоча може це і досить суб’єктивно. Це так абстрактно обговорюючи сферичні коні, бо в сі тієї try конструкції принаймні покищо немає, і якщо такого типу goto розглядати з точки зору стилістики, то треба булоб (зновуж по ідеї) навести існуючу альтернативу (в сі) чи інший існуючий підхід (в сі) для заміни, бо обговорювали саме сі.

p.s. і це навіть поки не цікавилися як розглядати breaks чи навіть різні варіанти використання returns з тієж точки зору стилістики gotos

то логічно повісити обробку signal з jump куди треба по ідеї (imho)

Логічно її вішають саме туди, де був би try.

if (setjmp(buf) == 0) {
  // try block
} else {
  // catch block
}

А яка і чому потрібна альтернатива?

не зовсім зрозуміло як читабельно буде в цілому в деяких випадках, нп що зустрічав — всі деталі не згадаю зразу, але приблизно такого типу

// задали обробку на сигнали
set-sig-handlers;
// потім loop
loop {
  code;
  crit;
  code;
}

обробка приблизно така
— якщо прилітає зовнішній сигнал-команда який нас цікавить — виставляємо флаг (на який буде реакція потім десь в loop)
— якщо прилетів посеред crit секції/функції (з setjmp) ще і додатково повертаємось з longjmp туди

p.s. початковий ремарк взагалі був що замість узагальнення «такато конструкція то ознака поганого стилю», мабуть булоб краще сказати що її треба уникати якщо є можливість обійтися без неї (longjmp цікавило у цьому випадку), а якщо іншої існуючої альтернативи десь не знайшли — то це скоріше не питання стилю, а питання можливостей з існуючими засобами у мові програмування

обробка приблизно така
— якщо прилітає зовнішній сигнал-команда який нас цікавить — виставляємо флаг (на який буде реакція потім десь в loop)

І знову, це принципово різні випадки (і те, що в Unix вони обʼєднані в один механізм сигналів — тут заважає і розумінню, і, може, обробці).

Асинхронні сигнали на зразок SIGTERM, SIGINT, SIGIO, SIGUSR1/2, вся RT-група і не тільки — їх обробляти має сенс, для більш-менш складних програм, як раз тим чином, що ти описав: просто налаштувати канал прийому повідомлень і читати його. Це може бути зроблено декількома варіантами:
1) Традиційні обробники, ставлять флаг (типу sig_atomic_t) і виходять, і більш нічого не трапляється. Десь вже нагорі флаг регулярно перевіряється.
2) Сигнал замаскований, в циклі перевіряється, що прийшло, через sigpending().
3) signalfd (Linux), EVFILT_SIGNAL (BSD) ловлять факт сигналу в формі, придатної для mass poll форми.

Можна, звісно, і робити терміновий вихід з того коду, що зараз працює, але чим складніше програма і її дії, тим менш імовірно, що це буде з нагоди.

А ось синхронні події, такі, як доступ по невалідній адресі, вимагають обробки в тій нитці або корутині, де вони стались, і для них саме розмотка по стеку є найбільш природним підходом. А відкладати її в принципі не можна.

І ось тому для синхронних — якщо взагалі програма має вижити, то це або longjmp(), або SEH — принципово вони роблять одне і те ж. А ваш приклад з циклом в принципі не має відношення до цього.

Повторюсь, поєднання цього в одному механизмі було не зовсім адекватною ідеєю, і це збиває з пантелику.

мабуть булоб краще сказати

А так завжди. Хтось просто каже «не використовуйте goto там, де можна написати розгалуження через if або цикл через while, for; не стрибайте в середину циклу або блоку під if, якщо це не один cleanup на всіх», і це нормальна робоча порада. А хтось буде волати раненим вовком «кожний goto це злочин, вбивати на місці». І от других я не підтримую.

синхронні/асинхронні
поєднання в одному механизмі

погоджуся з більшістю опису та мабуть і в цілому також, а в нюанси з трохи відмінним баченням в якихось частинах — не продовжуватиму бо буде вже явно поза основною тезою

якось не задумувався над тим, які трейдофс з тим можливі?

Зараз, мабуть, ніяких, всі можливі недоліки вже пророблені.

В реалізації win32 була ціна на утримання стекового фрейма на кожну функцію, яка хоч якось обробляє винятки. В win64 замінили на табличний пошук, для якого лінкер генерує дані. Це складно, згоден, але все вже вироблено.

В Unix та ж задача була вирішена в ті ж часи в рамках C++, зі схожими підходами (sjlj-exceptions замінені на table-based), тобто код є, зневаджений, треба лише його прилаштувати.

Перевести синхронні винятки, викликані кодом, як то SIGFPE (ділення на 0), SIGSEGV (некоректна адреса памʼяти) і все таке — тривіально. Можна це робити викликом для конкретної нитки. Асинхронні, що приходять з інших ниток/процесів — тут треба подумати, включати чи в той же механізм, але спішити нікуди.

А ось переваги у вигляді поєднання всіх стилів обробки винятків тут можуть бути дуже смачними.

Щодо процедурного програмування — згоден, сама ідея з’явилася раніше. Мова C лише зробила її більш практичною та зручною для масового використання.

Таки не так. З мовою поширилось програмування в цілому. А в тих межах, в яких воно було раніше, до епохи, умовно, персональних компʼютерів класса від 386 и 1MB оперативки, те ж саме досягалось іншими мовами. Мови загального призначення і не лялькової без процедур не існувало, навіть в крихітному бейсіку з ПЗУ був gosub.

Сі тут має цікаву історію тому, що спочатку «на коні» Unix вʼїхав в світ серйозної розробки, а потім з IBM PC став відомим ширнармассам, в довгій боротьбі таки перемогши Pascal, фактично, за рахунок немочі найбільшої фірми, що його просувала. Якби не це, вся історія склалась би інакше.

GOTO ніхто й сьогодні не забороняє, але його застосування — радше ознака поганого стилю, ніж інженерної необхідності.

Є вимоги, коли goto неминучий. Але задля тої ж верифікації його обмежують. Навіть просте правило «goto тільки вперед по коду» усуває >90% проблем від його використання, і саме таке правило присутнє в стандартах типу MISRA. (90% решти усуває правило не стрибати в тіло циклу.) Але ці правила виробили пізніше того, про що писав Дейкстра, і, головне, той факт, що у переважній більшости випадків можна його замінити розгалуженнями, циклами і раннім return — рятує вже читача. А коли він всеж таки залишається — значить, реально був потрібний.

де головний акцент — на наслідуванні як інструменті повторного використання коду.

Ну ось тут проблема. У Go, Rust, деяких інших таке явно не дозволене чи має суттєві обмеження. Але казати, що з ними не можна ООП — це перебільшення.

Для мене ООП у першу чергу це подумкове встановлення сутностей (не обовʼязково з домену) і границь між ними, оформлення відповідальности (що дає інкапсуляцію) і взаємодії (інтерфейси, контракти і фінально LSP), а буде там наслідування чи ні — це вже друге (або третє, якщо вторим вирішити, чи мають обʼєкти бути активними).

Щодо Go — повністю погоджуюсь: відсутність наслідування справді призводить до дублювання логіки.

Ось :)

Коли ми говоримо про технології, не можна відривати їх від людського фактору. Популярність часто визначає не лише технічна доцільність, а й маркетинг.

Є таке (згадаємо той же Паскаль).

Достатньо згадати, що компанія Sun Microsystems витратила близько 500 мільйонів доларів на просування Java у перші роки її існування.

І вони зробили її ;)

Загалом, стаття не про процедури чи класи, скільки про те, що, навчившись мислити по-різному й розуміти різні варіанти розв’язання задач, розробник отримує змогу вибирати найбільш оптимальний підхід у конкретній ситуації, незалежно від мови програмування.

Угу. Ну, тут треба дещо більше конкретики, це статей пʼять:)

Писав багато разів, що ООП в тому вигляді, в якому воно є зараз, має дуже вузьку спеціалізацію та не підходить до швидкозмінних систем. Найкращим прикладом використання ООП є DOM. Але при використанні ООП для систем, які не детерміновані з самого початку та швидкозмінні за суттю, а особливо якщо вони ще й будуються за принципами fail-safe та fault-tolerant, то ООП-код настільки швидко підвищує рівні абстракцій, що миттєво стає малочитаємим та незрозумілим.

Події реального світу важко описувати в ООП, тому що він вимагає чіткої структури даних. А світ набагато варіативніший та не такий детермінований, як здається.

Події реального світу важко описувати в ООП, тому що він вимагає чіткої структури даних.

Здесь нет противоречия. Хотя и с ООП нет противоречия. четкость структуры данных способствует четкости мышления. В системах реального времени на первом месте проблема порядка выполнения.

Чіткість мислення не є вимогою реального світу. Тому що варіативність зазвичай набагато більша, ніж того хочуть розробники. Уявімо, що ви розробляєте систему автоматизації робочого процесу компанії. Поточний процес виглядає як A —> B —> C. Але через деякий час він змінюється під впливом обставин на C —> A —> B’ —> D. У вас не просто змінюється порядок, а ще й нові кроки додаються. Передбачити такі зміни майже неможливо на початку розробки, бо ані розробник, ані замовник не розуміють, що їх чекає через рік використання системи. Тому зазвичай в світі ООП робиться спрощення та «фіксація» правил. Інакше неможливо, бо ООП гарно в описі структур, але не в описі взаємодії між ними (тут ще імперативність своє з гори додає)

Поточний процес виглядає як A —> B —> C. Але через деякий час він змінюється під впливом обставин на C —> A —> B’ —> D. У вас не просто змінюється порядок, а ще й нові кроки додаються. Передбачити такі зміни майже неможливо на початку розробки, бо ані розробник, ані замовник не розуміють, що їх чекає через рік використання системи

Это интересная, но отдельная и очень важная тема. Но опять же. Это не проблема ООП. Я уже где-то здесь писал. Интуитивно большинство программистов подразумевают последовательное выполнение операторов. А теперь представь что машина работает строго по принципу адресация-событие-подписка. Тогда нет проблем добавить в любое место любое изменение последовательности выполнения. Необходимо только не начудить с ближайшими событиями. Что б сохранить новый требуемый порядок выполнения. Можно добавить в любое место что угодно, и построить новую цепочку. Этот принцип создает уникальные возможности в автоматизации и умных домах. Пользователь сам по своему желанию строит необходимые цепочки вообще не касаясь уже созданных объектов и их взаимодействие. Он просто делает подписки на необходимые события для выполнения актуальной проблемы.

А теперь представь что машина работает строго по принципу адресация-событие-подписка.

Так. Але цей патерн можна реалізувати не використовуючи ООП взагалі. Ось в чому сіль, ООП втрачає всі свої переваги, якщо йти в сторону подій та обміну сигналами.

Але цей патерн можна реалізувати не використовуючи ООП взагалі. Ось в чому сіль, ООП втрачає всі свої переваги, якщо йти в сторону подій та обміну сигналами.

Я ж говорю нет противоречия.

Скорее обратное, четкость мышления — пораждает четкось алгоритмов и структур данных. В обшем и всю область познания — науку, которая вообще вся базируется на формальной логике Аристотеля, и сама она в свою очередь базируется на системе мышления философии Сократа — аналитике, когда причина-следсвие. Если есть такой аппарат мышления, то парадигма программирования не столь уж и сушественна. Хоть Prolog хоть Haskel, хоть непосредсвенно ассемблер.
А когда мышление спутаное, выходит говнокод — он же спагетти код, на чем угодно.

Швидкозмінні скоріше про вимоги. З позитивних прикладів напевно VCL у Delphi 5, коли вимоги (Windows API) зрозумілі від самого початку. А от вже різні спроби перенести під Linux, .NET вже проблеми.

Один з головних китів ООП це наслідування, але проблема у тому, що ієрархія важко рефакториться і часто на початку ти просто не знаєш всі вимоги. DOM робили просто пофіксити щось на сторінці, ніхто не планував, що на ньому будуть будувати інтерфейси.

Друга проблема ООП це те, що вона провокує до оверінженірінга, часто можна бачити, що система фактично підтримує один сценарій використання, але проєктувалася під різні. Звісно що з часом підтримка різних стає атавізмом: вже не працює, але є.

і часто на початку ти просто не знаєш всі вимоги.

Це вимога розробників, які використовують ООП як основний патерн розробки. Їм потрібна чітка й детермінована задача. Інакше стає кепсько, бо рівні абстракій улітають в космос.
При інших патернах розробки, наприклад структурно-подійних, такої вимоги немає, бо вони сфокусовані на процесах, а не структурах даних. Структури там важливі, але виключно в контексті протоколів обробки даних. Пейлоад взагалі можна ігнорувати, він мало впливає на систему в цілому.

DOM робили просто пофіксити щось на сторінці, ніхто не планував, що на ньому будуть будувати інтерфейси.

Тут більше про успішність самого рішення з точки зору ООП. Ідеальний приклад, як на мене.

Друга проблема ООП це те, що вона провокує до оверінженірінга

Вона не провокує, це є основним недоліком ООП. Як там жартома кажуть, будь-яку проблему в ООП можна вирішити шляхом підвищення рівня абстракцій, окрім проблеми занадто великої кількості рівнів абстракцій.

Один з головних китів ООП це наслідування,

ніт

Події реального світу важко описувати в ООП, тому що він вимагає чіткої структури даних. А світ набагато варіативніший та не такий детермінований, як здається.

Там, де з ООП надто складно, без нього, майже завжди, непідйомна складність настає ще раніше.

Саме тому до сих пір ООП-шники шукають свій святий грааль та срібну кулю. Бо наче й не складно все, а криваві сльози з очей не перестають литися... :D

Я багато бачив прикладів, коли люди бралися за задачу без розуміння того, що вони мусили зробити в решті решт. Перші йшли шляхом «спрощення», тобто бачу стіл — створюю клас, бачу килимок — створюю клас. Стіл можна ставити на килимок? Ось метод та стан. Другі намагалися передбачити хоча б трохи майбутні задачі та зміни, та займалися улюбленим оверінженірінгом.

Результат в обох випадках був однаковим. Через пару років система була крихкою, мінімальні зміни були дороговартісними та з постійними помилками, не дивлячися на тестування та купу інших методик, які, начебто, мусили покращувати якість коду.

Спільне між двома підходами було одне. ООП. ;)

Саме тому до сих пір ООП-шники шукають свій святий грааль та срібну кулю.

Хто шукає? Всі хто хотів реально — давно знайшли.

Перші йшли шляхом «спрощення», тобто бачу стіл — створюю клас, бачу килимок — створюю клас. Стіл можна ставити на килимок? Ось метод та стан.

Виглядає нормально для простої гри. Що не так?

Другі намагалися передбачити хоча б трохи майбутні задачі та зміни, та займалися улюбленим оверінженірінгом.

Тоді справа в оверінжинірингу, а не в ООП. Overengineering можна зробити на чому завгодно і без ООП, і взагалі без компʼютерів.

Спільне між двома підходами було одне. ООП. ;)

Без якого не впорались би створити навіть таке, все б розвалилось під складністю задачі ще на далекій відстані.

Без якого не впорались би створити навіть таке, все б розвалилось під складністю задачі ще на далекій відстані.

Зновуж напевно термінологія та фокусування в абстрактних рамках, якщо взяти що маємо на практиці — нп два мейнстрім DE на базі GTK та Qt відповідно, обидва достатньо однаково популярні та розповсюджені. GTK підхід віднесемо до складних задач? бо хтось вбачає там деякі OOP властивості на далеких відстанях, хтось ні.

GTK підхід віднесемо до складних задач?

Да.

бо хтось вбачає там деякі OOP властивості на далеких відстанях, хтось ні.

Воно там є. Але реалізація на C вимагає glib-них трюків, після яких комусь таки може здаватись, що ООП нема.

після яких комусь таки може здаватись, що ООП нема

Навколо цього і вся дискусія крутиться, що вкладається в термінологію OOP або його рамки, і відповідно характеризується (абож оцінюється якимось чином) у залежності від того що вкладено.

p.s. тому певно легше іноді щось використовувати на практиці ніж надати тому універсальне визначення з яким усі погодяться

Хто шукає? Всі хто хотів реально — давно знайшли.

Це називається змирилися з реальністю. Нові патерни проектування, впевнений, до сих пір розробляють.

Виглядає нормально для простої гри. Що не так?

Прикол в тому, що то була не гра, а SaaS.

Тоді справа в оверінжинірингу, а не в ООП.

Під оверінжинірингом тут малося на увазі створення надлишкового рівня абстракцій, не потрібного в даному проекті, але закладеному, бо може знадобиться. Хоча проблема була взагалі в іншому місці. Не можна будувати статичну систему для варіативних потокових даних. Навіть з достатнім рівнем абстракцій.

Без якого не впорались би створити навіть таке, все б розвалилось під складністю задачі ще на далекій відстані.

Це вже припущення. ;)

Нові патерни проектування, впевнений, до сих пір розробляють.

Поки у нас фоннеймановські компʼютери — вони будуть не заміняти, а доповняти.

Прикол в тому, що то була не гра, а SaaS.

Непринципово. Коли підуть нові вимоги, стане ясно, куди рухатись. Але керування складністю завжди буде.

Не можна будувати статичну систему для варіативних потокових даних. Навіть з достатнім рівнем абстракцій.

Або ви погано пояснили, що ж там не так було, або проблема принципової зміни вимог.

Це вже припущення. ;)

Просто статистика і власний досвід. Нічого не ідеалізую, але без подумкового розділення сутностей і відповідальности, яка потім відображається у код, не можна написати ніць серйозного.

Просто статистика і власний досвід. Нічого не ідеалізую, але без подумкового розділення сутностей і відповідальности, яка потім відображається у код, не можна написати ніць серйозного.

Це підхід ООП. Я не кажу, що він поганий, але це один з підходів, які можна використовувати. ООП концентрує увагу в основному на логічній структурі та опису обʼєктів в першу чергу. Взаємодія також описується, але тільки в рамках того, що вкладається в певну структуру.

Але є інший світ. Світ, де функціональна складова є драйвером всієї архітектури, не другорядним якимось членом. Простий приклад — той самий ETL. Тут функція є основою. Немає різниці взагалі, що прийшло на вхід, якась конкретна структура, потік бінарних даних, чанк, чи ще щось. Важливо те, як саме буде вона оброблена.

Або візьмемо CRUD. Це чиста функціональна модель. Взагалі чхати з яким саме обʼєктом будуть проводитися операції. Це взагалі не важливо.

Знання та комбінування парадигм відкриває більше свободи й можливостей у написанні коду.

(і збільшують вимоги до розробника?)

ps взагалі цікаво але висновок не зрозумілий — бо знати усе і бути людиною оркестром неможливо

Спробую пояснити на прикладі. Уявіть, що ви проєктуєте нову систему й обираєте базу даних, яка найкраще відповідає задачі.
Для соціальної мережі логічно взяти графову БД — вона природно відображає зв’язки між користувачами. Для CRM, швидше за все, зручніше реляційна БД, де дані організовані у таблицях. А для системи аналітики поведінки користувачів — колонкова, як-от Redshift.

Так само і з парадигмами: одну й ту саму логіку можна реалізувати по-різному, і кожен підхід має свої сильні сторони. Ваш код може бути зрозумілішим, ефективнішим або лаконічнішим — залежно від того, наскільки вдало ви обрали підхід до задачі.

Тож питання не у зростанні вимог до розробника, а у розширенні його можливостей і глибшому розумінні інструментів, якими він володіє.

а у розширенні його можливостей і глибшому розумінні інструментів, якими він володіє

де ж тоді спрощення на які націлені сучасні ЯП, коли складність збільшується усюди?

Щоб відповісти на це запитання, спершу треба визначити, що таке складність.
Складність — це не властивість системи сама по собі, а когнітивне навантаження, яке виникає, коли ми стикаємось із проблемою (детальніше — у посиланні наприкінці статті).

Нові мови програмування дійсно прагнуть зменшити це навантаження — вони дозволяють писати код зрозуміліше, лаконічніше. Те саме стосується і парадигм.

Спочатку, коли ви опановуєте нові інструменти чи підходи, дійсно здається, що стає складніше. Але коли застосовуєте їх у реальних задачах, рішення стають простішими — для вас і для команди.

Наприклад, DDD пропонує створити спільну мову проєкту — це може виглядати складно на старті, зате пізніше значно спрощує спілкування в команді й зменшує непорозуміння.
Так само й обмежені контексти: їх важко визначити спочатку, але працювати в межах чітко окресленого контексту набагато легше, ніж у хаосі всього проєкту.

а когнітивне навантаження, яке виникає

Цикломатичну складність я ще можу зрозуміти, а от як виміряти когнітивне навантаження?

вони дозволяють писати код зрозуміліше, лаконічніше

Не завжди, є наприклад Rust. Будь яка нова мова в принципі намагається вирішити якусь конкретну проблему, для якої немає гарного вирішення в конкурентах. Наприклад, є проблема з bad pointer access, та інші помилки, які важко відслідкувати. От Rust пропонує щоб компілятор доводив, що таких помилок немає.

Метрики складності коду корелюють з розумовим напруженням розробника який має справу з кодом. Тому рахувати метрики і намагатись їх зменшити корисна штука.

Метрики складності коду корелюють з розумовим напруженням розробника

Як конкретний параметр може корелювати з балабольством?

намагатись їх зменшити корисна штука

Угу, в результаті отримуєш ідеальний за метрикам код, з яким неможливо працювати. Будь яка складність, яка притаманна задачі, неможливо прибрати. А метрики привести можна завжди.

Головна проблема «метрик»: вкладаючись в «цикломатичну складність» люди часом винаходять «прихований інтерпретатор» з своїми власними «if-ами», «циклами» й тд...

Як в тому анекдоті «Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.» тільки то не «Common Lisp» а набір «конфігурацій» що нібито «задає взаємодію» й всяке таке, а по факту просто переносить складність галуження та прийняття рішень в інше місце, таке, що не покривається «метриками»...

(звісно «це все» неодмінно на XML/JSON/YAML з своїми прихованими стейтами, підстановками тексту та рештою приколів, аби тільки не було подібне на код, й то практично неможливо дебагати, go to definition не робе, й ніхто насправді не знає як «конфігурити», зато метрики зашибісь)

«задає взаємодію» й всяке таке, а по факту просто переносить складність галуження та прийняття рішень в інше місце, таке, що не покривається «метриками»...

але ж це дозволяє не перекомпілювувати бінар кожного разу для нових параметризуючих змінних

це тільки якщо «конфігурація» зовнішня, а не є частиною білда... а вона ще й «кодогенерує», причому для «коду згенерованого вілідованого тулою» проджастіфікували, що «метрики не міряться», й там «каша», дебагати неможливо...)

Втім, навіть зовнішня «конфігурація з файлів», де самовинайдена «кастомна мова конфігурації , але що з своїми власними «if-ами», «циклами», «варіейблами», «підстановками», то велика печалька, її цілком можна було б замінити на умовну Lua (чи й «заембеджений» Python!) й тоді «конфігурування» стало б в рази легшим, але ж «нізя, бо тоді це вже код»...

а то що вони на XML/JSON/YAML/кастомній «конфігураційній мові» по факту створили свою власну нову тюрінг компліт мову програмування (тобто це також код!) де все глобальними варіейбами, й яку саму треба тестувати, мейнтейнити (а спеки/туторіала так ніхто й не написав, а ще після чергового «фікса» вилітають «конфігурації» в деяких з юзерів), то таке чомусь «ок» для «винахідників», бо «це ж XML/JSON/YAML»...

Й «тюрінг комплітнес» такої кастомної мови не визнається розробниками спецом «з політичних/маркетингових міркувань», мало того, подаєтьться і продається що «це просто», як «no code солюшен» й тому подібне, в той час як по факту надурені маркетологами «кінцеві юзери» (вірніше рядові працівники, кому їх менеджмент втюхав no-code інструмент) придумують всі можливі воркераунди щоб зааб’юзити «мову конфігурування» під свої потреби, й там «каша» в рази гірша, ніж найпотворніші конструкції темплейтів та макросів в С++ (на які в самому проекті — строгі обмеження, «нізя, бо це ускладнює»)... а потім знову розробники «no code» г*внотули повинні розгрібати то все в намаганні репродюснути, знайти руткоз «що нетак»...

В результаті всі гроблять час на освоєння й дебаг унікальної (й нікому непотрібної за межами убогої «екосистеми») кастомної мови, що її навіть в резюме не згадаєш, тому «текучка кадрів» навіть в ті часи, коли з роботою не просто.

всі гроблять час на освоєння й дебаг унікальної ...

В раст середовищі «всі знають що» — якщо зібралося значить працює так як треба. Тому дебажити слово застаріле, і залишено покищо мабуть тільки для сумісності та роботи зі старими багами)

а шо раст ансейф? — було десь в коментах щось типу що там — ансейф це не той ансейф який ансейф, а так... якби легка форма мета-сейфті, ні?)

Ем... я щось не зрозумів, то «закид» до того, що Rust «теж не святий» й його треба дебагати... Ну треба, і що?
Звісно, що навіть якщо умовний <назва_мови_програмування> не дозволить «натупити» в <перелік_запроваджених_гардів>, то є ще купа способів «натупити» в чомусь іншому (що не покрито тими гардами)... і що?

Чи то закид до того саморобна Тюрінг компліт г*вномова на базі XML/JSON/YAML по якій нічого не нагуглиш, яка не має повної документації, ні підтримки IDE і так далі все одно краще від <назва_вже_існуючої_мови_програмування>?))

Чи «щось інше», на тему «метрик складності коду», звідки й почалася власне розмова в цій гілці, зокрема й про те, як люди винаходять способи перенести складність за межі «метрик», й від того стає не «краще» а «гірше», бо складність для людей тепер вища, зато за прийнятими «метриками» нижча.

на тему «метрик складності коду», ... винаходять способи перенести складність за межі «метрик», ... бо складність для людей тепер вища, зато за прийнятими «метриками» нижча

занадто складно викладено без прикладів, не так складно як «делікатна рейнфорест екосистем», але таки складно)

Не порушуючи NDA, пропоную на прикладі... XSLT (чисто для ілюстрації, не має нічого спільного з конкретними проектами), вона Тюрінг компліт, але в той же час XML...

... І от хитрі програмісти замість того, щоб писати умови й цикли в своєму коді покритому метриками, вони пишуть їх на умовному «XSLT» (не на справжньому/готовому/задокументованому, а на видуманій ними мові, з своїми «правилами», своїми «варіейблами», «стейтом» й спецом з таким інтентом, щоб не покривати код метриками... й мова не про трасформації XML в XML а про «інші галузі»)...

Тепер формально «метрики хороші» (й навіть регулятно покращуються!!! коли ще чергова частина логіки переїхала в «конфігураційну мову на базі XML/JSON/YAML») але насправді мейнтейнити/дебагати/підтримувати/розвивати таку «пакращену» систему стає все складніше й сладніше всупереч «кращим метрикам»...

PS/ звісно, що початково девелопери не мали «злого умислу приховати правду», просто «так вйшло»...))

чимось нагадує complexity в ракурсі declarative vs imperative порівнянь у програмуванні

Єдиний «об’єктивний критерій» то садити людей вирішувати одну й ту саму задачу різними мовами й міряти час (теж «з нюансами», бо взятий HRами випадково «простий смертний» vs «підготовлена й натаскана людина» то дві великі різниці, й спочатку в зразково-показовому тесті «підготовлена й натаскана людина» переможе, а на практиці HRи все одно знайдуть тільки «простого сметного»)...

Ну й, врешті решт, одразу взяти вже готову мову (не розглядаємо declarative чи imperative) виглядає більш раціонально, ніж методом ходження по граблях «винайти» потворну пародію поступово додаючи «фічі».

я не шукав помилки в метрико-складності, не знаю

Складність — це не властивість системи сама по собі

та що ти кажеш!
В тебе є розмірний ланцюг на 2 елементи, і є на 10.
Який складніший?
Яка імовірність поломки системи при однакових імовірностях поломки елементів?

В контексті розробки ПЗ важливо наскільки ви гарно розумієте код та систему в цілому, для того щоб мати можливість її змінювати і розвивати.

Тому говорячи про складність я і беру контекст розробника. Один розробник гарно знає систему, для нього система не складна. Інший, наприклад тільки почав з проектом працювати, і тому реалізація логіки у нього може викликати труднощі. Система одна, але для різних розробників вона по різному складна.

Звісно чим більше файлів, зв’язків, методів, і т.д. тим важче для розробника буде зрозуміти програмний проект. На основі цих артефактів можна порахувати метрики складності, і скоріше за все при збільшенні значень метрик буде зростати розумове навантаження програміста.

Тому, якщо брати ваш приклад, то так, система з 10ох елементів скоріше за все буде складнішою для розуміння за систему з 2ох.

Ваш контекст оцінки не має критеріїв для вимірювання складності системи і є суб«єктивним, тобто нічого не вартий: «я художнік, я так віжу»

Якраз про це й ідеться — складність (згідно попереднього визначення ) не є абсолютною характеристикою системи, а залежить від того, хто і як із нею працює.
Наприклад, зрозуміти код стає простіше, якщо його просто підсвітити різними кольорами — як це роблять сучасні IDE. Сама система при цьому не змінюється, але розробнику працювати з нею легше.

Метрики — це лише спроба об’єктивізувати те, що насправді впливає на розуміння людини.
Тож мій контекст — не «я так бачу», а усвідомлення того, що програмна система складна настільки, наскільки складно її зрозуміти й змінити.

Складність не залежить від того хто і як з системою працює.
Це властивість системи. Напр. як маса, чи довжина.
Ви інженер?

інженер

А

складність

треба пояснювати по айтішному, хочби в такому стилі youtu.be/ct1-zq8gf_0?t=54

система з 10ох елементів скоріше за все буде складнішою для розуміння за систему з 2

дуже залежить від того, як ті елементи взаємодіють й про які елементи мова... й що саме розуміємо під складністю, що досліджуємо...

2 елементи, кожен з який по 200АПІшок — значно складніше за 10елементів з 5-7 АПІшок...

Й яку «метрику» не придумай, як тільки її показати воконавцям, а особливо якщо почати їх панішити їх за фігові показники й винагороджувати за кращі, то вони придумають як ту «метрику» обійти й перемістити складність туди, де вона не вимірюється взагалі...

Зазвичай ти дивишся на структуру даних, конкретні запити та як просто та ефективно їх реалізувати.

А от парадигми це погляд менеджера, який щось там чув, щось читав, тому впевнений, що саме база даних XXX найкраще підходить для вирішення задачі. А потім розробники це розгрібають.

Зазвичай ти дивишся на структуру даних, конкретні запити та як просто та ефективно їх реалізувати.

Очень показательная точка зрения. Т.е. то, что операторы выполняются последовательно само собой разумеется. А вот и отнюдь.

Архитектурные решения о том, какую БД использовать для проекта, принимаются на таком уровне абстракции, на котором мало кто думает о том, как выполняются отдельные операторы.

Вот не хорошо когда такие архитекторы принимают решения.

Ось вам задача:
У системі соціальної мережі великого розміру потрібно визначити, чи пов’язані між собою два користувачі ланцюжком знайомств будь-якої довжини, та за потреби визначити послідовність користувачів, через яких проходить цей зв’язок.
Порівняйте рішення на основі Postgres та Neo4j по простоті рішення і часу відповіді.

Але знову це конкретна задача пошуку в графі, конкретний запит. Для його виконання треба графові бази. Але... виникає питання, чи дійсно така задача актуальна для соцмережі? Скільки я не користувався, я не бачив чогось подібного, друзі друзів максимум. Тому знову, це не на рівні парадигм, це на рівні конкретних вимог.

чи пов’язані між собою два користувачі ланцюжком знайомств будь-якої довжини

Задача нереальна з самого початку. Як академічна, можливо, як практична — безглузда та не має вирішуватися через хибність початкових умов.

Порівняйте рішення на основі Postgres та Neo4j по простоті рішення і часу відповіді.

Ви порівнюєте тепле з мʼяким. Рішення PostgreSQL може бути швидше за Neo4j, якщо там всі варіанти звʼязків будуть попередньо предкалькульовані та складені в форматі JSON під певним хешем, ключі партиційовані та розбиті на шарди.

Нажаль на ООП лайні навчили ШІ моделі і тепер недолугі вайбкодери будуть його штовхати в натовп ще років 20.
Замість того щоб його позбутися звільняючи дорогу більш потужним парадигмам, вирішили заткнути дзюрки цифровим монкі кодєром, який пише код навіть ще гірше ніж людина.
Історія в ІТ завжди якось звертає туди де більше складності та треша, щоб на черговому колі зробити ще більшу бульбашку з ІТ.

Історія в ІТ завжди якось звертає туди де більше складності та треша

і не тільки іт, це як «наші недоліки продовження наших переваг» або «боротьба за мир була такою що від світа не залишелось каміння на камінні» або «зворотьня сторона прогресу» тобто чим більше шось покращуємо тим більше його перевантажуємо складністю, тому потрібні «прості, елегантні, інженерні рішення» а не вигадувати чергову пимпу «зроби мені красиво» або «універсальна парадигма» все одне фізику не обдуриш, треба працювати мізками very hard якщо хочеш гарний результат і ніякими «універсальними парадигмами» це не замінити

«універсальна парадигма» все одне фізику не обдуриш, треба працювати мізками very hard якщо хочеш гарний результат і ніякими «універсальними парадигмами» це не замінити

Все правильно. Есть всего одна проблема. Физический мир не детерминирован, алгоритмы и вся императивная парадигма детерминированы. Поэтому на лицо противоречие для построения универсальной модели.

Поэтому на лицо противоречие для построения универсальной модели.

якщо алгорими та імперативна парадигми детерміновані то чому не можна створити «універсальну парадигму»?

якщо алгорими та імперативна парадигми детерміновані то чому не можна створити «універсальну парадигму»?

Потому что «физику» не обманешь

так ви ж самі вище сказали, що мова не про фізику яка НЕ дермінована, але про алгоритми які детерміновані, то у чому проблема? у тому що алгоритми також НЕ детерміновані як і «фізика»?

Я так не говорил. Это вы так поняли. Повторюсь. Физический мир не детерминирован. Вот так получилось. Алгоритмы, машина Тьюринга-детерминированы по определению.

Алгоритмы, машина Тьюринга-детерминированы по определению.

якщо так, то чому не може бути унівесальної парадигми в мовах програмування?

якщо так, то чому не може бути унівесальної парадигми в мовах програмування?

В императивной парадигме не может. А в моей парадигме может. Вот он. www.youtube.com/watch?v=jLsKa4Oy3xk

квантова невизначеність, ентропія, розподіл Больцмана-Максвела і т.д. і т.п.

Автору спасибо. Не детскую тему поднял

Я за свої 25 років у програмуванні, зрозумів, що для кожного завдання треба вибирати свій інструмент. Тоді виходить ефективніше та якісніше. А ліпити, наприклад, патерни всюди, заради патернів, ну ліпіть, але без мене. Ось простий приклад із практики останньої, для мого проекту, яким я працюю вже понад два роки, треба розробити десктопну програму. Воно потрібне з двох причин тому, що зручно користувачам і тому що є у конкурентів. Вибір підтримуваних ОС: лише Windows 10/11. Вибір засобу розробки: .NET 10 + C# + WinUI або WinForms — я ще не починав розробку. При чому я не впевнений, що завдання вирішуване на WinUI, основна проблема реалізувати аудіо/відео плеєр з базовими функціями — це не так просто як здається. Підкажіть куди копати, якщо знаєте? Чому не C++ і Qt чи там C++ MFC/ATL. З двох причин я не настільки добре знаю ці бібліотеки і коли я з ними працював, це було просто дуже повільно і жахливо.

Вибір засобу розробки: .NET 10 + C# + WinUI або WinForms — я ще не починав розробку.

Ну раз ещё не начинали разработку, значит лучше посмотрите на Flutter, а не на старые темы увязанные строго под венду. Встроить аудио/видео плеер там не является проблемой. Ну а под венду для мультимедиа есть старая как говно мамонта библиотека MCI, и вполне простая.

лучше посмотрите на Flutter

Там наче чітко написано, лише віндовс 10/11, а значить беремо стандартні засоби розробки під вінду, а саме дотнет і вінформи. Тим паче флаттер працює усюди погано, і взагалі він має зникнути.

Насправді, якщо трошки подумати то ці парадигми/мови не такі вже й різні. Крок за кроком:
— В нас немає нічого — окрім go-to
— В нас є процедури, що таке процедура? Фактично то й ж самий go-to туди-назад, ну й записали аргументи в участки памʼяті. Ну й отримали костильний С
— В сі в нас є структури, давайте писати приватні поля з _ - отримали інкапсуляцію, додали функцій які першим аргументом приймають структуру — ось вам примітивний С++. Можна погратись з вказівниками й навіть наслідування й поліморфізм зробити.
— Будь яка мова яка дозволяє функцію як параметр — дозволяє писати в функціональному стилі.

Що я хочу цим сказати? А нічого, такий ж набор букв без жодної корисної інформації як ця стаття.

Набагато важливіший розподіл коду на рівні, правильні абстракції, а вони є усюди, навіть в простому c — в нас є хедери, в яких можна задати інтерфейс, й імплементації — .c файли, треба переписати програму під інший девайс? Просто підключаємо інші .c файли які інтегрують залізо, без змін в логіці. Й це можна робити й без ООП, функціональщини й так далі й так далі.

якщо зазирнути в середину, то все воно нуль та одиниця )))

Ну в цілому так ) Там нижче Andrii Sevastianov допоміг мені правильно сформувати думку )

Будь яка мова яка дозволяє функцію як параметр — дозволяє писати в функціональному стилі.

Ок, якщо брати чистий функціональний стиль, то це не просто «функції як аргументи», а заборона змінних і циклів, а також строгий контроль над сайд-ефектами. Саме це дозволяє, наприклад, реалізувати STM (Software Transactional Memory), такий механізм роботи зі спільними ресурсами, який повністю усуває data race та deadlocks. Якщо виявлено конфлікт, транзакція просто перезапускається з початку. Трохи це нагадує блокчейн, де кожен стан це чистий «сліпок». У мові без таких обмежень це неможливо: якщо сайд-ефекти можуть відбуватися будь-де, ти ніколи не зможеш гарантувати, що транзакція дійсно «атомарна».

Тому для мене будь-яка парадигма це не додавання можливостей, а накладання обмежень. Структурне програмування — відмова від goto. ООП — інкапсуляція, яка ховає стан. Функціональне (чисте) програмування — відмова від мутації та довільних ефектів.

Саме обмеження створюють нові можливості. Бо з ними йдуть гарантії, а гарантований код можна компонувати, аналізувати, розпаралелювати... і довіряти йому. Саме тому мультипарадигмові мови іноді виглядають як повії: вони дають усім, але ні з ким не зобов’язані.

Ок, якщо брати чистий функціональний стиль, то це не просто “функції як аргументи”, а заборона змінних і циклів, а також строгий контроль над сайд-ефектами.
Тому для мене будь-яка парадигма це не додавання можливостей, а накладання обмежень.

В цілому я це й хотів сказати, що воно більше про стиль написання коду, ніж про можливості мови, тому я з вами згоден тут. Плюс щось схоже писав й Мартін у clean architecture:

Structured Programming. ... Dijkstra showed that the use of unrestrained jumps (goto statements) is harmful to program structure. As we’ll see in the chapters that follow, he replaced those jumps with the more familiar if/then/else and do/while/until constructs.

Object-Oriented Programming. ... We can summarize the object-oriented programming paradigm as follows: Object-oriented programming imposes discipline on indirect transfer of control.

Functional Programming. ... We can summarize the functional programming paradigm as follows: Functional programming imposes discipline upon assignment.

Notice the pattern that I’ve quite deliberately set up in introducing these three programming paradigms: Each of the paradigms removes capabilities from the programmer. None of them adds new capabilities. Each imposes some kind of extra discipline that is negative in its intent. The paradigms tell us what not to do, more than they tell us what to do.

Функціональне (чисте) програмування — відмова від мутації та довільних ефектів.

Це приблизно як в асашай корупцію побороли: назвали її лобізмом і легалізували.
І все — НЕМА!

Будь яка мова яка дозволяє функцію як параметр — дозволяє писати в функціональному стилі.

Сміливо. І в самому загальному сенсі — навіть правильно (turing machine еквівалентна lambda calculus). Але питання в тому наскільки це буде зручно, бо можливість передати функцію як параметр — це зовсім не еквівалентно тому, що тепер в нас мультипарадигменна мова.

І що?
Я, власне, про те що можливість передати функцію відноситься до сучасного ФП — приблизно як «в нас тепре є кейворд class» у старому C++ (він же С з класами) до сучасного ООП в нових стандартах C++.
Тобто — воно потрібно, але явно недостатньо.

«Funarg problem» явно показує що «можливість передати функцію як параметр» взагалі сама по собі явно «недостатня» для «писати в функціональному стилі»...

Фраза «наскільки це буде зручно» багатьох не спиняє, й вони вважають, ніби зафмаються «ФП» втім навіть не розвязали «Funarg problem» в своїх «фреймворках»...

(зараз можна розвести ще одну дискусію впаралель про те, хто й що розуміє під «ФП», яке «ФП» є «канонічним» а яке «недуже», й, може так виявитися що «правильного фефінішена для ФП не існує» так само, як ото не знайдеться «єдиного істинно правильного дефінішена» для «ООП»...))

А що ще мертве?
Хто там на черзі?

В октябрі, в октябрі
Частий дождік на дворі.
На полях мєртва трава,
Замолчал кузнєчик.
Заготовлені дрова
На зіму для пєчєк.

Маршак©

Але при цьому дуже швидку.

а с чем сравниваем? с Python? ну тогда — да

Casey Muratori недавно сделал большую ретроспективу, посвященную истокам ООП идей
кто интересуется темой и еще не смотрел — рекомендую
youtu.be/...​zx5nI?si=0Bcsyp24cUbVfmlT

Клікбейт. Не витрачайте час.

Схоже, ви зупинилися на заголовку і не читали саму статтю.

На жаль прочитав. Тому і раджу не витрачати час іншим.

Тоді буду вдячний за конструктивні зауваження. На жаль, ваша порада занадто лаконічна, щоб навколо неї можна було вести дискусію.

Ще раз, матеріал статті неконструктивний, псевдофілософський, недоказуємий, будується на уявленях автора. Які тут можуть бути конструктивні зауваження?

Оу, прям, з язика зняли. Дякую. Я б ще додав що у ресурса є заявка на серйозність і такі назви не припустимі, бо люди витрачають час на читання а профіт — трохи менше нуля.

Ваш коментар — гарний приклад різних парадигм мислення 🙂. «Я не побачив сенсу у викладеному матеріалі...»:
— отже, матеріал поганий, бо я найкраще знаю і розумію цей предмет;
— можливо, варто уважніше ознайомитися з контекстом і джерелами, щоб зрозуміти задум автора.
Зрештою, саме вам обирати той підхід, який видається більш конструктивним і корисним особисто для вас.

отже, матеріал поганий, бо я найкраще знаю і розумію цей предмет

Ні, я писав, що немає сенсу. Що таке сенс? Ландау, коли йому задавали питання з квантової механіки, любив першим ділом починати «А чи має сенс це питання?» Або, чи можна його за дати з використанням математичного апарату. Якщо цього принципово зробити не можна, то це не питання.

Так і тут, ми не бачимо визначень, ми бачимо терміни які можна розуміти по різному, в результаті не отримуємо комбінаторний вибух математичних інтерпретацій, що помножує на нуль користь від читання. Єдине що це може наштовхнути тебе на певні свої думки.

Ок, візьмемо більш менш конкретний фрагмент:

Функціональне програмування:
— Задачі без стану: трансформації, фільтрація, агрегація.
Де використовується: компілятори.

Тут виникає питання, що таке стан? Монада State у Haskell це стан чи не стан? Software Transaction Memory працює зі станом чи це щось інше? Будь яка компіляція це в принципі робота зі станом, чи як треба це розуміти??? Так можна чиплятися до кожного речення, але.. навіщо? Це як намагатися зловити на протиріччях в регілії ортодоксальних євреїв.

і джерелами

Греді Буча я читав 30 років тому. Дейскстру... можливо читав, це просто окрема стаття про досить екзотичну можливість, яка зараз неактуальна, тому що окрім goto exit в embedded (drivers) знайти його в коді ще проблематично. Еванса я й читати не хочу.

Що таке сенс? ... питання з квантової механіки

Поряд з сенс і розумінням чого-небудь — це антітеза, і в цьому випадку — квантову механіку можна наводити як приклад нерозуміння природи яких-небудь явищ, тобто квантово-класичні — shut up and calculate

а то нічо, що це не перший такий коментар про клікбейт і ніачом

ООП мертва? Ні, автор інфором, а загаловок клікбейт.

А чи не може такого бути — що необхідність використання клікбейт для привернення уваги до ООП топіка — говорить що в деякому сенсі «ООП мертва»?

А для чого, щоб викопати стюардесу і продовжити непотребство?

Для чого це може бути наступним питанням, а якщо заговорили про «викопати» — напевно вважаєте що відповідна парадигма таки «мертва».

тоді, якщо ти користуєшся GUI, то трахаєш труп ООП

GTK нп це сішний фреймворк (хоча при бажанні абстрагування можна також сказати що все то є ООП бо оперує деякими об’єктами). А про «викопати» та парадигма «мертва», то дехто інший цікавився)

Є ціла книжка про Object oriented progrmannig in C

як приклад flexibility and adaptability of a procedural language?)

так, це одна з приємних фіч чому може подобатись C, навіть в рамках GUI фреймворка

Все правильно: заголовок зроблено лише для привернення уваги. Хоча часто зустрічаю (на жаль) проєкти, де ООП радше «мертве», ніж «живе» — навіть там, де воно було б цілком доречним. Те саме з ФП та SQL: щоб отримати від них користь, потрібно не просто використовувати терміни, а справді знати й уміти застосовувати ці підходи.

Ну чому ви знов звалюєте ФП та SQL в один казан? Типу «here be dragons» — не ходіть сюди?
Ну до того що ФП прийнято вважати одночасно складним «конгрес, німці якісь ... тобто монади, функтори — взяти все й поділити» і «ми можемо передати функцію як параметр — наша мова теж вміє в ФП» вже звикли давно.
А що ми вже дожилися до часів, коли SQL — це теж щось складне, що не кожен знає? Краще не лізте, а то як напишете select * без where і почнете в пам’яті результати обробляти?

Ну тут по болючому. Працював над фронтендом одного проекту, треба було кілька записів за раз створювати, кажу бекендеру — додай такий-то кінець в апі. Він мені — так ти в циклі надсилай, по одному. Відповідаю — це довго буде 😅, а так за раз надішлю і усе. Каже — ну так тут теж довго буде, поки в бд буду записувати...

Довелося йому сказати, що insert може кілька записів приймати за раз...

чув таке, що кілька values в інсерт за раз — це не по стандарту sql, лише розширення мов різних реалізацій. перші sqlite приймали лише одне значення. правильно завертати кілька інсертів в одну транзакцію. begin; insert ... ; intsert ...; ... commit;

Як автор пропонує вирішити UI? Там об"єк на об"єкті і об"єктом поганяє.

Ну... ідеї досить популярного React взяті з функціонального програмування. Є Elm, де це можна побачити в чистому вигляді. Якщо брати класичний традиційний ООП, то маємо обʼєкт (Button), який має стан, і можна писати button.setText("Click me!"); Обʼєкт сам себе малює, повідомляє про зміни, тощо. Це виглядає на початку круто (привіт Delphi!), але у складному UI стан розмазаний по сотнях об’єктів.

Якщо брати функціональний підхід, то у нас UI це функції стану: UI = render(state); Якщо брати той же Elm, то у нас Model  -> View -> Update, де Model це імутабельний стан, View це функція Model -> HTML, Update знову чиста функція (Msg, Model) -> Model.

Якщо брати сучасні UI фреймворки, то виглядає так що вони багато запозичують з чистого функціонального підходу (без імутабельності).

Стаття про те, що треба використовувати ту парадигму, яка в даних умовах є найбільш доречною. Відповідно, щодо UI потрібно враховувати швидкість і ресурси. Те, що може виглядати доречно з точки зору зрозумілості коду і моделі, на практиці може працювати недостатньо продуктивно або споживати велику кількість ресурсів.
Ідея в тому, що можна розширити свої можливості в межах однієї мови, просто навчившись мислити по-іншому.

Йой, а якщо в процедурній мові є бібліотека, де реалізоване, що зараз прийнято називати ООП — це точно не заперечує ООП як парадигму?

Треба згадати і про DOD і напевно один з найбільш популярних докладів по цій парадигмі neil3d.github.io/...​ssets/img/ecs/DOD-Cpp.pdf

Автор пише про парадигми так, ніби вони існують насправді. Це більше піар та хайп. Не існує конструктивного визначення ООП, щоб можна було для кожної мови програмування автоматично визначити чи є вона ООП, чи ні. Ми не будемо сперечатися, чи підтримує мова ADT, чи є там GC. А от у разі ООП...
Для Java-розробника: якщо немає класів, то це не ООП. Для Go-розробника: інтерфейси + методи = ООП. Для Smalltalk-ентузіаста: немає повідомлень значить не ООП. Для C-програміста: якщо я можу змоделювати об’єкт, значить це ООП. Python та C++ це просто дві абсолютно різні мови, між якими немає нічого спільного. Якщо їх обидві відносять до ООП, то це означає, що краще термін не використовувати. І коли Дейкстра та Вірт казали про ООП протилежні речі, то я впевнений, що це вони казали про різні реалізації.

Не кажучи про те, що визначення змінюються, я памʼятав три кита ООП, зараз туди вліпили абстракцію, щоб ніхто не розібрався. Будь яка мова це абстракція над асемблером.

І це...
Процедурне: мінімум абстракцій, писати треба ядро ОС. Ну-ну... пиши ще.

Проте кількість задач, які зручно вирішувати в рамках функціональної парадигми, значно менша у порівнянні з іншими. Про це свідчить статистика використання мов програмування.

Статистика використання мов програмування це відображення популярності, екосистеми, ринкового попиту, історичного навантаження, доступності навчальних ресурсів, а не об’єктивної зручності чи ефективності парадигми для вирішення певних задач. На Haskell не пишуть тому, що треба переродитися, забути все та навчитися програмувати знову з нуля.

На Haskell не пишуть тому, що треба переродитися, забути все та навчитися програмувати знову з нуля.

Пожертвування «переродитися» та «знову з нуля» можна віднести до об’єктивної незручності опанування конкретної мови програмування як інструменту для роботи. Незручність засвоєння/опанування (як і кількість витраченого для того часу) певним чином виливається і в популярність чи статистику використання. Потім можна поставити питання — якщо вимагають «переродитися» саме під мову програмування, то можливо і з самою функціональною парадигмою щось не так, чи тільки з конкретною реалізацією?

Ну... у дитинстві, коли я тільки почав грати в бадмінтон, тримав ракетку «як зручно». Потім довелося перевчатися: ефективна техніка виявилася зовсім іншою. Те саме з морськими вузлами: спочатку здаються надуманими, але потім розумієш, що вони працюють краще, ніж твої «інтуїтивні» в’язки.

Тож, на мою думку, конкретно Haskell це не «неправильна» парадигма, а просто неінтуїтивний, але ефективний інструмент. Проблема не в самій мові чи підході, а в тому, що вона вимагає змінити звичне мислення. І це нормально. Багато чого в інженерії спочатку здається «незручним», доки не почнеш розуміти, навіщо воно таке.

І, чесно кажучи, я б уникав загальної розмови про «функціональну парадигму». Це поняття настільки розмите, що під нього можна підкласти що завгодно.

неінтуїтивний, але ефективний інструмент

— якщо достатньо ефективний в цілому — то мав би існувати значний об’єм софта у загальному використанні, незважаючи на зусилля які потребує засвоєння такого інструменту
— якщо не в цілому — то повертаємося до пункту «задач, які зручно вирішувати в рамках ...», і можна додати ще актуальність саме тих задач

Хоча як деякий баланс між різними факторами також можливо розглядати, але тоді відповідно булоб досить логічно розглядати ефективність зновуж в цілому.

Не треба недооцінювати вартість входу. Математика це дуже потужний інструмент, але математики не займаються бухгалтерським обліком, вони працюють із гомотопічними типами, будують ∞-категорії або класифікують кобордизми. Таким чином виникає невеличкий орден фанатів, який вирішує свої проблеми неймовірної складності, орден відкритий, але щоб вступити в нього треба прикладати чимало зусиль. Спільнота функціональщиків чимось нагадує такий орден. Вони не намагаються довести, що мова програмування Сі це гівно. Вони не намагаються переписати весь софт на OCaml чи Haskell. Великого виклику в цьому немає. Так, силами спільноти розроблені cabal, NixOS, бо це загальне велʼю в інтересах кожного у спільності. А от вигід на межу в той же Open Source ускладнюються: одному розробнику ще й поєднуючи з роботою, зробити складно, а підхопити нікому.
Але все ж таки чисте функціональне програмування впливає й на звичайну розробку, багато архітектур популярний фреймворків мають ясні корені. Виглядає так, що є проблеми, приходять до функціональщиків: я ви як вирішуєте? А ось так! Гарно, треба й нам: React, SwiftUI, Jetpack Compose, Entity Framework Core, Effect. А якщо філософствувати, то можна сказати, що async await це кастрована монада IO, де робиться акцент лише на одному з побічних ефектів.

Таким чином виникає невеличкий орден фанатів, який вирішує... але щоб вступити в нього треба прикладати чимало зусиль

спершу подумав що то відносно раст було

Вони не намагаються довести ...

а тут зрозумів що мабуть ні)

А якщо філософствувати

то добре що не про логіки

вони працюють із гомотопічними типами, будують ∞-категорії або класифікують кобордизми. Таким чином виникає невеличкий орден фанатів

й, якби не «Learn You a Haskell» через оту «орденську термінологію», що «лише для посвячених», для більшості той поріг «входження в орден» нездоланний, якщо не виробити якоїсь «побутової інтуіції» (так само як побутова інтуіція потрібна щоб писати звичайні SQL запити... а «реліційна алгебра» з її «премудростями» для більшості так й лишається «наукоподібною ахінеєю»)...

й ще одна річ — для «посвячених» воно «все само собою зрозуміле», але «зі сторони» то все виглядає як «секта»... (й навіть коли хтось «увірував» то все одно не розпочне на тому новий проект, бо знає що HRи не підберуть команду)

async await це кастрована монада IO

для простого смертного (якщо не читати learnyouahaskell) то все оце «a monad is a monoid in the category of endofunctors of some fixed category» абсолютно нездоланно...

Й в тому, напевно й є головна проблема «ордену» — вони розмовляють такою термінологією, що їх ніхто не розуміє...

«a monad is a monoid in the category of endofunctors of some fixed category» абсолютно нездоланно...

Ну... можна також сказати, що IEnumerable це функтор в категорії типів C# і далі заумно висловлюватися. Це не буде мати ніякого відношення до C#. Якщо занудствовати, то це категорне визначення монад, а в Haskell це strong monads. А так... монада це просто typeclass, читай інтерфейс, дуже корисний якщо ти його зрозумів. А проблеми в Haskell починаються більше від того, що у тебе забрали змінні, це головне.

Й в тому, напевно й є головна проблема «ордену» — вони розмовляють такою термінологією, що їх ніхто не розуміє...

Іронія в тому, що так базікають не ті, хто пише на Haskell, а ті, хто його не освоїв. Залякують новачків цитатами з книжок, які самі не зрозуміли

Learn You a Haskell якраз чудова книжка, бо все починається з «людської мови»...
А про «класифікують кобордизми», то це шановний пан сам таке написав, напевно для того, щоб мене залякати))

Парадигма програмування — це спосіб мислення і підхід до побудови програм, який визначає, як формулюються задачі та як організовується код для їх розв’язання.

Різні способи мислення дійсно існують :)
А інструменти більшою чи меншою мірою дозволяють реалізувати на практиці те, що ви напроєктували, виходячи зі свого способу мислення.

Після таких коментарів я пригадую анекдот про ректора та деканів фізичного, математичного та філософського факультетів: ректор дивиться на смету від физичного факультету, та й каже: стільки обладнання, такі шалені кошти, беріть он краще приклад з математиків, їм треба лише олівці, папір та гумки. А потім — а ще краще з філософів, їм навіть гумки непотрібні.

Спосіб мислення, що це в біса таке? Це парадигма яка використовується в процесі мислення? Сепулька, сепулькарій, сепуління? Різні способи мислення існують? З одного боку інстують, кожен має свій особистий індивідуальний спосіб мислення. З іншого боку не існує, усі ми примати, біохімія одна й та сама. Така собі інтелектуальна мастурбація без жодної користі.

Знову ж таки, підхід до побудови програм у С++ та Python, як на мене, відрізняються кардинально, нічого спільного.

Анекдот гарний, але не про те. :) Наведу приклади «способів мислення», щоб ідея була зрозумілішою:

— У процедурному стилі ми мислимо послідовністю інструкцій: зроби А, потім Б, потім В.
— В ООП ми уявляємо систему як об’єкти, що взаємодіють між собою.
— У ФП ми розкладаємо задачу на чисті функції, які можна комбінувати.
— У декларативному стилі ми формулюємо не як робити, а що хочемо отримати.

В ООП послідовності інструкцій немає? Це ідеалізація, я хочу експерименти, які це доведуть. Тому що як ми мислимо, невідомо.

Ботвінник думав що він розуміє, як він мислить в шахах, намагався написати шахову програму. Але він помилявся. Фрейд також описував мислення.

Для мене мислення це несвідомий процес, який я не можу поділити на складові. Я дивлюся на код та до мене приходить думка: треба робити так. Звідки? Хз. Тому все це маячня та натягування сови на глобус.

Будь яка просунута мови дозволяє конструювати складні типи, на значення ти дивишся як на екземпляри обʼєктів. Будь яка взаємодія це послідовність дій. Тому весь цей розподіл це пусте. Я би описав скоріше що є несвідома модель, які дійсно ближче до обʼєктів та дій, яка потім матчиться на особливості тієї чи іншої мови програмування. Тому такий погляд, як на мене, дуже спрощений та неконструктивний.

Будь яка просунута мови дозволяє конструювати складні типи, на значення ти дивишся як на екземпляри обʼєктів

але, все ж, є мови які «зручніше лігають» на «способи мислення»,
звісно, це все «нечітко», «суб’єктивно», та й взагалі важко описати,
але заповнювати VMT «руцями» на Cшці — відвертий мазохізм... хоча цілком собі спосіб «роблення ООП» (як автори такого коду собі те ООП уявляють)

Різні способи мислення існують? З одного боку інстують, кожен має свій особистий індивідуальний спосіб мислення. З іншого боку не існує, усі ми примати, біохімія одна й та сама. Така собі інтелектуальна мастурбація без жодної користі.

Не биохимия а формальная логика одна. А вот мышление может быть разным.

Знову ж таки, підхід до побудови програм у С++ та Python, як на мене, відрізняються кардинально, нічого спільного.

та ні, всі мови програмування однакові (Тьюрінг компліт), ми вже про це спілкувалися десь в іншій гілці))

До речі, не всі Тьюрінг повні. Ну а так рішення на одній мові часто неможливо механічно відворити на іншій. Це те що я вкладаю в слово різні.

якщо не лізти до декораторів, трюків з __отевсе__, метакласами, дестрипторами (ну чи перевантаження оператрівб темплейт метапрограмінга), то якраз цілком собі транслюється механічно (й умовний баблсорт цілком собі ідентичний, навіть попри різний синтаксис)

Ну... Haskell, немає змінних, вже не вийде. Навпаки отримуємо lazy обчислення. C# -> C++ відразу GC. Навпаки unsafe. Завжди щось та вилазить, хоча більшість ширвжиткових мов можна транслювати.

ми з почали з

С++ та Python

))

звісно, що «щось знайдеться», але С++ та Python ніразу не «аж такі різні» щоб аж «неможливо механічно відворити на іншій» цілком собі можливо, й вже тут десь навіть мелькало py2many...

беззаперечно з умовним Haskell той трюк вже «так просто не пройде», але С++ та Python вони «приблизно то саме» тому вердження про

підхід до побудови програм у С++ та Python, як на мене, відрізняються кардинально, нічого спільного

«притянгуто за вуха»

звісно, що «щось знайдеться», але С++ та Python ніразу не «аж такі різні» щоб аж «неможливо механічно відворити на іншій» цілком собі можливо, й вже тут десь навіть мелькало py2many...

Ну... треба написати тип Variant на C++. В принципі можна перекласти будь що на будь що, але треба написати інтерпретатор. Але це неприродній шлях: писати Variant на C++ тільки для того щоб писати як на Python?

Тому я не згоден, що вони «такі самі».

треба написати тип Variant на C++

тут я «загубив ниточку», бо вже є std::variant, std::any... та купа «саморобок» (й недуже) довкола того, той же CComVariant ще «від царя Гороха» (десь там поруч й IDispatch + купа обгорток й всі оті приколи світу «до того як M$ вдарилася в .NET» й в одному проекті можна було через COM «подружити» С++, ЖС й навіть ВБ)...

Й навпаки на Пайтоні купа проектів де «затайпанотоване» буквально все, й то все цілком собі можна «механічно перекласти» на С++ навіть не задумуючись, а там, де таки не"затайпантооване" поюзати оті std::variant, std::any... та купу «саморобок»...

(задумуючись, бо гарбіч колектор на шаред поінтери при циклічних посиланнях легко не змапується, ну але то не є «аж така принципова різниця» з точки зору власне механічного перекледу алгоритмів... точно легше, ніж в Сшному світі з його «здогадайся хто овнер й коли то можна буде видалити»)

За все языки уже не надо. Недавно написал транслятор реализующий исполнитель не эквивалентный Тьюрингу www.youtube.com/watch?v=jLsKa4Oy3xk

то ж якщо є фізична реалізація, на які раниться то все відтрансльоване, вона на Тьюрінг компліт машині, отже, таки еквівалетнна, ні?

вона на Тьюрінг компліт машині, отже, таки еквівалетнна, ні?

Нет, не эквивалента. На моей машине можно смоделировать любую машину Тьюринга. Обратное, в общем случае, не верно. Работать будет, а распараллеливания не будет. А это и есть суть недетерминированности. Доказательство где-то в роликах на моем канале на тему теории многопроцессорного программирования. Ссылку давал. Т.е. чем больше шин данных и процессоров тем лучше. Думаю, очень годится для нейронной сети. Но, я не дорос написать пример. Не моя тема. А для автоматизации хоть сейчас в коммерцию. И примеры есть.

Маячня. Будь-яку недетерміновану машину Тюрінга можна змоделювати детермінованою, яка просто перебере всі варіанти.
Паралельність не збільшує обчислювальну потужність, лише впливає на швидкість.
Справжнє розширення можливостей дає лише оракул, який може відповідати на нерозв’язувані запити.
Такі оракули утворюють ієрархію обчислювальної нерозв’язності, кожен рівень сильніший за попередній.
Це базові речі з теорії обчислюваності.

Маячня. Будь-яку недетерміновану машину Тюрінга можна змоделювати детермінованою, яка просто перебере всі варіанти.

Я б Вам посоветовал быть не таким агрессивным. Когда то я приблизительно так же думал. И даже приводил в пример теорему что из любой не детерминированной машины Тьюринга можно сделать детерминированную с тремя лентами. Потом мне пришлось углубиться в эту тему что б определиться что такое я сочинил, и пришел к выводу что не детерминированной машины Тьюринга вообще не существует. Это фантом, который сам Тьюринг не стал глубоко вникать. Советую просмотреть на моем канале теорию многопроцессорного программирования. Я там изложил мой взгляд на Алгоритмы, машину Тьюринга, конечные автоматы и прочее. Там же моделирование машины Тьюринга на моей машине.
Могу согласиться с Вашим высказываением

Паралельність не збільшує обчислювальну потужність, лише впливає на швидкість.

. Хотя при желании можно придраться. Но, в теме речь идет о новых способах мышления и парадигмах. Что я и предложил. Можем пообщаться подробнее если Вас интересует моя машина. Думаю здесь не очень удачное место для этого. Спасибо!

Це не агресія, це констатація факту. У теорії обчислень працюють десятки тисяч людей, і базові властивості машини Тюрінга відомі понад сімдесят років.
Якщо ти вважаєш, що недетермінована машина Тюрінга «не існує», то маєш спростувати не чиюсь точку зору, а цілу галузь формальної математики. Хто, ймовірніше, помиляється, ти чи всі вони?

Якщо ти вважаєш, що недетермінована машина Тюрінга «не існує», то маєш спростувати не чиюсь точку зору, а цілу галузь формальної математики. Хто, ймовірніше, помиляється, ти чи всі вони?

Вы не математик. А мне плевать кто прав. Даже тысячи мух не убедят меня в том, что говно это вкусно. Читай то, что я написал. Я не политик и не собираюсь никого убеждать. Умный поймет и задумается. Хочешь понять иди на канал, или в личку. Меня найти легко.
P.S. За 20 лет на этом сайте и 70 в моей жизни еще никто не обвинял меня то я глупость написал или сказал. Но бывало делал))

базові властивості машини Тюрінга відомі понад сімдесят років.

Кстати, именно то, что я прочитал в определении машины Тьюринга в википедии и послужило поводом для моего возмущения. А именно Маши́на Тью́ринга — абстрактный исполнитель (абстрактная вычислительная машина) — математическая модель вычислений, предложенная Аланом Тьюрингом в 1936 году для формализации понятия алгоритма. Это не так. Машина Тьюринга это исполнитель вычислительных алгоритмов.

Turing machine can be formally defined as a 7-tuple M = ⟨Q, Γ , b, Σ, δ, q0, F⟩ where Q is a finite, non-empty set of states; ... Що не так?

А далі просто інтерпретації навколо визначення, вікі зазначає для чого ця конструкція була придумана, телепати у відпусті, Тʼюринга не читав, але не бачу чому це може бути так, досить очевидно, що сама ідея була мінімізувати кількість операцій для того, щоб полегшити математичні докази. Можна сказати, що це виконувач, але дуже незручний. Але визначення це 7-tuple (є еквівалентні 5-tuple, ...)

Справжнє розширення можливостей дає лише оракул, який може відповідати на нерозв’язувані запити.

Удачно сформулировал. Не совсем оракул, но нечто похожее есть. У нас же много процессоров и есть варианты. Например, двухоперандные команды могут вычислять операнды параллельно с синхронизацией динамически, во время выполнения. Правда, должно быть оттранслировано советующим образом. Ибо процессоры то выделяются динамически. На канале где разбор выражений я более подробно об этом рассказываю.

Парадигма програмування — це спосіб мислення і підхід до побудови програм, який визначає, як формулюються задачі та як організовується код для їх розв’язання.

Отсюда следует что язык и способ мышления зависит еще и от архитектуры процессора. Парадигмы ООП и функционального программирования должны благодарить изобретению подпрограмм и с адресом возврата. Вот я не обнаружил здесь парадигму логического разбора (интерпретаций) язык Пролог. В принципе это можно считать декларативным программированием. Это я к тому что разработал еще одну архитектуру. (Не машина Тьюринга) Без адреса возврата, но ООП и параметрами могут быть не только функции, но и события. Совсем другая парадигма. Название не придумал. Но работает на много процессорных и многошинных машинах. Здесь оставлю архитектуру и ссылку. За язык и примеры отдельно дам ссылку.

Машина Кузьмина представляет собой перечислимое множество ячеек (концептов) и перечислимое множество управляющих устройств (можно считать их головками, кому это удобно) назначение которых — адресация (активация) концептов четырех видов (для чтения, записи, выполнения и инициализации). Номер концепта будем называть адресом.
Ячейка (а не головка как у МТ) имеет множество состояний (значений) S (возможно бесконечное). Пока событием будем называть состояние концепта. Это не противоречит интуитивному представлению о событии как о процессе изменения состояния потому что факт изменения состояния определяется анализом на принадлежность новому состоянию (истинность события), и зачастую событие имеет имя этого нового состояния.
Каждое событие может иметь конечное множество подписок. Подписка — номер концепта к которому осуществляется адресация управляющего устройства и при условии истинности события (Т.е. при определенных состояниях концепта.), которому принадлежит подписка.
Работа машина заключается в адресации концепта. При активации концепта, запускается анализ на истинность всех событий концепта (анализ не изменяет состояние концепта и потому может выполняться одновременно для всех событий) имеющих подписки, и при истинности этих событий машина активирует концепты с номерами, указанными в подписках (одновременно, если истинных событий с подписками больше одного). При отсутствии подписок адресация выполняет предназначенную функцию в зависимости от вида адресации (чтение-запись-выполнение-инициализация). Т.е. осуществляется чтение-запись, выполнение арифметической операции или создание нового концепта, используя адресуемый как класс. На чем работа и заканчивается.

www.youtube.com/watch?v=qKUoCeGvXnA

Отсюда следует что язык и способ мышления зависит еще и от архитектуры процессора.

Якщо ви пишете на низькому рівні, то без сумнівів залежить. Проте інструменти, як обгортки дозволяють речі, залежні від архітектури заліза приховати.
Для вирішення практичних задач можна створювати свої «обгортки», інструменти над мовою програмування у вигляді бібліотек, і таким чином спрощувати опис задачі.
Гарний приклад UI бібліотеки типу React. Під капотом JS, але бібліотека дає інший спосіб мислення при побудові інтерфейсу. А до процесора ще буде декілька шарів, які дозволяють на його архітектуру не зважати.

Вот я не обнаружил здесь парадигму логического разбора (интерпретаций) язык Пролог.

я робив зауваження, що буду згадувати тільки найбільш розповсюджені. А загалом їх багато.

І дякую за цікавий приклад.

Якщо ви пишете на низькому рівні, то без сумнівів залежить. Проте інструменти, як обгортки дозволяють речі, залежні від архітектури заліза приховати.

Это если архитектура классическая(Тьюринга). Или детерминированная. Я дал описание новой архитектуры. Не детерминированной. Ее полноценно нельзя реализовать на машине фон неймана. Что б разобраться надо по ссылке мой канал посетить. Это реально другая машина и другой способ мышления. Вы ж понимаете что в императивной парадигме реализовать многопроцессорную работу не получится. А у меня это норма.

У вас в архітектурі відсутній процесор в класичному розумінні, але для таких задач люди давно придумали пліси, там відсутнє програмування як таке і інший спосіб мислення. Задачі там вирішуються шляхом створення відповідних зв’язків між примітивними цифровими елементами і тому можна задати будь-який паралелізм в межах можливостей відповідного чіпу пліс.
З жодною системою ваше рішення отак з коробки несумісне і представляє собою щось принципово нове. Цікаво, але що з тим робити...
Люди тут говорять про мови, які вже абстраговані на тих рішеннях, що були заточені під рішення, які були створені на рішеннях, що були створені на рішеннях ... і так багато разів, поки ми дійдемо до класичної машини Тьюрінга, яку ми маємо викинути і замінити на машину Кузьміна.

У вас в архітектурі відсутній процесор в класичному розумінні, але для таких задач люди давно придумали пліси

Отнюдь. Предполагается наличие нескольких процессоров и несколько шин данных. процессор стековый. И работает почти классически. Так же адресация для чтения, записи и выполнение арифметических команд. Добавлен диспетчер событий, который анализирует события и запускает их обработку и адресацию на выполнение при истинности событий соответствующих подписок параллельно. Это становится возможным так как анализ состояния не изменяет состояния. Вот здесь описание работы процессора.
www.youtube.com/watch?v=21mdovBWVRA
Это другое мышление. Ощутить можно разобрав примеры. Коих тоже не мало на канале. Плис это действительно заготовка, на которой можно сделать все. том числе и мою машину.

Попробую по простому разницу машиной тьюринга описать. Вместо одной головки имеем несколько. работа начинается с адресации какой-то ячейки. каждая ячейка имеет состояния и подписки на состояния. если на текущее состояние имеются подписки (номера ячеек для адресации по этому состоянию) , то к ним адресуются свободные головки. все!

В принципі чат гпт каже що це має сенс і навіть намагається малювати якісь блок-схеми. На жаль я навіть не знаю яку кваліфікацію треба мати щоб це все осягнути, навряд чи на цьому форумі хтось подібний існує.
Чому б вам не подивитися в сторону fpga і не спробувати реалізувати це на практиці? Виглядає як щось що можна зробити.

Для повноти мабуть можна булоб вже додавати також і можливий вплив ШІ на програмування в майбутньому, та який вже починають потрохи розглядати. Нп як опція — відмирання з часом усіх мов програмування напряму не пов’язаних із залізом, та появу замість них якоїсь проміжної мови (чи мов) між ШІ і обчислювальним залізом, тобто чогось більш оптимального саме для ШІ генерації (і зовсім не обов’язково що там будуть використані саме ті концепти/парадигми/абстракції з сучасних мп які створювались для людини).

Мої 5 копійок зі зведенням розподілених систем до трьох парадигм програмування metapatterns.io/...​-architectural-paradigms

Питання в тім, що люди геть не вміють готувати ООП. А використання класів — ще не робить той код ООП.

Класів без об"єктів? Чи об"єкти класів? Чи як.
В ООП перше слово об"єкт (не наслідування, чи інкапсуляція чи що там ще)

Про усіх не треба, але на загал — так проблема ООП в тому, що це дуже складна парадигма з порогом входження, яка вимагає професійних знань практики і наснаги. Більшість інших проблем з перформансом сучасним інсрументарієм відносно вирішина.
Ящо же йдеться про використання готових фреймерків бібліотк і інстументів які збудовані за ООП, то навпаки тут є полегшення. За великим рахунком перехід з Turbo Pascal на Delphi займав менше місяця. Аналогічно на Visual Basic з Basic або Visual C++/MFC/ATF з С/С++ під DOS.
Іншим треба штудувати ООП дизайн, паттерни проектування : GoF, GRASP, MVC, MVA, ADR, Enterprise Integration Patterns тощо. А ще і принципи типи: SoC, YAGNI, Refactoring тощо. Це все шобла книг та купа практики. Тобто і певний поріг входження.
Власне тому такі популярні зараз : JavaScript/TypeScript та Python. Це на сам перед скриптові мови орієнтовані на швидке отримання простих шаблонних прикладних комерційних результатів з використання фреймверку та платформи типу браузера, Node/Next.js чи Ternsorflow.

Про усіх не треба, але на загал — так проблема ООП в тому, що це дуже складна парадигма з порогом входження, яка вимагає професійних знань практики і наснаги.

В чому саме цей порог?

паттерни проектування

напишу «єресь»:
вони часом цікаві лише своїми назвами й концепціями, але показані в книжках «приклади реалізації» — як правило сміття, що непридатне до використання (й ті, хто намагається всюди копіпейстом ліпити паттерни з книжок, буквально так, як вони там описані, то якраз ті, хто продукує найбільше г@внокоду й «спагеттів» з індірекшена на проекті, бо «коли в руках молоток, то все довкола — цвяхи»)...

Я вже про те писав в одній з сусідніх тем, то закопіпейстчу сюди:

Тому що «банда чотирьох» придумувала деякі свої паттерни саме як воркераунди до обмежень (тодішнього) С++ (й ті воркераунди також розповзлися в тодішню Джаву і так далі... стали «біблією» в девелопменті)

Воркераунди бо тоді ще не було повноцінної "ламбди"/"делегату«/std::function<>/Function<>/Action<>, які можуть «захопити» стейт й «подорожувати» разом з «тим всім, що треба» десь «туди, куди треба», щоб виконати «щось, що треба»...

Відповідно всі «Обзервери», «Стратегії», «Команди», «Декоратори» насправді за допомогою отих базових класів і «перевизначення» в похідному «апдейта», «алгоритму», «екзекута», «операції» просто імітують «функції першого класу» (ті, що ламбди/кложури, що їх можна передавати «як є» замість «поінтера на базовий клас з перевизначаємою операцією»)...

Сам Пайтон, до речі, бай дізайн, вдало позбувся класичного «декоратора з класами» саме завдяки «@декораторам», що, по факту, оперують над «функціями» й повертають "ламбди"/"кложури"...

Це ви в сутності виразили думку великої кількості народу, яким от не треба усі ці шаблони і т.д. А треба швидко робити якийсь прикладний софт і заробляти гроші. Умовно головна бізнес ідея того же PHP, Python та Node.
Інша купа народу бере книжку Кріса Річардсона «Мікросервіси. Патерни розробки та рефакторингу» і просто повторює рекомендовану архітектуру Amzon 6 для AWS або клонів типу GCP чи Azure. Те саме в цілому декстопна розробка, iOS, Andoroid і т.д. Code monkey бізнес, ну або гоблінський за старим сленгом, цехове ремесло.
Реально розробляють системи з нуля або стартапи різного типу або Big Tech. І відповідно — так нафіг треба за великим чином знати шаблони проектування, тобто пророблені вже кимось стандартні елементи з яких можна збудувати архітектуру, коли ти просто віддтворюєш одну якусь завчену архітектуру типу MVC паттерн і можеш навіть не знати як вона називається.
Якщо же мати інженерний підхід та технологію, певним чином гарантувати результати — то різні парадигми і підходи мають місце іноді, зокрема і в дебазері не сидіти днями.
BTW Банда 4 із Xerox PARC писали на Small Talk. І популярність ООП отримало саме разом із графічним інтерфейсом користувача та Lisa/Macintosh та Windows 95. Тобто з тих же причин, чому сьгодні набирає популярність чисте функціональне та мультіпарадгмене програмування — це кліент серверна архітектура.

яким от не треба усі ці шаблони і т.д.

чому це «не треба»? Цілком собі треба, просто треба вміти «це» виразити сучасними засобами, а не «лише й тільки» методами 1994року!

BTW Банда 4 із Xerox PARC писали на Small Talk.

то якраз показує що «класичну» книжку GoF той пан не читав
бо там якраз оте усе C++ тих часів про

class Observer {
public:
    virtual ~Observer();
    virtual void Update(Subject* theChangedSubject) = 0;
protected:
    Observer();
};
і тд
на С++ версії 1994!

Моя претензія якраз до того що це треба зробити похідний клас й менеджити його лайфтайм,
замість того, що б передати в std::function<сигнатура> одразу те, що треба))

чому сьогодні набирає популярність чисте функціональне та ... — це кліент-серверна архітектура

о, обговорення OOP схоже ще ускладнюється тим хто що вкладає в функціональне програмування в рамках можливих використань

Класичне розуміння функціонального програмування — в процессі реалізації обробки вхідних данних та отримання вихідних, алгоритм не має загального стану. Що ідеально вписується в клієнт-серверну архітектуру, багато поточність тощо.
Імперативний же парадигма в цілому — программа є кінцевим автоматом і обробка вхідних данних та отримання вихідних, є процессом послідовного зміну стану. Що в сутності ідеально вписується в усі задачі системного програмування, керування обладнанням периферійними пристроями, десктопні застосунки із графічиним чи псевдографічним інтерфейсом тощо.
Є ще логічна (Prolog, ASP, Datalog) і декларативні парадигми (HTML, SQL)

алгоритм не має загального стану.

А монада State це не стан?

Я давно зрозумів, що готувати ООП складно. І подумав: навіщо мені ця зайва складність? Проблем і так вистачає, навіщо їх множити? Якщо багато хто намагається, та ні в кого не виходить, то великі питання в доцільності самого підходу.

Нічого складного, якщо не лізти в дійсно складні области. Але так зі всім.
Головне, для чого потрібне ООП, це розділення надскладного на таке складне, щоб людина смогла усвідомити, а далі зручно розвивати код. І з цею задачею воно справляється.

Як на мене проблема ООП що окремі обʼєкти це часто дуже малі блоки. Дуже часто ти бачиш купу простих методів, та не розумієш як вони працює разом, та де знаходиться потрібний функціонал. Проблема відома з часів Smalltalk. А зараз з мікросервісами.

Мені більше комфортно працювати з більшими модулями.

що окремі обʼєкти це часто дуже малі блоки.

Ну, розмір обʼєктів визначається декількома факторами: необхідністю мати границю через принципове розділення (Страуструп — літак не може бути наслідником двох його двигунів), логічне за рахунок information expert + high cohesion (а інфоциган Мартин зводить в SRP), і оцінка незалежности аспектів реалізації (часто штучна). А, ще повністю штучні посередники через dependency injection.
Якщо використовуються по більшости природні фактори, то не буде надто малих обʼєктів.

Якщо використовуються по більшости природні фактори, то не буде надто малих обʼєктів.

Теоретично звучить круто. Якщо проект статичний та ніхто нічого не буде вносити в нього через пів року. Реалії бізнесу кажуть про те, що зміни прилітають частіше, ніж розробники встигають писати код. Саме це й найгірше лягає на ООП.

Простий приклад (втомився його вже приводити, але він шикарно показує всю складність). Треба нагодувати котика. Є власник, є котик, годуймо. А тепер котиків два. Один з них не любить кролятину. Власників тепер теж два. А ще є сусід, який періодично приходить погодувати котів, коли власники у відрядженнях. А тепер ще додамо собаку. Та черепаху. А ще купили автоматичний автофідер, але один з котів його боїться.

Ця задача виглядає дуже простою на початку. Але зі зростанням складності взаємовідносин та умов, рішення в світі ООП буде вкрай затратним. Саме тому, що треба правильно описати кожен з обʼєктів, кожні взаємовідносини, систематизувати все та зробити хоча б трохи універсальним. Це вимога ООП.

А тепер беремо абсолютно іншу декомпозицію задачі. В нас є ряд структур: географія (помешкання, вулиця, світ), ієрархія (собака головна, коти в певному порядку наступні, черепаха), реляція (власник, не власник, тварини), та купа інших. Кожен з субʼєктів є незалежною системою, яка самостійно приймає «рішення». Та є просто обмін сигналами між цими системами з урахуванням структур. Чи можна таку штуку побудувати в ООП? Легко! Але це буде лютим оверінжинірінгом.

Саме тому, що треба правильно описати кожен з обʼєктів, кожні взаємовідносини, систематизувати все та зробити хоча б трохи універсальним. Це вимога ООП.

«Хоча б трохи універсальним» автоматично зробиться з будь-якої спроби вирішення задачі. Але, якщо не впадати в режим FizzBuzzEnterpriseEdition, воно буде максимально простим.

Здається, ви навмисно плутаєте просто ООП і спробу максимувати рецепти типу SOLID навіть на мінімальній задачі.

Кожен з субʼєктів є незалежною системою, яка самостійно приймає «рішення». Та є просто обмін сигналами між цими системами з урахуванням структур.

І це є теж ООП, проте типу «активні обʼєкти», воно ж імені Алана Кея, а-ля Simula і Smalltalk (тобто раніше ООП на пассивних обʼєктах, стиля C++). Але воно не обовʼязково буде простішим.

втомився його вже приводити

Ну і для чого ви втомились, коли це реально нічого не показує, крім того, що ви не знаєте, що таке ООП? 🤷‍♂️

«Хоча б трохи універсальним» автоматично зробиться з будь-якої спроби вирішення задачі.

За декілька ітерацій, кожна з яких буде ускладнювати систему, вимагати рефакторінгу, тестування, що є вельми витратним.

Здається, ви навмисно плутаєте просто ООП і спробу максимувати рецепти типу SOLID навіть на мінімальній задачі.

Я не плутаю. В мене є реальні приклади двох діаметрально протилежних підходів та наслідки їх використання. Про це й шла мова в моїх постах вище.

І це є теж ООП,

Це не є ООП. Цей патерн можна реалізувати за допомогою ООП, але це не є ООП. Бо так можна що завгодно називати ООП ;)

Ну і для чого ви втомились, коли це реально нічого не показує, крім того, що ви не знаєте, що таке ООП?

Ок, що таке справжнє, тру-ООП? :)

Підписатись на коментарі