Разомнем мозг при помощи Forth?

image

Порой возникает желание размять свой погрязший в объектно-ориентированном программировании мозг чем-то новеньким и необычным. Конечно, на помощь в этой ситуации может прийти любой функциональный язык программирования, например, Haskell, Erlang, Lisp или OCaml. Но сейчас даже ими уже вряд ли кого-то можно удивить. Нет, хочется чего-то совершенно другого. В такой ситуации на помощь к нам спешит Forth — стековый язык программирования.



Я буду рассматривать программирование на Forth в рамках операционной системы Ubuntu. Список компиляторов для других операционных систем можно посмотреть здесь. Так же можно воспользоваться онлайн-интерпретатором Forth, но он работает не очень хорошо, но терпимо. Я буду использовать gforth, который можно установить следующим образом:

sudo apt-get install gforth

Все, как только мы его установили, можно запустить в терминале Форт в интерактивном режиме, выполнив команду:

gforth

Но перед тем, как написать «Hello world» я хотел бы немного рассказать об отличиях синтаксиса этого языка от привычного нам. Наверняка, многие из вас привыкли к инфиксной записи (когда знак операции стоит между операндами), некоторых уже не испугать префиксной записью (когда оператор стоит перед операндами), но Форт пошел своей дорогой — он использует обратную польскую нотацию, то есть постфиксную запись. Например, чтобы сложить два числа, нужно написать так:

1 2 +

В результате этой операции мы получим 3. Но это далеко не все особенности Форт. Изначально ядро этого языка представляет из себя некий словарь: набор слов, при помощи которых мы можем выполнять некоторый поднабор операций над данными. При этом основной единицей языка собственно и является СЛОВО. Мы можем использовать уже имеющиеся слова (DUP — дублировать лежащий на вершине стека элемент, SWAP — поменять местами два верхних элемента стека, и так далее), так и определять свои собственные. В общем то, именно определение своих слов, через имеющиеся, а затем все более новых и новых слов — это и есть основной механизм программирования на Форте.

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

Ладно, вроде бы вводная озвучена и теперь можно посмотреть на Hello world на этом языке:

." Hello world"

Если выполнить эту команду в интерактивном режиме, то в ответ мы получим:

Hello world

Но на самом деле это не демонстрирует вообще ничего! В принципе, как и любой другой Hello world на любом другом языке программирования. Давайте лучше рассмотрим несколько базовых принципов написания программы на Forth.

Forth — это стековый язык, а это значит, что все передаваемые значения кладутся в стек, а когда мы производим некоторые операции над ними, то они вынимаются из стека. Например, положим в стек четыре элемента выполнив следующее в интерактивной оболочке Forth:

1 2 3 4

Теперь при помощи оператора извлечения верхнего элемента со стека ("."). Мы вытащим все элементы из стека:

 . . . .

Получим следующий вывод:

4 3 2 1 ok

То есть мы увидели в действии принцип FILO: первый элемент, положенный в стек, был вынут из стека последним. Давайте теперь попробуем выполнить следующее арифметическое действие: (2 + 4) * 5 / 10. В результате мы должны получить 3. На Форте мы эту операцию можем записать так:

2 4 + 5 * 10 / .


Точка в конце выражения нам нужна для того, чтобы вывести верхний элемент стека. На момент выполнения «точки» этим элементом будет как раз необходимый нам результат.

Но только лишь подобными вычислениями далеко не уедешь. Давайте посмотрим, как можно определять собственные слова на примере слова для возведения числа в квадрат. Для этого нам нужно вспомнить слово дублирования верхнего элемента стека DUP:

: POW DUP * . ;

Все, мы определили собственное слово, которым можно воспользоваться вот так:

4 POW

В результате мы получим 16. Давайте рассмотрим более подробно, что мы тут написали. Первым делом после двоеточия нам нужно дать имя своему слову, затем после пробела мы начинаем описывать тело своего слова. Сначала мы говорим, что нам нужно дублировать верхний элемент стека, а затем перемножить два верхних элемента. Вот, собственно, мы и получили слово для возведения в степень, нужно только помнить, что все в Форте нужно отделять пробелом, например, такая запись не будет работать:

:POW DUP * . ;

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

В Форте так же есть оператор ветвления (if) и цикл (do… loop), но их можно использовать только в определении слов. И есть одна особенность в использовании if. Давайте попробуем написать что-нибудь с использованием ветвления:

 : testif    
    dup 1 = if ." One" else
    dup 2 = if ." Two" else
    dup 3 = if ." Three"
 then then then drop ;

Кстати, Форт — регистронезависим, так что dup и DUP, это одно и то же.

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

1 2

<

.S

Здесь мы сначала кладем два числа в стек, затем выполняем операцию сравнения двух верхних элементов стека. Она их вынимает, сравнивает и кладет результат в стек. Третья команда выводит все содержимое стека, которым будет одно единственное число: -1. Минус единица в Forth является булевой «истиной», а ноль — «ложью».

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

: testif 
    dup 1 = if ." One" else
    dup 2 = if ." Two" else 
    3 = if ." Three"
then then then ;

то получим тот же самый результат, но этот вариант не принят, так как мы ухудшаем читаемость кода. Хоть мы и сократили код на два слова (dup и drop (удаление верхнего элемента стека)), но ухудшим читаемость.

Теперь давайте рассмотрим цикл:

 : doloop 10 0 do cr ." Some text" loop ;

Здесь мы распечатываем текст 10 раз. Сначала мы определяем слово, затем в обратном порядке (у нас же стековый язык) указываем границы стека (10 0 do), затем выполняем некоторые действия (в нашем случае каждый раз с новой стоки выводим текст), а затем указываем, что это цикл (loop).

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

Давайте определим слово, которое бы высчитывало факториал заданного числа:

: FACTORIAL recursive
dup 1 > if
    dup 1 - FACTORIAL *
else
    drop 1
endif ;
 
: OURLOOP
swap 1 + swap
do
    i . i ." ! = " i FACTORIAL . cr
loop ;

А теперь попробуем наше слово в действии в действии:

17 0 OURLOOP

Если этот язык заинтересовал вас, то можете смело вникать в него дальше, изучая литературу и ресурсы посвященные ему. Например, я использовал для подготовки этой статьи книгу «Starting FORTH» от Leo Brodie, которая доступна в виде web-ресурса и, кстати, очень приятно читается.

Этот язык неплохо разминает мозг, раздвигает рамки представления о программировании ничуть не хуже, чем Haskell, например. Ну и напоследок шутка про Forth:

«Йоды джедаев магистра речи тайна раскрыта — на Форте просто старый программер он есть»
Поделиться публикацией

Комментарии 117

    +1
    моя студенческая любовь — обязательно скачаю поностальгировать!
      +2
      А можно не качать, а купить за 100 руб девайс (TI LaunchPad с MSP430, привозят за неделю), прошить в него Форт — www.4e4th.us/ и поностальгировать заодно по компьютерам 80х :)
    +6
    Интересует с 98 года. Вся проблема, в том, что я еще не видел КАК с помощью форта считать из текстового файла строки и как выполнить SQL запрос. Да я понимаю, что надо вызывать DLL, но сил больше нет уже. Чтоб небыло обидно я спокойно писал графики на PostScript. Форт красив, но надо простые вводные. Немножко. Ну и спасибо. Это всетаки прорыв на хабре.
      +2
      Да, вы безусловно правы, что на Форте сложновато решать многие задача разработки, но, в принципе, есть Factor, который так же как и Форт — стековый, но в большей степени развит на данный момент. У него есть стандартная библиотека, которая помогает решить многие прикладные задачи. Так что, если вам интересен Форт, то можно взглянуть на его современную инкарнацию.
        0
        Factor — не Форт. А кто «больше развит» — SP-Forth или Factor — это еще посмотреть…
        +4
        Когда сидел под виндой, то в качестве интерпретатора FORTH использовала nnCron, где один из диалектов FORTH использовался в качестве встроенного скриптового языка (а может и сам nnCron на FORTH был написан). Обёртки к о многим функциям Windows32 API там были, как и средства вызова произвольных функций из DLL, благодаря чему написание обёртки к libmysql.dll (или как там она называлась) максимум несколько часов заняло, больше потраченных на изучение собственно API, предоставляемого этой библиотекой. Более того, поскольку обёртки к DLL это не совсем FORTH-way, написал, как бы сейчас назвал, свой DSL на базе этой обёртки, благодаря которому чуть ли не чистый SQL в своих скриптах использовал, то есть писал не нечто вроде " SELECT * FROM table" MYSQL_QUERY DO MYSQL_FETCH_ROW LOOP , а почти (подробностей уже не помню) SELECT * FROM table
          +3
          nnCron целиком написан на русском SP-Forth ( spf.sourceforge.net/ ) и этот же форт в него и встроен.

          Еще более крупная и навороченная программа на том же SP-Forth'е — Eserv ( www.eserv.ru/ ) — комплект серверов для Windows (почта, веб, ftp, прокси и т.д.). В него Форт тоже встроен соответственно — используется в конфигах, для расширений и как server-side скриптер. Там, кстати, SQLite используется активно, так что все для работы с SQL во встроенном форте есть.

          Для работы с MySQL в SP-Forth есть несколько библиотек (см. по первой ссылке каталог devel на CVS) — работают как через libmsql, так и через ODBC. Уже лет 10 как.

          SP-Forth есть версия для Linux, многие популярные портабельные либы (dll/so) единообразно подключаются как к Linux, так и к Windows-версии (см. примеры в devel/~ac/lib/lin/).

          Кстати, SP-Forth'у в этом году стукнуло 20 лет!
          0
          PostScript же тоже стэковый и весь тьюринг-полный?
          Не пробовали написать на ps нортон-коммандер? :)
            0
            PostScript — это фактически специфический графический диалект Форта. Встраиваемый Форт для принтеров. Нортону-коммандеру нечего делать в принтере…
              +1
              Нет. В PostScript есть кодовые блоки — он более современный, более полноценный и более стековый, чем Форт.
                0
                Но это уже не Форт :) Форт по своей сути — метаязык. PS — это язык, реализованный в Форт-концепции.

                Из Форта можно сделать любой язык (собственно, видел Форт, расширенный до ЛИСПа, до Бейсика, до Си), но это будет уже не Форт.
              0
              Помнится где то ходила инфа про веб сервер, написанный на ps.
              0
              А я для этого написал свой интерпретатор форта, в котором для выполнения SQL запросов был и операторы типа SELECT". И даже продал его потом…

              Выглядело это примерно так:
              5 18 SELECT" id, score from users where age>? limit ?"

              Параметры для подстановки брались из стека, так что их надо было тоже в обратном порядке туда класть. Правда я не совсем помню как результаты в стек клались…
                0
                Это, всё же, не совсем Форт-стиль. На Форте, скорее, нужно делать отдельный словарь со всеми словами для формирования запроса. Что-то типа.
                SQL:
                \…
                18 «age>» WHERE 5 LIMIT «id, score» «users» SELECT
                Я бы так делал.
                Сам, правда, пока в подобном случае использовал тупую обёртку:
                SELECT: и тут SQL-запрос до конца строки
                  0
                  Согласен. Меня немного извиняет, что это я, ещё учась, писал. Это я ещё забыл упомянуть, что тот интерпретатор был написан на Pascal. Тем не менее случайное изучение Forth — одно из лучших событий в моей жизни как программиста.
                    0
                    Это скорее для объектно-ориентированных квери-билдеров словарь… Если при построении запроса надо два раза пропихнуть физически одну и ту же конструкцию — самое оно.
                +4
                В начале 90х написал на форте аналог нортон-коммандера, Просто ради фана
                Компилировался он, кстати, в .com файл размером около 40 кб. Почти как ассемблер
                Это, скажу я вам, была та еще акробатика :)
                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    «магистром йодой картинку с новости к поставить если
                    тему в зайти нельзя будет не»

                      0
                      Почти искажённый фиджийский хинди…
                        0
                        По поводу этих постоянных приколов над якобы неестественным синтаксисом Форта есть старая заметка: www.forth.org.ru/~ac/rationale/FORTH.TXT
                          0
                          С японским языком знакомиться не пробовали, кстати?
                            0
                            В японском «в другую сторону» переворачивается :)
                            0
                            Не зайти будет нельзя в тему, если Йоду магистра к новости на картинку поставить
                            Так лучше :)
                              +1
                              У вас в первой части stack overflow: «не зайти» — глагол, а стэк аргументов пустой.
                              И для «если» агрументы неправильные (впрочем у меня тоже), нужно добавлять слово «тогда» чтобы получилось по йода-forth-ски: условие ЕСЛИ результат ТОГДА другое ИНАЧЕ
                              (также это более соответствует всяким китайсикм: сначала тема(известное) потом рема (новое)

                              Хотя и непонятно как это вообще работает на одном стэке, логично было бы наоборот:
                              ТОГДА результат условие ЕСЛИ
                              (оператор ЕСЛИ проверяет верх стэка и если там не тру, просто дропает всё до метки ТОГДА) Вродебы на МК-54 так и было.

                              И с предлогами вы не совсем правы: предлоги обозначаую роли сущности.
                              Можно рассматривать как функцию модификации сущности, либо как обозначение аргумента функции (типа как именованные аргументы).
                              Второе, как я понимаю, для forth чуждо.
                              Зато первое роднее для русского и частично реализуется падежами.

                              Более стэково правильная формулировка:

                              «Йоду магистра картинкою новостною поставить если, тема пропущена небудет тогда»

                              stack trace:

                              Йоду		"Йода"
                              магистра	"магистр Йода"
                              картинкой	"магистр Йода" "картинка"
                              новостной	"магистр Йода" "новостная картинка"
                              поставить 	"новостная картинка с магистром Йодой"
                              если 		(bang!) "факт наличия новостной картинки с магистром Йодой"
                              тема		"тема"
                              пропущена	"пропущенная тема"
                              небудет 	"не пропущенная тема"
                              тогда		(bang!) "факт наличия новостной картинки с магистром Йодой" -> "не пропущенная тема"
                              


                                0
                                Блин, я на C# пишу :)
                                  +1
                                  уже нет! :)
                          0
                          Странно, в лиспе ведь тоже используется почти такая же нотация, только оператор пишется в начале. Но при этом лисп по сравнению с фортом не кажется таким уж причудливым.
                            0
                            Необычность Форта только отчасти вызвана постфиксным типом записи, в большей степени необычна его стек-ориентированность. В лиспе хоть и используется префиксная запись, но интерес в нем вызывают другие моменты: ориентированность на лямбда-исчисление, мощное метапрограмммирование. В принципе, проще читать конструкции, где одной функции передается другая, и так далее, то есть, когда идет некая вложенность, чем конструкции, когда все данные лежат в стеке, а мы вызываем в нужном порядке операторы (или слова, в случае Форта) для достижения необходимого результата.
                              +1
                              Переключением режимов исполнения в Форте можно создать «эффект ФВП». Даже ваш самый первый пример ." Hello World" таким в какой-то мере является. Аргумент для ." берётся не из стэка ведь, а из последующего ввода. IF… THEN, DO… LOOP из той же серии — они создают свои структуры на стэках, и интерпретируют вложенные команды особым образом. Эти слова — по сути обычные FORTH-слова, через FORTH-слова же и определяемые (только в целях оптимизации их пишут на ассемблере или других языках, как и слова типа 1 или 2, в отличии от слов типа +, которые средствами собственно Форт-машины не реализуются, если на ней не реализовывать ассемблер) элементы библиотеки можно сказать, а не элементы синтаксиса как в мэйнстрим языках. В какой-то (довольно большой) мере DO… LOOP это аналог map/reduce/filter функций в ФП. И если ориентироваться не на синтаксис, а на суть, то Форт куда ближе к функциональным языкам, чем к процедурным. Просто по умолчанию параметры в функции передаются через стэк постфиксным способом. И даже классическая ФВП реализуется на форте легко — используем слово, помещающее адрес любого следующего слова, используемого в качестве ФНП, а в ФВП используем адрес этого слова для его вызова.
                                0
                                В Eserv'е реализация большинства интернет-протоколов (SMTP, POP3, IMAP, HTTP, FTP и т.д.) сделана просто как расширение Форта, т.е. эти интернет-протоколы интерпретируются встроенным транслятором Форта — он «думает», что команды протокола — это текст Форт-программы. Для него они «родные». Врядли в каком-либо еще языке программирования такое возможно.
                                  –2
                                  Пипец. Как же там ошибки хендлятся? С++ дубль-два: кроссплатформенный ассемблер с макроязыком, корчащий из себя язык высокого уровня… Шаг влево, шаг вправо — имеем хрен знает что с непонятными последствиями, очень трудно поддающееся отладке из серии «проще выкинуть и написать заново, чем выяснять, почему неправильно работает».
                                    +1
                                    В смысле? Что вам не нравится в фортовой обработке ошибок? Есть структурная обработка CATCH/THROW, как в большинстве языков. Аппаратные исключения тоже через этот механизм бросаются и ловятся (в SP-Forth'е по крайней мере).

                                    Отладка в Форте удобнее, чем в С++, т.к. кроме тех же инструментов есть и диалоговый режим.

                                    С высокоуровневостью тоже порядок (что собственно и подверждается существованием такого крупного проекта как Eserv — он развивается с 1996 года).
                                      0
                                      Диалоговый режим — это великая вещь…
                                  0
                                  IF… THEN, DO… LOOP — это не «обычные слова», это слова с немедленным выполнением: они выполняются сразу, а не во время интерпретации. ifelse — это «обычное слово» в PostScript: условный лямбда-оператор: берёт со стека логическое выражение и два кодовых блока и запускает на исполнение (или исполняет — хз, точно не помню) первый или второй.
                                    0
                                    У нас разные понятия слова «интерпретировать» значит :) Для меня Форт-транслятор это прежде всего интерпретатор символов входного потока, который может переключаться в некоторых случаях (типа ":") в режим компиляции, создавая новую статью. При этом в случае чего-нибудь типа : DUP? IF DUP THEN ; он временно из режима компиляции переключается обратно в режим интерпретации на словах IF и THEN интерпретируя их немедленно и модифицируя процесс компиляции.
                                      0
                                      а поясните, как на одном стэке работает «условие IF результат THEN»?

                                        0
                                        На каком «одном стеке»? У PostScript их тоже два.
                                          0
                                          А что пихается во второй стэк?
                                          В статье об этом ни слова.
                                          В википедии мутно.
                                            0
                                            Ну один — стек возвратов, на другом делаются вычисления. У «нормальных» языков глобального второго стека нет, вместо него локально используется верхушка первого.
                                              0
                                              В одном данные (выступают в роли регистров ассемблерных), в другом адреса возврата.
                                            +1
                                            Грубо говоря, стэк данных используется по разному во время компиляции и исполнения. Когда вы вводите что-то вроде : слово условие IF результат THEN ;, то слово IF компилятор не компилирует на прямую, а вставляет служебное слово в статью, аргумент которого адрес перехода (пока пустой) и сохраняет на стэке адрес адреса перехода, после чего возвращается в режим обычной компиляции, а затем слово THEN берёт со стэка адрес адреса возврата и пишет по нему адрес перехода. А скомпилированное служебное слово берёт адрес со стэка и если не тру, то делает переход на адрес, который был записан THEN во время компиляции.
                                              0
                                              Вот нифига себе.
                                              Я пожалуй, пойду искать мануал с картинками.
                                                0
                                                Достаточно написать свой транслятор :)
                                                  0
                                                  я уже нашёл онлайн транслятор на жаваскрипте, но он стэк не показывает.
                                                    0
                                                    S. — наше всё :)
                                                      0
                                                      .S
                                                      оно печатает только один стэк
                                                        0
                                                        упс, очепатался. но есть ещё .R
                                          0
                                          В Форте изначально есть и такая новомодная «фича» из Lua, как «тупли»;-)
                                          +1
                                          В Форте вполне возможно метапрограммирование. Так же как и Лисп, Форт позволяет переключаться между режимами «компиляции» и «интерпретации», что открывает дорогу для создания макросов, так как помимо стека данных в Форте программисту доступен и стек возвратов, что дает неограниченный простор для создания собственных структур управления и реализации метапрограммирования.
                                            0
                                            Стековые языки с лямбдой и списками тоже существуют…
                                            0
                                            Наоборот. Лисп заметно сложнее и хитрее в реализации. И намного сложнее на практике. Форт чище синтаксически и имеет несравнимо более простой транслятор. Я не видел реализаций Лиспа в 512 байт на ядро системы и в пару килобайт на всю систему с компилятором :)
                                              +1
                                              Я имел в виду причудливость с точки зрения «обычного программиста», а не с точки зрения реализации.
                                              Когда я прочитал первые строки статьи, я сразу всё понял, то есть почему Forth такой старый язык и почему для него так легко сделать компилятор :). Но стеке писать на издевательство форменное программистом над.
                                                0
                                                В Форте есть локальные переменные (стандартное расширение locals), а глобальные переменные есть в базовом форте (т.е. даже если без расширений). Так что, кому сложно уследить за стеком, может упростить себе жизнь.
                                                  +1
                                                  Разница между:
                                                  СТЕК НАД ПИСАТЬ
                                                  и
                                                  (писать (стек, над))
                                                  не принципиальна :)
                                                  В первом случае хоть скобки считать не надо. Более того, для Thinking Forth заявляется требование, чтобы новое слово не превышало 7±2 слов. То есть очень легко и просто видна вся логика выполнения. А вот в Лиспе постоянно практикуются портянки на целый экран кода, завершающиеся гирляндой скобок. На Форте здорово упрощается работа из-за манипулирования потоком исполнения. Лисп этого лишён.
                                                    0
                                                    Разница между:
                                                    СТЕК НАД ПИСАТЬ
                                                    и
                                                    (писать (стек, над))
                                                    не принципиальна :)
                                                    Принципиальна. Без скобок быстро ломаешь мозг. Вот если бы
                                                    ((СТЕК) НАД) ПИСАТЬ
                                                    и
                                                    (писать (над, стек))

                                                    или

                                                    СТЕК НАД ПИСАТЬ
                                                    и
                                                    писать над стек
                                                    (как в Лого вроде)

                                                    — то да, непринципиальна.
                                                      0
                                                      Это у кого как мозг заточен. Я вот начинал программировать на МК-61 (семейство Б3-34), где также применяется постфиксная запись и стэк данных является основным средством вычислений. Для меня FORTH стал отдушиной после BASIC и C :)
                                                        0
                                                        Та-же ботва, только MK-52, и отдушиной стал ассемблер…
                                                        … видимо это и вызвало необратимые изменения психики :-)
                                                          0
                                                          Я тоже на нём начинал…

                                                          Хорошо, что я сразу привык к наличию косвенной адресации и косвенных переходов (фактически начала функционального программирования).
                                                        0
                                                        Если вы считаете скобки в лиспе, то вы что-то делаете не так. Это занятие примерно одного уровня с акробатикой со стеком в форте.

                                                        Есть, конечно, недолиспы вроде Clojure, автор которой намеренно сделал синтаксис, который заставляет считать скобки, но это уже проблемы отдельного неосилятора.
                                                          0
                                                          А как их в нём можно не считать?
                                                      0
                                                      А у HP был ещё и RPL…
                                                      0
                                                      Там ещё и скобки…
                                                      0
                                                      Куда больше Starting Forth я рекомендую Thinking Forth. На русском — в переводе Сергея Дмитренко. Полезно далеко не только фортерам. Я даже в PHP использую многие концептуальные подходы оттуда. Ну а вообще, с Фортом на практике работаю с 1991-го :)
                                                        –1
                                                        А кто-нибудь когда-нибудь видел вакансии где знание FORTH хотя бы упоминался в качестве плюса?
                                                          +2
                                                          Фортеры сами себе работу придумывают. Поэтому работодатели таких слов не знают :)
                                                            +1
                                                            Я видел и собеседовался. Требовался основной скилл — форт.
                                                            В 94 году.
                                                            С тех пор ни разу не видел ни одной вакансии с упоминанием форта
                                                            :)
                                                            0
                                                            Я разрабатываю сайт, на котором пользователь может решать различные задачи на разных языках программирования. Особенность в том, что задачи для каждого языка свои специфические и призваны показать преимущества языка, или просто должны быть интересными для решения на этом языке, или просто расширять кругозор. Меня заинтересовал Forth и я бы хотел его добавить. Какие интересные/красивые/познавательные задачи для Forth вы знаете/решали? Желательно задачи небольшие, пример с аналогом нортон командера из коментов выше будет слишком круто.
                                                              0
                                                              Кстати,
                                                              ." Hello world"
                                                              — это неправильно. По действующему стандарту надо
                                                              .( Hello world)
                                                              А с кавычкой — только для режима компиляции (т.е. внутри определений — процедур или функций).

                                                              И еще: регистронезависимость — это не свойство Форта, а свойство отдельных реализаций. Стандарт допускает оба варианта и требует это оговаривать в документации.
                                                                0
                                                                " Hello world" PRINT
                                                                Будет более кросс-фортово.
                                                                  0
                                                                  Нет в стандарте Форта слова PRINT.
                                                                    +1
                                                                    <Картинка о едином унифицированном стандарте>.jpg

                                                                    VECT EMIT
                                                                    
                                                                    : PRINT // addr -- 
                                                                     DUP C@ IF
                                                                      BEGIN
                                                                       DUP C@ EMIT
                                                                       1 +
                                                                      DUP C@ NOT UNTIL
                                                                     THEN
                                                                     DROP
                                                                    ;
                                                                    
                                                                      0
                                                                      Тот же самый коренной недостаток, что и в С++ — нет стандартной реализации и вместо неё куча самопальных…
                                                                        0
                                                                        Недостаток? Скорее фича для истинных творцов, а не ремесленников!
                                                                        Дающая возможность этих самых ремесленников использовать в крупном строительстве, сотворив им уютный, для понимания, мирок а-ля Arduino…
                                                                          0
                                                                          Да, даже под «Обдурину» Arduino пишут не на Форте, а на Ассемблере и С…
                                                                  +4
                                                                  Главный плюс Forth — это легковесность. Когда на контроллере память исчислялась байтами, это было очень важно. Сегодня этот плюс уже не актуален. А что осталось из минусов? Жесткий самоконтроль по поводу позиций на стеке, сколько и чего взяли, сколько положили. Одна ошибка и вот мы пошли перекапывать стек. Такой абсурд может продолжатся довольно долго и есть шанс, что все таки все хорошо совпадет и программа выдаст результат, но совершенно бессмысленный.

                                                                  Попыткой это исправить была особая нотация в комментариях, так что бы компилятор знал сколько и чего берем со стека. Но этот костыль не может найти все ошибки логики, а такие ошибки на Forth очень легко сделать. Ну и наконец извечная игра с перестановками на стеке (мне нужен третий элемент, а не верхний). Если не выработался какой то свой стиль работы со стеком, то вагон ярких эмоций обеспечен. А стиль рубится на корню, если использовать библиотеки слов других разработчиков. Forth вообще такой тонкий способ потроллить своих коллег =)
                                                                    +2
                                                                    «Самоконтроль» состояния стека — это вообще не вопрос. Форт-стиль — это короткие, однозначные и «тупые» (без сайд-эффектов и смешанного поведения) слова, которые полностью тестируются по мере написания. Поэтому Форт-программа по факту получается более безопасная, чем код на традиционных языках. Акробатика с параметрами на стеке тоже обычно иллюстрирует прокол в архитектуре. Если тебе понадобился третий параметр с вершины, то нужно внимательно присмотреться, в 90% случаев ты допустил где-то концептуальную ошибку.
                                                                      +2
                                                                      Согласен, потому и сказал, что это вопрос выработки стиля. Почему только стиля? Потому, что все таки бывают не только «тупые» слова. Их мало, но они есть (обработка ошибок от внешних сервисов и т.п.). И танцы с позициями на стеке неизбежны. И со временем их становится только больше. Я наком с Forth еще с микроконтроллеров, но мы как то быстро все перешли на C и не пожалели. Сейчас все Scala и Python и уже далеко не под «микроконтроллеры». О Forth вспоминаю с приятной ностальгией, но боже упаси писать на нем снова.

                                                                      Но! Forth как пища для ума и расширение кругозора — очень даже рекомендую.
                                                                    0
                                                                    А мне больше всего импонирует что в Forth все слова имеют определения через другие слова языка. Даже те, которые являются встроенными, для ни определения всё равно есть, хоть и только ради академического интереса.
                                                                      0
                                                                      А мне больше всего импонирует что в Forth все слова имеют определения через другие слова языка.
                                                                      На сановской Яве с классами почти также. Этим она мне и понравилась в 1998;-)
                                                                      0
                                                                      Когда-то тоже разминал мозг (http://habrahabr.ru/post/138667/) конкатенативными языками, и Forth самый известный его представитель. Понравились и Joy, и Factor, это как тренажеры для развития стека у себя в голове и нестадандартных функциональных подходов.
                                                                        –2
                                                                        Когда то писал на ассемблере для 8087. Немного напомнило Forth. Тоже со стеком извращаться приходилось.
                                                                          +1
                                                                          Ничего общего. Тоесть вообще
                                                                            0
                                                                            Ну, кое-что, таки есть…
                                                                            Постфиксность, стек за которым надо следить.
                                                                            Но фишка форт систем, конечно-же не в этом.
                                                                            Хотя технически, форт можно рассматривать как продвинутый макроассемблер: код редактора\интерпретатора + базовые слова (по сути макросы ассемблера) в достаточном объёме, что бы можно было создать\загрузить весь остальной словарь.
                                                                              0
                                                                              Хотя технически, форт можно рассматривать как продвинутый макроассемблер
                                                                              Про С так и пишут: кроссплатформенный макроассемблер.

                                                                              Да, а ещё есть стековые процессоры — не VM, а «железные»…
                                                                              0
                                                                              Вообще ничего общего? Даже наличие стека как основной структуры данных?
                                                                                0
                                                                                Фишка форта, имхо, «шитый код» :)
                                                                                  0
                                                                                  У паскаля и бейсика тоже он есть…
                                                                                    0
                                                                                    Самая популярная в этих краях реализация, SP-Forth, как раз работает не на шитом, а на машинном коде :)
                                                                              0
                                                                              моя любовь. когда то я написал на нём BIOS и систему тестов для одного проекта…
                                                                                –2
                                                                                > в рамках операционной системы Ubuntu.
                                                                                ну вот и пришло то время, когда Ubuntu уже воспринимается как отдельная операционная система. Какое там Linux или GNU/Linux, как любит поправлять Ричар Столман.

                                                                                Простите за вброс. Сам сижу на Ubuntu.

                                                                                По теме: Forth для меня был третьим языком, который я изучал. Теперь его место на почетном месте в музее. Ну и для разминки мозга, как справедливо заметил автор.
                                                                                  0
                                                                                  Что реально мешает в стековых языках — это постоянная необходимость ручной манипуляции со стеком: пропустишь DUP — и лови ошибку час…
                                                                                    0
                                                                                    С другой стороны, именно этот момент дисциплинирует, требует постоянно держать в голове как данные, так и предшествующие преобразования над ними. Это неплохо развивает. Возможно. вы никогда не будете после написания первой программы на Forth прикасаться к нему снова, но аккуратность привитая Фортом останется даже при использовании других языков.
                                                                                      +2
                                                                                      В смысле «пропустишь DUP»? Почему вы его вдруг должны пропустить? Вы же программист, а не машинистка, набивающая текст с листа.

                                                                                      Никаких специальных манипуляций со стеком при правильном стиле программирования на Forth не требуются. Тут уже писали, что ручные манипуляции со стеком, это как goto структурных языках, признак неправильной архитектуры программы.
                                                                                        0
                                                                                        Есть опыт написания скриптлетов на самодельном стековом языке. «Пропустить манипуляцию со стеком» (обычно как раз «DUP») — самая распространённая ошибка, правда в 90% случаев валится на следующем же операторе: на находит на стеке данные подходящих для него типов.
                                                                                          0
                                                                                          Вы же программист, а не машинистка, набивающая текст с листа.
                                                                                          Разница невелика: всё равно хочется feedback как можно раньше. Желательно на этапе компиляции или в IDE при наборе кода. У Лиспа, если упустить баланс скобок, так и получится.
                                                                                            0
                                                                                            В режиме интерпретации при наличии тестовых данных, вы его будете практически сразу. Быстрее будет просто не куда… Если вы судите о Forth'е по самописному стековому языку, то это зря…
                                                                                              0
                                                                                              Если вы судите о Forth'е по самописному стековому языку, то это зря…
                                                                                              Ну да, тот настроен на командную строку, файлы исходников и скриптлеты. Разница в стиле как у C# и Java — вроде бы VM похожи, но политика настолько разная, что для C# чего-то типа Ant, Maven и богатства библиотек и серверов как для Java ещё долго не предвидится…
                                                                                          +1
                                                                                          Чем ближе к железу, тем больше аккуратности и дисциплинированности. Корни, торчащие из управления телескопом, биосы, прошивки спутников, etc — не дают оторваться от реальности. Уже не ассемблер, но еще не похапня. Золотая середина, в каком-то смысле.

                                                                                          Давно не писал на нем, иногда даже скучаю :)
                                                                                            0
                                                                                            Чем ближе к железу, тем больше аккуратности и дисциплинированности.
                                                                                            «Только бондаж и дисциплина, только хардкор»…
                                                                                          0
                                                                                          {1 @y {+x 0 = {}{* ?x 1 - 1 ! !} ? !}! -x} 'factorial !
                                                                                            +2
                                                                                            Что плохо в Форте и иже с ним: длинные названия слов.

                                                                                            Что плохо в Форте и Лиспе/Схеме: вся программа представляет собой выражение. В самом клиническом случае — в Форте — если упустишь «баланс скобок», то система посчитает, что так и надо и что-то выполнит с каким-то результатом.

                                                                                            Программы на «нормальных» языках разбиты на куски, внутри которых баланс стека/скобок отслеживается компилятором. Программируя на таком языке, ты программируешь фактически на двух языках: один — язык потока управления, другой — язык выражений. Что вносит разнообразие и даёт более приятные ощущения глазам. На Форте и Схеме язык один (на Форте — один синтаксис, на Схеме — одни выражения). Уровни «логики» и «выражений» никак визуально не разделены.
                                                                                              +1
                                                                                              >Что плохо в Форте и иже с ним: длинные названия слов.

                                                                                              Здрасьте! Как раз Форт характерен массой соглашений по сокращению слов (которые, кстати, нередко создают проблему понимания у новичков). Типа:
                                                                                              . (точка) символизирует печать, вывод
                                                                                              / — символизирует отношение
                                                                                              # — символизирует количество
                                                                                              @ — чтение
                                                                                              ! — запись
                                                                                              и т.д.

                                                                                              Всё это здорово сокращает синтаксис, делая Форт-программы крайне лаконичными.

                                                                                              >Программы на «нормальных» языках разбиты на куски, внутри которых баланс стека/скобок отслеживается компилятором.

                                                                                              На Форте каждая программа разбита на куски — короткие «слова». Каждое из которых легко и полноценно тестируется в момент написания.
                                                                                              +2
                                                                                              Для интересующихся фортом (да и вообще для всех, кто любит головоломки), есть прекрасная игра Grobots (Wiki, Documentation, Tutorial).

                                                                                              Жанр — стратегия. Ваша задача написать AI для роботов, на фортоподобном языке. Вот пример кода:
                                                                                              #type Killer Vegetable
                                                                                              #color F0E
                                                                                              #hardware
                                                                                                solar-cells .3
                                                                                                constructor .3
                                                                                                armor 100
                                                                                                processor 5
                                                                                                energy 100 0
                                                                                                grenades 30 15 34
                                                                                                robot-sensor 15
                                                                                              #code
                                                                                              do
                                                                                                autoconstruct
                                                                                                grenades-reload-time periodic-robot-sensor if
                                                                                                  robot-found if
                                                                                                    robot-position robot-velocity lead-grenade
                                                                                                  then
                                                                                                then
                                                                                              forever


                                                                                              Вначале вы определяете, из каких роботов будет состоять ваша команда, и какие у них будут характеристики:
                                                                                              процессор — скорость выполнения команд
                                                                                              двигатель — определяет скорость передвижения (если вы вообще его ставите на данного робота),
                                                                                              оружие — бластер, гранаты, бомба,
                                                                                              сенсоры — сенсор других роботов, сенсор ресурсов, сенсор летящих снарядов,
                                                                                              ресурсы — вы будете их собирать на карте, или вырабатывать солнечными батареями

                                                                                              Далее вы описываете алгоритм поведения каждого из ваших роботов: когда они будут искать ресурсы, когда атаковать, куда передвигаться, будут ли производить новые юниты — набор тактик неограничен.

                                                                                              Язык — довольно простой. API — тоже не сложный. «Физика» и экономика — неплохо сбалансированы.

                                                                                              Чтобы определить, кто сильнее, запускается симуляция — ваша команда против команд, написанных другими. Задача — убить всех противников, или дожить до конца битвы. Побеждает тот, чьих роботов осталось больше.

                                                                                              Вот скриншот битвы:
                                                                                              image
                                                                                                –1
                                                                                                Смотрю на код и не вижу что-то там фортоподобного?
                                                                                                  0
                                                                                                  Там всего лишь для читабельности добавили идентацию и переносы строк, которые парсер игнорит. Без этого было бы совсем плохо. Вот абсолютно эквивалентный код:
                                                                                                  ... do autoconstruct grenades-reload-time periodic-robot-sensor if robot-found if robot-position robot-velocity lead-grenade then then forever ...
                                                                                                  
                                                                                                    –1
                                                                                                    Как-то постфикса не наблюдаю :) понимаю, что извратиться можно так и на форте и писать 2 + 2, а не 2 2 +, но это будет уже не форт.
                                                                                                      +1
                                                                                                      В одной из ссылок, которую я дал в своем комментарии, есть следующий пример:
                                                                                                      What in a conventional language would be:
                                                                                                          gamma = 1 / sqrt(1 - (v / c)^2)
                                                                                                      is in Grobots:
                                                                                                          1 v c / square - sqrt reciprocal gamma!
                                                                                                      
                                                                                                        0
                                                                                                        Стилистически
                                                                                                         1 <hablabla...bla...bla> -

                                                                                                        это конструкция хуже, чем
                                                                                                         1 - <hablabla...bla...bla>

                                                                                                        потому, что
                                                                                                         <hablabla...bla...bla>
                                                                                                        вставляется внутрь выражения.

                                                                                                        Неконкатенативно.
                                                                                                0
                                                                                                Особенно «весело» выглядит в стековых языках конкатенация… хоть строк хоть списков…
                                                                                                  0
                                                                                                  А что с ней не так? Не думаю, что сильно сложнее или запутаннее, чем на любом другом языке получится.
                                                                                                    0
                                                                                                    В инфиксном виде она выглядит много более наглядно, чем в постфиксном…
                                                                                                      0
                                                                                                      new_string = "string 1" + "string 2";


                                                                                                      " string 1" " string 2" S+ TO new_string


                                                                                                      Особой разницы, вроде бы, и нет.
                                                                                                        0
                                                                                                        Разницы нет пока строк мало.

                                                                                                        " string 1"" string 2"+" string 3"+" string 4"+" string 5"+" string 6"+ new_string!

                                                                                                        Или, с соблюдением стиля

                                                                                                        " string 1" " string 2" + " string 3" + " string 4" + " string 5" + " string 6" + new_string !
                                                                                                      0
                                                                                                      Да, и при приклеивании головы к списку нагляднее, когда оператор с той же стороны, что и голова, а не с противоположной.

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

                                                                                                  Самое читаемое