Подобный вопрос был закрыт на SO.
Иногда, когда мы программируем, мы обнаруживаем, что какая-то конкретная структура управления была бы очень полезна для нас, но не доступна напрямую в нашем языке программирования.
Какие альтернативные структуры управления, по вашему мнению, являются полезным способом организации вычислений?
Цель здесь состоит в том, чтобы получить новые способы мышления о структурировании кода, чтобы улучшить чанкинг и рассуждение.
Вы можете создать желаемый синтаксис / семантику, недоступную сейчас, или привести менее известную структуру управления на существующем языке программирования.
Ответы должны дать идеи для нового языка программирования или улучшения реального языка.
Думайте об этом как о мозговом штурме, поэтому опубликуйте что-то, что вы считаете сумасшедшей идеей, но это может быть жизнеспособным в некотором сценарии.
Это про императивное программирование.
Ответы:
ОК, это забавный вопрос.
Я также хотел бы иметь общее
else
для циклов while и for, когда условие не выполняется в первом тесте:Это позволяет избежать неловкого пересчета условия или сохранения его в переменной.
источник
while ... else
конструкции так, как Macneil описывает ее в PHP. Я думаю, что это отличная идея, потому что «вот результаты / результатов не было» - довольно распространенная идиома в веб-приложениях.Почему бы не смешать несколько ответов в один?
Расширяемый обобщенный синтаксис конструкции управления потоком на императивном языке был бы весьма полезным и интересным. Пока это не появится, думаю, я просто буду использовать Лисп или что-то в этом роде.
источник
seventh { ... }
тоже нужно .Управляющие структуры как функции.
Я хочу
for
,if
,else
,while
и т.д. , чтобы быть функции, а не специальные структуры.Я хочу
return
,try/except
иgoto
быть производными продолжения.Это, конечно, связано не столько с конкретной структурой управления, сколько с тем, как вы видите структуры управления в целом, с мета структур управления.
источник
for
,if
,else
иwhile
как функция заставляет меня сделать вывод , что параметры этих функций должны быть выполнены лениво, чтобы вести себя так же , как оригинальные конструкты. Иметь возможность выполнять ленивое выполнение было бы неплохо.return
, исключения и т. Д. Но теперь у опытного программиста есть мощный дополнительный инструмент в его наборе инструментов, если возникнет такая необходимость. Кроме того, языки ИМХО не должны быть «заглушены». Языки должны обладать способностью поддерживать растущий опыт и знания CS.Связанная статья определенно делает это правильно о петлях N + 1/2 Дональда Кнута . Выражается в C / C ++ / Java:
Это полезно для чтения строк или символов из файла, проверки достижения EOF и последующей обработки. Я так привык видеть этот шаблон,
for(;;)..if(..)break;
что он идиоматичен для меня. (До того, как я прочитал статью Кнута, перепечатанную в книге « Грамотное программирование» , эта статья была «wtf?».)Кнут предложил ключевые слова
loop/while/repeat
:Где
S
иT
являются местозаполнителями для ряда нулевых или более операторов, иC
это логическое условие. Если бы не былоS
оператора, то это был бы цикл while, а если бы не былоT
оператора, то это был бы цикл do.Эту конструкцию можно обобщить, допуская ноль или более
while C
предложений, что делает ее идеальной для выражения бесконечных циклов, а затем некоторых более редких условий, которые потребуют двух проверок.В той же статье Кнут предложил механизм сигнализации, который будет локальной версией исключения / перехвата (в качестве альтернативы использованию goto).
Для меня? Я хотел бы, чтобы Java поддерживала оптимизацию хвостового вызова, чтобы я мог выражать любую общую структуру управления по мере необходимости.
Обновление: я забыл упомянуть, что многие программисты на C / C ++ / Java обходят это, используя встроенное присваивание в условии
while
:Используя термины из конструкции Кнута, это допустимо, когда
S
иC
может быть объединено в одно выражение. Некоторые люди не хотят видеть внедренный назначение выше, в то время как другие ненавидят , чтобы увидетьbreak
вfor (;;)
выше. Но когдаS
иC
не могут быть объединены, например, когдаS
имеет несколько операторов,for (;;)
единственная альтернатива без повторения кода. Другой вариант - просто продублироватьS
код:loop/while/repeat
Альтернатива Кнута кажется намного лучше.источник
repeat-until
цикл Паскаля .do while ... loop until
и предварительное условие, и постусловие являются необязательными, и я (смутно) помню, что оба использовались в одном цикле. Для вашего среднего состояния есть Адаexit when ...;
. Ключевым преимуществомif ... break;
является то, что вы можете писатьexit loopname when ...;
для выхода из нескольких (но не обязательно всех) вложенных циклов одновременно. Возможно, чуть более заметен, чем этот разрыв, тоже.В языке BCPL есть
valueof
выражение, которое можно использовать для преобразования последовательности операторов в одно выражение:Где
some series of statements
может быть что угодно, и всеvalueof
оцениваетv
.Это может быть удобно в Java, когда вам нужно вычислить аргумент для вызова a
this()
илиsuper()
(который требует, чтобы ничего не происходило до этого). Конечно, вы можете просто написать отдельный метод, но это может быть неприятно, если вам нужно передать много локальных значений для контекста.Если вы можете использовать
final
переменные, которые вам нужны, вы уже можете делатьvalueof
в Java, используя анонимные внутренние классы:источник
({ statement1; statement2; ...; result-expr; })
. Я видел подобное и в других местах, но я не помню где. Вероятно, все скопировано из BCPL, хотя.делает то же самое, что и:
делает то же самое, что и:
источник
unless
.С другой стороны, я хотел бы видеть лучшую поддержку итераторов в языках программирования. В частности, когда вы хотите собрать две коллекции попарно :
Некоторые динамические языки могут уже иметь это или легко поддерживать через библиотеки и макросы, но я думаю, что это в духе вашего вопроса.
Если два набора не имеют одинаковый размер, это может вызвать исключение, или вы могли бы иметь
else
после цикла, чтобы сигнализировать о разнице в размерах.Естественно, вы могли бы обобщить это для перехода в три или более списков.
Обновление: также полезно было бы делать декартово произведение между итерациями:
который был бы не более чем вложенными циклами:
Я немного обеспокоен тем, что между двумя обозначениями, которые я привел здесь, есть разница O (n) и O (n ^ 2) в количестве пар, с изменением только одного символа.
источник
for a, b, c in itertools.product(iter1, iter2, iter3):
дает вам декартово произведение лениво оценивается. Что это? Вы тоже хотите перестановки и комбинации данного итератора?itertools.permutations
,itertools.combinations
.Существует так называемая «петля Дейкстры» (также называемая «охраняемая петля Дейкстры»). Это было определено в «Охраняемом командном языке» (GCL) . Вы можете найти некоторую информацию о его синтаксисе и семантике в вышеупомянутой статье в Википедии в разделе 6 Повторение: сделайте .
В настоящее время я на самом деле знаю один язык программирования, который напрямую поддерживает эту структуру управления. Это Оберон-07 (PDF, 70 КБ). И он поддерживает «петлю Дейкстры» в форме оператора while. Взгляните на раздел 9.6. Хотя заявления в приведенном выше PDF.
PS Это копия моего SO ответа .
источник
Выражения в стиле иконок со встроенным возвратом.
Python получает много преимуществ генератора иконок - и делает их лучше в целом, IMO. И в принципе обратный путь был просто своего рода исключением, но это была простота выражений, грубый эквивалент ...
обрабатывать неудачные случаи, такие как деление на ноль.
Куда Icon сходила с ума - никаких операторов сравнения с логическим возвратом. Сравнения всегда либо удавались, либо вызывали обратное отслеживание, и была еще одна семантическая проблема, которую я сейчас отчаянно пытаюсь вспомнить ... ну, скажем так, это скорее подавлено, чем забыто.
Я всегда думал, что у них должно быть
if
выражение без какой-либо другой части - что-тоif (condition, success-value)
вроде этого, возвращаться назад, если условие возвращает false - и отбрасывать странные сравнения.РЕДАКТИРОВАТЬ Я помню - очевидно, действительно Сравнение с двумя аргументами либо успешное, либо неудачное - оно не вычисляет новое значение для возврата. Поэтому , когда это удается, что делает его вернуть? Ответ - один из аргументов. Но если вы напишите
a > b
, какой логический аргумент для возврата -a
илиb
? А что еслиb < a
вместо этого написать ? Я думаю, что он всегда возвращал правильный аргумент, который имеет столько же смысла, как и все остальное, но обычно он мне показался неправильным аргументом.источник
Это просто общая идея и синтаксис:
ТАКЖЕ условие всегда оценивается. ELSE работает как обычно.
Это работает для случая тоже. Вероятно, это хороший способ устранить оператор прерывания:
можно прочитать как:
Я не знаю, полезно ли это или просто читать, но это пример.
источник
Продолжение Passing Style приходит на ум. Тогда, конечно, вы хотели бы также оптимизировать Tail Call .
источник
goto return ...;
оператора, делающего намерение явного вызова хвоста, поэтому, если компилятор не может сделать это итеративным, это ошибка.Бесшовное ветвление потока, он имеет синтаксис как функция, но выполняется в отдельном потоке и не может получить доступ к данным, которые первоначально не были переданы ему.
Когда ветка вызывается, она немедленно возвращает дескриптор.
Дескриптор может использоваться, чтобы проверить, выполнена ли задача.
Если результат запрашивается до завершения выполнения, основной поток просто ждет.
Это не будет охватывать более продвинутые сценарии многопоточности, а скорее обеспечит легко доступный способ начать использовать несколько ядер.
источник
handle.finished()
испытание, ноspawn
иsync
все , что нужно для 90% параллельных задач программирования.Блоки FIRST и THEN запускаются, если любое из 3 условий оценивается как true. Первый блок выполняется до условного блока, а затем - после выполнения условного блока.
Условная или окончательная запись ELSE после операторов FIRST и THEN не зависит от этих блоков.
Это может читаться как:
Эти функции просто форма для чтения. Они не будут создавать возможности. Это больше похоже на госуб / возврат из Basic.
Полезность и читаемость как предмет обсуждения.
источник
Иногда я пишу цикл, который должен сделать что-то другое во время первой итерации. Например, отображение тегов <th> вместо тегов <td>.
Я справляюсь с этой ситуацией с помощью логического флага. Что-то вроде этого:
Кажется глупым проверять значение
first
на каждой итерации, когда она будет ложной в большинстве случаев.Я хотел бы иметь возможность зацикливания, чтобы указать другое тело цикла на первой итерации. Там не будет необходимости в отдельной переменной. Скомпилированный код тоже не понадобится, потому что сгенерированный код будет иметь два тела, одно для первой итерации и одно для остальных.
источник
print(out, first "<th>" then "<td>")
if (!first) gimme-a-comma ();
но это одно и то же. Однако у меня есть возражение - если вы оберните его должным образом, вы получите такие вещи, как метод объединения строк Python - как бы часто вам не требовался базовый шаблон, базовый цикл не нужно так часто переписывать.if (!first)
, но микрооптимизаторы могут выдвигать возражения против предсказания ветвлений.if (!first)
и позволить оптимизирующему компилятору решить, достаточно ли мало тело цикла, чтобы развернуть и избавиться от негоfirst
- это чистый выигрыш.[скопировано из моего собственного ответа на stackoverflow]
ignoring
- игнорировать исключения, возникающие в определенном блоке кода.С игнорирующей управляющей конструкцией вы можете написать ее более кратко и более наглядно, как:
[Scala предоставляет это (и многие другие конструкции управления обработкой исключений) в своей стандартной библиотеке в пакете util.control. ]
источник
try..catch
блок - это одно; это заставляет вас признать ошибку и сознательно игнорировать ее; в то время как бросание кусков кода в глобальное игнорирование может привести к проблемам при создании этих исключений, а также к плохим привычкам программирования.try
блок, за исключением того, что он перечисляет исключения, которые он перехватывает и игнорирует сразу, а не позже. Это может даже стать преимуществом читабельности - например, дать читателю понять, что отсутствующий файл не является ошибкой даже до того, как он прочитает открытый вызов.Вместо того:
Сделайте это на Python, а теперь и на C #:
Scala имеет много новых функций.
Наконец, языки, такие как Clojure, могут быть расширены для обеспечения дополнительной функциональности.
источник
У меня есть две идеи.
Часто я обнаруживаю, что повторяюсь в
catch
блоках. Этому можно помочь с помощью извлечения методов, но это может вызвать ненужный беспорядок, если методы очень короткие или иным образом не заслуживают метода. Итак, было бы неплохо вложитьcatch
блоки:В веб-программировании я часто обнаруживаю, что часто делаю что-то подобное (это не реальный пример, поэтому не анализируйте вымышленные случаи):
В Javascript (ну, ECMAScript и, возможно, других, с которыми я не знаком), поскольку любое значение может быть оценено как условие,
||
может помочь.Мне действительно нравится, как это выглядит, и я хотел бы, чтобы больше языков, особенно некоторые на стороне сервера, имели поддержку для этого. (PHP может вычислить что-либо как условие, но преобразует все условное выражение в логическое значение вместо сохранения значения. Я не знаю насчет Python или Ruby.) Это может стать громоздким после трех случаев или около того, но если у вас есть больше чем в трех случаях, вы также можете иметь плохой дизайн программного обеспечения.
источник
x if c else y
синтаксис условных выражений , главная причина этого состояла в том, что многие выражения использовали эту семантику для||
и&&
были слегка ошибочными. IIRC распространенным случаем было значение (например, ноль), которое было допустимо для приложения, которое обрабатывается какfalse
, и, таким образом, отбрасывалось, так что вместо него использовался неправильный запасной вариант. Однако - см. Мой ответ WRT Язык программирования Icon, который может иметь такие выражения, какget1() else get2() else default
.Обобщенный коммутатор сказал выше:
В Хаскеле:
источник
В C # я хотел бы использовать простые
switch () { ... }
, но расширяемые с такими выражениями:И так далее. То же самое с числами или другими типами (что поддерживает
IComparable
,IConvertible
...)Это может сделать мой код более лаконичным и читабельным.
источник
Это интересный вопрос, как сказал @Macneil.
Моя любимая необычная структура управления, которую я (смиренный кашель) обнаружил, это дифференциальное исполнение .
Это имеет определенные применения. Для меня подавляющее использование в программировании пользовательских интерфейсов, что является примером более общей проблемы поддержания избыточных данных в соответствии. С одной стороны, есть данные приложения, а с другой - элементы управления пользовательским интерфейсом, которые необходимо согласовать. Это звучит как «связывание», но на самом деле это намного больше.
Обычно я реализую это с помощью макросов на C или C ++. В C # я должен делать это с помощью расширений рук. Это боль, но это работает.
Однажды я реализовал это в терминах макросов Lisp, и тогда это было очень чисто. Это не требует осторожности со стороны программиста. Я мог бы сделать то же самое на любом другом структурированном языке, если бы попытался написать полный анализатор и затем сгенерировать все нужные вещи. Это большой проект, и я этого не делал.
источник
«Традиционные» структуры управления, такие
for
как управление рабочим человеком, подчинение его коррупционным идеологиям правящей капиталистической элиты. Вот почему яph0r
вместо этого использую альтернативные структуры управления . Это какfor
, но более радикально: вы не поймаетеph0r
носить костюм и галстук, извергая некоторые корпоративные BS.ph0r
Держи это по-настоящему, чувак.Бороться с властью!
источник
Самый
for
простой циклисточник