Я программирую с восьми лет, и основную часть жизни был разработчиком в том или ином качестве. На протяжении своей жизни кодера, как любителя, так и профессионала, я изучил множество языков программирования, которые казались клонами друг друга. Но было и несколько языков, изменивших мой взгляд на программирование, а то и мышление в целом.
Я перечислю их в том порядке, в котором узнавал о них. В большинстве случаев я буду ассоциировать функциональность с языками, в которых они появились не впервые. Это не ошибка, я просто хочу показать, когда узнал об этих возможностях.
▍ Basic
Язык, разработанный для того, чтобы сделать программирование простым.
- Взрыв мозга: программирование собственных игр!
- Взрыв мозга: массивы (или
DIM
, как они в нём назывались)! - Взрыв мозга:
GOTO
! - Взрыв мозга:
GOSUB
!
Первый Basic с нумерацией строк давно мёртв, но его наследие живёт в VB.Net, VBA, а также в современных динамических языках (Python, JavaScript и так далее).
▍ (Turbo) Pascal
Наверно, этот язык сильнее всего повлиял на моё формирование как программиста. Подростком я выпустил несколько приложений на Turbo Pascal, в том числе и одно коммерческое (хотя, если откровенно, основную часть работы выполнил Алан Фриш).
- Взрыв мозга: туториал по программированию!
- Взрыв мозга: IDE!
- Взрыв мозга: компилятор действительно помогает находить твои ошибки!
- Взрыв мозга: по-настоящему полезный отладчик!
- Взрыв мозга: структурированное программирование!
- Взрыв мозга: юниты («модули»)!
- Взрыв мозга: объектно-ориентированное программирование (хоть и не особо полезное в библиотеках)!
- Взрыв мозга: тулкит для создания UI!
- Взрыв мозга: динамическое распределение памяти!
- Взрыв мозга: сообщество разработчиков (а также SWAGS)!
- Взрыв мозга: оверлеи памяти!
Несколько лет спустя, всё ещё подростком, я попробовал перейти на C, и был немного разочарован, обнаружив, что, по сути, это такой же язык, только читать его сложнее (что за странный цикл
for
с тремя компонентами?), он больше подвержен ошибкам (дальние указатели? серьёзно?) и с зияющей нехваткой некоторых возможностей (как это так — нет модулей?), поэтому я не буду включать C в этот список.Язык Pascal по-прежнему существует как Turbo Pascal, Lazarus Pascal и Delphi, но ещё и продолжил своё развитие в Ada (из-за его синтаксиса) и во всей существующей документации (JavaDoc, rustdoc, Sphinx, Doxygen и так далее), ведь первый инструмент для разработки документации (WEB) был спроектирован для и на Turbo Pascal.
▍ x86 ASM
Одно из основных ограничений Turbo Pascal заключалось в том, что его BGI (API для общения с графическим адаптером) был ограничен 16 цветами и относительно низкими разрешениями. Когда появились более современные графические карты, все разработчики внезапно начали учить язык ассемблера, чтобы иметь возможность общаться с устройствами. Я не стал исключением.
- Взрыв мозга: адресация памяти!
- Взрыв мозга: стек — это иллюзия!
- Взрыв мозга: прямое взаимодействие с графическим адаптером!
- Взрыв мозга: прерывания!
- Взрыв мозга: регистры!
Сегодня очень немногие люди пишут на языке ассемблера вручную, потому что это не особо полезно и не портируемо на 100%, но, разумеется, он всё равно присутствует внутри вашего компилятора или JIT. Я очень часто вижу, как разработчик на Rust или C++ демонстрирует дизассемблированную версию своего двоичного файла, и это напоминает мне о старых (не таких уж) добрых временах.
▍ HyperCard
На другой части спектра находился HyperCard — язык программирования, придуманный для тех, кто не хочет изучать языки программирования. Он выглядел как приложение для рисования, но можно было использовать встроенный язык, чтобы превратить его в полнофункциональную IDE, а также писать новые программы.
- Взрыв мозга: настройка своей среды.
- Взрыв мозга: мой первый скриптовый язык, хотя в то время я этого и не понимал.
- Взрыв мозга: программирование на почти естественном языке.
- Взрыв мозга: стек и шаблоны, мои первые абстракции UX.
- Взрыв мозга: программирование как форма беседы между программистом и компьютером.
- Взрыв мозга: сборка мусора (хотя тогда я этого ещё не осознавал).
- Взрыв мозга (в плохую сторону): невозможность портирования кода на платформы, не связанные с Apple; вероятно, это одна из причин того, что сегодня я в основном придерживаюсь опенсорса.
Наверно, этот язык стал первоосновой для всего «визуального», от Visual Basic
и Visual Studio до любого инструмента для рисования UX. Кроме того, в какой-то степени, HyperCard стал одним из предков веба. Время от времени я наблюдаю возрождение какого-нибудь потомка HyperCard, но надолго их обычно не хватает.
Разумеется, многие из этих идей используются и в SmallTalk; вероятно, он более революционен, но я изучил SmallTalk гораздо позже, поэтому взорвать мой мозг по этим пунктам ему уже не удалось!
▍ (O)Caml
Caml (позже OCaml) стал для меня неожиданностью. Я был пресыщенным студентом-первокурсником, уверенным, что после выпуска коммерческого ПО знаю уже всё; обычно я лучше владел программированием, чем учителя программирования в старшей школе, и это, разумеется, означало, что я лучший во всём. Я прочитал документацию OCaml ещё до первой лекции и ошибочно понял «полиморфизм» (сегодня мы называем это «дженериками») как «слабую типизацию». Как же я ошибался. На первой лекции преподаватель показал нам, как обходить дерево на OCaml. Это был крайне лаконичный, надёжный и читаемый код. Кроме того, преподаватель оказался сильным разработчиком и автором одного из текстовых процессоров, так что это, разумеется, стало столь необходимым мне уроком смирения.
Я влюбился в OCaml. Он быстро стал моим основным языком программирования до выгорания, вызванного разработкой Opalang.
- Взрыв мозга: параметрический полиморфизм (aka «дженерики»)!
- Взрыв мозга: выведение типов!
- Взрыв мозга: сборка мусора!
- Взрыв мозга: сопоставление с образцом!
- Взрыв мозга: REPL!
- Взрыв мозга: программирование высшего порядка!
- Взрыв мозга: монады!
- Взрыв мозга: Continuation-Passing Style!
- Взрыв мозга: конкурентность передачи сообщений с произвольными сообщениями (включая каналы)!
- Взрыв мозга: полиморфические варианты и рядный полиморфизм (aka «статическая утиная типизация»)!
- Взрыв мозга: изменяемый синтаксис!
- Взрыв мозга: написание DSL!
- Взрыв мозга: Multistage programming!
- Взрыв мозга: программирование на уровне типов между модулями!
Сообщество OCaml по-прежнему очень активно. Он использовался в разработке языков программирования (в том числе и первых прототипов Rust), инструментов статического анализа для ядерных электростанций, операционных систем для космических спутников и других ситуаций, требующих чрезвычайно высокой степени безопасности. Кроме того, это один из непосредственных предков Rust, F#, Elm, ReasonML и, если память мне не изменяет, первой версии React. А, и ещё Opalang. По какой-то причине конкурентность передачи сообщений позиционируется сегодня как «gochannels», но, насколько я знаю, она берёт начало ещё в Concurrent ML, одном из предков OCaml.
▍ Java
Я начал изучать Java, когда пытался модернизировать код, написанный на Turbo Pascal, чтобы он мог работать в Linux, Windows и System 7 (предшественнице macOS). Этот язык показался мне многословным, я не мог понять, почему разработчики не поставляют установщик, учитывая сложность выпуска и/или запуска классов, и мне очень не хватало дженериков, алгебраических типов данных и сопоставления с образцом. Однако на долгое время Java стал моим базовым языком — не таким, на мой взгляд, хорошим, как OCaml, но с доступом к более качественным библиотекам.
- Взрыв мозга: стандартная библиотека, в которой, похоже, есть всё необходимое мне!
- Взрыв мозга: документация, которую писали так, чтобы она была понятна пользователям!
- Взрыв мозга: JVML!
- Взрыв мозга: очень простой в использовании тулкит UX (даже если результаты разочаровывали)!
- Взрыв мозга: синхронизация как примитив языка (хоть это и не особо великолепная идея)!
- Взрыв мозга:
finally
! - Взрыв мозга: компиляция Just in Time!
- Взрыв мозга (в плохом смысле): понимание того, как
finally
реализовано в JVM.
В наши дни Java, разумеется — один из столпов отрасли. Также это один из предков C#, Scala и Go.
▍ Prolog
Если вы никогда не писали код на Prolog, то лишь рекомендую попробовать. Это полностью изменит ваше мышление о программах. В Prolog вы не пишете алгоритмы, а учите программу, как думать. Написать простой алгоритм поиска пути можно, задействовав примерно 2-4 тривиальных правила. Написание простой системы типов будет чуть длиннее.
- Взрыв мозга: учим программу думать!
Сегодня Prolog практически не существует. Однако его наследие огромно. Если память меня не подводит, SQL в большой мере основан на подмножестве Prolog с большим упором на оптимизацию в ущерб простоте. Система шаблонов C++ — это, по сути, более усложнённая реализация Prolog. Части системы типов Rust переписываются на Chalk — потомке Prolog.
Я подозреваю, что рано или поздно кто-нибудь начнёт комбинировать LLM с Prolog (или с Coq), чтобы создать поверх ChatGPT нечто надёжное. Кроме того, недавно я обнаружил TypeDB, очень похожий на новое поколение Prolog с API, напоминающим реляционные базы данных.
▍ Coq
Coq (и его родственники Twelf, Isabel и так далее) — это нечто совершенно иное. Вы кодируете спецификации целиком, как типы. Эти типы и есть ваша цель.
Вы программируете не с помощью функций и библиотек, а используя инструменты для преобразования ваших типов, чтобы постепенно упрощать их в независимые подцели. Можно описать это так: вместо кодинга вы решаете головоломку. Разумеется, подцели в результате превратятся в ваши функции, в ваши структуры данных и модули. Но произойдёт это почти случайно.
И, разумеется… модуль контроля типов настолько мощен, что ваша программа — это, на самом деле, формальное, математически проверенное доказательство её соответствия спецификациям. Множество математических теорем было доказано благодаря превращению их в код на Coq.
- Взрыв мозга: типы как спецификации.
- Взрыв мозга: программы как доказательства.
- Взрыв мозга: когда лемма проста, достаточно попросить Coq написать функцию за вас!
- Взрыв мозга: типы высших родов.
- Взрыв мозга: ожесточённые споры о том, какой же математик надёжнее, мозг или компьютер.
Я уже довольно давно не следил за разработкой Coq и других языков того же семейства. Насколько я понимаю, они довольно активно используются в научных кругах, где служат для формального доказательства соответствия спецификациям компиляторов и ядер операционных систем. Подозреваю, что если Prolog не вернётся, чтобы создать надёжные LLM, то кто-нибудь использует для этого Coq или Idris.
▍ Erlang
Erlang (а теперь и Elixir) был и остаётся лучшим языком для распределённых систем. Ядро гораздо проще, чем у Python, но легко масштабируется на миллионы узлов.
- Взрыв мозга: тривиальная реализация распределённых систем.
- Взрыв мозга: развёртывание нового кода из языка отправкой замыканий.
- Взрыв мозга: архитектура Let it fail.
Хотя многие всё ещё не слышали о Erlang/Elixir, этот язык использовался в отрасли начиная с 90-х в высокораспределённых системах. Его экосистема вполне жива, сейчас тестируется система статических типов. Модель let it fail применяется в мобильных операционных системах. Конкурентность и модели распределения распространились на Scala, Go и практически на всё остальное, где есть слова «микросервисы» или «акторы». На самом деле, меня печалит, когда я вижу микросервисы или Kafka, ведь по большей мере это повторные реализации архитектуры Erlang/Elixir, а также их внутренней BEAM Virtual Machine, но основанные на технологиях, которыми гораздо сложнее пользоваться и разворачивать, а также на протоколах, которые на множество порядков медленнее.
О, да, и Opalang тоже позаимствовал кое-что у Erlang.
▍ Пи-исчисление
Здесь я сжульничал. Пи-исчисление — это не язык программирования, а исчисление, то есть математическая модель, спроектированная для рассуждений о системах. Эту модель можно полностью определить всего в десятке строк спецификации и очень легко реализовать. Она использовалась для выполнения статического анализа моделей криптографических протоколов, протоколов банкинга… а также биологических процессов. Я использовал её для определения системы типов, которую разработчики теоретически могли бы применять, чтобы гарантировать правильную деградацию своих протоколов в условиях (D)DoS-атаки.
- Взрыв мозга: совершенно другой взгляд на условия гонки.
- Взрыв мозга: полнота по Тьюрингу любого вида последовательной операции не нужна.
- Взрыв мозга: описание сложных конкурентных/распределённых систем при помощи простой математики.
Я уже давненько не видел новых публикаций о пи-исчислении, но, возможно, просто не там смотрю.
▍ Opalang
Особый для меня случай, ведь я присоединился к команде и какое-то время был ведущим архитектором языка. Представьте, что вы пишете единую кодовую базу на простом функциональном языке + на основе акторов, сравнимом с OCaml/F#/ReasonML/Elm или с Erlang со статической типизацией, затем компилятор анализирует код на надёжность, безопасность и возможность распределённого использования, далее разделяет его на клиентский код (компилируемый в JavaScript + HTML + CSS), серверный код (компилируемый в нативное приложение) и код на стороне баз данных (компилируемый в схему базы данных и компилируемые запросы).
Я влюбился в этот язык. А затем выгорел, проектируя, разрабатывая и продвигая его в токсичном окружении. После этого мне понадобилось довольно много времени, чтобы вернуться в сферу проектирования языков программирования.
- Взрыв мозга: автоматизированное разделение на клиент, сервер и базу данных.
- Взрыв мозга: HTML со статической типизацией.
- Взрыв мозга: автоматическое устранение большинства проблем безопасности из Top 10 OWASP.
- Взрыв мозга: автоматическое распределение между веб-серверами (хоть мы и немного это переусложнили).
- Взрыв мозга: системы типов для анализа безопасности.
- Взрыв мозга: асинхронные волокна (fibers) в JavaScript (до
Promise
,async
/await
и воркеров DOM). - Взрыв мозга: база данных, ориентированная на структуры данных.
- Взрыв мозга: распределённая масштабируемая база данных (к сожалению, мы совершили ошибки, и на практике она оказалась довольно медленной).
Я считаю, что Opalang (и его родственники ReSharper и Ur/Web) был слишком большим прорывом для своего времени. Вся идея многоуровневого программирования, похоже, оказалась полностью забыта. Возможно, когда-нибудь она вернётся. WASM должен сильно упростить эту задачу.
▍ Rust
Потом я влюбился в Rust. Он сочетал в себе многие преимущества OCaml и Haskell, обещая дать разработчикам возможность писать высококонкурентный код и выполнять разработку на уровне систем. Кроме того, на тот момент революционными идеями были модульная сборка мусора и планирование M:N, хоть от этих идей и отказались до версии 1.0. В то время я начал экспериментировать с языком, по большей мере это был исследовательский проект. Помню обсуждения обработки ошибок, строк и итераторов. Один из важнейших пунктов в моём резюме: я один из тех, кто внедрил идею макроса
try!
, который затем преобразовали в оператор ?
.- Взрыв мозга: использование аффинных типов данных для доказательства свойств typestate.
- Взрыв мозга: писать код, по производительности сравнимый с C++, но с гарантиями уровня OCaml.
- Взрыв мозга: эффективная модель компиляции для
async
/await
. - Взрыв мозга: то, насколько успешно система типов приводит к безопасным конкурентным решениям.
- Взрыв мозга: помогающие сообщения об ошибках.
- Взрыв мозга: удобный процесс до RFC/RFC.
- Взрыв мозга: экосистема cargo и крейтов.
- Взрыв мозга: юнит-тестирование с принятием однозначной позиции (opinionated unit testing).
- Взрыв мозга: тестирование документации.
- Взрыв мозга: дружелюбное и приветствующее новичков сообщество.
- Взрыв мозга: частичная поддержка в написании моей собственной постепенной системы типизации (gradual type system).
У меня уже довольно долго не хватает времени, чтобы заниматься контрибьютингом в компилятор или stdlib, но когда оно найдётся, я планирую к этому вернуться!
К сожалению, мне кажется, Rust испортил для меня многие другие языки. Теперь когда я пишу на Python или Go (и тем, и другим я занимаюсь, чтобы зарабатывать на жизнь), или даже на TypeScript, мне всегда неприятна перспектива того, что мой код поломается, как только я его запущу. В Rust я кодирую в системе типов столько свойств, сколько могу, из-за чего перед написанием кода приходится немного дольше подумать, зато тесты обычно проходят с первого раза.
▍ А почему не $(ВАШ ЛЮБИМЫЙ ЯЗЫК)?
За свою карьеру я писал код на десятках языков программирования. В том числе на Haskell, Scheme, SmallTalk, (Tw)elf, Idris, Python, Go, PHP, Perl, Bash, C, C++, JoCaml,
JavaScript, TypeScript, Scala, C#, F#, Visual Basic, Ruby, (D)TAL, Squeak, Logo,
Scratch, UnrealScript, GDScript, Lua, SQL…
Если я не включил их в статью, значит, они не взорвали мой мозг. Это не значит, что эти языки не хорошие и не новаторские. Просто их концепция не вызвала во мне особого отклика или, что бывает чаще, я уже обнаружил те же концепции в каких-то других языках потому, что изучал их в таком порядке.
▍ Что дальше?
Я уже долгое время не видел ничего революционного, но это ничего не значит. Возможно, новая идея уже на подходе, где-то в небольшом исследовательском проекте, о котором я не слышал.
Когда я пришёл в PASQAL, то надеялся, что буду поражён языками для квантовых вычислений. Пока этого не случилось, но я не теряю надежды!
Мне кажется, что, несмотря на чрезмерный ажиотаж и безумный урон для окружающей среды, что-то полезное получится из ChatGPT и LLM, но пока не вижу этого. Я видел только интересные эксперименты, и многие игрушки уже кажутся поломанными. Любопытно, каким окажется будущее.
А какие языки повлияли на ваше мышление, связанное с программами?
Telegram-канал со скидками, розыгрышами призов и новостями IT ?
Комментарии (76)
smt_one
06.11.2024 13:11Эх, нет упоминания ATS. Надо действительно запланировать статью про него, а то про такую жемчужину на Хабре ничего и не видно.
ednersky
06.11.2024 13:11Взрыв мозга:
GOTO
!Очень хороший оператор. Мания удалять его из языков программирования - это победа сил зла над силами разума.
Moog_Prodigy
06.11.2024 13:11Меня всегда это удивляло. Ну давайте тогда и в асме отменим jmp, rjmp и прочие безусловные переходы. Как легко станет писать то сразу! Никаких переходов, никакой путаницы, исключительно условные операторы, условные переходы - красота.
nagayev
06.11.2024 13:11В асме пусть живет)
Все же если человек пишет в 2024 на асме он по идее точно знает что делает.
А вот на каком-нибудь JS не всегда.
ednersky
06.11.2024 13:11goto - идеальный оператор для написания, например, парсеров и вообще стейтмашин. при этом пофиг какой язык, если оператор goto есть, то читабельность кода в этом случае значительно выше, чем если этого оператора нет
SerafimArts
06.11.2024 13:11Неа. Достаточно while с continue и со сменой стейта. А peg или parser-combinator вообще даже без continue можно. Последний вообще через рекурсию, тупо с новыми аргументами (которые опять же можно развернуть в обычный while с массивом/вектором из стека).
Короче, goto не нужен. Только если хочется сделать одну километровую говнокодистую портянку сразу со всеми видами состояний, да и то спорно.
acsent1
06.11.2024 13:11Рекурсия обычно гораздо сложнее для понимания чем GOTO
SerafimArts
06.11.2024 13:11Ну вот тут я вообще крайне не согласен. Это же получается вызов метода с явными аргументами, пусть и рекурсивно, против запуска всего заново с непонятно как изменившимся стейтом.
В любом случае в первом варианте аргументы очевидны, а во втором - нужно искать по коду что поменялось вообще.
vanxant
06.11.2024 13:11Это если у вас язык поддерживает рекурсию "искаропки". Скажем, Паскаль и Си такое умеют с рождения, а вот Фортран и Бейсик тех лет (в частности, Спектрумовский) - нет.
Рекурсия там была всё ещё возможной, вот только её реализация вручную была ну эээ никак не проще GOTO.
y_mur
06.11.2024 13:11Эх давно хочу но руки не доходят написать серию статей с названием Антирекурсия. Разумеется с большим набором конкретных примеров. Суть в том что если вы видите "лаконичный" код с использованием рекурсии, то на самом деле внутри него всегда скрывается мозгодоробительнейшая логика, которую никто в здравом уме не будет использовать (если будет её видеть). Меня всегда удивляют люди, которые восхищаются рекурсией. Мне кажется что они просто не понимают как она работает на самом деле, хотя они думают с точностью до наоборот, что не понимают те кто не используют рекурсию :)
Ogoun
06.11.2024 13:11В высокоуровневых языках для стейтмашин хорошо подходит switch, кроме безусловного перехода еще и всякие pattern matching на него хорошо ложатся.
MrSpud
06.11.2024 13:11Есть и другой взгляд на вещи - существует только команда безусловного перехода и команда пропуска следующей команды. Такой подход позволяет просто реализовать конвейер
nagayev
06.11.2024 13:11Понятно, что в каких-то случаях использовать GOTO нормальная практика. В ядре линукса например он используется в том числе чтобы реализовать что-то вроде деструктора - позакрывать там файлы при выходе из функции например. Но в целом для современных языков GOTO не очень нужен. GOTO прямо провоцирует нарушать правило одного выхода из функции (см. misra), которое не лишено смысла. Используя что-то современное вроде Python или C++ в отличие от Си у вас есть инструменты для этого вроде менеджера контекста with или идиома RAII, которую удобно реализовывать через деструкторы.
diakin
06.11.2024 13:11GOTO прямо провоцирует нарушать правило одного выхода из функции
Это как это?
nagayev
06.11.2024 13:11Ну потому что у вас есть возможность прыгать почти в любое место в коде (в С++ например нельзя обходить инициализацию переменной).
А имея просто return шанс что выход будет один все же выше.
А еще у goto есть другие недостатки: усложнение статического анализа например.
diakin
06.11.2024 13:11В смысле вплоть до из одной функции в другую? В этом случае программиста уже никакие парадигмы не спасут.
OldNileCrocodile
06.11.2024 13:11Сам оператор GOTO осуществляет переход по метке, но только в рамках одной функции. Для прыжков между функциями используются функции Си
setjmp / longjmp
sigsetjmp / siglongjmp.
Префикс sig значит signal, сохраняет маску сигналов процесса (еë можно и потерять при прыжке)
В самом ассемблере есть три вида прыжков: shortJump, Jump, longJump. Последний позволяет прыгать на другие сегменты. А первые два отличаются набором допустимых адресов.
vanxant
06.11.2024 13:11а чего вы так упёрлись в единственность return? Вообще-то есть противоположный и очень толковый паттерн про early return / fail fast.
Да и для функций с развесистыми деревьями решений множественный return рулит.
adeshere
06.11.2024 13:11Очень хороший оператор. Мания удалять GOTO из языков программирования - это победа сил зла над силами разума.
Кстати, а в каких современных языках, кроме фортрана, он реально используется (а не формально присутствует для обратной совместимости), и в каком обычно контексте?
Я застал древний фортран, где GOTO использовался на каждом углу, и читать этот код было невозможно. Даже когда прыжки GOTO строго вложены друг в друга, это уже нечитаемо, имхо. А если траектории прыжков пересекаются (например, со строчки N1 прыжок на N4, а со строчки N2 прыжок на N5), то это та самая катастрофа, попав в которую хочется вырезать все GOTO каленым железом, включая и их использование
в быту ;-)
Как известно, в русском языке такой оператор появился очень задолго до первых языков программирования и вообще вычислительной техники ;-)
P.S. Вдогонку сообразил еще один аргумент супротив неправильного употребления GOTO: совсем небольшая модификация этого простонародного оператора запросто может приводить (и во многих алгоритмах из позапрошлого века реально приводит)
к UB
... иди туда, не знаю куда ....
;-)
Сейчас я по-прежнему пишу на фортране, но немного в другом стиле: а именно, почти без GOTO. Однако, есть пара контекстов, где я не просто не избегаю GOTO, а наоборот, использую его, как стандарт. Наиболее типичный случай - это переход из тела функции в самый ее конец (обычно на стандартную метку 900) при обнаружении каких-то проблем в любом месте функции. Код после метки 900 анализирует локальный номер ошибки и ее контекст, формирует диагностические сообщения для юзера и для протокола, восстанавливает среду (например, функция могла открыть какой-то файл или аллоцировать память - файл надо закрыть, а память освободить) и устанавливает возвращаемое значение с учетом вида ошибки. Такая схема позволяет:
1) приблизить проверочный код в теле функции к тому месту, где проверяемые условия непосредственно задействованы, не разрывая логику функции. Так, входные параметры проверяются сразу при входе в функцию, а условный знаменатель - непосредственно перед делением на него. Это упрощает модификацию кода: проверочные операторы легко менять одновременно с исполняемыми;
2) При этом код, выявляющий нештатную ситуацию, занимает минимальное место и не мешает чтению общей логики (обычно он состоит из одного-двух IF-ов с последующим GOTO);
3) Весь код восстановления собран в одном месте, что позволяет избежать его дублирования после каждой проверки. Причем, он знает, из какого именно места произошел переход на метку 900, и с учетом этого выполняет все нужные операции в нужном порядке.Еще изредка у меня GOTO заменяет простой и короткий цикл WHILE с постусловием в тех случаях, ЕСЛИ
1) этот цикл практически всегда выполняется один раз (и лишь изредка надо его повторить два-три раза) И
2) запись постусловия в формате IF(...) GOTO улучшит читаемость кода.Я таким способом подчеркиваю для себя линейность алгоритма. Но имхо этот случай гораздо более спорный, чем описанный выше. Даже несмотря на обязательное требование к таким GOTO, что они должны вести не более, чем на несколько операторов назад, и что во внутреннем блоке не должно быть никаких ветвлений или условий.
Cheater
06.11.2024 13:11Кстати, а в каких современных языках, кроме фортрана, он реально используется
Внезапно, в C и C++ для выхода из вложенных циклов. Насколько мне известно, это последнее оставшееся в живых "легальное" использование goto в высокоуровневом коде на C/C++.:)
Ещё он есть в Rust для тех же целей, под именем labelled break.
adeshere
06.11.2024 13:11Внезапно, в C и C++ для выхода из вложенных циклов. (...)
Ещё он есть в Rust для тех же целей, под именем labelled break.
А это точно GOTO?
Я не знаю ни C, ни Rust, но если я правильно понял пример по ссылке, то создается впечатление, что это больше похоже на обычный exit с указанием уровня вложенности (на какой уровень выйти). В фортране для этого точно так же надо присвоить нужному циклу имя (даже синтаксис совпадает ;-), после чего оператор "
exit LoopName
" передает управление из любой точки внутри циклаLoopName
(включая внутренние циклы любой вложенности) на первый оператор ПОСЛЕ циклаLoopName
. С той символической разницей, что вместо закрывающей скобки цикл у нас закрывается фразой "end do
" либо (по желанию программиста) "end do LoopName
".Разумеется, такой exit можно заменить на GOTO + метку, но зачем? В фортране такое сейчас и в голову никому не придет. Если в Rust эта конструкция работает аналогично, то мне очень трудно сассоциировать ее со спагетти-кодом.
vanxant
06.11.2024 13:11А это точно GOTO?
Точно.
Собственно, можете посмотреть какое-нибудь ядро линукс, там именно для этого goto широко используется.
Допустим, функция должна захватить ресурсы А и В, и ещё выделить память. Тогда у неё в конце три-четыре метки выхода:
exit3: kfree(mem); // освободить память exit2: fclose(B); // освободить ресурс В exit1: fclose(A); // освободить ресурс А exit: return result; // выйти
Соответственно, если где-то возникла ошибка, будет goto на одну из этих меток.
В языках без ключевого слова goto, а также без
defer
и/или RAII можно заменить это цикламиdo
илиwhile
и использоватьbreak <метка>
. Но это лишние уровни вложенности кода.
MaNaXname
06.11.2024 13:11А это точно GOTO?
Да. Просто они называются по разному но по сути:
switch, if, break, return, catch, finally
они все под капотом меняют ход программы и по сути - GOTO. (или в терминах асемблера - jump)
vanxant
06.11.2024 13:11Очень хороший оператор
Соглашусь с комментатором выше. Вы просто не видели программ, построенных на базе пересекающихся goto. Какая-нибудь машина состояний. например. Я понимаю, что там это оправданно, и компилятор в итоге именно такую лапшу из goto (jmp, br, you name it) и выдаст. Но лучше пусть он этим и занимается.
omxela
06.11.2024 13:11Мысль о том, что что-то можно довести до абсурда, а потому вообще не следует это употреблять, никогда не казалась мне разумным аргументом. Даже в эпоху яростной борьбы с goto, которую я застал. Плохо и неправильно можно употребить вообще что угодно. На мой взгляд, из этого не следует совсем ничего.
vanxant
06.11.2024 13:11На моей памяти с goto яростно боролись в университетской среде - потому что так проще проверять работы студентов. Из реальных языков никто goto не выпиливал. Ну точнее если Вирт ещё оправдывался, что goto оставлен для переноса функций из фортрана, то в js ключевое слово goto не реализовали, но зарезервировали, а главное сам goto имплементирован.
vitalyvitaly
06.11.2024 13:11В "классических" Бейсиках GOTO, кажется, бывал и вычисляемым и даже использование функции RND напрямую иногда мог допускать (?!!).
ermouth
06.11.2024 13:11В классических бейсиках с помощью гото можно было изнутри подпрограммы в основной код обратно вынырнуть. И потом обратно занырнуть.
Вот это фича так фича )
vitalyvitaly
06.11.2024 13:11По-моему, там чаще всего просто не контролировался выход из цикла, например цикла FOR, и таким образом можно было неограниченное число раз выпрыгнуть оттуда и запустить этот цикл снова и так далее, и других средств контроля и стека возвратов не было - по крайней мере, в самых ранних версиях. Во всяком случае, раннний Бейсик типа WANG был этими "фичами" очень богат.
ImagineTables
06.11.2024 13:11Showing my age, in VIC20 basic you could say
On X Goto 100, 200, 300, 400
which would Goto line 100, 200 etc depending on X being 1, 2, 3 etc. And the good news is, it works in VB6 too! You'll get an error if the line numbers you're going to don't exist though.vitalyvitaly
06.11.2024 13:11Это вариант оператора раннего Фортрана. В Спектрумовском Бейсике работает и такое
5 Let b=5
10 Let n=100
15 Input a - здесь можно спокойно ввести b+n или любую другую формулу. Только a пока ввести не получится (его еще нет)
20 Goto n
100 Print a
foal
06.11.2024 13:11Мне голову сломал FORTH. До сих пор, как вспомню так вздрогну :)
Rigidus
06.11.2024 13:11Тогда возможно понравится исследование, насколько он может быть быстр (спойлер: очень быстр) https://habr.com/ru/articles/856480/
SannX
06.11.2024 13:11Помню, познакомился с ним в школьные годы на клоне ZX Spectrum. После Pascal и Basic "идеология" написания кода в Forth действительно взрывала мозг. Но этим и запал в душу )))
vitalyvitaly
06.11.2024 13:11Мне кажется, что Спектрумовский Бейсик был уникален тем, что позволял юзеру при вводе данных по INPUT писать формулы и обращаться к числовым функциям интерпретатора и кажется, и к переменным в коде тоже. Не знаю, где еще такое использовалось, но эта "фича" сражала наповал.
MrSpud
06.11.2024 13:11FORTH, наверное, нельзя в полной мере назвать языком, скорее это способ реализации 0-адресной машины. Те, кто помнит калькулятор Электроника Б3-21, ностальгируют. Стек на 60 слов, и ни в чем себе не отказывай. А реально на FORTH выполняли управляющие системы, существовала даже м-схема, реализующая ядро.
geher
06.11.2024 13:11Lazarus Pascal
Вообще-то Free Pascal. Lazarus - это IDE для Free Pascal, использующее компилятор fpc.
functyon
06.11.2024 13:11в детстве для меня самое сильное озарение в программировании было, когда я узнал, что в языке есть возможность написать функцию, которая вернет значение. было круто.
a-tk
06.11.2024 13:11Какой любвеобильный автор, который восхищается непонятно чем. Ему надо бы поработать с XSLT, интересно было бы послушать впечатления...
danielsedoff
06.11.2024 13:11В языке Basic оператор Dim объявляет любую переменную, совершенно не обязательно массив
Giox_Nostr
06.11.2024 13:11Сегодня Prolog практически не существует.
Сейчас у автора оригинальной англоязычной статьи будет очередной "взрыв мозга". Не поверите! Реализаций языков Prolog более сотни. Из этой сотни в настоящее время активно (коммерчески и промышленно) применяют более тридцати реализаций. Например, почитайте про XSB, SWI, Ciao.
В Prolog вы не пишете алгоритмы, а учите программу, как думать.
Вот эта фраза — это оговорка по Фрейду, которая говорит о том, что автор оригинальной статьи никогда не программировал ни на одном из языков Prolog. Программисты (любые, в т.ч. и логические) не учат компьютеры "думать". Они всего-лишь пишут программы, компилированный код которых машины (тупо) исполняют. И машине всё равно на чём там изначально писали — на ассемблере, на языке Visual Prolog или на языке Python.
SQL в большой мере основан на подмножестве Prolog с большим упором на оптимизацию в ущерб простоте.
Автор совершенно безграмотный. Грамотный специалист отметил бы что языки SQL и языки Prolog относят к группе декларативных языков программирования. Ни одна классификация не относит ни одну из реализаций SQL (кстати, их тоже много) ни к какому "подмножеству" языков Prolog. Если разработчикам PostgreSQL рассказать, что по мнению пиндосских блогеров они "подмножество" Visual Prolog, они будут долго и нервно курить в углу.
RikkiMongoose
06.11.2024 13:11Множество математических теорем было доказано благодаря превращению их в код на Coq.
Реклама такая реклама.
Названия этих многих теорем в статье стыдливо опущены
GospodinKolhoznik
06.11.2024 13:11Я как то даказал на Coq комутативность и ассоциативность сложения и умножения. Ещё дистрибутивность. А на большее меня не хватило, забросил Coq.
illinav
06.11.2024 13:11Названия какого рода вы ожидаете? «Теорема Пифагора»? «Теорема о четырёх красках» (пожалуй, самый известный для обывателя случай)? «Теорема о корректности системы типов в dependent dependency calculus» [1]? Тому подобные теоремы из прочих подобных статей?
RikkiMongoose
06.11.2024 13:11Теорема Пифагора была доказана ещё древними вавилонянами.
Теорема о четырёх красках была доказана перебором 1936 вариантов. В 2005 её только повторили.
Теорема о корректности системы типов в dependent dependency calculus и прочие удручающе напоминают те самые особенные интегралы, которые можно взять... но которые встречаются только в курсе интегрального анализа.
Очень многие математики относятся к Coq крайне скептически - фактически, он требует просто записывать готовое доказательство, разворачивая все "после тривиальных преобразований получим".
illinav
06.11.2024 13:11Вот я и пытался понять, какой род теорем вы бы хотели услышать.
Теорема о четырёх красках была доказана перебором 1936 вариантов.
Только корректности самого перебирающего кода надо было доверять.
В 2005 её только повторили.
Сведя требуемую поверхность доверия к ядру Coq, но это, конечно, мелочь.
Теорема о корректности системы типов в dependent dependency calculus и прочие удручающе напоминают
Это, конечно, мощный аргумент, против него не попрёшь. А мне не напоминают, что с этим будем делать?
Очень многие математики относятся к Coq крайне скептически
Многие программисты на мейнстримных языках скептически относятся к тестам, а лет 20 назад скептически относились к линтерам, автоформаттерам, системам контроля версий, и так далее. О чём это говорит?
фактически, он требует просто записывать готовое доказательство, разворачивая все "после тривиальных преобразований получим".
Для тривиальных преобразований уровня равенств во всяких полукольцах есть куча тактик, которые это делают за вас (и тактики — единственное хорошее, что есть в Coq по сравнению с другими подобными языками).
Интересно, считаете ли вы, что множество теорем доказано «благодаря» математической логике? Ведь она формально тоже требует расписывать разные шаги, например, вместо простого и понятного математикам 19-го века тривиального утверждения «очевидно, что непрерывная функция дифференцируема везде, кроме множества её изолированных точек». Потом, правда, Вейерштрасс всю малину испортил, но то такое, неправильный математик был просто. Ну и Кантор ещё этот поехавший, зачем-то доказавший формально про неравномощность powerset'а, хотя равенство мощностей рациональных и вещественных чисел тоже было тривиально, а потом эти вот все со своими брадобреями, тоже ломающими всякие очевидные и тривиальные вещи. Плохо зделоли тупо, не могли как в начале 19-го века, чтобы неудобные или очевидные вещи заметать под ковёр из «тривиально».
Что, собственно, вообще такое для вас «доказательство»?
RikkiMongoose
06.11.2024 13:11Думаю, за меня неплохо ответит книжка Имре Лакатоса "Доказательства и опровержения". Там довольно подробно расписана проблема того, как одна тривиальность проваливается в другую.
Поэтому открытие теорем кажется мне более важным, чем их формальное доказательство.
illinav
06.11.2024 13:11Думаю, за меня неплохо ответит книжка Имре Лакатоса "Доказательства и опровержения".
[По-видимому, в отличие от вас], я Лакатоса таки читал (так как это имя входит в кандидатский курс философии науки, а я его сдавал). Нет, он не отвечает на этот вопрос, по крайней мере, в контексте математики.
Там довольно подробно расписана проблема того, как одна тривиальность проваливается в другую.
Описание этой проблемы не является ответом на вопрос о том, что такое для вас доказательство.
Поэтому открытие теорем кажется мне более важным, чем их формальное доказательство.
Невозможно отличить теоремы от не-теорем без доказательства, что утверждение теоремы действительно следует из данного набора аксиом.
RikkiMongoose
06.11.2024 13:11Из материалов этой книги довольно ясно следует, что однозначное определение доказательства вообще невозможно. Можно говорить только о тавтологических утверждениях, но пользы от них немного (они не увеличивают знание). Ну или о консенсусе математиков по какому-то вопросу.
Ну и вспоминайте получше кандидатский курс - то неужели там не рассказывают, что до конца неясно, на каких аксиомах основана математическая модель ОТО (понятно, что пространство неэвклидово, но как его описать неясно) и что мы не знаем, выполняется ли там, к примеру, аксиома Архимеда? Однако эта нехватка формализации не мешает вести исследования. Есть даже подходы, которые прямо отрицают важность этих оснований.
Невозможно отличить теоремы от не-теорем без доказательства, что утверждение теоремы действительно следует из данного набора аксиом.
То есть великая теорема Ферма до 1995 года не была теоремой? Это новое слово в истории математики.
Из этой заявления следует много не менее странных: например, неясно, как быть с невыводимыми теоремами, которые описываются теоремой Гёделя о неполноте. Их истинность доказать можно, а вывести из аксиом - нельзя.
illinav
06.11.2024 13:11Из материалов этой книги довольно ясно следует, что однозначное определение доказательства вообще невозможно.
То есть, вы изначально всю вашу аргументацию основывали на термине, который по-вашему определить невозможно? Ну, в принципе, для открывателя теорем, которому их не нужно доказывать, это неудивительно.
Можно говорить только о тавтологических утверждениях, но пользы от них немного (они не увеличивают знание)
Они не увеличивают знание в смысле этакого платонического идеала форм и идей, но они увеличивают доступное вам для оперирования на практике знание. Условно, до того, как вы узнали, что сложение коммутативно, вы не могли этим пользоваться при решении примеров, а после этого — смогли.
(понятно, что пространство неэвклидово, но как его описать неясно) [...] Однако эта нехватка формализации не мешает вести исследования.
Упомянутая вами в скобках часть прямо мешает.
То есть великая теорема Ферма до 1995 года не была теоремой?
Верно, она была гипотезой. Собсна, даже википедия говорит:
The proposition was first stated as a theorem by Pierre de Fermat around 1637 in the margin of a copy of Arithmetica. Fermat added that he had a proof that was too large to fit in the margin. Although other statements claimed by Fermat without proof were subsequently proven by others and credited as theorems of Fermat (for example, Fermat's theorem on sums of two squares), Fermat's Last Theorem resisted proof, leading to doubt that Fermat ever had a correct proof. Consequently, the proposition became known as a conjecture rather than a theorem.
(курсив мой)
Это новое слово в истории математики.
Это новое слово только для тех, кто с математикой знаком по научно-популярным видосам на ютубе.
Из этой заявления следует много не менее странных: например, неясно, как быть с невыводимыми теоремами, которые описываются теоремой Гёделя о неполноте. Их истинность доказать можно, а вывести из аксиом - нельзя.
Что неясного? Это теоремы метаязыка (в котором мы рассуждаем об аксиомах языка, и в котором их истинность доказывается), а не языка.
RikkiMongoose
06.11.2024 13:11Упомянутая вами в скобках часть прямо мешает.
И какие же математические проблемы стоят перед современной физикой? Для многих случаев ситуация прямо обратная: из формул следует существование мультивселенных, физического смысла парадокса Баноха-Тарского и т.п. Проблем с математическими методами (как было при открытии дифференциального счисления или комплексных чисел) нет.
Исследования Воеводского или Вопенки ничего не меняют в современной физике. Даже теория струн в ней ничего принципиально не поменяет (КЭД и так даёт избыточную точность для практически всех экспериментов).
Довольно странно, что вам это неизвестно. Если вы учились в аспирантуре, то хотя бы лекции Фейнмана по КЭД должны быть вам знакомы.
Это новое слово только для тех, кто с математикой знаком по научно-популярным видосам на ютубе.
Ну назовите мне хотя бы 5 математиков, которые не считали Великую Теорему Ферма теоремой до того момента, как она была доказано.
Только, пожалуйста, с точными ссылками на соответствующие места в их работах.
Это теоремы метаязыка (в котором мы рассуждаем об аксиомах языка, и в котором их истинность доказывается), а не языка.
В первой теореме Гёделя речь идёт именно о теоремах языка (в его классическом доказательстве - над числами).
illinav
06.11.2024 13:11Для многих случаев ситуация прямо обратная: из формул следует существование мультивселенных, физического смысла парадокса Баноха-Тарского и т.п.
Следовательно, отсутствие этих формул (выводимых и обосновываемых средствами математической логики) не дало бы вам шанса на соответствующее физическое содержание.
Если вы учились в аспирантуре, то хотя бы лекции Фейнмана по КЭД должны быть вам знакомы.
Для протокола — в программе аспирантуры нет лекций Фейнмана, особенно если у вас было, например, 01.01.09. Хотя конкретно книжечку Фейнмана я просмотрел ещё в старшей школе.
Ну назовите мне хотя бы 5 математиков, которые не считали Великую Теорему Ферма теоремой до того момента, как она была доказано.
Я вам сослался на википедию, где это написано в самом начале. Играть в «а теперь побегайте-поищите 5 конкретных математиков» я не буду. Тем более, что это и не нужно.
Ваша фундаментальная
проблемаособенность в том, что вы воспринимаете математику исключительно как социальный процесс: теорема это то, что называют математики, доказательство это то, с чем соглашаются многие математики, формальные доказательства плохи потому, что многие математики…, и так далее. Это ничем не отличается от кружка поэтов или импрессионистов-прогрессивистов, где стих красивый и картина прогрессивная потому, что так договорились поэты и импрессионисты-прогрессивисты.До формализации математики этому действительно не было альтернатив. С развитием матлогики решать корректность теоремы большинством голосов больше не нужно.
В первой теореме Гёделя речь идёт именно о теоремах языка (в его классическом доказательстве - над числами).
Супер. А теперь перечитайте то, что я написал, держа в уме ту формулировку понятия теоремы, которую я имею в виду (утверждение с предоставленным деревом вывода в данной логической системе), а не то, что имеете в виду вы (что-то там про большинство математиков).
RikkiMongoose
06.11.2024 13:11Следовательно, отсутствие этих формул (выводимых и обосновываемых средствами математической логики) не дало бы вам шанса на соответствующее физическое содержание.
У вас большие проблемы с логикой. И комментарием выше вы признавали, что эти формулы невыводимы средствами математической логики, потому что для ОТО нет системы аксиом.
Я и спрашиваю - какие ПРОБЛЕМЫ у ОТО из-за отсутствия системы аксиом? Формулы спокойно получены и подтверждены и без этой базы.
Если в нашем мире не выполняется аксиома Архимеда - как это изменит современную физику?
И опять же. по какой из математических логик вы собираетесь их выводить? По аристотелевой? Что изменится, если мы будет выводить, пользуясь интуиционной? А есть ещё темпоральная и много какая ещё.
Хотя конкретно книжечку Фейнмана я просмотрел ещё в старшей школе.
Вы, видно, имеете в виду его автобиографию. Его книга по КЭД посвящена другим вопросам.
До формализации математики этому действительно не было альтернатив. С развитием матлогики решать корректность теоремы большинством голосов больше не нужно.
Из курса истории математики вам должно быть известно, что и формализм Гилберта, и логицизм Рассела так и не нашли окончательного решения.
А ваше трепетное отношение к формальным доказательствам вызвано тем, что вы больше просто ничего не умеете.
illinav
06.11.2024 13:11У вас большие проблемы с логикой. И комментарием выше вы признавали, что эти формулы невыводимы средствами математической логики, потому что для ОТО нет системы аксиом.
Почему фундаментальные ошибки в логике делаете вы, а проблемы приписываете мне?
Если для ОТО используется данный математический аппарат, то аксиоматика этого аппарата входит в набор аксиом ОТО. Просто использование математики — это настолько привычное действие, что физики про это не вспоминают и не приписывают аксиомы используемой математической теории к своим физическим теориям.
Более того, ОТО, конечно же, аксиоматизируема, и я нигде не признавал, что это не так.
Формулы спокойно получены и подтверждены и без этой базы.
Откуда получены, если по-вашему там аксиом нет? Из эфира? Из тех же наблюдений, которыми они потом подтверждены?
Если в нашем мире не выполняется аксиома Архимеда - как это изменит современную физику?
Как минимум появится необходимость объяснить, почему мир выглядит так, будто эта аксиома выполняется на доступных людям для
прямыхтекущих наблюдений макромасштабах.И опять же. по какой из математических логик вы собираетесь их выводить? По аристотелевой? Что изменится, если мы будет выводить, пользуясь интуиционной?
Это правильные вопросы, и вполне возможно, что это даст разные физики с разными наблюдаемыми результатами. Например, если у вас для описания мира остались две теории-кандидата, одна из которых выведена классической логикой, а другая — интуиционистской, и которые дают разные предсказания, и эксперименты отвергают теорию поверх классической логики, то результат понятен.
А есть ещё темпоральная и много какая ещё.
Нагуглили, молодец. Жаль, что не в тему.
Вы, видно, имеете в виду его автобиографию. Его книга по КЭД посвящена другим вопросам.
Вам вообще неважно, что я пишу? Я не дал вам ни единого повода сделать выводы о том, какие вопросы по моему мнению рассматривались в этой книге, но вы смело берётесь утверждать, что там рассматриваются «другие вопросы».
Хотя, если держать в уме, что логический вывод вам не нужен…
Из курса истории математики вам должно быть известно, что и формализм Гилберта, и логицизм Рассела так и не нашли окончательного решения.
Не нашли окончательного решения чего? Давайте, высказывайте свои тезисы до конца (правда, тогда есть риск, что все поймут, что вы не шарите, но это другой вопрос).
А ваше трепетное отношение к формальным доказательствам вызвано тем, что вы больше просто ничего не умеете.
Да я и формальные доказательства не умею, а в свободное время так, делаю всплывающие окна на JavaFX. Нельзя мне высказываться на тему, эх.
d00m911
06.11.2024 13:11Не знаю уж, сколько ему лет, но мне кажется, что даже 5-6 языков с детства/подросткового возраста и вплоть лет до 40 выучить и применять на регулярной основе, причем так, чтобы оценить преимущества/недостатки в полной мере, очень тяжело.
PrinceKorwin
06.11.2024 13:11Сейчас наверное да, но раньше с этим было проще. Мой примерный путь был:
basic с конструкциями data, seek, peek для asm вставок для скорости
для этого в маш. кодах сразу программировал
из маш. кодов в asm перешел
из asm в С
из С в Pascal
И это где-то за 3 года в сумме. Было очень весело :)
pocheketa
06.11.2024 13:11"функциональность с языками, в которых они появились не впервые"...
Кто они? В ком появились?
pocheketa
06.11.2024 13:11PHP, javaScript — неплохие языки (особенно когда работаешь с вебом).
А сейчас Python завоевал всю молодёжь... Не знаю, насколько это хорошо или плохо )
Turbo_Pascal_55
06.11.2024 13:11Паскаль рулит.
Тоже с Turbo Pascal 5.5 хотел на Turbo C 2.0 перейти - не смог. Тупизна страшная. А в паскале - всё логично и понятно.
saboteur_kiev
06.11.2024 13:11А где же bash или perl с их незабываемой работой с текстом
kekoz
06.11.2024 13:11bash, в отличие от perl, с текстом работать практически не умеет. В bash-скриптах почти вся работа с текстом осуществляется внешними программами.
Wesha
06.11.2024 13:11(Презрительно сплёвывая через зубы:) Пацан! А собирал ли ты свой первый элемент ИЛИ из
овна и палокпроволочек и диодов?!
Zenitchik
У автора, я смотрю, от каждой мелочи мозг взрывается...
sse
Автор просто эмоциональный. Вот его блог по ссылке
Wesha
В те^H^H мозге такая приятная гибкость образовалась!