Forth http://fforum.winglion.ru/ |
|
FORTH-рефакторинг http://fforum.winglion.ru/viewtopic.php?f=2&t=3013 |
Страница 1 из 2 |
Автор: | gudleifr [ Чт июл 17, 2014 13:01 ] | ||
Заголовок сообщения: | FORTH-рефакторинг | ||
Код: VARIABLE RESULT VARIABLE TAIL : INCREMENT ( A --) DUP @ 1+ SWAP ! ; : DECREMENT ( A --) DUP @ 1- SWAP ! ; : NORM ( N, K -- N, K | N, N-K) 2DUP 2* - DUP 0< IF + ELSE DROP THEN ; : REDUCTION ( N, K -- N-1, K, N-1, K-1 | ) NORM ?DUP IF TAIL INCREMENT SWAP 1- SWAP 2DUP 1- ELSE RESULT INCREMENT TAIL DECREMENT DROP THEN ; : COMPUTE ( N, K -- CNK) 0 RESULT ! 1 TAIL ! BEGIN REDUCTION TAIL @ 0= UNTIL RESULT @ ; Имеется очевидный кусок (надеюсь все понимают, что он делает), реализованный в лоб (разве что, без факториалов). Налицо избыточные сравнения и перетасовки стека. Предложения по причесыванию? P.S. Это задача именно на "классический FORTH", а не на рассуждения по его "развитию".
|
Автор: | Hishnik [ Чт июл 17, 2014 13:25 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
А что, по работе надо, или так, в рамках общего просвещения нас, убогих? |
Автор: | gudleifr [ Чт июл 17, 2014 13:30 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Хищник писал(а): А что, по работе надо..? Вчера было надо. Написал в статье, что случай маловероятен, а насколько - пришлось срочно считать.Однако, вопрос серьезен. Я вижу здесь только два направления рефакторинга: активное переписывание в кодах и возможность "на лету" отказываться от стека для вычислений и создавать подходящие структуры. "Классического" решения я не знаю. Разве что, переменные в стек возвратов перебросить... |
Автор: | gudleifr [ Пн авг 04, 2014 23:10 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Ладно, раз никто не предложил ничего путного, делаем очевидное: Код: VARIABLE RESULT : CN0 ( N, 0 -- -1) 2DROP 1 RESULT +! -1 ; : CN1 ( N, 1 -- -1) DROP RESULT +! -1 ; : CNK ( N, K -- N-1, K, N-1, K-1, 1) SWAP 1- SWAP 2DUP 1- 1 ; : NORM ( N, K -- N, K | N, N-K) 2DUP 2* - DUP 0< IF + ELSE DROP THEN ; : REDUCTION ( N, K -- N-1, K, N-1, K-1, 1 | -1) NORM DUP IF DUP 1- IF CNK ELSE CN1 THEN ELSE CN0 THEN ; : COMPUTE ( N, K -- CNK) 0 RESULT ! 1 BEGIN >R REDUCTION R> + ?DUP 0= UNTIL RESULT @ ; Очевидно? Очевидно! Но, как бы, непонятно, как от первого варианта перейти ко второму, не зная "смысла задачи"? И, конечно, чем дальше, тем больше скрупулезных проверок типа "а точно ли мы не порушили стек в этой ветке?" Кто знает более симпатичные варианты причесывания? |
Автор: | gudleifr [ Пн авг 11, 2014 21:33 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Тут коллега KPG облыжно обвинил меня в неуважении к национальному достоянию - материалам RusFIG. Воспользуюсь наводкой и попробую поискать там что-то то теме (недаром же, наверное, коллега true-gue как-то заметил, что я пишу старомодно). Найденные "выводы" принадлежат если я не ошибаюсь к мейнстриму: один из непоследних людей написал библиотеку, а другой на ее примере показал, как надо чужие программы читать. Раз я рассуждаю здесь о писании кода, то ожидания читателей должны бы мне помочь. Итак: Цитата: * Для подхода к изучению чужого кода нужно во-первых иметь хотя бы примерное знакомство с предметной областью, теорией (совсем необязательно досконально знать, достаточно хотя бы "плавать" в терминах, а непосредственные детали реализации можно будет уяснить из самого кода). Если не отходить далеко от нашего примера — к началу конкретного этого разбора я знал в чём состоит задача "сборки мусора", знал что она обозначается как gc, имел смутное представление о том "как оно работает". * Правило "читай с конца" применённое в самом начале разбора обосновывается технологическими особенностями Форта. Так как forward-ссылки в форте из-за однопроходности компилятора не используются, то определения (процедуры) идут в тексте по мере нарастания сложности, из-за чего "главные", наиболее мощные слова оказываются в конце текста. Отсюда и идёт правило что разбирать программу на форте надо с конца и разматывать клубок нужно, начиная с "торчащей нитки" — главного слова или одного из них. * Последовательность разбора каждой процедуры примерно такая: имя, комментарии, код. Если смысл слова становится понятен на более раннем этапе, то остальные делать соответственно незачем. * Авторы всегда стараются давать говорящие названия своим процедурам (по крайней мере — говорящие им), ваша задача — постараться понять что имелось в виду. Есть стихийно сложившийся "пиратский кодекс" по построению названий форта, который был обзорно описан в "Этимологии", он может помочь. Также можно посмотреть советы по именованию от ~pinka. Но главное подспорье — это здравый смысл (как впрочем и всегда). * Проверяйте ваши "догадки", осознанные предположения о структуре/работе программы эмпирически — то есть непосредственно запуская програму и прогоняя тестовые куски. И что? Где здесь FORTH? Есть ли здесь хоть что-то, чего не знают "не-FORTH-программисты"? Нет. Это, конечно, подтверждает мои догадки о стремлении Rus-FIG привести FORTH к нормам "обычных языков", но, все равно, обидно. Говорим о самодокументированности, о лексиконах, о интерпретации на всех этапах... А на деле - полная беспомощность... По крайней мере, на поставленные в теме вопросы ответа я не получил. Может, кто-то, сможет копнуть материалы Rus-FIG более удачно? P.S. Прошу мне простить некоторую категоричность. Она объясняется тем, что мне достаточно часто приходилось читать чужой код. И смею, вас заверить, там все по-другому. См., например, игрушечный пример того, с чем приходится иметь дело: http://www.gudleifr.h1.ru/4i.html, с середины. |
Автор: | Hishnik [ Вт авг 12, 2014 00:31 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
gudleifr писал(а): Это, конечно, подтверждает мои догадки о стремлении Rus-FIG привести FORTH к нормам "обычных языков", но, все равно, обидно. Говорим о самодокументированности, о лексиконах, о интерпретации на всех этапах... А на деле - полная беспомощность... Да, это одна из проблем. Быть лидером в какой-то области не так уж просто. Всем хочется иметь какой-то якорь. Вот и берется за основу Си или даже Бейсик. |
Автор: | gudleifr [ Чт окт 23, 2014 19:30 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Еще одна задачка на рефакторинг: http://www.gudleifr.h1.ru/c84.html. Вычлененные там операторы - СЛУЧАЙ, ПЕРЕХОД, ВЫДАЧА, КОНЕЦ, ХОД-ИГРОКА, ХОД-БАРТА - в нормальных языках реализуются, разве что, макросами (или дурацкими объектами). А на FORTH? Попутно хорошо бы: 1. Добавить симметрию игрок-компьютер; или, наоборот, полностью отказаться от нее в пользу улучшения играбельности (книжности). 2. Структурировать программу таким образом, что бы упомянутые ошибки стали более явными, и добавление новых фич стало бы более простым. 3. Навесить средства сбора статистики/выбора стратегии. |
Автор: | gudleifr [ Пн фев 16, 2015 12:26 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Продолжение оттуда же: Цитата: В PASCAL-играх "стратегические" части - это набор вложенных циклов (вульгарно олицетворяющих кибернетическое понятие "сверхустойчивости"). Когда "бой" заканчивается, его результаты принимаются и проверяется их невыход за границы разумного. Превышение "пределов" вызывает прекращение текущего цила повторения "боев", и проверку более слабых условий, если и они нарушаются, то прерывается следующий цикл... По мере погружения в циклы, условия должны становиться все строже и строже, чтобы "бои" проводились в строго заданных условиях, а каждый цикл должен добавлять к этим условиям все новые, исправляя ошибки, возникающие при работе его внутренних частей. Например, внешний цикл Mario.bas перебирает игроков, а вложенный в него - уровни игры. Если уровень проходится игроком благополучно, игрок переходит к следующему, а если нет - цикл прервывается и очередь переходит к другому игроку. Если бы PASCAL-программист имел в голове "схему вложенности условий", непротиворечивую и достаточную, все было бы очень красиво - программа "думала бы сама собой", разумно реагируя на все неприятности... Однако, всегда бывает наоборот: общий набор условий берется "как у всех", а затем, при необходимости что-то добавить, программист выбирает "примерно подходящий" цикл и обвешивает новый блок кучей новых условий/флагов (и никто не гарантирует, что они не будут конфликтовать с другим). Вплоть до добавления новых циклов, противоречащих изначальному плану. Если считать, что самый нижний уровень все-таки связан с ЭВМ (ведь, должна же программа делать что-то полезное), то вся остальная программа - многоступенчатый перевод c "языка PASCAL" на "язык машины". Отсюда - и дикий размер кода (даже, с учетом излишней универсальности на всех уровнях и хранения данных в виде PASCAL-процедур). От "нормального гомеостата" эта конструкция радикально отличается тем, что как бы не "переключались лампочки" на верхних уровнях, работает-то все равно только один самый внутренний цикл, только в разных условиях. Т.е. очевидно, существует возможность установки нужных условий/флагов, не поднимаясь "до самого верха", а тут же "по месту" (как АВАРИЯ в "Лунолете"). В FORTH все еще хуже (или наоборот?), ведь у него и так есть внешний цикл от которого не уйти - Цикл Управления. И, даже, применяется схожая матрешка циклов вокруг WORD. Так, может, в FORTH-программировании можно перенести часть этих "гомеостатов" на сам FORTH? Или придумать другой способ написания диалоговых программ? P.S. Кстати, невозможность организовать "матрешку циклов" в визуальных программах привела к тому, что "визуальные программисты" вообще ничего не могут написать... |
Автор: | gudleifr [ Пн фев 16, 2015 15:04 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
P.P.S. На неразрешимость проблемы "правильности зацикливания" как бы намекает старая C-фича "курица или яйцо". Допустим наша программа: Код: main() { A; for (i=...) { B; } } Со временем наборы операторов A и B разрастаются до размеров, требующих их выделения в отдельные подпрограммы: Как правильно? Код: b(i) { B; } main() { A; for (i=...) { B(i); } } или Код: b(i) { for (i=...) { B } } main() { A; b; } Понятно, что если цикл один, то делаем как удобнее/логичнее/нагляднее. Да и какая разница?.. А если в матрешке десяток циклов и способы выделения процедур внутри или снаружи цикла чередуются? Черт ногу сломит... |
Автор: | Hishnik [ Вт фев 17, 2015 03:42 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
1) Код: 10 0 DO I ОЧИСТИТЬ-ЯЧЕЙКУ LOOP 2) Код: ОЧИСТИТЬ-МАССИВ Во втором случае мне неинтересны детали очистки. Может быть, там и еще что-то делается, кроме записи в ячейки, неважно. И так, в принципе, на каждом уровне - если мне на этом уровне важно видеть, что действие выполняется в цикле, цикл будет виден. Если нет - спрячу внутрь. |
Автор: | gudleifr [ Вт фев 17, 2015 13:27 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Hishnik писал(а): И так, в принципе, на каждом уровне - если мне на этом уровне важно видеть, что действие выполняется в цикле, цикл будет виден. Если нет - спрячу внутрь. И я об том же. Если циклов много - будет страшно. И речь не о том, как сделать "менее страшно", а как вообще туда не ходить... Большинство циклов в структурных программах - от лукавого.
|
Автор: | Hishnik [ Ср фев 25, 2015 00:43 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
gudleifr писал(а): И речь не о том, как сделать "менее страшно", а как вообще туда не ходить... Большинство циклов в структурных программах - от лукавого. Конечный автомат, по крайней мере, в некоторых случаях. |
Автор: | gudleifr [ Ср фев 25, 2015 01:07 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Hishnik писал(а): Конечный автомат, по крайней мере, в некоторых случаях. Ну, как бы, хорошо откомпилированный конечный автомат (не претендующий на гомеостатичность) превращается просто в набор IF...GOTO. Что на FORTH обычно смотрится препохабнейше и может быть оправдано только желанием разбиратьр егулярные выражения.Конечно, можно вовремя вспомнить, что сам FORTH является конечным автоматом, но решений, использующих этот факт я не встречал (хотя, сам писать пытался). P.S. Из "Лунолета" пришла идея организовать гомеостаз в виде "вычислительного управляющего воздействия" блока "обработки флагов" на "вычислительный блок (зарылись в грунт - отсчитываем время назад с тем же ускорением, кончилось топливо - выполняем расчет за сверхбольшой интервал и т.д.) |
Автор: | Hishnik [ Ср фев 25, 2015 01:28 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
gudleifr писал(а): Ну, как бы, хорошо откомпилированный конечный автомат (не претендующий на гомеостатичность) превращается просто в набор IF...GOTO. А CASE смотрится вполне изящно и сопровождаемо. Он внутри, конечно, тоже в какой-то степени IF.. GOTO, но по большому счету это относится к любой управляющей конструкции. gudleifr писал(а): зарылись в грунт - отсчитываем время назад с тем же ускорением Да ну зачем же? Из кинематики выводится время до грунта. |
Автор: | gudleifr [ Ср фев 25, 2015 02:00 ] |
Заголовок сообщения: | Re: FORTH-рефакторинг |
Hishnik писал(а): А CASE смотрится вполне изящно и сопровождаемо. Изящных не встречал. Обычно - источник ошибок и причина полной нечитаемости кода. Впрочем, я не видел, чтобы какому нибудь PASCAL-исту CASE помешал бы плодить циклы.Hishnik писал(а): Из кинематики выводится время до грунта. Его и отсчитываем. (В позднихх версиях "Лунолета", правда, этот блок не поместился в память калькулятора, и его заменили на "итерактивное самовыкапывание" (с забавными побочными эффектами)).
|
Страница 1 из 2 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |