Forth
http://fforum.winglion.ru/

Учимся на примерах...
http://fforum.winglion.ru/viewtopic.php?f=24&t=2905
Страница 4 из 6

Автор:  true-grue [ Ср дек 19, 2012 09:55 ]
Заголовок сообщения:  Re: Учимся на примерах...

Я ведь выше говорил по поводу хранения счетчика по индексу -1. Просто в исходном варианте не хотелось заниматься инструментарием для создания массивов. Но если не лениться, то в результате получаем вполне лаконичное и читаемое улучшение.

Код:
: length ( array - length) -1 cells + @ ;
: length! ( length array) -1 cells + ! ;
: {array ( - here) 0 , here ;
: array} ( here "name") dup here swap - cell / over length! constant ;

{array 1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 , array} arr

: each: ( array)
   r> swap dup length 0 do 2dup 2>r @ swap execute 2r> cell+ loop 2drop ;

Автор:  WingLion [ Ср дек 19, 2012 10:24 ]
Заголовок сообщения:  Re: Учимся на примерах...

true-grue писал(а):
: {array ( - here) 0 , here ;
: array} ( here "name") dup here swap - cell / over length! constant ;

{array 1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 , array} arr

Да, левой пяткой правое ухо вполне доставабельно для акробата...кому-то даже покажется, что так "удобнее"
Цитата:
Да, Петр, Петрович! Пригодились мне интегралы! Вот, как-то утопил я ключи от мерседеса в унитазе, никак было не достать, а я взял кусок проволоки, в виде интеграла согнул и ДОСТАЛ!

Автор:  true-grue [ Ср дек 19, 2012 13:41 ]
Заголовок сообщения:  Re: Учимся на примерах...

WingLion писал(а):
Да, левой пяткой правое ухо вполне доставабельно для акробата...кому-то даже покажется, что так "удобнее"

Благодарю за критику! :)

(обращаясь ко всем) Будут ли иные мнения у уважаемой публики?

Автор:  mOleg [ Ср дек 19, 2012 19:16 ]
Заголовок сообщения:  Re: Учимся на примерах...

предлагаю несколько модифицировать задание:
1) массив чисел задается содержимым файла, числа перечислены через ',' (пробельные символы допустимы), в виде чисел в формате с плавающей точкой
2) посчитать и вывести надо следующие значения: общее количество, минимальное, максимальное, среднее и медианное среднее.
так будет чуток поближе к практике 8)
можно добавить отрисовку графика по заданным значениям с автомасштабированием

Автор:  chess [ Ср дек 19, 2012 22:39 ]
Заголовок сообщения:  Re: Учимся на примерах...

Alex писал(а):
да простят меня коллеги, покажу как можно написать его используя стековые манипуляторы.в начале подробный вариант с комментариями, а затем сжатый.

Alex, похоже не объяснить по-простому, что манипуляторы это очень просто и упрощают программирование. Народ испытывает когнитивный диссонанс, входит в ступор, испытывает реакции отторжения, попадает в плен иллюзий и тп. :D
Но все-же вот еще одна попытка:
При выписывании манипуляторов используется несколько другая модель вычислений, а именно дополнительно со стеком параметров используется линейный отрезок памяти из 10-ти ячеек(буфер).
операции 'положить адрес этих ячеек на стек' записываются как: '0 '1 '2 '3 '4 '5 '6 '7 '8 '9
операции 'положить содержание этих ячеек на стек' выписываются как: 0 1 2 3 4 5 6 7 8 9
операция перемещения содержимого N ячеек стека в ячейки буфера записывается как N\, где N от 0 до 9
операция копирования содержимого N ячеек стека в ячейки буфера записывается как N|, где N от 0 до 9
операция перемещения содержимого N ячеек стека в ячейки нового буфера записывается как N/, где N от 0 до 9

Предположим на стеке находится 5 параметров a b c d e нужно сделать (c+d)*e и удалить параметр b, таким образом на стеке должно остаться
\ 0 1 2 3
a b c d e -- a [c+d]*e , все параметры в затрагиваемом диапазоне параметров нумеруем от 0 до нужного и выписываем число затрагиваемых параметров символ сброса их в буфер, а потом выкладываем их на стек и вписываем нужные операции. Вот и все. Большинство процедур-слов форта записываются одним символом, поэтому просвет между символами естественный разделитель. Исключений при такой записи немного. Так как значение символов зафиксировано и не меняется
удержание смысла символов мало чем отличается от удержания смысла слов, которые тоже по сути символы.
Искомый манипулятор 4\12+3*, параметр а мы не затронули, а b, хоть и сбросили в буфер, но на стек не положили.

Автор:  true-grue [ Ср дек 19, 2012 23:20 ]
Заголовок сообщения:  Re: Учимся на примерах...

chess писал(а):
Alex, похоже не объяснить по-простому, что манипуляторы это очень просто и упрощают программирование. Народ испытывает когнитивный диссонанс, входит в ступор, испытывает реакции отторжения, попадает в плен иллюзий и тп. :D

Где-то в основе "манипуляторов" лежит далеко не новая и вполне здравая идея. Обобщение в единой конструкции/нотации всего множества стековых перестановок. Я даже допускаю, что на нашем форуме это самая интересная идея за последние несколько лет, после того, как форум покинуло множество изобретательных фортеров. Когнитивный диссонанс, ступор и реакцию отторжения вызывает реализация "манипуляторов". На мой взгляд, подобное выдумать можно только в сильном приступе мизантропии :)

Автор:  Hishnik [ Чт дек 20, 2012 00:52 ]
Заголовок сообщения:  Re: Учимся на примерах...

true-grue писал(а):
Когнитивный диссонанс, ступор и реакцию отторжения вызывает реализация "манипуляторов".

Именно из-за этого вся "здравость" идеи (эх... регистры в МК-51/62) оказывается не у дел.

Автор:  ArtemKAD [ Чт дек 20, 2012 02:42 ]
Заголовок сообщения:  Re: Учимся на примерах...

true-grue писал(а):
chess писал(а):
Alex, похоже не объяснить по-простому, что манипуляторы это очень просто и упрощают программирование. Народ испытывает когнитивный диссонанс, входит в ступор, испытывает реакции отторжения, попадает в плен иллюзий и тп. :D

Где-то в основе "манипуляторов" лежит далеко не новая и вполне здравая идея. Обобщение в единой конструкции/нотации всего множества стековых перестановок. Я даже допускаю, что на нашем форуме это самая интересная идея за последние несколько лет, после того, как форум покинуло множество изобретательных фортеров.


Э... SPF\lib\ext\locals.f которые стали уже общепринятыми, как по мне нагляднее, проще и логичней. Для тех кого коробит манипуляция со стеком самое оно.
Правда там "всего лишь" наглядная работа со стековым кадром и создание локальных переменных во временном словаре на время компиляции слова.

Автор:  VoidVolker [ Чт дек 20, 2012 08:23 ]
Заголовок сообщения:  Re: Учимся на примерах...

chess писал(а):
операции 'положить адрес этих ячеек на стек' записываются как: '0 '1 '2 '3 '4 '5 '6 '7 '8 '9операции 'положить содержание этих ячеек на стек' выписываются как: 0 1 2 3 4 5 6 7 8 9

А если числа заменить на буквы, то я думаю будет удобнее. Почти как с локалсами. Хочу сказать, есть такая идея: а что если вот эту самую идею стековых перестановок скрестить с локалсами? Т.е. делаем такой же синтаксис как и у локалсов, но вместо хранения их на стеке возвратов делаем стековые перестановки, причем с учетом всех остальных слов в определении. Тогда, наверно, надо иметь что-то вроде списка стековых нотация для каждого слова. Вот сейчас все функции, применяемые в стексах довольно ограничены, т.е. вот так вот запросто вставить свое слово в него не можем, да и синтаксис фиксированный.

Автор:  chess [ Чт дек 20, 2012 09:40 ]
Заголовок сообщения:  Re: Учимся на примерах...

true-grue писал(а):
Обобщение в единой конструкции/нотации всего множества стековых перестановок.

Целью было исключить инструментальную составляющую оперативного контекста(часть текущего состояния программы, которая удерживается в кратковременной памяти, а не в долговременной), появление которой было обусловлено использованием процедур стековых перестановок параметров. С помощью локальных переменных это делалось и раньше, но во первых, именовать локальные переменные слишком избыточное действие(при стековых перестановках параметры вообще безымянны),
а во вторых неплохо-бы иметь обзор, не мыслимый, а буквальный обзор состояния стека параметров(тот самый эффект видео-буфера). Поэтому и появились манипуляторы со встроенными процедурами, в той форме, в которой они есть.

К примеру написать ваш each: для массива заданного как ADDR LEN( длина в байтах), занимает несколько секунд:
Код:
: each: ( adrr len ) R> 3/01+0DI@2X`4N ;

Автор:  chess [ Чт дек 20, 2012 09:55 ]
Заголовок сообщения:  Re: Учимся на примерах...

VoidVolker писал(а):
А если числа заменить на буквы, то я думаю будет удобнее. Почти как с локалсами. Хочу сказать, есть такая идея: а что если вот эту самую идею стековых перестановок скрестить с локалсами? Т.е. делаем такой же синтаксис как и у локалсов, но вместо хранения их на стеке возвратов делаем стековые перестановки, причем с учетом всех остальных слов в определении. Тогда, наверно, надо иметь что-то вроде списка стековых нотация для каждого слова. Вот сейчас все функции, применяемые в стексах довольно ограничены, т.е. вот так вот запросто вставить свое слово в него не можем, да и синтаксис фиксированный.

Все уже так и сделано, а буквы нужнее для ввода символов слов.
Новые слова можно вводить в манипуляторы в скобках [new-word].
См. https://github.com/chess2007/-chess, там почти все написано.

Автор:  Alex [ Чт дек 20, 2012 12:32 ]
Заголовок сообщения:  Re: Учимся на примерах...

для SPF4 each: можно определить и так ( это вариант когда счетчик CELL- от указателя на массив)
Код:
: each: ( array) DUP CELL- @ 0 DO DUP >R @ RP@ 16 + @ EXECUTE R> CELL+ LOOP DROP RDROP ;

а для случая когда указатель указывает на счетчик даже чуть короче
Код:
: each: ( array) DUP @ 0 DO CELL+ DUP >R @ RP@ 16 + @ EXECUTE R> LOOP DROP RDROP ;

здесь RP@ 16 + @ магия с помощью которой из под цикла вытаскиваем адрес продолжения исполнения. RP@ адрес вершины стека возвратов растет в сторону уменьшения адресов,
значит для доступа нужно прибавлять смещение, на вершине лежит временное значание
адреса массива ( RP@ + 0 ), далее три ячеки задействованные под цикл ( RP@ + 4, RP@ + 8, RP@ + 12)
и нужный нам адрес продолжения в ячейке ( RP@ + 16) Возможно в других фортах, где для
циклов используется свой стек, смещение может быть равно 4 (CELL)

в SPF4 магическая фраза RP@ 16 + @ может быть записана и так 16 RP+@

Автор:  ArtemKAD [ Чт дек 20, 2012 12:37 ]
Заголовок сообщения:  Re: Учимся на примерах...

chess писал(а):
С помощью локальных переменных это делалось и раньше, но во первых, именовать локальные переменные слишком избыточное действие

Это "слишком избыточное" все равно обычно делается в стековой нотации слова. Так почему замена ничего не делающего комментария на объявление локальных переменных слова избыточно? В чем избыточность?

chess писал(а):
(при стековых перестановках параметры вообще безымянны),

Они не безумянны - они заранее именованы. Причем жестко, непонятно и не расширяемо. Т.е. таблицу правил именования в спец.строке приходится запоминать. А память имеет хреновое свойство - подводить в самый интересный момент. Т.е. вместо нескольких простых правил в локалсах вводится несколько десятков правил для каждого символа в перестановках. Причем правил навязывающих достаточно жесткую работу с уже определенными словами и контекстом.
Т.е. вот эту таблицу:
Код:
таблица односимвольных операторов манипуляторов         двойная разрядность       
                                                                             
A  ACCEPT          a  ABS              ~  INVERT        `+  D+                 
B  BEGIN           b  C@               !  !             `-  D-                 
C  CASE            c  EMIT             @  @             `n  DNEGATE             
D  DO              d  DUP              #  >NUMBER       `a  DABS                           
E  ENDCASE         e  ELSE             $  SFIND         `|  DOR                                         
F  FILL            f  NextWord         %  MOD           `^  DXOR               
G  ?DO             g                   ^  XOR           `&  DAND               
H  WITHIN          h                   &  AND           `~  DINVERT             
I  I               i  IF               *  *             `l  DLSHIFT             
J  J               j  BRANCH,          (  OF            `r  DRSHIFT             
K  EKEY            k  KEY              )  ENDOF         `>  D>                           
L  LOOP            l  LSHIFT           -  -             `<  D<                 
M  MAX             m  MIN              _                `=  D=                 
N  +LOOP           n  NEGATE           +  +             `Z  D0=                 
O  AGAIN           o  THROW            =  =             `z  D0= INVERT         
P  DEPTH           p  CHOOSE           {  LAMBDA{       `d  2DUP                           
Q  LEAVE           q  COMPARE          }  }LAMBDA       `x  2DROP               
R  REPEAT          r  RSHIFT           :  /MOD          `@  2@                           
S  SPACES          s  SEARCH           ;  EXIT          `!  2!                 
T  TYPE            t  THEN             \  CR            `.  D.                               
U  UNTIL           u                   |  OR            `S  D>S                           
V  MOVE            v  EVALUATE         /  /             `D  S>D                             
W  WHILE           w  C!               <  <                                     
X  EXECUTE         x  DROP             >  >                                     
Y  TRUE            y  FALSE            .  .                                     
Z  0=              z  0<>                                                     
                                                                               
                                                                               
двухсимвольные операторы                                                                                             
                                                                                                             
'ha  ALLOCATE                  '._  .BL                                                                             
'hf  FREE                      '.0  .0
'hr  RESIZE                    '.h  HEX . DECIMAL
                               '.b  .BIN
'cs  SET-CURSOR               
'c?  GET-CURSOR               

'f;  CLOSE-FILE                'Ks  EKEY>SCAN
'f:  CREATE-FILE               'Kc  EKEY>CHAR
'F:  CREATE-FILE-SHARED        'k?  KEY?
'Fo  OPEN-FILE-SHARED          'K?  EKEY?
'fx  DELETE-FILE               
'fp  FILE-POSITION             'b?  NB?
'fs  FILE-SIZE                 'bs  NB1
'fo  OPEN-FILE                 'bc  NB0
'fr  READ-FILE                 'b~  NB~
'fP  REPOSITION-FILE           'bl  NLB
'lr  READ-LINE                 'bh  NHB
'fw  WRITE-FILE                'qb  QB1
'fS  RESIZE-FILE         
'lw  WRITE-LINE         
'ff  FLUSH-FILE         
'fe  FILE-EXIST         
'fE  FILE-EXISTS         

'ts  START               
't|  SUSPEND             
'tr  RESUME             
't;  STOP               
'tp  PAUSE               
'tx  TERMINATE           
'ti  THREAD-ID           


трехсимвольные операторы

"hex HEX
"dec DECIMAL
"bin BINARY

"b=? NB=?
"blc LB0
"bhc HB0
"bsm SWBM

"rnd RANDOMIZE

префиксы

` перед 0...9 - число, перед a...z, A...Z, ~...? - односимвольные операторы двойной разрядности                                                                                 
' перед 0...9 - адрес ячеек 0...9, перед a...z, A...Z, ~...? - признак двухсимвольных операторов
" перед a...z, A...Z, ~...? - признак трехсимвольных операторов

скобки включения форт-слов в манипулятор

[ отмечает начало имени слова
] отмечает конец  имени слова

суффиксы

_ ставится в местах разрыва манипулятора, например, разрываем манипулятор 3\12+22*02- на три части
3\12+_ 22*_ 02-
или так
3\12+_
22*_
02-

надо прикладывать к каждому использованию манипуляторов иначе практически никто не поймет, а чего там в этой строке имелось ввиду.

Автор:  Hishnik [ Чт дек 20, 2012 22:41 ]
Заголовок сообщения:  Re: Учимся на примерах...

chess писал(а):
Целью было исключить инструментальную составляющую оперативного контекста

А для совсем бестолковых можно? А то "прочитал все буквы, но не смог назвать слово"...

Автор:  Alexander [ Пт дек 21, 2012 17:04 ]
Заголовок сообщения:  Re: Учимся на примерах...

хД ))) куда вас увело к стековым манипуляторам. к инструкциям PICK с последющим примененимем операции и пройденной оптимизации - вот так эти стековые манипуляторы смотрятся.

Идея Олега понятна - показать легкую расширяемость языка .
повтороное использование слов (про это true-grue отмечал).

Можно было вообще учить людей итерационному приближению к поставленной цели.
Всякий раз сравнивая корректность задачи и адекватность применямых конструкций -что есть всегда правильно.
Но уже отмечали, что без знания чего хотим получить в конце - с места не сдвинутся.

Страница 4 из 6 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/