Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Флейм > язык HQ9+ и его дальнейшее развитие


Автор: UniBomb 4.12.2009, 12:42
Добрый день. Сначала сопливая предыстория.

Началось всё очень давно, 20 минут назад. Я захотел создать интерпретатор/компилятор какого-нибудь языка. Я долго сидел и выбирал язык - хотелось создать чего-то полезное, чем могли бы пользоваться сотни тысяч человек во всём мире. Ещё хотелось чего-нибудь посложней - так сказать разминка для мозгов. Ну ещё и прославится конечно  smile Я рассматривал такие языки как C#, С++, java, ruby, haskel, lua, lisp, smalltalk. Но в итоге остановился на языке с романтичным названием http://ru.wikipedia.org/wiki/HQ9%2B 

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

Код

#include <iostream>

int main()
{
 char code;
 int some_counter(0);
 std::cin >> code;     
 switch(code)
 {
  case 'H': std::cout << "Hello world!" << std::endl; break;
  case 'Q': std::cout << code << std:: endl; break;
  case '+': some_counter++; break;
  case '9': 
           for(int i = 99; i > 0; i--)
            {
             std::cout << i << " bottles of beer. You take one down, pass it around "; 
             if(i-1)
              std::cout << i-1 << " bottles of beer on the wall." << std::endl;
             else
              std::cout << "no more bottles of beer on the wall." << std::endl;     
            }
 }
 return 0;
}



И тут я задумался - а ведь потенциал языка огромен, с его помощью можно делать намного больше. Посему предложение - а давайте вместе разовьём этот язык! Продемонстрируем весь неиспользованный потенциал! Не дадим забыть этот прекрасный язык!


Автор: kosmonaFFFt 5.12.2009, 07:35
ИМХО интерпретатор не очень, ибо нет возможности писать большие программы, например HQ999HHQQ++ smile Так что для начала надо бы заменить char code; на std::string program; smile

Автор: ~FoX~ 5.12.2009, 11:05
UniBomb, Для начала хотя бы дополнить до HQ9++ и HQ9+- ... А так же можно дополнить все это дело какими нить стандартными процедурами... например "2*2"...

Автор: GrayCardinal 5.12.2009, 15:19
На этом не прославишься. :(

Автор: UniBomb 7.12.2009, 09:26
kosmonaFFFt, это не интерпретатор виноват, а документация на язык  smile  Но зато уже есть первое расширение языка (точнее будет готово в обед (кстати можно назвать его обеденным языком или HQ9+ lunch edition)).


~FoX~, HQ9++ и HQ9+- не являются кошерными расширениями языка и заведомо ведут в тупиковый путь развития. Надо идти своим путём (ведь всем известно, что велосипедоводство спасёт мир). Насчёт "2*2" - не получится. Максимум "*2". Иными словами  - оператор "+" инкрементирует счётчик, так что по логике оператор "*" должен умножать его же. Если дополнить до всех команд, то можно получить следующее:

+ [value] - увеличивает счётчик на значение value, если оно не задано, то на единицу;
* [value] - умножает счётчик на значение value, если оно не задано, то на само себя;
/ [value] - делит счётчик на значение value, если оно не задано, то на само себя;
- [value] - уменьшает счётчик на значение value, если оно не задано, то на единицу;

Ещё чего стоил бы ввести - деление на ноль. Ну почему нигде нельзя делить на это замечательное число? Пусть хоть в этом языке это можно делать. Результат деления на ноль - операция не определённая, так что пусть эта конструкция возвращает рандомное число.

С другой стороны - действительно было бы неплохо доработать этот язык до Тьюринг-полного. Но тогда нужно будет вводить типы данных. Какие нужны в первую очередь?


GrayCardinal, невидимый тег irony для кого придумывали  smile 

Автор: RockClimber 7.12.2009, 11:23
Цитата(UniBomb @  7.12.2009,  09:26 Найти цитируемый пост)
Но тогда нужно будет вводить типы данных. Какие нужны в первую очередь?

Ну раз это lunch edition и под лицензией beerware - то и главные типы должны быть beer и lunch. А то как иначе определить, кто перед кем должен "ку" делать?

Автор: Shaggie 7.12.2009, 11:26
Цитата(GrayCardinal @  5.12.2009,  15:19 Найти цитируемый пост)
На этом не прославишься. :( 

А вот если доработать язык до HQ9#, то вся слава твоя будет! Посему первое, что надо сделать, это компилировать программу на нашем замечательном языке в LLVM-байткод.

Автор: ~FoX~ 7.12.2009, 11:28
Цитата(UniBomb @  7.12.2009,  10:26 Найти цитируемый пост)
Ещё чего стоил бы ввести - деление на ноль. Ну почему нигде нельзя делить на это замечательное число? Пусть хоть в этом языке это можно делать. Результат деления на ноль - операция не определённая, так что пусть эта конструкция возвращает рандомное число.

Деление на ноль возвращает бесконечность...В зависимости от деления на +0 или -0 вернется +бесконечность или -бесконечность соответственно...

Цитата(UniBomb @  7.12.2009,  10:26 Найти цитируемый пост)
С другой стороны - действительно было бы неплохо доработать этот язык до Тьюринг-полного. Но тогда нужно будет вводить типы данных. Какие нужны в первую очередь?

Нафига типы? пойдем по пути брейнфака! "<", ">" перемещаемся по ячейкам бесконечно ленты, S - записать данные L - прочитать данные из ячейки...Дальше как описано можно изощрятся...
Цитата(UniBomb @  7.12.2009,  10:26 Найти цитируемый пост)
+ [value] - увеличивает счётчик на значение value, если оно не задано, то на единицу;
* [value] - умножает счётчик на значение value, если оно не задано, то на само себя;
/ [value] - делит счётчик на значение value, если оно не задано, то на само себя;
- [value] - уменьшает счётчик на значение value, если оно не задано, то на единицу;

Нужно предусмотреть интерфейс куда все это дело можно выводить - экран, файл, принтер, поток етц. 

Автор: UniBomb 7.12.2009, 12:13
Цитата(~FoX~ @  7.12.2009,  12:28 Найти цитируемый пост)
Деление на ноль возвращает бесконечность...

Не совсем так. Деление на ноль вызывает неопределённость, а вот бесконечность получается при делении на бесконечно малую величину. В любом случае можно оставить рандом как фичу)))


Цитата(~FoX~ @  7.12.2009,  12:28 Найти цитируемый пост)
Нафига типы? пойдем по пути брейнфака!

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

Код

; 2 + 3

+2
01P          ;записали в ячейку 01   
0              ;обнулили счётчик
+3
+P01        ;сложили с содержимым ячейки 01



Цитата(~FoX~ @  7.12.2009,  12:28 Найти цитируемый пост)
Нужно предусмотреть интерфейс куда все это дело можно выводить - экран, файл, принтер, поток етц. 


ну так нет ничего проще)))

Код


S               ;вывели на экран по-умолчанию
L               ;сосчитали с клавиатуры по-умолчанию
S(printer)  ;вестимо понятно
S(file)  ;вестимо понятно



Цитата(Shaggie @  7.12.2009,  12:26 Найти цитируемый пост)
А вот если доработать язык до HQ9#, то вся слава твоя будет!

Ну вот так всегда - делаешь-делаешь что-то полезное, потом приходит GrayCardinal, дописывает в конце # и забирает себе всю славу :(


RockClimber, бир к ланчу - это профит, а не сущности в языке  smile

Добавлено @ 12:16
ё-мае, уже треть обеда просидел в этой теме, думаю не успею сделать всё в этот раз (((

Автор: ~FoX~ 7.12.2009, 17:27
Цитата(UniBomb @  7.12.2009,  13:13 Найти цитируемый пост)
, а если вместо ленты оставить один единственный счётчик (типа как аккумулятор), но с возможностью его сохранять в стеке. Ну т.е. как в асме:

Тока не в стеке, а в очереди  smile  FIFO в данном случае лучше LILO  smile 

Автор: UniBomb 7.12.2009, 17:42
Цитата(~FoX~ @  7.12.2009,  18:27 Найти цитируемый пост)
Тока не в стеке, а в очереди 


А может ну его, издевательство это?  smile  Может просто массив ячеек с произвольным доступом к любой из них?  smile

Добавлено через 2 минуты и 48 секунд
О, а пусть ещё эта ячейка может иметь произвольный тип данных  smile  В одной ячейки будет число, в другой строка  smile 

Автор: Zloxa 8.12.2009, 16:08
Друзья, по моему вы в своей фантазии несколько отошли от идеологии языка.

Язык - интерфейс взаимодействия программиста и вычислительной машины. Каждый язык надо рассматривать с двух сторон. Со стороны машины и со стороны программиста

Основная идея языка HQ9+ - позволить программисту очень просто осваивать те задачи, которые обычно ему трудно даются. Вспомните сколько времени у вас заняло написание самого первого хелловорда в вашей жизни.. Сколько времени ушло чтобы понять что присваивание и равенство - суть разные понятия. Сколько времени ушло на понимание что есть суть цикл. Как радовались когда "поняли" как этот код может воспроизвести себя сам.

Благодаря HQ9+, у начинающего программиста появилась возможность очень просто и быстро пройти эти фазы. HQ9+ дружественен прежде всего к программисту. Более того - к начинающему, мало опытнтному программисту.

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

Пытаясь развить HQ9+ заимствованием из BrainFuck вы губите обе идеи.


Я думаю HQ9+ обязательно надо дополнить рекурсией. Понимание рекурсии, обычно, требует от новичков много усилий. Классический же пример рекусрии - ханойские башни./*факториал, как пример рекурсии не интересен, потому что новичек, приступая к изучению рекурсии, обычно уже знает о циклах и понимает абсурдность решения факториала рекурсией*/
Думаю следующий шаг - HQ9+H
При вводе H, должна решаться задача ханойских башен с высотой башни равной текущему значению внутреннего счетчика.

Автор: SoWa 8.12.2009, 16:19
UniBomb, когда новую версию зарелизишь? ))

Автор: UniBomb 8.12.2009, 17:44
Zloxa, Ты не совсем нас понял. Та лёгкость, с которой HQ9+ позволяет решать задачи, стоящие перед начинающими программистами никуда не денется, а наоборот даже дополнится. Взять к примеру твоё предложение дополнить язык оператором H. Этот оператор добавится в ближайшую версию.

С другой стороны - у языка не имеющего недостатков (а вед все мы прекрасно понимаем - HQ9+ идеальный язык) может быть ещё непокрытые задачи. Так например тренировка мозга. Почему не научить человека не только справляться с задачами, но ещё и думать? Никто ведь не может сказать, с каким задачами придётся столкнуться начинающему гуру в дальнейшем.

А по поводу BrainFuck - приглядись - в нашем случае от брейнфака позаимствовано ровно столько, сколько в нём позаимствовано например от Java. 

И в качестве контр-аргумента скажу, что мы специально остановились на HQ9+, а не на HQ9+PSL. Это значит, что у нас рождается новый язык, в который мы закладываем новые идеи для всестороннего развития языка. А вот какой именно частью пользоваться - пусть решает сам программист. Ну и напомню, что наш язык называется HQ9+ Lunch Edition.


SoWa, со дня на день. Я столкнулся с некоторыми трудностями, но я работаю над собой.

Автор: ~FoX~ 8.12.2009, 18:24
Наверное большинство программистов в первую очередь сталкиваются с проблемой рекурсивного поиска файлов...
А еще начинающие, с присущим им максимализмом хотят написать самый злостный вирус во вселенной  smile  smile 

Автор: Zloxa 8.12.2009, 18:27
мой небольшой вклад в ваше дело.
реализация интерпретатора на SQL
Код

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 
Connected as common
 
var programm varchar2;
exec :programm := 'HQ9+';
 
PL/SQL procedure successfully completed
programm
---------
HQ9+
select
 sum(decode(cmd,'+',1,0)) over (order by s.rn) some_counter
 ,coalesce(decode(cmd,'H','Hello World')
           ,decode(cmd,'Q', code)
           ,bob
           ,decode(cmd,'+',null,1/0)
          )
   output
from (
  select
    level rn
    ,substr(:programm,level,1) cmd
    ,:programm code
  from dual
  connect by substr(:programm,level,1) is not null
 ) s
left join (select level rn,100 - level || ' Bottles of Beer on the Wall' bob from dual connect by level < 100) b
       on cmd = '9'
order by s.rn, b.rn;
 
SOME_COUNTER OUTPUT
------------ --------------------------------------------------------------------------------
           0 Hello World
           0 HQ9+
           0 99 Bottles of Beer on the Wall
           0 98 Bottles of Beer on the Wall
           0 97 Bottles of Beer on the Wall
.
.
.
           0 4 Bottles of Beer on the Wall
           0 3 Bottles of Beer on the Wall
           0 2 Bottles of Beer on the Wall
           0 1 Bottles of Beer on the Wall
           1 
 
102 rows selected
programm
---------
HQ9+

Автор: UniBomb 6.9.2010, 17:15
Ха-ха, вы думали я забросил это дело? Нет! Я всего-лишь немного пересмотрел систему ценностей и решил применить несколько иной подход.

В общем как бы то ни было, вот вам исходник:

Код

lexx = 'h'
counter = [0]
index = 0

loop do
    print "> "
    tokens = gets.chomp
    break if tokens == ''
    
    lex = tokens.split
    
    for lexx in lex do
    
        case lexx
            when "h"
                puts 'Hello world!'
            when "q"
                puts tokens
            when "9"
                101.times do |i|
                    if i < 100 then
                        puts "#{100-i} bottles of beer"
                        puts "you take one down, pass it around"
                    else
                        puts "no more bottles of beer on the wall."
                    end
                end
            when "+"
                counter[index] += 1
            when "-"
                counter[index] -= 1
            when "d"
                index -= 1
                if index < 0 then
                    inde = 0
                    puts "Error: out of range index"
                end
            when "i"
                index += 1
                if counter.length == index then
                    counter << 0
                end
            when "r"
                puts counter[index]
            else
                puts "Error: Unknown token \'#{lexx} \'"
        end
    
    end
end


Интерпритатор написан на ruby. И кстате - почему нет его подсветки. В общем о нововведениях можно рассказывать часами, небольшая программа скажет всё сама за себя:


Код

+ + + + + + + r + + + i + + + r + + h d q r 9 - r

Автор: diadiavova 6.9.2010, 17:18
Цитата(UniBomb @  6.9.2010,  18:15 Найти цитируемый пост)
Ха-ха, вы думали я забросил это дело?

Ну не то чтобы думали...скорее надеялись smile 

Автор: UniBomb 6.9.2010, 18:36
Цитата(diadiavova @  6.9.2010,  18:18 Найти цитируемый пост)
скорее надеялись

 smile  smile 

Автор: Zloxa 16.3.2012, 12:29
Цитата(UniBomb @  7.12.2009,  13:13 Найти цитируемый пост)
. Деление на ноль вызывает неопределённость, а вот бесконечность получается при делении на бесконечно малую величину.

Мне кажется деление на ноль лучше реализовать выводом фразы "стою себе, делю" в количестве, равном значению счетчика. Тем самым мы введем в язык новый функционал и потдержим старый. Тогда можно будет депрекатнуть команду "9" и рекомендовать использовать вместо нее команду "0"

Автор: LSD 16.3.2012, 12:36
Цитата(Zloxa @  16.3.2012,  13:29 Найти цитируемый пост)
Мне кажется деление на ноль лучше реализовать выводом фразы "стою себе, делю" в количестве, равном значению счетчика. Тем самым мы введем в язык новый функционал и потдержим старый.

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

А тут уже появляется возможность какого-то применения.

Автор: UniBomb 17.7.2025, 19:17
Столько воды утекло со времени последнего релиза. И пусть человек еще не ступил на поверхность марса, работа над идеальным интерпритатором продолжается. И пусть уже и надеятся некому, встречайте, новый релиз. Теперь на питоне. Ура, товарищи!

Код

def interpret_hq9p(code: str):
    acc = 0
    output = []
    
    def generate_flooders_song():
        lines = []
        for n in range(99, 0, -1):
            if n == 1:
                line1 = "1 flooder writing comments in the sandbox!"
            else:
                line1 = f"{n} flooders writing comments in the sandbox!"
            
            if n == 1:
                line2 = "He went to the real world... the sandbox is empty!"
            else:
                remaining = n - 1
                if remaining == 1:
                    line2 = f"One went to the real world, {remaining} flooder remains..."
                else:
                    line2 = f"One went to the real world, {remaining} flooders remain..."
            
            lines.append(f"{line1}\n{line2}")
        
        lines.append("The forum is empty.")
        return "\n".join(lines)
    
    flooder_song = generate_flooders_song()
    
    for char in code:
        char = char.upper()
        
        if char == 'H':
            output.append("Hello, world!")
        elif char == 'Q':
            output.append(code)
        elif char == '9':
            output.append(flooder_song)
        elif char == '+':
            acc += 1

    output.append(f"Accum is {acc}")
    print("\n".join(output))

if __name__ == "__main__":
    program = input("_> ")
    interpret_hq9p(program)

Автор: LSD 13.8.2025, 16:59
Это надо на Гитхаб залить, настроить релизы, документацию написать.

Автор: UniBomb 18.8.2025, 17:07
LSD, пока рано. Я всё еще не нашёл идеальный рецепт интерпретатора этого замечательного языка. Покуда я играю с формой, я могу поделиться только с близкими. Рано еще миру показывать

Добавлено через 14 минут и 47 секунд
Как видишь, поиск идеального интерпретатора дело небыстрое, медитативное. Тут не нужна спешка.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)