Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Чт мар 28, 2024 20:37

...
Google Search
Forth-FAQ Spy Grafic

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




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

Зарегистрирован: Ср июл 05, 2006 14:44
Сообщения: 236
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
небольшое забавное путишествие с итератором:
Код:
: each: ( arr ) DUP @ 0 DO CELL+ DUP >R @ RP@ 16 + @ EXECUTE R> LOOP DROP RDROP ;

а как будет манипуляторная калька?
Код:
: each: ( arr ) R> 2\1d@`0D`4+d'1!@2X1Lx ;

хм, а у chess-a то короче:
Код:
: arr# ( arr -- adrr len ) DUP CELL+ SWAP @ CELLS  ;
: each:  ( arr ) arr# R> 3\12+1DI@3X`4N ;

попробуем перейти назад к аналогу в форте
Код:
VARIABLE tail
: bounds  OVER + SWAP ;
: each:  ( arr ) arr# bounds R> tail ! DO I @ tail @ EXECUTE CELL +LOOP ;

в принципе tail можно сделать и стеком. или вспомнив о хаке:
Код:
: tail ( -- xt ) RP@ 16 + @ ;
: each:  ( arr ) arr# bounds DO I @ tail EXECUTE CELL +LOOP RDROP ;


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

Зарегистрирован: Чт июн 25, 2009 11:12
Сообщения: 412
Благодарил (а): 41 раз.
Поблагодарили: 8 раз.
Я понимаю, что гибкость и портабельность--это не для форта, но... в for-each можно было бы просто передавать xt через стек данных.


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

Зарегистрирован: Ср июл 05, 2006 14:44
Сообщения: 236
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
dynamic-wind писал(а):
Я понимаю, что гибкость и портабельность--это не для форта, но... в for-each можно было бы просто передавать xt через стек данных.


тут true-grue говорил очень правильные слова про лексикон и решение задач,
посмотрите как эффектно выглядит вызов итератора each: в данной задаче.
Код:
: zeroes ( array - count)    0 SWAP each: 0=  IF 1+ THEN ;

а реализация самого итератора тоже может быть задачей и потребовать разработки
собственного лексикона. сравните оригинальное определение и через лексикон (arr#,bounds,tail)
Код:
: each: ( arr ) R> SWAP DUP @ >R CELL+ R> 0 DO 2DUP 2>R @ SWAP EXECUTE 2R> CELL+ LOOP 2DROP ;
: each: ( arr ) arr# bounds DO I @ tail EXECUTE CELL +LOOP RDROP ;

каждый уровень абстракции может иметь свой лексикон, как у каждой матрешки своя красота.
Ваше предложение передавать xt через стек имеет право быть, но будет ли
оно на внешнем уровне так красиво?


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

Зарегистрирован: Пн ноя 05, 2007 13:54
Сообщения: 144
Благодарил (а): 0 раз.
Поблагодарили: 13 раз.
dynamic-wind писал(а):
Я понимаю, что гибкость и портабельность--это не для форта, но... в for-each можно было бы просто передавать xt через стек данных.


Судя по нику, Вы знакомы с языком Scheme и функциональным программированием. Буду отталкиваться от этого.
Функцию высшего порядка трудно представить без функциональных литералов (анонимных функций). Иначе дальше выразительности qsort из Си мы не уйдем. Функциональный литерал в Форте можно ввести двумя способами.

1. "[: do-something ;] each". Это та же конструкция LAMBDA{ }, которую я предложил в SU.FORTH еще в конце 90-х.
2. "each: do-something ;". Текущий вариант. Никаких дополнительных конструкций, лишь одно слово r> (или r@) внутри функции высшего порядка. Легко читаемый код с участием each:, и вполне в духе Форта (напоминает DOES>).

В настоящий момент мне нравится второй вариант, особенно с учетом общего, малоисследованного еще подхода к стеку возвратов, о котором я выше говорил.

По поводу гибкости. Давайте сравним реализацию negatives и .array на Scheme и Форте.
Код:
(define (negatives array)
  (foldl (lambda (element count) (if (< element 0) (+ count 1) count)) 0 array))

(define (.array array)
  (for-each (lambda (element) (printf "~a " element)) array))

Код:
: negatives ( array - count) 0 swap each: 0< if 1+ then ;
: .array ( array) each: . ;

Заметьте, что на Scheme, в отличие от Форта, приходится использовать две различные функции (fold и for-each).

И, наконец, самое главное. Почему-то коллеги на форуме редко берут за труд содержательно, конструктивно аргументировать свои мысли. Хотелось бы подтверждения безапелляционным "проще" на основе каких-то известных положений, источников. На основе собственного опыта, в конце концов, с подтверждением кодом. Свой опыт работы с функциями высшего порядка я изложил еще в старенькой статье "Функциональное программирование на языке Форт".


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

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
Для each: видится вариант со стековой нотацией ( addr, count -- ), поскольку текущий вариант требует вполне определенную реализацию массивов. А вообще я уже настроился добавить в кварк набор таких итераторов для данных разных типов :)


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

Зарегистрирован: Вт мар 20, 2007 23:39
Сообщения: 1261
Благодарил (а): 3 раз.
Поблагодарили: 19 раз.
Хищник писал(а):
А вообще я уже настроился добавить в кварк набор таких итераторов для данных разных типов :)

А еще бы кварк-64 и под линукс бы... :shuffle;

_________________
Cтоимость сопровождения программного обеспечения пропорциональна квадрату творческих способностей программиста.
Роберт Д. Блисc


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

Зарегистрирован: Чт июн 25, 2009 11:12
Сообщения: 412
Благодарил (а): 41 раз.
Поблагодарили: 8 раз.
Alex писал(а):
посмотрите как эффектно выглядит вызов итератора each: в данной задаче.
Код:
: zeroes ( array - count)    0 SWAP each: 0=  IF 1+ THEN ;

Эффектно, не спорю.
Теперь попробуйте написать слово, которое печатает сумму чисел больше данного.
Приходится ваять что-то вроде:
Код:
: count> ( x array --) 0 swap each: не-знаю-сколько pick > if 1 + then ;
: .count> ( x array --) .count> . ;

А как написать слово, выполняющее операцию для каждого элемента, который удовлетворяет предикату?
Код:
: appIf ( predxt opxt array --)
  each: dup где-чёртов-predxt pick execute
     if где-чёртов-opxt pick execute else drop then ;

Как образец элегантности, вот решение на SML через три стандартных (!) комбинатора:
Код:
fun appIf pred oper = (app oper) o (filter pred)


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

Зарегистрирован: Ср май 10, 2006 15:37
Сообщения: 1132
Откуда: Chelyabinsk ( Ural)
Благодарил (а): 0 раз.
Поблагодарили: 9 раз.
dynamic-wind писал(а):
Теперь попробуйте написать слово, которое печатает сумму чисел больше данного.

Мне не совсем понятно о чём вопрос, но такое решение к этому?
Код:
: sum(
    depth >r 0 [char] ) parse evaluate
   depth r> - 1- 0 ?do + loop ;

sum( 1 2 3 4 5 ) .


dynamic-wind писал(а):
Приходится ваять что-то вроде:
Код:
: count> ( x array --) 0 swap each: не-знаю-сколько pick > if 1 + then ;
: .count> ( x array --) .count> . ;


реализация each: может быть более (или менее ) универсальна.
В моём коде each: "мусорит" (не совсем "правильно" сделано т.к. переставляет параметры вызываемого кода и оставляет свои на стеке данных при обратном вызове ) у true-grue нет.
"Проблема" обсуждаемого варианта each: , что он плохо переносим (из-за "девальвированой" функциональности стека возвратов для многих Форт систем)

dynamic-wind писал(а):
А как написать слово, выполняющее операцию для каждого элемента, который удовлетворяет предикату?

А разве реализация анализа доп. условия вызывает определённые сложности?
Решение с "заданной" степенью "эллегантности" и "эффектности" тоже можно составить.
Не хватает комбинаторов? Добавляйте их реализацию.


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

Зарегистрирован: Ср июл 05, 2006 14:44
Сообщения: 236
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
dynamic-wind писал(а):
Теперь попробуйте написать слово, которое печатает сумму чисел больше данного.

В рамках этой задачи, один из возможных вариантов, мы не меняем итератор
Код:
0 VALUE level
: sum>  ( lev,arr -- sum) SWAP TO level 0 SWAP each: DUP level > IF + ELSE DROP THEN ;
4 arr sum> .  ( 14 )

можно конечно и модифицировать итератор, например в конкурсе задач в моем решении есть цикл по счетчикам
Код:
: KeyCikl ( byte - ) 8 0 DO DUP I cnt+ LOOP DROP ;
можно записать и через итератор
: each-key:  R> 8 0 DO 2DUP I SWAP EXECUTE LOOP 2DROP ;
: KeyCikl2 ( byte -- ) each-key: ( byte cnt ) cnt+ ;

здесь итератор each-key: перед вызовом хвостовой части готовит байт от клавиатуры и индекс счетчика ( а не значение массива )


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

Зарегистрирован: Пн ноя 05, 2007 13:54
Сообщения: 144
Благодарил (а): 0 раз.
Поблагодарили: 13 раз.
Все-таки жаль, что г-н dynamic-wind уклонился от прямой полемики. Его потребительский подход к Форту достаточно типичен. Впрочем, и без меня найдутся желающие с ним подискутировать.

Проблема же рассматривается известная. Стековой эквилибристикой заниматься не хочется. Локальные переменные имеют слишком много ограничений. Манипуляторы... не подходят заурядным умам. Но фортерам претит унылое "приходится ваять что-то вроде" и беспомощное "а как написать слово". Предлагаю рассмотреть следующее несложное решение.

Вводится специальная конструкция, в виде аналога стековой картинки, где в именованном виде фигурируют несколько элементов от вершины стека данных.

Пример.
Код:
: swap { first second - second first } ;

Будем считать, что { ... } генерирует необходимый код для преобразования стека данных (например, с помощью pick, roll и т.п.). Разумеется, что first, second это никакие не слова, а лишь фрагменты текста, которые подлежат сравнению.
Хочу обратить особое внимание на крайне полезный побочный эффект введения подобной конструкции: код становится самодокументированным.

Несколько дополнительных примеров.
Код:
: d { a b c - a c b b} * { a c b^2 - b^2 a c} * 4 * - ;

: count> ( x array - x count)
   0 swap each: { x count element - x count element x} > if 1 + then ;

: appIf ( pred op array - pred op)
   each: { pred op element - pred op element element pred} execute
   if { pred op element - pred op element op} execute else drop then ;

Реализацию { ... } было бы интересно предложить в качестве задачи на форумном конкурсе.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вт дек 25, 2012 14:12 
По моему все вопросы давно сняты в locals.f из SPF. Комментарий оттуда (занимает аж треть всей реализации)
Код:
( Простое расширение СП-Форта локальными переменными.
  Реализовано без использования LOCALS стандарта 94.

  Объявление временных переменных, видимых только внутри
  текущего слова и ограниченных временем вызова данного
  слова выполняется с помощью слова "{". Внутри определения
  слова используется конструкция, подобная стековой нотации Форта
  { список_инициализированных_локалов \ сп.неиниц.локалов -- что угодно }
  Например:

  { a b c d \ e f -- i j }

  Или { a b c d \ e f[ EVALUATE_выражение ] -- i j }
  Это значит что для переменной f[ будет выделен на стеке возвратов участок
  памяти длиной n байт. Использование переменной f[ даст адрес начала этого
  участка. \В стиле MPE\

  Или { a b c d \ e [ 12 ] f -- i j }
  Это значит что для переменной f будет выделен на стеке возвратов участок
  памяти длиной 12 байт. Использование переменной f даст адрес начала этого
  участка.

  Часть "\ сп.неиниц.локалов" может отсутствовать, например:

  { item1 item2 -- }

  Это заставляет СП-Форт автоматически выделять место в
  стеке возвратов для этих переменных в момент вызова слова
  и автоматически освобождать место при выходе из него.

  Обращение к таким локальным переменным - как к VALUE-переменным
  по имени. Если нужен адрес переменной, то используется "^ имя"
  или "AT имя".


  Вместо \ можно использовать |
  Вместо -> можно использовать TO

  Примеры:

  : TEST { a b c d \ e f -- } a . b . c .  b c + -> e  e .  f .  ^ a @ . ;
   Ok
  1 2 3 4 TEST
  1 2 3 5 0 1  Ok

  : TEST { a b -- } a . b . CR 5 0 DO I . a . b . CR LOOP ;
   Ok
  12 34 TEST
  12 34
  0 12 34
  1 12 34
  2 12 34
  3 12 34
  4 12 34
   Ok

  : TEST { a b } a . b . ;
   Ok
  1 2 TEST
  1 2  Ok

  : TEST { a b \ c } a . b . c . ;
   Ok
  1 2 TEST
  1 2 0  Ok

  : TEST { a b -- } a . b . ;
   Ok
  1 2 TEST
  1 2  Ok

  : TEST { a b \ c -- d } a . b . c . ;
   Ok
  1 2 TEST
  1 2 0  Ok

  : TEST { \ a b } a . b .  1 -> a  2 -> b  a . b . ;
   Ok
  TEST
  0 0 1 2  Ok

  Имена локальных переменных существуют в динамическом
  временном словаре только в момент компиляции слова, а
  после этого вычищаются и более недоступны.

  Использовать конструкцию "{ ... }" внутри одного определения можно
  только один раз.

  Компиляция этой библиотеки добавляет в текущий словарь компиляции
  Только два слова:
  словарь "vocLocalsSupport" и "{"
  Все остальные детали "спрятаны" в словаре, использовать их
  не рекомендуется.
)


В чем "слишком много ограничений"?


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

Зарегистрирован: Пн ноя 05, 2007 13:54
Сообщения: 144
Благодарил (а): 0 раз.
Поблагодарили: 13 раз.
ArtemKAD писал(а):
В чем "слишком много ограничений"?

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


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

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Учимся на примерах...
СообщениеДобавлено: Вт дек 25, 2012 16:19 
true-grue писал(а):
ArtemKAD писал(а):
В чем "слишком много ограничений"?

"Загрязнение" стека возвратов, невозможность их введения внутри управляющих конструкций...

Стек возвратов там "постольку поскольку" - это просто удобное место под временный буфер. Введите отдельный стек и не будет загрязнения. Там ведь абсолютная адресация памяти ячейки во временном буфере.

В чем проблема с управляющими конструкциями? Кроме досточтимого DO - LOOP остальные вроде на стек возвратов не покушаются и доработок не требуют...


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

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
true-grue писал(а):
. Предлагаю рассмотреть следующее несложное решение.

viewtopic.php?p=34749#p34749

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


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

Зарегистрирован: Пн ноя 05, 2007 13:54
Сообщения: 144
Благодарил (а): 0 раз.
Поблагодарили: 13 раз.
mOleg писал(а):
true-grue писал(а):
. Предлагаю рассмотреть следующее несложное решение.

viewtopic.php?p=34749#p34749


Очередную реализацию локальных переменных и решение примеров выше на ее основе пусть показывают поклонники этих самых локальных переменных. Еще раз поясню: меня сейчас локальные переменные не интересуют. Ни в каком виде. В данном случае я совершенно солидарен с сообщением покинувшего нас г-на gudleifr'а по ссылке :)


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

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


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

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


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

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