Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Ср июн 20, 2018 22:32

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 85 ]  На страницу 1, 2, 3, 4, 5, 6  След.
Автор Сообщение
 Заголовок сообщения: Учимся на примерах...
СообщениеДобавлено: Сб дек 15, 2012 01:48 
Не в сети
Аватара пользователя

Зарегистрирован: Вт ноя 06, 2007 21:23
Сообщения: 227
Откуда: Екатеринбург
Благодарил (а): 4 раз.
Поблагодарили: 7 раз.
Нет ничего проще в освоении нового, чем учится на примерах.
Поэтому рассмотрим небольшой пример, в котором решается задача нахождения количества положительных, отрицательных и нулевых чисел в некотором массиве.
Ниже приведён код программы, за которым последует её объяснение. Программа "нашпигована" различными конструкциями языка, так необходимых для изящности её структуры.
Код:
0 VALUE ARR_SIZE

CREATE ARR  HERE
   1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 ,
HERE SWAP - CELL / TO  ARR_SIZE

CREATE Q  3 CELLS ALLOT

: SIGNUM
   DUP  0> IF DROP 1 EXIT THEN  0< ;

: HOW-MANY-NUMBERS ( WHERE SIZE - )
   0 ?DO  DUP @  SIGNUM 1+ CELLS Q + ++  CELL+ LOOP  DROP ;

: .ANSWER
   Q
   CR ." Negatives=" DUP @ . CELL+
   CR ." Zeroes="    DUP @ . CELL+
   CR ." Positives=" @ . ;

: MAIN
   Q 3 CELLS ERASE
   ARR ARR_SIZE HOW-MANY-NUMBERS
   .ANSWER ;
Программа была протестирована в SwiftForth. Поэтому при возникновении нестыковки различных версий ФОРТ от разных производителей необходимо корректировать программу под ту систему, которую применяете именно Вы.

Наша задача - найти количество положительных, отрицательных и нулевых чисел в массиве.
Массив будет одномерным, и все его элементы будут расположены в непрерывной области памяти.
В общем случае, массив может быть набором произвольных участков памяти, но для примера будем задавать массив непосредственно в самой программе.
Размер массива, который мы создадим, заранее не известен. Следовательно, под хранения значения размера массива надо зарезервировать память. Делается это с помощью строки кода:
Код:
0 VALUE ARR_SIZE
Вот так мы зарезервировали участок памяти под хранения числа элементов массива и дали ему имя ARR_SIZE для удобства обращения с ним в дальнейшем.
Что же значит "0" в начале? Существующие в языке способы именования участков памяти делятся на две категории по действию при обращении к ним - возвращающие адрес участка памяти или же возвращающие само значение. В данном случае имеем то, что возвращает значение.Изначально запишем,чтобы возвращалось значение 0.Если укажем другое число,то оно и будет возвращаться при обращении.
Итак, с тем где хранить размерность массива мы разобрались. Как нам задать значения самого массива и как к нему обращаться. Это достигается в строчках кода:
задание адреса начала участка памяти откуда начнется массив
Код:
CREATE ARR
непосредственно запись значений массива
Код:
1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 ,
Кто повнимательней сразу же задаст вопрос:" а что там делает HERE?". Вернемся к нему чуть позже.
Итак, слово CREATEсоздает в программе именованную область памяти, при этом выделения самой памяти не происходит. Просто создается удобство для обращения к некоторому участку памяти.В нашем случае имя нового участка будет ARR. Далее записываются значения с помощью специального оператора (слова) ЗАПЯТАЯ, которая должна быть ОБЯЗАТЕЛЬНО ОТДЕЛЕНА ПРОБЕЛОМ. Эта ЗАПЯТАЯ тесно связана с HERE - она всегда увеличивает его значение.
Так что же такое HERE? Не вдаваясь в подробности будем считать, что это текущий адрес памяти куда помещается значения с помощью оператораЗАПЯТАЯ. Что он делает в нашей программе ? При обращении к оператору (слову) HERE на стек помещается адрес.
Теперь о всём блоке сразу
Код:
CREATE ARR  HERE
   1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 ,
HERE SWAP - CELL / TO  ARR_SIZE
При выполнении создается именновая область ARR, с помощью HERE значение ARR помещается на стек. Оно есть адрес куда будут складываться наши значения - у нас их 9. После размещения в памяти девяти значений мы снова вызываем HERE и ведем несложный подсчет числа элементов
Код:
SWAP - CELL /
меняем два числа на стеке, вычитаем и делим на размер одной ячейки. Ячейка - стандартно адресуемый элемент памяти в ФОРТ (обычно 2 или 4 байта).
На стеке будет сформировано число элементов массива.Далее это число записывается в ранее определенную нами область памяти ARR_SIZE с помощью слова TO
Код:
TO  ARR_SIZE
Далее по тексту программы выделяется 3 ячейки в именованной области памяти Q . Делается это с помощью слова ALLOT
Код:
CREATE Q  3 CELLS ALLOT
Что же эта область хранит? Зачем она понадобилась? А хранит она как раз три значения для количества отрицательных, нулевых и положительных чисел в массиве..... (to be continued)


Последний раз редактировалось Alexander Пн дек 17, 2012 21:20, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 00:27 
Не в сети

Зарегистрирован: Пн ноя 05, 2007 13:54
Сообщения: 135
Благодарил (а): 0 раз.
Поблагодарили: 11 раз.
Предлагаю разобрать более занятный вариант.

Код:
create arr 9 , 1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 ,

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

: negatives ( array - count) 0 swap each: 0< if 1+ then ;
: zeroes ( array - count) 0 swap each: 0= if 1+ then ;
: positives ( array - count) 0 swap each: 0 > if 1+ then ;

: main
   cr ." Negatives=" arr negatives .
   cr ." Zeroes=" arr zeroes .
   cr ." Positives=" arr positives . ;


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


Последний раз редактировалось true-grue Вс дек 16, 2012 10:51, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 01:31 
Не в сети
Moderator
Moderator

Зарегистрирован: Ср май 10, 2006 15:37
Сообщения: 1132
Откуда: Chelyabinsk ( Ural)
Благодарил (а): 0 раз.
Поблагодарили: 9 раз.
true-grue писал(а):
К сожалению, во многих современных (квази)фортах программисту запрещены наиболее интересные манипуляции со стеком возвратов.

код true-grue на online сервисе исполнения Форт кода для GForth не выполнился
Набранный код


Последний раз редактировалось Kopa Вс дек 16, 2012 02:08, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 02:06 
Не в сети
Moderator
Moderator

Зарегистрирован: Ср май 10, 2006 15:37
Сообщения: 1132
Откуда: Chelyabinsk ( Ural)
Благодарил (а): 0 раз.
Поблагодарили: 9 раз.
Alexander писал(а):
Нет ничего проще в освоении нового, чем учится на примерах.
Программа была протестирована в SwiftForth. Поэтому при возникновении нестыковки различных версий ФОРТ от разных производителей необходимо корректировать программу под ту сиситему, которую применяете именно Вы.

Проверен:)
в Форте сервиса не было обнаружено слово ++ поэтому определил и добавил 1+! (что тоже вроде правильно)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 21:03 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2107
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 34 раз.
Alexander писал(а):
Нет ничего проще в освоении нового, чем учится на примерах.

На манипуляторах это все проще делается: :)
Код:
\       0 1               2 3 4
q-0+: ( a u -- n- n0 n+ ) 0 0 0  c( 1+! ) \ счетчики отрицательных-нулевых-положительных чисел в массиве
s+( ." q+ = " ) s-( ." q- = " ) s0( ." q0 = " )
5\01+0GI@'5!5y<i'2[c]e5Zi'3[c]e'4[c]tt`4N[s-]2.\[s0]3.\[s+]4.\0'hfo ;

gen-arr: ( dn dq -- a u )  \ генератор случайного массива
2\"rnd0pd'2!`4*'hao2`4*1 3\01+0G2p`3p`1-*d.I!`4N\\01 ;

STARTLOG
100 400 gen-arr q-0+

log
Код:
0 -289 -373 0 0 -30 0 0 -250 0 -35 0 306 38 393 -101 -109 0 0 -64 0 0 10 318 0 -354 -350 0 0 0 -145 341 -247
-271 -55 -45 -156 303 316 0 0 361 0 76 0 0 0 383 182 0 -277 287 0 209 228 -132 67 0 93 -234 -399 -39 -115 0
0 14 0 -35 0 -209 278 0 -361 259 0 -346 0 269 0 -147 -312 -41 0 0 -139 324 0 371 -92 -85 -360 -66 0 -212

q- = 35
q0 = 36
q+ = 23

Ok 

_________________
С уважением, chess


Последний раз редактировалось chess Вс дек 16, 2012 21:27, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 21:10 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6328
Благодарил (а): 14 раз.
Поблагодарили: 99 раз.
chess писал(а):
На манипуляторах это все проще делается:

С учетом приведенного ниже кода после этого заявления не хватает смайлика...


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 21:32 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2107
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 34 раз.
Хищник писал(а):
С учетом приведенного ниже кода после этого заявления не хватает смайлика...

Смайлик поставил, но после чтения текстов на https://github.com/chess2007/-chess он потеряет смысл.

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 21:35 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6328
Благодарил (а): 14 раз.
Поблагодарили: 99 раз.
chess писал(а):
Смайлик поставил, но после чтения текстов на https://github.com/chess2007/-chess он потеряет смысл.

Откуда уверенность, что сам факт наличия http::/чего-то_там сам по себе является доказательством?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 21:56 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2107
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 34 раз.
Хищник писал(а):
Откуда уверенность, что сам факт наличия http::/чего-то_там сам по себе является доказательством?

Уверенность - это субъективно. Доказательства всегда основываются на каком-то наличии (фактов). А откуда уверенность, что
факт наличия http::/чего-то_там, не является доказательством?

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 22:03 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6328
Благодарил (а): 14 раз.
Поблагодарили: 99 раз.
chess писал(а):
Уверенность - это субъективно.

Тогда надо было написать: "мне проще сделать это на манипуляторах". Субъективно можно хоть иероглифами писать - почему нет, если кому-то удобнее именно так.
chess писал(а):
А откуда уверенность, что факт наличия http::/чего-то_там, не является доказательством?

Пошла в ход демагогия? :) Я ясно написал - самого факта еще недостаточно. Потому что от размещения текста в другом месте его содержание и доказательная сила никак не меняются. Но вот для тех, кому лень щелкнуть по ссылке, красивое http:// может быть "как бы аргументом", несмотря на то, что писано тем же человеком, просто доведено до сведения не на словах, а через веб-ресурсы. Мне вот решение от true-grue понравилось настолько, что я слегка подкорректировал свое отношение к стеку возвратов (впрочем, тут тоже есть варианты). А иероглифоподобная запись так и останется иероглифоподобной и трудной для восприятия и анализа, какие бы аргументы насчет "операционных пространств" ни притягивались за уши.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 22:22 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2107
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 34 раз.
Хищник писал(а):
Тогда надо было написать: "мне проще сделать это на манипуляторах".

Это тот же субъективизм. Смысла то есть в этом никакого. Меня не интересуют субъективные моменты чьего-либо восприятия
Хищник писал(а):
Пошла в ход демагогия?
Нет, это я повторил ваши слова.
Хищник писал(а):
Мне вот решение от true-grue понравилось настолько,..
Это тоже ваше субъективное мнение. Мне например оно не понравилось, потому, что можно проще, что в моем решении и было приведено.
Хищник писал(а):
А иероглифоподобная запись так и останется иероглифоподобной и трудной для восприятия и анализа, какие бы аргументы насчет "операционных пространств" ни притягивались за уши.

Я против выводов ни на чем кроме голословных фраз типа выше вами приведенной не основанных. Это все субъективные утверждения никак не касающиеся сути процесса программирования.

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вс дек 16, 2012 23:50 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6328
Благодарил (а): 14 раз.
Поблагодарили: 99 раз.
chess писал(а):
Это тот же субъективизм. Смысла то есть в этом никакого. Меня не интересуют субъективные моменты чьего-либо восприятия

А объективных критериев оценки простоты на примере комбинаторов мы так и не видели.
chess писал(а):
Я против выводов ни на чем кроме голословных фраз типа выше вами приведенной не основанных. Это все субъективные утверждения никак не касающиеся сути процесса программирования.

Я не думал, что это стоит разжевывать. Неоднократно на форуме отмечалось, что набор символов, не образующий читаемые слова, труден для восприятия. Конкретно в теме мы имеем:
1. Прямое и непосредственное решение от автора топика, легко читаемое и понимаемое, в котором сразу видно возможные ошибки.
2. Решение от true-grue, основанное на особенностях работы Форт-транслятора и реализующее... как бы ни странно это звучало, но как раз-таки комбинатор foreach. Причем реализующее ad hoc.
3. Набор символов, который прочитать можно только при наличии под рукой таблицы, что чему соответствует. Впечатление такое, что внутрь можно засунуть хоть "format c:", и оно там успешно замаскируется :)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Пн дек 17, 2012 00:02 
Не в сети
Moderator
Moderator

Зарегистрирован: Ср май 10, 2006 15:37
Сообщения: 1132
Откуда: Chelyabinsk ( Ural)
Благодарил (а): 0 раз.
Поблагодарили: 9 раз.
Хищник писал(а):
Впечатление такое, что внутрь можно засунуть хоть "format c:", и оно там успешно замаскируется :)

Для кого то и Форт является "китайкой" грамотой:) Код chess в контексте его восприятия можно сравнить с использованием
в практике регулярных выражений, что тоже требует некоторых навыков для использования и насколько удобно или нет
без практики применения трудно сказать.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Пн дек 17, 2012 13:34 
Не в сети

Зарегистрирован: Ср июл 05, 2006 14:44
Сообщения: 231
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
Вариант от Alexander можно немного упростить,
подсчитывая отрицательные числа и числа равные 0 на вершине стека с помощью
хитрого счетчика, где старшие 16 бит счетчик отрицательных чисел,
младшие 16 бит счетчик нулевых чисел, а положительные просто вычеслить позже
как разницу от общего числа чисел:
Код:
0 VALUE ARR_SIZE
CREATE ARR  HERE
   1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 ,
HERE SWAP - CELL / TO  ARR_SIZE
: SIGNUM  DUP  0< IF DROP 0x10000 EXIT THEN 0= 1 AND ;
: HOW-MANY-NUMBERS ( WHERE SIZE - N ) CELLS OVER + SWAP ?DO I @ SIGNUM + CELL +LOOP ;
: MAIN
   0 ARR ARR_SIZE HOW-MANY-NUMBERS
   CR ." Negatives=" DUP  16 RSHIFT  DUP .
   CR ." Zeroes="    SWAP 0xFFFF AND DUP .
   CR ." Positives=" + ARR_SIZE SWAP -   .      ;

так же можно поступить и в варианте true-grue и не делать третий проход.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Пн дек 17, 2012 15:44 
Не в сети

Зарегистрирован: Пн ноя 05, 2007 13:54
Сообщения: 135
Благодарил (а): 0 раз.
Поблагодарили: 11 раз.
Когда говорят, что какая-то программа лучше/хуже или проще/сложнее другой, то подразумевают определенную "систему координат" в которой эти критерии качества имеют смысл. Попробую объяснить, что такое хорошая программа, как я это понимаю. Сразу скажу, что Америку не открою, благо изложенное ниже имеется в учебниках и принято на вооружение современными коллективами разработчиков.

Программа является результатом формализации некоторого вычислительного (или, если хотите, информационного) процесса и предназначена, в первую очередь, для понимания людьми, а не компьютерами. Легкость чтения обеспечивается структурированностью, иерархичностью, регулярностью кода, использованием проблемно-ориентированных нотаций (человечество накопило большой опыт в их создании, см., например, музыкальную или химическую нотации). Не зря было замечено, что хорошие программисты отличаются и владением литературным словом. Борьба с длиннотами, новоязом и прочими литературными изъянами имеет значение и при составлении программ. Помимо легкости чтения, хорошую программу легко поддерживать и развивать. Для того, чтобы программу могли читать и изменять различные разработчики она должна быть самодокументируемой. То есть, помимо собственно комментариев и прочей документации, сама структура программы и использованная нотация должны опираться на, так сказать, общечеловеческие знания, а не "эзотерику". Хаки, оригинальничанье недопустимы. Если для понимания программы необходимы специальные знания (за пределами, допустим, университетского курса), то ссылки на соответствующую литературу указываются специально. Опытным разработчикам известно, что очевидный для понимания, простой код -- самый безошибочный, а оптимизациями следует заниматься лишь в тот момент, когда программа уже написана, и написана правильно. Стоит отметить, что из первоначального, ясного для понимания варианта программы можно получить множество ее оптимизированных частных случаев не только вручную, но и путем метапрограммирования. Что такое ясный для понимания код? Это код декларативного характера, для понимания сути которого читателю не придется в голове имитировать работу компьютера по шагам. Ценить нужно, в первую очередь, время разработки, поддержки и развития программы, а не процессорное время. Программа получается расширяемой, если вместо одного решения частной задачи мы создаем специализированный язык для решения различных ее вариаций. Расширяемая программа может быть использована в различных контекстах, отсюда необходимость в гибкости ее структуры, отсутствии глобальных переменных и тому подобного.

Теперь, что касается моего варианта примера выше. Программа написана в привычном стиле Форта, когда сначала создаются языковые средства для более простого и выразительного решения задачи, а далее уже в новых терминах решается сама задача. Итератор each:, как абстракция перечисления элементов в некоторой структуре данных, не является чем-то новым для грамотного программиста, подобные конструкции и лямбда-выражения в них фигурирующие имеются в том или ином виде в современных языках программирования. Новой для многих фортеров может показаться реализация итератора, и здесь было бы нелишне дать уточняющий комментарий. Очевидно, что введенный итератор позволяет решить целое семейство подобных задач (например, подсчитать число четных элементов или получить сумму элементов массива, при желании можно посчитать количество -/0/+ элементов за один проход и т.д.). Важно также, что глобальные переменные отсутствуют и программу можно использовать в различных контекстах.

chess писал(а):
Alexander писал(а):
Нет ничего проще в освоении нового, чем учится на примерах.

На манипуляторах это все проще делается: :)

На векторном языке J делается еще проще: ({. , #)/.~ * arr
Вот только "манипуляторы" к векторному стилю относятся примерно также, как незабвенный язык LUX к Форту :)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 85 ]  На страницу 1, 2, 3, 4, 5, 6  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB