I.
Просто тому, що ФП має більшу когнитивну складність.
Ні, не має. Щонайменше, поки не звикнеш до процедурного стилю. А ось з процедурного вже переходити на функціональний складніше, бо ламає звички.
Тому я і кажу, що якісний програміст має знати хоча б основи одної мови ФП (LISP, Erlang...) і Forth, щоб побачити те ж саме з різних сторін. Тоді для будь-якого засобу розуміння буде вже кращим. (Не кажу про Prolog, це вже для джедаїв-первертнів. Але і він може бути на користь.)
Але для крудошльопства це таки не обовʼязково.
II. А ви взагалі побачили різницю між функціональною мовою і мовою з розвиненою системою типів, як в статті? Мені здається, що не побачили.
Звісно, з ФП простіше накласти на базовий рушій мови розвинену систему типів, бо в ній значно простіше забезпечити аналіз компілятором і відсутність сторонніх ефектів. Але і на процедурну мову це теж накладається з деякими ускладненнями.
Порівняйте у цьому аспекті хоча б C, Pascal і Ada. В Ada автовиводу типів, здається, немає, але ви можете легко обмежувати діапазони значень. Алгебраїчні типи на зразок {ok,Result}|{error,Error} теж можна, з ускладненнями. Це вже щось більш цікаве.
Зараз Rust дає схожі можливості, теж у процедурній парадигмі. І, здається, саме Rust у першу чергу буде тим, що покаже такі підходи до типізації головній масі програмістів.
Не памʼятаю, чи наводив я тут приклад. Функція заповнює масив до 4 значень і повертає кількість заповненого, або −1 якщо помилка, в int8_t. Функція, що її викликає, кладе результат в uint8_t, заповнює масив значень (дивом нічого не ломає) і передає по мережі. При помилці воно втискує 255 (бо −1) значень в масив на 4 комірки. Інший модуль приймає, десеріалізує і нарешті крешиться через переповнення в стеку і псування адреси повершення. Зрозуміло, що мова з AutoMM, як Java, C#, Python, Go, чи десятки інших, не дозволила б такий ефект. Але і щось рівня C, але з якісним контролем типів, просто не спонукала б на таке диверсійне використання одного значення...
А здавалось би стандартизоване обладнання!
Хто попрацював в розробнику такого обладнання, знає, що «стандартизоване» обладнання це у більшости випадків щось все одно прохиблене, а якщо вже виглядає згідно стандарту — то на самісінькій межі відповідности ;(
І вихід на крок за межі happy path, зазвичай, призводить до зламу сценарію і неочікуваним ефектам.
На жаль все саме так...
Passkey не обов’язково має бути фізичним.
Ага, ага. Ви нишком відредагували статтю:
За два роки, відтоді як паскейси (passkeys)
Ось цього «(passkeys)» не було. Але ви знову схибили: ніхто в здоровому глузді не буде передавати англійське key як «кейс» при наявности слова case. А разом з таємним редагуванням... «кращі» традиції пострадянської журналістики — невіглацтво і нахабство — на марші. Поточну версію я зберіг, на випадок, якщо ще раз таємно відредагуєте.
Після такого писати щось конструктивне про підняті питання якось не хочеться :crash:
За два роки, відтоді як паскейси були анонсовані та стали доступними для споживачів, FIDO Alliance нещодавно повідомила, що обізнаність про паскейси зросла на 50%, з 39% у 2022 році до 57% у 2024 році.
Passcase ще щось фізичне, типу такого.
Здається, журналіста знову хтось зґвалтував.
Ну я поки не бачив, скільки треба платити тому ШІ, щоб він виконував хоча б задачі рівня мідла 8×5x52 і з достатньої точністю. І щоб сам міг розробляти, тестити, деплоїти і все таке. Більше зарплати людини чи менше?
От тільки з практичної точки зору зазвичай якщо у нас немає пам’яті, то це із серії, що зникло живлення
А ось це вже диверсія — настільки закладатись на памʼять.
Так я не о проблеме останова :)
Так я и написал, что это аналогия.
Продолжаю удивляться, почему гопники такие агрессивные. Ах да, подождите...
Шаг 1: читаем, что проблема останова неразрешима в общем случае.
Шаг 2: пишем алгоритмы, которым конкретно (в смысле the particular algorithm) можно доказать все нужные свойства, включая конечность выполнения. Это несмотря на.
Шаг 3: убеждаемся, что компьютеры всё ещё работают, а не уходят в вечный цикл на каждое действие пользователя.
Если это и аналогия, то очень точная. Всё описать типами, может, и вредно для скорости написания. А вот защититься от наиболее типовых граблей, чтобы тебе не писало, что через NaN минут к тебе приедет [object Object] — это как раз то, для чего вообще придумали типизацию.
Ну це вже занадто;\
никто не не указал, что оно было слегка побито
А, может, потому и не понял.
Спасибо, с таким намёком видно — как тип уточняется «по месту» и неявно.
Это, конечно, очень простой пример. Я не уверен, что оно переносимо в ту обстановку, которую я описывал — там будет сильно сложнее вычислить такие вещи, компилятор может не потянуть. И не представляю себе, возможно ли вообще перепроектировать, чтобы он потянул;\
Но есть о чём думать.
або кричати щоб Oracle відмовилась від trademark на Javascript)
Краще перейменувати Javascript, щоб HRи не плутали більш з Java. Така назва з самого початку була некоректним трюком на збігу. Так що тут я за Oracle :)
В Erlang ещё тоже примерно так же можно.
Там будет слишком много заката солнца вручную. Если вы не перезапускаете на новом процессе с другими данными, то делать все эти выборы в коде... на gen_fsm нормально не укладывается, а иначе писать самому.
Или — «отказаться» от переменных как в ФЯ. Нет ссылок, нет проблем :)
Есть ссылки — а как иначе будут структуры данных реализовываться? — и есть проблемы. Если переносишь в фиксированное декларацией состояние — сам процесс переноса требует кода, и легко что-то потерять. Если оставляешь «там же» (насколько этот термин подходит) — могут быть недоинициализированные или лишние. Если какой-то прокси — ручная работа по его построению.
В одном из подкастов по Пайтон услышал что жалеют уже, что в Пайтон вставили номинативную. «Структурную надо было...»
Как по мне, ещё замороченнее было бы. А там уже жутковато.
І що поганого в цьому?
Под «доступными» я имел в виду те, на которых мы могли писать это соответственно корпоративным условиям. Smalltalk туда не входил.
По любому, спасибо, запишу в копилку, что он такое позволяет.
Вам це так важливе для програміста і QA?
Почитайте про «ринок лимонів».
Десь як раз такий випадок :))
Читав фанфіки про Поттера, в списку unread поруч було про фонд «Повернись живим».
І прочитав топік як «Як ви ставитеся до етики проходження співбесід за живих?»
Замислився...
Почнемо з того, функціональний підхід зʼявився раніше. Лямбда-зчислення народилось у 1920х і було доведено до розвиненої теорії у 1930х, коли ще жодного реального компʼютера не було.
Чому поширення такого не мав? Дуже просто. Компʼютер на найнижчому рівні працює процедурно. У нього є послідовність станів і переходи між станами. Коли був тільки асемблер, вчили процедурній роботі. Коли зʼявились перші мови вищого рівня, вони теж були процедурні, бо не вистачало ресурсів на ефективну трансформацію з функціональної побудови. Тоді навіть гарних оптимізуючих компіляторів не було, вони зʼявились ближче до 1990, а раніше найліпші робили код в рази повільніший за людину з асемблером.
І саме в цей період виникли всі основні мови и виникли традиції. Вибачте за міряння сивиною, але я почав в80-х і все це бачив власними очима. Якась ЕС-1022, що споживала десятки кВт, мала швидкість і памʼять в сотні разів менше найменшої Raspberry Pi. Не могли тоді нормально ганяти програми на якомусь LISP всюди і для всього, всі ФП були нішевими саме через ресурси.
Власне, лінія ML, Haskell і інших виникла тоді, коли побачили, що сучасні ресурси дозволяють компілювати програми на функціональних мовах в щось досить ефективне.
А традиції, в яких, звісно, процедурний стиль займав головне місце, вже склались.
Я не мав досвіду в широкій масі з тим, що хтось навчився спочатку на LISP, а потім його пересадили на якийсь Python. Але є окремі знайомі, що скаржаться, що їм так незручно. І є група, яка вчилась майже з нуля програмуванню під Erlang, і їм легко зайшло. Так що не тільки навпаки.
Нітъ! Процесор працює саме повністю і безперечно з процедурним кодом. Альтернативи тут немає.
Навіть якась LISP-машина, яких робили навіть серійно, просто має орієнтацію на конкретні структури даних і методи їх покрокової обробки.
Обирається той підхід, на який є люди і ресурси. І ось тут спрацьовує, що всі 80 активних років IT перевага була на боці процедурного підходу саме через його близкість до заліза. Його не просто використовують — йому, через те, вчать. А раз йому вчать — то він і далі розвивається більше, ніж альтернативи. Замкнене коло.
А поясніть-но мені, до чого тут не мої слова? Ви вставили як цитату щось що я не писав.
Хоч і не мій приклад, але прокоментую:
Якщо ви просто передаєте крізь себе дані, то навантаження однакове. Вам треба просто використати універсальний контейнер. Такі є і в Rust.
Якщо ви далі обробляєте дані в цьому ж коді, то вам треба зрозуміти, що робити з цими даними. І ось тут вистрілює те ж саме навантаження.
Я не бачу принципової різниці.
Чому складно? В чому саме різниця?
Поки що я не побачив нічого крім того, що просто звикли до покрокового виконання у процедурному стилі.