KISS («оставайся простым, глупым» или «делай это простым глупым», см., Например, здесь ) является важным принципом в разработке программного обеспечения, даже если он явно возник в инженерном деле. Ссылаясь на статью в Википедии:
Этот принцип лучше всего иллюстрируется историей о том, как Джонсон вручил команде инженеров-конструкторов несколько инструментов, при этом задача, которую создавал реактивный самолет, должен был быть отремонтирован средним механиком в поле в боевых условиях только с этими инструментами. Следовательно, «глупый» относится к связи между тем, как вещи ломаются, и изощренностью, доступной для их исправления.
Если бы я хотел применить это в области разработки программного обеспечения, я бы заменил «реактивный самолет» на «часть программного обеспечения», «средний механик» на «средний разработчик» и «в боевых условиях» на «при ожидаемой разработке / обслуживании программного обеспечения». условия »(сроки, временные ограничения, встречи / перерывы, доступные инструменты и т. д.).
Таким образом, это общепринятая идея, что нужно стараться, чтобы часть программного обеспечения была простой (или просто глупой , если вы пропустили запятую), чтобы потом было легче работать с ней.
Но может ли принцип KISS быть применен и к дизайну языка программирования? Знаете ли вы о каких-либо языках программирования, которые были разработаны специально с учетом этого принципа, то есть, чтобы «позволить среднестатистическому программисту при средних условиях работы писать и поддерживать как можно больше кода с наименьшими когнитивными усилиями»?
Если вы цитируете какой-либо конкретный язык, было бы здорово, если бы вы могли добавить ссылку на какой-либо документ, в котором это намерение четко выражено разработчиками языка. В любом случае мне было бы интересно узнать о (задокументированных) намерениях дизайнеров, а не о вашем личном мнении о конкретном языке программирования.
источник
Ответы:
Когда я думаю о минимализме, я думаю о Lisp и Go . В Lisp все, что у вас есть, это функции и списки, которые настолько просты, насколько вы можете получить (ну, есть немного больше, но неважно). Тем не менее, я думаю, что дело Go более интересным.
Go был разработан, чтобы быть простым (это достойное чтение). Используемый ими термин «ортогональность элемента» означает, что любой элемент следует добавлять только в том случае, если он обеспечивает нечто действительно уникальное. Похоже, это связано с участием авторов ( на ум приходят Расс Кокс и Роб Пайк ) с Plan9 , который представлял собой переосмысление UNIX с учетом простоты. (Если вы заинтересованы в минималистичном дизайне, статья Роба Пайка о простой оконной системе является хорошим чтением.)
Вот несколько простых примеров синтаксиса:
Только одна циклическая конструкция
Цикл может выглядеть следующим образом:
Бесконечная петля
Пока цикл
Традиционный для цикла
Цикл по каждому элементу
Многоцелевой выключатель
Многократный возврат
Интерфейсы
Вложение
каналы
Может использоваться для реализации семафоров
Используется для передачи сообщений между потоками
Может использоваться для обработки асинхронных событий
Вывод
Я не буду вдаваться в каждую часть синтаксиса, но, надеюсь, вы увидите, на что способен минимализм. Язык интригует не потому, что он добавляет массу новых функций, а потому, что он использует лучшие функции из других языков без каких-либо дополнительных.
Обычно есть один «лучший» способ решения проблемы. Например, в списке рассылки многие пользователи жалуются на отсутствие генериков. После обсуждения они понимают, что все, что они хотят сделать, можно сделать с помощью интерфейсов. Читайте об эффективном переходе к примерам идиоматического синтаксиса.
Преимущество языков KISS заключается в возможности написания идиоматического кода, поскольку стиль кода ограничен языком. Например, в Go вы не можете написать что-то вроде этого:
Вы должны использовать фигурные скобки:
В синтаксисе есть много других примеров, облегчающих чтение кода других людей.
Преимущества языка KISS перед популярными языками:
источник
for i=1 to 10
или питон:for item in group
for i = 1 to 10
в том,i
будет ли когда-нибудь 10. Это может зависеть от языка (bash включает 10, python нет). Традиционный цикл for универсален.Я думаю, что Zen of Python скажет, почему Python является простым языком намного лучше, чем я могу:
Редактировать в ответ на @Giorgio
Как говорится в вашем вопросе,
Для меня Python - это то, что сразу приходит на ум. Дизайн Python является прямым ответом на методологию Perl, известную «Есть больше, чем один способ сделать это». Хотя это здорово, позволяя программистам очень легко писать код, это не помогает в обслуживании. До того, как я управлял (очень плохо написанной, я признаю) программой, написанной на Perl, я ценю, что Python вынуждает использовать как хорошие методы кодирования, так и лаконичный язык.
Python также не заставляет вас следовать какой-то определенной методологии при написании программ. Я могу выбрать строгий объектно-ориентированный стиль программирования или написать простой скрипт для последовательного выполнения. Не нужно инициализировать класс, а затем вызывать
main()
метод, который вы вынуждены делать в Java, очень хорошо. (Кроме того, печать на стандартный вывод в Python - это замечательно, но это довольно ноль).Наконец, методология «Батареи в комплекте», включающая обширную стандартную библиотеку с языком, замечательна. Вместо того, чтобы искать какой-то внешний репозиторий для пакетов, большая часть того, что мне нужно, уже включена в язык. Также хорошо иметь это внешнее репо, но не нужно копаться в нем, чтобы выполнить основную операцию, это действительно удобно.
источник
import this
команды.Основным ключом к поддержанию «простоты» является признание того, когда сложность будет необходима, и наличие частей системы, которые могут наилучшим образом с ней справиться. Наличие единственного вида ссылки на объект, который не делает различий между неизменяемыми значениями, изменяемыми значениями и сущностями, делает Java «простой», не устраняет необходимость различать значения и сущности; это просто лишает программистов инструментов, помогающих им в этом.
В более общем случае, если кто-то пытается, чтобы язык программирования или фреймворк поддерживали несколько вариантов использования, следует убедиться, что не будет ситуаций, в которых различные варианты поведения будут подходящими для разных вариантов использования, но компилятор не сможет сказать, их врозь. Добавление большего количества типов к языку или структуре может показаться сложным, но во многих случаях это может фактически упростить задачу.
Рассмотрим, например, путаницу правил, окружающих подписанные и неподписанные типы в C. Сложность этих правил проистекает из того факта, что некоторые коды используют целочисленные типы без знака для представления чисел, в то время как другой код использует их для представления членов оберточного алгебраического кольца. (в частности, набор целых конгруэнтных мод 2ⁿ). Правила преобразования типов ведут себя так, что иногда они подходят для одного использования, а иногда - для другого. Наличие отдельных типов переноса и неупаковывания удвоит число целочисленных типов, но может упростить связанные с ними правила:
Любой не-кольцевой целочисленный тип любого размера может быть назначен кольцу любого размера; кольцо может быть назначено только кольцу равного или меньшего размера.
Операции, отличные от реляционных операторов, включающие целое без кольца и кольцо, будут неявно преобразовывать целое число в тип кольца.
Кольца могут быть явно приведены к числам или к большим кольцам; значение беззнакового кольца - это наименьшее неотрицательное целое число, которое при добавлении к нулю кольца даст значение кольца. Значение кольца со знаком - это целое число наименьшей величины, которое при добавлении к нулю кольца даст значение кольца, причем отрицательное значение будет предпочтительным в случае связи.
За исключением упомянутого выше, кольца ограничиваются операциями с кольцами одинакового размера или меньшего размера.
Операции над целыми числами без колец различных типов должны преобразовывать числа в тип, который может вместить все значения любого операнда, или должен быть отклонен компилятором, если подходящего типа не существует
Казалось бы, определение типов колец удвоит число целочисленных типов, но значительно упростит написание переносимого кода. Использование одинаковых типов без знака для чисел и колец уменьшает количество типов, но приводит к сложным правилам, которые делают практически невозможным написание эффективного переносимого кода.
источник
Возможно, Tcl был разработан в этом направлении. Весь язык может быть описан только в 12 правилах на одной странице руководства . Это удивительно просто и последовательно.
Создатель Tcl утверждал следующие исходные цели:
Из " Истории Tcl " - http://www.tcl.tk/about/history.html
источник
Если язык зафиксирован в его дизайне из-за KISS, он не может расти. Язык, который не может расти, умрет.
В следующем видео Гай Стил умело объясняет, что язык программирования должен развиваться и почему. Если вы применяете KISS, то как может расти язык, потому что после выпуска его набор инструментов исправлен и никогда не может изменяться.
Это часовое видео, но стоит посмотреть. Если вы не знаете, кто такой Гай Стил, вы действительно должны говорить о языковом дизайне.
Я выбрал это видео в качестве ответа, потому что считаю, что применять KISS к языковому дизайну в целом неправильно, и надеюсь, что просмотр речи известного человека, занимающегося языковым дизайном, поможет расширить ваше понимание будущего языкового дизайна.
Поскольку вы пришли сюда, чтобы узнать о языковом дизайне, и я дал вам причину не использовать KISS, будет справедливо указать на то, что я нахожу полезным в языковом дизайне. Когнитивные измерения обозначений
РЕДАКТИРОВАТЬ
Когда я писал приведенный выше ответ, он основывался на рассуждениях: если движок можно поддерживать только с помощью фиксированного набора инструментов, то моя переформулировка этого значения в отношении языкового дизайна заключается в том, что язык не может измениться после освобождения. Комментарии указывают, что это не то, что имелось в виду. Итак, позвольте мне предложить этот измененный ответ, который будет более соответствовать пересмотренному пониманию.
Если взглянуть на когнитивные измерения нотаций, то вы поймете, что существует множество конкурирующих измерений, связанных с языковым дизайном, а не просто простота, и если вы слишком сосредоточитесь на одном, вы будете страдать в других. С вопросом сильно сосредоточив внимание на простоту (ПОЦЕЛУЙ) хорошо, и подкреплено отметили людьми дизайна языка, я представил выступление на Guy Steele , чтобы показать , что пытаюсь сохранить дизайн исключительно простым будет влиять другие размеры. Более того, я пытаюсь донести до вас, что вам нужно взглянуть на многие аспекты и взвесить все за и против, а не просто простоту.
источник
Вот большая цитата из Hardcore Visual Basic Брюса Маккинни , которая, в свою очередь, вкладывает слова в уста дизайнеров BASIC, Kemeny и Kurtz . Подчеркивает мое.
источник
Хорошо, что вы пояснили, что вы подразумеваете под «простым», потому что, на мой взгляд, простой язык программирования - это язык с минимальным синтаксисом и несколькими функциями (Scheme, Forth, ML), который напрямую не переводится в ваше определение. Я думаю, что вы действительно ищете дизайн языков с учетом RAD (быстрой разработки приложений), и их немало. См. Этот поток StackOverflow, например: /programming/66227/what-is-the-best-multi-platform-rad-language
источник
Я удивлен, что никто еще не упомянул C, хотя он ставит простоту на первое место по нескольким важным причинам, часто настолько радикально, что программисты не могут оценить простоту:
Там нет скрытой магии. Если вы пишете
a + b
на C, у вас есть гарантия, что он будет скомпилирован не более чем с одной инструкцией ассемблера.Даже в относительно простых языках, таких как Java, простое утверждение типа
a + b
может занять несколько микросекунд (если переменные являются строками). Другие языки добавляют много, намного больше к этому с крайним примером C ++, гдеa + b
могут быть перегружены, чтобы появились розовые слоны. В C это не так: если это не вызов функции, это займет не более нескольких наносекунд. Эта предсказуемость производительности является одной из ключевых особенностей C, и, безусловно, является формой простоты.Типы данных настолько просты, насколько это возможно, и в то же время описывают все интересные структуры данных, которые вы, возможно, захотите встроить в память: есть только основные типы, которые ЦПУ может обрабатывать + агрегация (
struct
) + повторение (массивы) + ссылки (указатели) ).Это правда, что различные языки на основе lisp намного проще, чем C в этом отношении. Однако они не пытаются позволить программисту свободно манипулировать памятью, как это делает C.
Ортогональность функций: вы можете свободно комбинировать функции, и они будут работать вместе, как и ожидалось. Многие языки терпят неудачу, позволяя некоторым конструкциям появляться только в определенных контекстах.
Возьмем, к примеру, массивы переменной длины в C и C ++: C позволяет везде использовать длины среды выполнения, в то время как самые либеральные запросы на расширение стандарта C ++ допускают их только в определенных контекстах, таких как автоматические массивы, и даже там, только в первом измерении. Это позволяет C обрабатывать истинные многомерные массивы с размерами, известными только во время выполнения, тогда как программисты на C ++ вынуждены писать
data[k + (j + i*lineLength)*lineCount]
снова и снова.Другим примером этого является указатель: указатель данных в C на самом деле является ничем иным, как просто переменной, содержащей адрес в памяти какой-либо другой переменной. Поскольку указатель сам по себе является переменной, двойной указатель является четко определенной вещью. Т.е. с учетом того, что
int
иint*
есть, понятно, чтоint**
должно быть. Сравните это со ссылками на C ++, где вы абсолютно не представляете, чтоint&&
означает значениеint
иint&
!)Это правда, что именно эта простота вызвала столько ненависти у С: простота языка дает программистам больше свободы, чем им полезно, что приводит к множеству проблем с неопределенным поведением и неправильно обработанными указателями. Особенно простота ортогональности, которая позволяет программисту определять переменную как
int (*array[m])(struct foo* (*arg)[n])
имеющую тип, который имеет тенденцию доставлять читателям головную боль, потому что действительно сложные вещи могут быть выражены в очень сжатой форме посредством либеральной комбинации нескольких простых функций . Это тот тип простоты, в котором C превосходит и который дает ему репутацию сложного языка для использования.Кроме того, простота языка вынуждает программиста писать намного больше кода, чем более многофункциональных языков, обеспечивая более плодородную почву для процветания ошибок. Тем не менее, он остается самым простым из возможных языков высокого уровня, если ваша основная задача - программировать реальный компьютер, а не виртуальную машину.
источник
Java Википедия - хотя это явно не указано в Википедии, упрощение упоминалось несколько раз и было первоначальной целью разработки, поскольку единственным серьезным языком, способным к ОО (термин использовался слабо) в те дни, был C ++, который, как мы все знаем, является мощным но есть несколько ловушек для неосторожных.
JVM была задумана как способ упростить кроссплатформенную разработку, и «Писать один раз в любом месте» стала мантрой Java на несколько лет - опять же, цель заключалась в простоте развертывания инфраструктуры.
Я считаю, что C # попадает в эту категорию упрощения языка.
источник
Хм ... на самом деле это сложный вопрос, на который нужно ответить "положительно", потому что, когда я думаю о простоте проектирования языка программирования (и о том, с чем "легче" работать), я сразу думаю о:
Есть ряд языков, которые хорошо справляются с этой задачей, но мне в голову приходит язык, который плохо работает как «язык программирования»: PHP.
[Отказ от ответственности - я написал PHP, и PHP все еще мой «переход на язык» для простых веб-проектов. Это критика любви ...]
Во-первых, PHP хорошо работает в среде, в которой он обычно работает - веб-серверах. Это легко установить, легко поддерживать и т. Д.
Где я борюсь с PHP: когда вы хотите сделать что-то «необычное» - то, что вы обычно не делаете на регулярной основе (в случае, если я думаю, что это потребляет веб-сервис SOAP - не то, что я с PHP), вы столкнулись с двумя вариантами:
1) Различные расширения с открытым исходным кодом для PHP. Объектная модель PHP достаточно свободна, когда дизайн интерфейса также не очень согласован от библиотеки к библиотеке, от разработчика к разработчику. Когда вы сталкиваетесь с набором кода, в котором кто-то использовал библиотеку, о которой вы никогда не слышали, вы тратите много времени на выяснение «какого черта это происходит», потому что язык позволяет свободно создавать API / библиотеки.
2) «Встроенные» функции - которых очень много . Я прошел через несколько кроличьих дыр либо в поиске другой библиотеки, либо в реализации некоторой функциональности, чтобы потом как-то наткнуться на
impossiblyfound_basefunction()
На мой взгляд, простота - это последовательность.
источник
Теперь подход KISS к языкам программирования - забавное понятие, по крайней мере, если вы рассматриваете языки программирования как уровень абстракции для набора команд ЦП и т. Д. Если вы не определяете «KISS» более близко. Я просто говорю здесь, что повозка - это ПОЦЕЛУЙ, примененный к автомобилю в его полном объеме.
Теперь другая интерпретация KISS может быть чем-то вроде «умно сделано без ненужных украшений и не слишком сложно». Особенно можно утверждать, что не должно быть слишком много конкретных случаев для подобных вещей и т. Д. Обычно математика достаточно хороша для того, чтобы свести вещи к своей сути, и, что удивительно, математики потратили некоторое время на размышления о программировании и компьютерах. ,
Для программирования существуют 2 довольно известные абстрактные модели:
Интересная вещь: хотя машина Тьюринга довольно проста в своей компоновке, она не является системой, с которой легко обращаться, и я не думаю, что она подходит под «умный KISS». Но лямбда-исчисление больше связано с известными нам языками программирования - и с новаторскими функциями Лиспа и Схемы лямбда-исчисления оно вошло во многие языки.
Lisp и Scheme ДЕЙСТВИТЕЛЬНО просты, по крайней мере, с точки зрения синтаксиса. Синтаксис - основная проблема языков программирования (возможно, поэтому они постоянно обновляются). В случае C ++ для человеческого мозга почти невозможно предсказать, как некоторые строки исходного текста интерпретируются компилятором.)
Лиспс уменьшает синтаксическую сложность, вводя одну общую форму для команд:
Это может быть вызов метода, такой как
а также ветвь if, цикл и т. д.
(весь код здесь псевдо-Lisp / диалект агностик)
Форма
также можно интерпретировать как список
И это основа простоты и красоты Lisps. Поскольку вложенные списки (как в
if
примере оператора) составляют деревья, и их легко понять как машине, так и человеку перед машиной.Еще одна особенность Lisps - макросы. Я не буду вдаваться в подробности, но поскольку синтаксических различий между обычными вызовами функций и синтаксисом нет («Синтаксис» (яйцо для циклов, объявление переменной и т. Д., Все, что анализатор должен обрабатывать в других случаях). языки программирования) вы можете создать свой собственный синтаксис. Макросы по сути являются манипуляциями с деревом, которое составляет вашу программу.
Я думаю, что Лисп имеет поцелуй в программировании. То, что вы можете манипулировать синтаксисом с помощью макросов, привело к тому, что Lisp развивался довольно динамично. Нужна новая языковая функция, например - скажем, ориентация объекта - просто напишите систему ООП с макросами!
В то время как C был расширен круговым движением в 2 раза с функциями ООП (C ++, Obj. C), Lisp был расширен несколько раз, в конце концов, был победитель.
Это еще одна причуда о Лиспе, он развивается (см. Clojure и Clojurescript для интересной новой мутации lisp).
Из-за его свойств KISS некоторые предпочитают Лиспс как язык обучения. Как Фогус излагает в своем проекте образовательного языка ( http://blog.fogus.me/2013/01/21/enfield-a-programming-language-designed-for-pedagogy/ )
источник