Заспорили мы однажды с Хейзером…
… А можно ли сделать игру на декларативном языке программирования?
В университете это было примерно так
Единственным декларативным языком программирования, на котором я программировал некоторое время, был Пролог (об уникальности коего можно читануть на Хабре, и на нём же ещё подробней). Что до Хейзера, то не знаю — пусть он сам нам поведает, какие языки ему были известны. Только не «просто известны», потому что слова «Хаскель» и «Лисп» я тоже знаю. А известны на практике, и опять же не примерно, а в реальной задаче, желательно всё-таки где-то возле программирования компьютерных игр.
Сошлись мы тогда на том, что если я создам 3Д-шутер на декларативном ЯП, то Хейзер будет должен мне купить лицензию на Гамак. Думаете, я остался доволен этим уговором? Нихрена подобного.
Естественно, никакого 3Д-шутера я не написал, а лицензию на ГМ Студию получу через недавний Humble Bundle, когда сайт ЙоЙоГеймс наконец-то перестанет виснуть от бешеного потока желающих прикупить лицензию за жалкие 12 долларов.
Объяснять разницу между декларативным и императивным программированием я не считаю нужным — достаточно констатировать, что первое не пользуется какой-либо особой популярностью в геймдеве. «Так в чём же суть?», спросите вы.
Суть в том, что Хейзер плохо очертил вопрос, который нужно решить. Вот есть игра на Гейм Мейкере (8.1, до-Студийный). Сам раннер (интерпретатор) ГМ написан на Дельфи, DirectX и прочее — на C/C++, хотя местами возможно тоже на Дельфи, а игра тем временем интерпретируется из скриптового языка GML, который Game Maker Language. На чём создана игра? На GML.
Это значит, что, подключи я DirectX/OpenGL (а там на пару и какой-нибудь аудио-движок) к Прологу, я бы уже получил прототип игры «на Прологе». Это конечно был бы ещё не шутер, и много возни было бы с 3Д — но эта возня была бы с любым языком, в любом движке. Чисто техническая не-языковая проблема, не теоретическая. Описать логику игровых объектов простенького шутера я могу легко, у них там всего пара состояний в зависимости от которых они меняют свой внешний вид, появляются и исчезают. Хейзер-то небось думал, что я должен буду писать драйвера (что было бы полным провалом на Прологе) — но я по такой постановке вопроса делать этого вовсе не должен.
Соответственно задачу считаю тривиальной, и спор — концептуально решённым в мою сторону.
Впрочем, разрабатывать 3Д-шутер на Прологе — всё ещё сомнительная идея.
Так дело не пойдёт.
Это нихрена не значит. Потому что непонятно как подключать. Можно ли вообще создать какие-то интерфейсы для этого дела?
Я понимаю откуда ноги растут — дескать Гамак юзает диркетиксы и кучу готовых либ для рендера. Но игровую логику создаёт разработчик в среде GML. Ты что, готов создать игровую логику в среде prolog? Клавиатура не треснет, а?
Спор будет решён в твою сторону когда ты мне покажешь 3Д шутер и скажешь «он сделан на прологе». Тогда я вдоволь наудивляюсь, вращая глазами в разные стороны, и побегу пытать разработчика не тему «КАК». А так какой смысл в твоём решении. Выглядит как «приладим вот это сюда, вот тут как-то так, ну и всё, последний пинок и заработает». У меня после этих мыслей на практике обычно «А оно нифига не так!», «А это почему не фурычит?», «А я то думал, сработает».
Давай тезисно, растекаться мыслью по древу мы все умеем.
Непонятно как подключать? Смотри:
OpenGL + Пролог есть? Есть. Значит как-то да подключается.
Игровая логика может оказаться на Прологе даже проще, чем на GML, особенно в областях ИИ и логических задач. Согласен, крестики-нолики в 3Д это не шутер. Вопрос — что именно ты понимаешь под 3Д-шутером, что ж там такого непрограммируемого декларативно?
Я понимаю 3Д-шутер так:
Приведи мне конкретное проблемное место.
Для начала нужно понять есть ли в прологе ООП. Парадигма-то у пролога декларативная, т.е. совсем другая. Как ты собрался эти объекты реализовывать? Я сам с прологом работал, но лет 5-7 назад. Так что не очень помню конкретный синтаксис. Но по идеологии они не отличается от поиска в базе данных. То есть программист задаёт шаблон при помощи языка, а язык при выполненни команд выдаёт результат по шаблону. Твой набор действий нихрена не декларативный.
Термины должны быть в духе «повреждённый враг», «прыгающий игрок» и т.д. Ты оперируешь состояниями объектов.
Prolog++
Logtalk
Костыль для подключения Пролога с помощью C++
Я тебе список составляющих игровой механики приводил, а не набор действий. Тем более это не список того что прямо пишется в исходный код, ни на Прологе, ни на GML. Я у тебя спросил — как ты видишь модель 3Д-шутера, и попросил привести проблемное место. В ответ я получаю что-то вроде «Ты не прав, а проблема везде».
Как ни странно, Пролог оперирует литералами предикатов ничуть не хуже, чем GML состояниями объектов — и то и другое это просто переменные, принимающие какие-то величины. Просто в Прологе обычно ищут строковый осмысленный ответ на запрос, а вычисления типа i=i+1 и состояние=следующее(состояние) являются в нём побочными, но не являются невозможными в принципе.
Проблемное место конкретно в описании игровой логики декларативно.
Сказал — как в лужу пёрнул.
Ну так давай покажи что её нет этой проблемы. Пока что ты даже не придумал как декларативно описать объекты, как опсиать состояния их и переход от одного состояния к другому.
В том что отрицающая теория в 99% случаев более сильная. Проще сказать что что-то невозможно. Поэтому я и принял такую удобную позицию с которой методично поплёвываю. Т.к. этот случай как раз в этих 99%. Ччтобы доказать возможность создания чего бы то ни было — нужно это создать.
Как бы тебе объяснить. Вот допустим мы бы поспорили о возможности создания из мухи слона. Ты говоришь что-нибудь в духе:
Как бы как раз то что ты называешь «хлопотно», «я не нерд» и т.д. — это то самое интересное. И не факт что оно получится. А так то конечно легко сказать что ты не собираешься выполнять тяжёлую работу и дескать ты потому и победил.
Поэтому я сказал что спор концептуально решён в мою сторону, а не что я победил.
Так как игру на Прологе уже создали, и не одну, что ты можешь видеть по ссылке, то просто поплёвывать с твоей позиции уже не получится.
Но я тебе могу облегчить задачу. Плюнь пока на пролог. Попробуй придумать сперва как написать 3Д шутер на регулярных выражениях. Это тоже декларативный язык и его логика проще. Ну или что совсем близко было бы тебе, наверное можешь подумать ту же самую задачу на SQL.
Собственно, декларативные языки — это по факту языки запросов, которые заточены на поиск в поле информации. Я не знаю как с такой семантикой можно писать игровую логику шутера.
Ну так покажи. Вот у тебя есть строчки, есть регулярные выражения которые ты знаешь как работают полагаю. Ты можешь применять к строчкам эти выражения и что-то получать. И то что получишь можешь использовать дальше или же передавать в какую-то функцию для визуализации. И по факту — твоя программа — последовательно применяемые выражения к каким-то строчкам которые ты можешь где-то хранить, допустим.
Вот и вопрос теперь как ты будешь в строчках представлять свои объекты? Как ты будешь составлять выражения и гарантировать что получишь нужный результат?
Что значит «как работают регулярные выражения»? Регулярные выражения никак не «работают», это форма записи и способ парсить то или иное из вводимых данных. Ты наверное имеешь в виду форму Бэкуса-Наура? В любом случае непонятно зачем мне отвечать на этот сторонний вопрос.
Гарантировать нужный результат это не моя задача, а задача целой теории нахождения резольвенты - о том, как Пролог ищет противоречия в высказываниях. Уж если Пролог используют для автоматизированного доказательства теорем, в чём ты конкретно тут хочешь усомниться? Наоборот, декларативные подходы славятся своей «очищенностью» от сторонних состояний и порчи глобальных переменных. Во всяком случае, когда программа действительно написана — а написать её сложней, чем в императивной парадигме.
Ну вообще там есть что-то типа присвоения величины пременной =) Это очень хитро реализовано. Что-то в духе запоминания позции последнего поиска. Я примерно год назад штудировал регулярки потому что мне нужно было распарсить ОЧЕНЬ хитрый документ. Получались конструкции в духе:
<big","(?:.*?<big>|\G)[^<]*?(?:<pic>([\d\w_\.\-\+\s]+?)<\/pic>[^<]*?<\/big>\z|<pic>([\d\w_\.\-\+\s]+?)<\/pic>)
Там было что-то типа выбрать все тэги pic внутри тега big. Количество тегов pic и big непредсказуемо. Отюсда как раз всплывают управляющие символы \G и \z. Которые правда не во всех реализациях regex есть.
Номера встреченных паттернов — это совсем не то!
Тут речь идёт о том что функция regex_match находит ВСЕ паттерны. Если пользовать её в стандартном виде. То есть при анализе строки она будет идти по ней и говорить «вот тебе один, вот тебе второй и т.д.». Вся сложность в том, чтобы оно говорило «так, я внутри big и вот тебе один», «вот тебе второй», «так я теперь не внутри big и это не считается». Вот в чём обычно проблема — распознавание кусков внутри кусков без дробления строки исключительно синтаксисом regex. А в моём случае искуственное дробление строки было недопустимым.
Это не просто XML, а салат из нескольких XML. Задача была в синхронизации информации со складами поставщиков. То есть нужно ежедневно брать файлы у поставщиков и обрабатывать. Основная проблема — способ представления информации у всех разный, а порой ещё и запутанный, т.к. инфа по одному товару может быть размазана по нескольким XML. А может прилететь от поставщика и вовсе не XML, а какой-нибудь CSV или SQL-дамп.
Обработка происходит в два этапа.
На первом — действительно разбираются XML файлы при помощи парсера, но тут скорее выделяются общие куски по товарам. Вычленять отдельные параметры здесь довольно хлопотно. К тому же есть ограничение на время работу скрипта. Поэтому и нужна данная обработка для того, чтобы рассортировать инфу по товарам.
Затем этот винегерет сваливается в пул-таблицу из которой парсер CRON-скриптом одинаковым образом обрабатывает все товары последовательно из этой таблицы. Берётся товар и к нему применяется пачка регулярок для этого поставщика. На выхлопе я сразу получаю нужный массив, который отправляется в апдэйты по товару. Сам товар после обработки удаляется из пул-таблицы.
Возможно, это не самая эффективная организация с точки зрения производительности, но она более эффективна с другой точки зрения. Собственно, раньше-то как раз и произодился разбор каждого XML-я своим парсером. Но практика показала что у такого подхода плохая отказоустойичость. То есть если прилетел кривой XML (а такое бывает регулярно) — то он и сам не разобрался, и другим не дал, а если ещё и инфа напрямую с него в БД пишется то полный абзац может настать. Обновления товаров на сайт не приехали, менеджеры бегают в панике. А при такой реализации XML может сколь угодно кривой приехать и ничего не случится. Навернётся только скрипт-разобрщик для XML-ей конкретного поставщика. Ну в пул-таблицу не приедут для него товары. Зато всё остальное работает. Но самое лакомое — при добавлении нового поставщика в систему синхронизации(а такое уже было несколько раз) достаточно написать несложный XML-парсер для первоначального разбора и пачку регулярок. Всё остальное обрабатывает данные универсальным образом и хорошо отлажено. Если у поставщика меняется формат XML (добавляются новые параметры, например) то изменения вносятся обычно только в список регулярок, а не в XML-парсер.
Эта система работает уже целый год. И очень хорошо автоматизировано работает на слабенькой машине. В первые месяцы приходилось кой-чего подшаманивать, конечно. На правах отладки. Но где-то полгода я к ней уже вообще не прикасаюсь.
Так а может надо было просто обернуть всё в try-catch? Или в чём конкретно тут решение? На чём написано?
Вот это немного странно. Пусть бы падал только тот, что кривой, зачем остальные-то ронять? Регулярки же почему-то не роняют при тех же условиях.
Потому что ту конструкцию реализовал не я и обработка всех XML-ей была одним php-скриптом.
Так регулярки распарсивают уже раздробленный на первом этапе XML. И если падает кусок регулярки то не обрабатывается всего один товар из выгрузки, а не вся выгрузка.
Если обрабатывать всё разом, то придётся ловить экспешены (на PHP-то LOL) и то нет гарантии что скрипт откажется работать по какой-то другой причине. Поэтому я всё это максимально разделил и затолкал в расписание crontab. Чтобы если падал php-скрипт, то его падение не причиняло бы ущерба, потому что по CRON расписанию вскоре запустится новый и он будет где-то там себе падать до тех пор пока от поставщика не приедет нормальный XML. Но это уже проблемы поставщиков что они там подсовывают.
Когда лишних сущностей не было и разбиралось всё XML-ями, и потом заталкивлось в базу товаров напрямую… Оказалось, что слишком много сбоев часто роняет систему. С этой целью и были введены промежуточные этапы и пул-таблица.
Почему не язык программирования? Что такое язык программирования по-твоему?
Я не знаю можно ли живой писькой танк проткнуть. А ты мне смело можешь сказать:
Вот как выглядят примерно твои слова. Без практики это пустой сотрясание воздуха. Мы же не о сущестовании бога теоретизирем, а о том что можно проверить экспериментом. Ну допустим не 3Д шутрер, попробуй для начала описать как ты декларативно будешь описывать простейшую игровую логику. Бег с препятствиями, например. Канабалта того же. Реализация на прологе, регулярках или сиквеле =)
Так ты это погоди. Речь шла именно о 3Д-шутере, а теперь ты его низводишь в класс задачи типа «создать раннер»? То есть по-твоему тогда получается что в декларативной парадигме вообще нельзя создать никакой реалтаймовой нелогической игры? Или какой класс игр ты хочешь выделить? Шахматы там сделать можно, я тебя уверяю, да и сам ты наверняка об этом догадываешься.
Мы как-то с тобой неправильно спорим. Вот есть список, нарытый нашим местным динозавром: (я не забыл про Андроид, скоро наконец получу нормальную машину)
Внимание — что «делает игру»? Да ничего её такого удивительного не делает, что требовало бы ООП или каких-то современных измышлений и обёрток. Как делали игры до ООП? Они что, были не реалтаймовыми? Или не играми? Но ближе к теме...
Итак — на Прологе нельзя написать Арканоид по-твоему? (ну или Канабальт, если в твоей формулировке)
Ну давай разберём по частям тобой написанноеАрканоид состоит из 2-мерного массива кирпичей, координат шарика (шариков), координат и размера платформы игрока, координат бонусов, и больше толком ни из чего.
Массивов в Прологе нет — там есть списки, реализованные как частный случай бинарного дерева (это не имеет никакого значения для рассматриваемой проблемы), соответственно для двух измерений используем список списков.
Циклов в Прологе нет — там есть рекурсия, соответственно используем рекурсию рекурсии.
Операции сложения, вычитания, сравнения переменной с числом (проверка коллизий же) — в Прологе есть.
Связку с OpenGL я уже привёл выше.
Твои аргументы?
Мои аргументы — заставить это работать. Наличие всех ингредеиентов ещё не гарантирует что салат будет съедобным и что вообще будет какой-то салат.
Вот выше ты правильно танцуешь. Если я увижу хоть одну реалтаймовую игру на прологе (арканойд, канабалт и т.д.) то до 3Д шутера уже можно дотеоретизировать. Но у меня сомнения в том, что получится вообще записать игровую логику декларативно да ещё и сделать саму игру чтобы работало.
В приведенном мной выше Logtalk есть и ООП, и даже «event-driven programming», то есть по теории всё «как в GML», только синтаксис другой.
Вот тебе пример исходников игры с игровой логикой написанной на Logtalk. Вывод — декларативной логикой можно описать игровую логику. Принципиальной разницы между реалтаймом и походовым хождением в текстовой строке нет — нужно всего лишь технически добиться запуска процедур, обрабатывающих один шаг, 30, 50 или там 60 раз в секунду. Ты, я думаю, это прекрасно знаешь.
Эта игра, кстати, древний прародитель нашей с Эсдиром (а потом и Дрейком) игры Castle of no Escape. И соответственно также Замка Лейгрефа - игры, от которой я отталкивался при создании.
Ты путаешь декларативные и предметные языки (DSL), которые заточены на какую-то предметную область, вроде тех же запросов. Большинство вторых являются первыми – потому что так действительно удобнее. Тем не менее, полно и декларативных языков общего назначения – и логических, как пролог (правда, они всё-таки узковаты), и особенно функциональных (хаскель, эрланг, некоторые лиспы), на которых можно сделать как минимум всё то же, что и на каких-нибудь C++ или Java.
Могут. Одни «ленивые последовательности» чего только стоят. Ну да ладно.
Только вот загвоздка — «новые уровни абстракции» означает что если раньше исходиники на С++ были просто тяжело читаемые, то «новые уровни абстракции» превращают наш код в соврешенно сумасшедшую ахинею. Потом собирается толпа программистов и думает над тем как работает очередная закорючка
В общем-то с одной стороны функциональное программирование позволяет писать меньше кода, но количество скрытого смысла не единицу языка растёт экспоненциально при этом. Не каждый мозг способен при такой смысловой нагрузке адекватно использовать всё то, что даёт функциональный язык.
Скорее дело в мышлении. Тяжело перестроиться, когда изучаешь функциональный язык после императивного.
соврешенно сумасшедшую ахинею.
О да, и все это для того, чтобы подружить императивность и функциональность. Одно функциональное реактивное программирование чего стоит. Про монады вообще молчу. Хотя при правильном подходе все выглядит прилично, вроде как.
Зато на этих «новых уровнях» становится очень весело.
Честно пытался понять что-то из этого.
Нет, это за гранью добра и зла. Особенно про moeb-loeb.
Ндык пиши на ассемблере, там никаких сумасшедших абстракций. Алсо, тот же хаскель гораздо проще C++.
Даже если это правда ([citation needed]), тащемта вся прелесть в том, что влазить в этот скрытый смысл не нужно, на то они и абстракции.Дело не в этом даже. Хороший язык — тот который близок к естественному и к естественному мышлению. Ассемблер слишком техничен для понимания. А функциональные языки слишком далёки от естественного мышления.
Ну вообще в этот скрытый смысл влазить всегда нужно, чтобы понимать как оно работает. Какой толк использовать абстракции если не знать как они работают и для чего они нужны?
ВСЕ языки программирования далеки от естественного мышления. Можно подумать, императивные ближе, с их-то микроменеджментом.
А что, ты каждый раз следишь, во что превращается твой код, чтобы понимать, как оно работает?
Разумеется, тут соглашусь, что понимать абстракции важно, но понять их достаточно один раз, а дальше спокойно применять, а разбираться только в тех редких (если абстракция хорошая) случаях, когда они начинают течь. И тут функциональные абстракции ничуть не хуже, чем любые другие.
Ну вообще-то ООП концепция для того и создавалась чтобы быть ближе к естественному мышлению. Люди оперируют образами. Классы и есть эти образы.
ООП — это парадигма близкая как человеку, мыслящему в предметах того, что «осязает» — объектов и их свойств, так и машине, как не сложная в понимании абстракция над процедурным. Эта взаимная «близость», золотая середина, и определила ее популярность.
Функциональная парадигма — это не просто на один уровень абстракции выше, это еще и смена парадигмы на такую, что не понятна ни человеку, мыслящему императивно, от задачи, ни машине, «мыслящей» императивно в силу природы ее создания императивно мыслящим человеком. То есть применима в задачах, императивным путем не решаемых (экспертные системы, математический анализ). Но в задачах, легко алгоритмизируемых человеком, она превращается в интуитивно не понятный ребус.
По моему мнению, нет градации «хороший\плохой», есть «удобный\неудобный».
Мне очень нравится Хаскелл, стараюсь прикладные задачи (не игры), реализовывать на нем. Когда перестроишь свое мышление, становится очень удобно программировать. И да, он дает множество новых способов более элегантно решить старые проблемы.
Но возникает другая проблема: удобность сред разработки и документации. Здесь C# и прочая уделывают все ФП вместе взятое. Попробуйте под Windows настроить Gtk для Haskell и написать пример интерфейса! После копания в кучах устаревших мануалов находишь пару строк актуальных примеров.
А для того же C# в Unity есть автодополнение, рефакторинг, и самое главное — актуальный и подробный мануал.
В итоге, при разработке более серьезных проектов (того же 3D) Хаскелл остается уделом посвященных. Но, повторюсь, лишь из-за скудности документации и отсутствия внятной среды разработки.
Не надо забывать еще про фреймворки над языком. Меня не хватило на платформер на Love2D, например.
Ты всё хорошо объяснил и я сам примерно такого же мнения. Среды, документация и поддержка платформ — важный фактор в игровой индустрии, т.к. обеспечивают скорость разработки и распространение проукта.
Но ведь функциональные языки не являются изобретением сугубо 21-го века. Тот же Lisp и C++ почти ровесники. Вот и вопрос, если бы они лучше подходили для решения большинства задач — почему для них за все эти годы не создали нормальной поддерживаемой документации и IDE? Что этому мешало? Почему выбор человечества пал не на них?
Вот, допустим есть Javascript, на котором можно писать в функциональном стиле. Этот язык используется в Unity. Вот и вопрос — почему именно он, а не Haskell или Lisp?
В этом я с тобой согласен.
Но если бы на заре программирования все повернулось в сторону функционального программирования, я уверен, мы бы сейчас сидели в UnityFP и Gλme Mλker. Но это уже к первому варианту.
Извини, но ты не разбираешься в том, что пишешь.
1. Нет языка Lisp, есть целое большое семейство лиспов, похожих синтаксически, но разных семантически. Первый LISP был в 1960-м. Common Lisp, который нынче чаще всего подразумевают под лиспом, таки ровесник C++.
2. Лиспы не функциональные, точнее, не эксклюзивно функциональные, как хаскель. Они поддерживают ФП, но ровно как и все прочие парадигмы. Сильнее всего на нём акцентируется весьма молодой Clojure.
3. Точно так же, лиспы и объектно-ориентированные. CLOS, Common Lisp Object System – возможно, самая мощная ООП-система эвар.
4. Если ты не знаешь про IDE, это не значит, что их нет. Для CL есть коммерческие LispWorks и Allegro, есть Emacs+Slime (бывалые лисперы говорят, что традиционные IDE и рядом не стояли, не знаю, не пользовался).
5. Про выбор человечеством – почему оно также выбрало джаву, PHP, Одноклассников, органик-еду и Дом-2? Тому есть множество причин, и качество и полезность продукта – далеко не первая из них.
А ты пользовался этими IDE?
К сожалению, в случае с Haskell не все так гладко. Решил писать не в Notepad++, зашел в нет: «Ого, как много разных IDE! Попробую-ка самую рекомендуемую». (Это была EclipseFP) Через пару дней чистого программирования (вывод консольный) все относительно ок. Как я писал раньше, решил сделать интерфейс, нашел gtk3, начал подключать, и понеслось...
Библиотека требовала посторонних утилит и танцев с бубном (из 10 руководств в интернете по установке - 9 устаревших), и на ее установку я потратил два дня. Что потом? Повисла IDE с концами.
Установил новую IDE (Leksah), та висла и просто так.
А, ну еще FP Complete, редактор которой работал (он встроен в веб-страницу), а серверы которой мне не отвечали и не давали сохранять проект.
Вернулся к Notepad++ и WinGHCi (интерпретатор под Windows, идет вместе с компилятором в сборке Haskell Platform). Интерфейс там еще не писал.
К чему я веду. Здесь Hrenzerg прав — все выглядит красиво со стороны. А подводных камней куча. Спор зашел до точки, когда нужна практика в подтверждение, а не только теория. А тут ты проигрываешь, как я понимаю.
В том что я пишу — я разбираюсь, но не настолько глубоко насколько тебе бы хотелось это так. Сообщество программистов — это далеко не быдло, а люди в подавляющем большинстве сообразительные и с хорошим образованием, и ИМЕННО ОНИ выбрали те или иные пути развития сферы программирования. Поэтому эти аналогии совсем неуместны.
Ладно, если тебе не нравится пример с LISP-ом. Тогда возьём возлюбленный ваш Haskell. Историческая справка гласит что он появился в 1990 году. То есть 25 лет назад. Так что списывать на молодое сообщество смысла нету. А тот же JavaScript появился в 1995-ом.
Вопрос примено тот же: Почему в Unity использовали C#, непонятный и мало известный BooScript, Javascript, а не Haskell?
Я к чему всё это пишу то. Придерживаюсь мнения что эффективность разработки склоняет к выбору тех или иных средств гораздо сильнее чем другие факторы. И если Хаскель за 25 лет не был выбран основным языком для разработки видеоигр — значит на то были причны и вряд ли они они кроются в отсутсвии документации и хорогих IDE. Если бы он был годен — это всё привалило бы само собой.
Да погоди ты про видеоигры, давай хотя бы просто про программы. Первые ведь частный случай вторых.
Я лично в жизни не видел ничего в работе ни одного университета, библиотеки и офиса где я был, что было бы написано на Хаскеле. Может, оно всё секретное? Не знаю. Я видел программы для работы с БД, написанные на Pick/BASIC. Видел TCL (не тот, а этот). Но никогда не Хаскель.
Мейнстримные серверные Джава-апплеты и прочее я не называю, это и так понятно.
93 из 10 на нём сделаны. А Хаскель?Извини, имелось в виду «ты не разбираешься в теме, которую критикуешь», но ведь правда же.
Программисты – свободное небыдло… да, да, хотелось бы мне тоже так думать. (тут должна быть фотка типичного индусского кодера). Начинающие программисты ничего не выбирают, а берут что оказалось под рукой (какой-нибудь BASIC с ZX Spectrum) и чему их научили в школах (си, паскаль), а дальше десяток лет идут по проторенной дорожке, а потом говорят «Нам проще выучить джаваскрипт, чем хаскель, поэтому виноват хаскель».
Хотя… почему опять съехали с темы на детали, при чём тут вообще хаскель?! Это изначально академический язык с довольно специфичной семантикой, естественно, для игр он не оч. Речь была про декларативщину VS императивщину вообще. А основным языком для разработки видеоигр 25 лет были си и сиплюсплюс, которые вовсе не отличаются эффективностью разработки, и для которых ровно так же нет ни удобных игроIDE, ни даже редакторов формочек.
Ну так нчинающие программисты и не создают фрэймворков и других ЯП. Историю то творят люди толковые. Впрочем и это не аргумент если говорить о начинающих людях. Народ с удовольствием переучивается с прочих ЯП-ов на C# и Javascript чтобы срздавать игры на той же Unity. Эффективность разработки сильнее чего бы то ни было ещё.
Я считаю что если бы появился чел который бы сделал на хаскеле рилтаймовую стратегию за неделю, а затем появлился бы ещё один такой чел — народ бросился бы учить хаскель. Но такие чудеса происходят почему-то не с хаскелем, а с Unity и GameMaker.
То что программисты привязаны к одному и тому же языку — это уже несколько лет как миф. Всё больше и больше людей готовы изучать более эффективнын новые решения. Потому что это мир капитализма. Если твой конкурент проще и быстрее пишет программы на Хаскеле — значит и ты вскоре будешь писать на Хаскеле. А за тобой и другие господа. Какой смысл работать с менее эффективным инструментом себе в убыток?
Почему мы всё время съезжаем на Хаскель поясню. Мне очень не понравилась твоя агтитаця:
Прозвучало как «нормальные люди давно делают игры на Хаскеле, а вы — быдло, до сих пор юзающее ООП». Так что вся моя агрессия направлена против этой мысли. Потому я и пытаюсь выяснить если это так, то где тому подтверждения на «историях успеха»? Я, как и большинство людей примитивно устроены по описанной мной выше схемы «Если твой конкурент проще и быстрее пишет программы на Хаскеле — значит и ты вскоре будешь писать на Хаскеле.»
Я пытаюсь выяснить «если это всё действительно так круто, давайте покажите мне как это круто работает на практике чтобы я мог пощупать». С Unity у меня так и было. Я в то время давно видел эту штуку, но тем что на нём было сделано не особо впечатлился. А потом я увидел игру Rochard и за полгода освоил новый инструмент.
А пока что я слышу только «Вы недостаточно умны чтобы всё это понять, чтобы понять всю крутизну этого подхода, понять что делать становится проще и быстрее». Разумеется, мне это не нравится. Да ещё и в некомпетентности обвиняют :C Если программисты на Хаскеле пытаются ТАК замотивировать программистов начать осваивать новые абстракции… Как это не очень метод, не находите?
Здесь ещё поясню. Имеется ввиду и сфера деятельности. Я уверен что есть некоторая сфера в которой такое с хаскелем произошло. Кто-то увидел что задача решается им хорошо и аналогичные задачи начали решать им. Но в мире игр такой революции не было. Но согласно той цитате про размахивание ООП выходит что она была эта революция, а её все пропустили, так что ли?
Может быть. Но мне показалось, что имело место следующее:
1) Юрри увидел как мы тут «на ООП делаем игры»
2) Он сказанул типа «Зачем вам для игр ООП, когда есть крутые компонентные системы? Да и тут ещё на хаскеле можно много чего сделать». Правда непонятно Хаскель последовал просто за компанию или действительно в контексте разработки игр. Но я воспринял как второй вариант.
3) Тема набухла комментами под напором моей ярости.
Эм.
Ксит спросил «новые возможности, выходящие за рамки «каких-нибудь C++ или Java», могут ли нам пригодиться в контексте геймдева?», я привёл несколько разнообразных примеров из разных языков, из которых хаскель-специфик ровно один, и из этого вдруг следует, что я пропагандирую его для геймдева? Ну извините.
Тогда я не понял зачем мы вообще все эти говна здесь натоптали. На мой взгляд всё должно было бы пройти по следующему сценарию:
1) Я сурово вопрошаю «Кто посмел эффективно делать игры на Хаскеле? Быстро показали мне как вы это делаете!»
Далее два варианта:
2.а) Мне быстро приводят живой пример или историю успеха или рецепт из трёх пунктов. Я затыкаюсь и иду изучать материалы.
2.б) Мне говорят «ну вообще никто на Хаскеле игры делать не собирался — не годится он для этого». Тогда я тоже затыкаюсь, но уже просто так — на правах победителя.
Но нет. Мне начали рассказывать что я ничего не понимаю. Что я к тому же ограничен интеллектуально. И что вообще я не в теме.
[citation needed]
Наздоровье. Мне не лень скопировать.
Ты, конечно, разбираешься в теме, но пункты 1-3 тут полезного ничего не привнесли, хоть и являются занимательной исторической справкой — в этой ветке речи про ООП не идёт, она идёт про выбор большинства / типа эволюцию (о чём тут пункт 5).
По пункту 4 — вопрос был, почему соответствующие IDE не распространены, а не почему их нет.
А что за органик-еда?
В игровой индустрии главный фактор — производительность (если мы говорим о ААА). То есть качественная графика и физика, но не ценой количества поддерживаемых машин. Тут функциональные языки проигрывают в сухую.
Помимо этого, игра — прежде всего взаимодействие с пользователем, то есть опять мимо функциональных языков с их «чистотой» и костылями для ее обхода.
Каждому делу свой инструмент.
Да, производительность – главная причина, почему невысокоуровневые языки вроде си заняли в геймдеве прочное место. С другой стороны, нынче не девяностые, компы уже совсем другие, и игры активно делают на managed-платформах, с которыми нативно компилируемая функциональщина вполне сравнима по скорости (даже ленивый хаскель, но там надо быть очень внимательным), а про скриптовые штуки и веб я вообще молчу.
Про чистоту немного не в кассу, это полезная концепция для любого языка, и функциональщина всячески её пропагандирует, но лишь единичные языки требуют её бескромпромиссно соблюдать (из практичных – наверное, лишь пресловутый хаскель, и, возможно, эрланг, но тут не уверен).
А я всё думал-гадал зачем смартфоны с 6Гб оперативки выпускать:
Но я теперь точно уверен что там будут запускать программы написанные на функциональных языках… Возможно, даже игры!
Ну есть множество полезных концепций, которые в традиционных языках выражаются через жопу или вообще никак. Вот например, традиционное «классовое» ООП, которым вы тут размахиваете, для описания игровых иерархий годится заметно хуже компонентных систем, которые делаются через трейты или мультиметоды (вот отличный пример на Scheme). Описывать динамические и интерактивные системы, где всё течёт и всё меняется, на чистых языках вроде хаскеля может быть очень неудобно – если не знать, что там есть линзы, которые позволяют не только имитировать присвоение, но и вытворять штуки, которые императивщине и не снились. Ну и к тому же это не единственный подход – есть FRP, которое, кстати, активно применяется во вполне мейнстримном вебе.
Это я уже не говорю о маленьких штучках вроде foreach, лямбд, LINQ или даже монад, которые облегчают жизнь, будучи встроенными в любой язык, и которыми вы все активно пользуетесь, даже если не осознаёте, что за ними скрывается.
P.S. Я всегда буду обновлять страницу перед отправкой комментария… >_<
Предположим… И сколько игр ты на Хаскеле написал?
А вообще вот такой вот вопрос
Миллионы мух не могут ошибаться, да?
Три, а что? А сколько игр ты написал на C++/C#/Java?
P.S. Я игры вообще теперь почти не делаю. Прочего кода на хаскеле я написал довольно много, он рулит.
Причём здесь мухи? Раз ты писал на Хаскеле и, видимо, действительно применял всё что ты описал в том своём посте интересно выяснить под «годится» понимается что? Просто удобство описания? Или удобство пихания кода интерпретатору без дополнительных приседаний? Или всё-таки оно реально ускоряет работу над проектом?
Какя либо концепция может быть очень годной теретически, выходит что всё так складн оскладывается и должно быстро работать и всё такое. Но сколько сил при этом уходит на это? Сколько сил уходит на то чтобы эту концепцию понять? Сила ООП подхода в том, что он очень близок к реальной жизни и естественному мышлению. И программисту, который такой подход применяет не нужно затрачивать усилий, на то, чтобы перевести логику естественного мышления на «новые уровни абстракции». В этом и суть изначального обсуждения.
К сожалению, С++/С#/Java — имеют слишком низкоуровневые для меня IDE. Поэтому я создал более 20 игр на GML в среде Game Maker, который, впрочем, тоже ООП. Поэтому мне совершенно плевать на новые уровни абстракции. Я то игры делаю, а не хернёй страдаю. GML содержит всё что нужно для реализации моих творческих идей, а что ещё для счастья надо то?
См. «Blub paradox» и «Golden hammer».
Ну то есть, им опять-таки недостаёт нужных абстракций, amirite? Но тогда беседа не о «императивные языки лучше подходят для создания игр», а «языки, заточенные под создание игр, лучше подходят для создания игр», слава Кэпу. Что, кстати, лишний раз доказывает пользу DSL.
Я практик, а не теоретик. В том плане что, я делаю игры, а не рассуждаю на тему «как делать игры лучше и проще» =)
О! давай так. В декабре будет лудум. Я пишу игру за два дня на GML, а ты — на Haskell. Вот и проверим НА ПРАКТИКЕ какая парадигма круче, ок?
Дело не в абстракциях, а в переизбытке рутины. IDE должна автоматизировать процессы разработки, а не усложнять.
Вообще беседа была о «А что, есть парадигмы которые позволяют проще и быстрее создавать игры?». По крайней мере такую телегу задвигает Кситилон, дескать на прологе то создавать даже легче чем на чём либо ещё.
То есть ты даже и не пытаешься искать, можно ли делать лучше и проще? Окей.
… который решается введением абстракций. Ресурсы, объекты, эвенты и прочее в GM – это самые что ни на есть абстракции. Именно они облегчают жизнь, а не GML, на месте которого могло быть что угодно.
Ок! Если мы сравниваем парадигмы, а не инструменты, то ты пишешь на GML без GM. Иначе это сравнение тёплого с мягким.
Ну ты как будто в первый раз с этим сталкиваешься. Аргумент очень простой — это слишком затратно.
Что до написания игры на GML без GM, то это тоже мимо — вся внутренняя часть GM XD (то что обеспечивает внутри игры работу всего того что можно накликать и написать в форме написанной на C#) - напечатана мной в обычном Блокноте.
Вы не можете ничего адекватно сопоставить на уровне парадигм из такого положения. По крайней мере такими странными мерами.
Впрочем, если ты имел в виду не использовать ни компилятор, ни раннер GM, которые легче написать на Хаскеле, то ты находишься в некоем выигрыше — но это не называется «писать игру».
Я в этом треде и перетираю как раз потому что пытаюсь искать что лучше и проще. В Game Maker я фактически жму на волшебные кнопки «сделайте мне охуенно» и мне делают охуенно. В прологе, выясняется, что непонятно как описывать игровую логику. А для Haskell, оказывается, нету нормальной IDE и документации. Выходит что я пока не могу найти лучшего решения. Я пробовал Unity и умею и в нём (создал пяток игр) — хорошая штука для 3Д игр. Я пробовал Stencyl который не способен переваривать столкновения. Я пробовал и флеш с IDE flashdevelop, которая не отличается особо от самых разных виденных мною ранее IDE в которых нету нормальной системы организации игровых ресурсов. UT3 не пробовал, но учитывая что рабочее на них могут осилить разве что команды разработчиков — решил что пока не стоит.
По сути и выходит пока что, что эффективно разрабатывать игры у меня выходит только с GameMaker и Unity. А Ludum Dare и позволяет мне проверить эффективность разработки. Если я могу при помощи инструмента воплотить свою задумку за два дня — значит инструмент эффективный.
Ты не прав. В GML ровно столько же абстракций(даже меньше) чем в тех же C++, C#. Преимущество именно в IDE, которая позволяет быстрее манипулировать частями проектов. Если там и появляются какие-то абстракции то они никак не относятся к программированию.
С чего это? А ты тоже готов писать на Haskell без интерпретатора Haskell, так что ли? GM — это интерпретатор GML + фрэймворк. Ко всему прочему как раз в GM я и занимаюсь чисто ООП парадигмой — как раз то что нужно ТЕБЕ. Я создаю классы и наследую друг от друга, использую базовый полиморфизм, я назначаю им события и описываю взаимодействие объектов друг с другом. Если твоя парадигма вынуждена работать с кодом напрямую — это уже чисто твои проблемы, и к слову, не свидетельствующие о том, что функциональное программирование так уж годно для разработки игр.
Кстати я тоже пробовал — лажа была, но это было давно. У тебя за какой год тест?
В GML абстракций больше, но их не обязательно знать. (проклятье, мы ходим по кругу с одинаковыми аргументами в каждую из рассматриваемых сторон)
Не согласен совершенно. Главное преимущество в интерпретирующем на лету движке, но оно было безнадёжно про… утрачено с переходом на Студию. После этого без IDE уже работать стало невозможно, и поэтому без него задница. Второе главное преимущество в ограниченном мета-программировании — можно собирать объекты на лету из ничего. Но и это в Студии уже не существует.
По-моему Юрри считает что
его кунг-фу кручеу него ООП лучше, так как там есть множественное наследование, миксины и ещё много всяких свистелок.Отсутствие множественного наследования в ГМ меня раздражает уже долго время, и поэтому я придумал скрипты, которые собирают объект из нескольких прото-объектов, совмещая их события. Я придумал систему макросов-подстановок, чтобы ре-юзать участки одинакового кода. А потом это всё просрали.
Ладно, это я так.
Ты рассуждаешь о каком-то технологическом преимуществе которого нет у старой среды GM. К тем же языкам программирования которые давно обладали рефлексией и возможностью генерации кода на лету. То есть твоё преимущество никак не затрагивает разработку именно игр.
Я то имел в виду преимущество именно этой IDE перед традиционными IDE для написания кода, которые пытаются выставляться «бывалыми программистами» в качестве полноценной IDE для разработки игр. По крайней мере в случае со всякими MVS, Flashdevelop, Eclipse, Netbeans и прочими которые заточены под написание кода а не разработки. Моя мораль в том что IDE для разработке игры должна обеспечивать не только удобство работы с кодом но и со всеми игровыми ресурсами и игровой логикой, игровым пространством и т.д. IDE типа GameMaker, Stencyl, Unity обладают этими качествами и тем самым выигрывают в эффективности разработки.
Наоборот — у старой есть, а у новой нет. Я, считай, сам дописал IDE, а с приходом Студии на ней это всё стало бесполезным. Не потому что там есть такое же — да я был бы рад этому невероятно — а потому что отвалился интерпретатор. Так что это прямым образом затрагивает мою методологию разработки именно игр.
А ты говоришь насчёт того что GM это не компилятор-переросток с подсказками кода (которых там почти нет), а инструмент для сборки продукта по конкретным частям, рабочий станок. Тут нечего добавить, это отлично, эффективность от этого выше, и аналога для Хаскеля или Пролога такого не существует.
Вот, и тебе не хватило возможностей конвенционального ООП, предоставляемых GM.
Преимущество?! Это не преимущество, это источник бесконечных тормозов. То, что его местами можно было использовать для расширения возможностей языка – не преимущество, а костыль.
Ну чего ты опять разжигаешь. Ты эти «бесконечные» тормоза в глаза видел? Я до сих пор использую все эти модули, потому что с ними я могу в пару кликов и десяток замен в коде переделать всё с управления клавиатурой на управление клавиатурой или джойстиком. И любыми кнопками при этом, всё кастомно. Пример не голый, а проверенный на практике, так работает и управляется Castle of no Escape.
И работает оно так:
to_execute+=«input[»+string(cmd)+"]|=keyboard_check("+ctrl_check[cmd,ctrl]+")"
to_execute+=«input[»+string(cmd)+"]|=(joystick_direction(1)="+ctrl_check_argument[cmd,ctrl]+")"
и так далее
execute_string(to_execute)
Каждый кадр, 60 раз в секунду.
А костыль или не костыль — это своей бабушке можно рассказывать.
Ещё немного подпилю, и будет автоматическая запись действий игрока прямо с потока управления. Я уже там и RLE-сжатие закодил.
Кавычки-ёлочки это Коленка ставит, если что.
Так работает же. Один раз написал, и работает. Причём это в разы более читаемо для меня, чем Хаскель тот же.
Замечу, что обсуждение было — можно ли делать игры «в декларативной парадигме» вообще. Плавно перешедшее в «как лучше писать программы».
На практике же ты проверишь, кто лучше владеет разработкой игр, а не какая парадигма лучше. Учитывая, что Юрри делает игры редко и мало, это странная затея.
GML это скриптовый язык для движка написанного на Delphi, который, как мы все знаем, является Паскалем с прикрученным к нему ООП.
Впрочем, о чём это я. Поведай мне тогда, какой именно фичи из ООП в GML нету.
Проблема с ООП в том, что никто не знает, что же это такое.
Ну окей. Если брать мейнстрим, то и симулоподобное (C++, Java и иже с ними), и смоллтокоподобное (ObjectiveC, Ruby), и прототипное (Javascript), например, позволяют добавлять произвольные методы к объекту/классу, в отличие от.
Ещё очень доставляет, что ресурсы и встроенные структуры данных в GML не объекты нихрена, из-за чего приходится городить зоопарк глобальных функций с весёлыми префиксами.
Что значит не знает?
ООП — это инкапсуляция, наследование, полиморфизм по классическому же определению. В универе говорили что там ещё что-то есть но я уже не помню… Абстракция, кажется.
И это ты называешь определением? Это даже не необходимо-достаточный список.
В джаваскрипте нет наследования. ООП там есть.
В го и расте нет наследования. ООП там тоже есть, но не такое, как в JS.
В хаскеле есть и инкапсуляция, и наследование, и полиморфизм. ООП там нет, потому что это не то наследование и не тот полиморфизм.
Ни в одном из динамических ОО-языков нет той половинки инкапсуляции, которая ответственна за сокрытие (по одному из определений).
Определением скорее могло быть что-то вроде «представление данных в виде объектов со внутренним состоянием, и потока выполнения в виде пересылки сообщения между объектами, меняющими их состояние», под которое действительно все вышеуказанные (кроме хаскеля) подпадают, но оно какое-то слишком мутное.
Так ты сам не можешь привести определение. Чего махать-то руками?
Я знаю то же что и Хейзер, потому что наличие или отсутствие ООП для меня глубоко вторично, в отличие от нужды мыслить «математическими категориями». Пролог я ещё понимаю. Хаскель — извините.
Как -то не очень убедительно. Или я чего-то не понимаю.
Не приходило в голову что если там «не то наследование» и «не тот полиморфизм» — значит это и не наследование и не полиморфизм вовсе, а разработчики Хаскеля просто поленились придумать для этого новые слова, внося тем самым путаницу во всю и вся? Наследование, покрайней мере, это не тот термин, который мог б вызвать трудности трактовки. По-моему он совершенно однозначно говорит о том что должен говорить. Вот с полиморфизмом сложнее, да.
inb4: там нет какого-нибудь «нативного» наследования, а это костыль.
Так это и не я говорил, что в javascript есть ООП =)
Или ты тоже не понимаешь того, о чём пишешь, а?
*facepaw*
Ты говорил, что ООП – это «инкапсуляция, наследование, полиморфизм». Подучи матчасть уже, чтобы убедиться, что традиционного наследования в JS, Go и Rust нет, а ООП есть, а сл-но, либо неверно твоё определение, либо оно требует расширения некоторых понятий, но тогда под него начинают подпадать не-ОО-языки. Ну или разверни свои определения, чтобы уточнить, что имел в виду.
Пфф. А откуда ты тогда взял что там есть ООП? Может быть там опять же есть что-то другое, что ты и кто-то ещё называет ООП, но это не ООП по факту? Какой смысл вообще вводить какие-то опредления, если они имеют неоднозначную трактовку?
Зачем вот так делать:
И всё только ради того чтобы потом где-нибудь сказать
Это даже не смешно. Это глупо. Мне вот насрать на все эти околотемы. Мне достаточно классического определения с инкапсюляцией, наследованием и полиморфизомом. Есть это в языке — значит он поддерживает ООП парадигму. Нету — значит не поддерживает, а все эти выебоны на тему «Оно там как бы есть, но как бы его нет потому что наследование там — не такое наследование и вообще...» — можете засунуть себе в задницу и прокрутить. Программирование — это формальная логика на формальных языках, а не какие-то непонятные пвседо-мета-рассуждения.
А кто сказал, что именно оно «классическое»? Мне вот например нравится определение из википедии:
Какие-то другие особенности (инкапсуляция, наследование, классы, прототипы, примеси и т.д.) — это уже дело конкретных языков.
Проблема этого подхода в том, что он на статические языки оче плохо ложится. Ну и классы (как и типы в целом) даже в динамике несут много полезного для организации сколь-нибудь крупных программ.
А так он вполне имеет право на жизнь, как справедливо заметил pevzi выше.
Аналог Game Maker для C# и Javascript — это Unity. И с этой средой я тоже периодически работаю. Она выигрывает по удоству разработки у GM, но из рук вон плохо работает с 2D. А я делаю в основном именно 2D игры — потому и выбрал Game Maker.
Аналог Game Maker для AS3 — это Stencyl. И с этой средой я работал. Очень тормозной выхлоп получается.
Что касается попытки преодолеть ограничения инструмента — я пытался делать игры на фрэймворке AS. На практике же (заметь, я проверяю на практике) у меня это заняло больше времени чем разработка ТОЧНО ТОГО же на Stencyl. Причина — лучшая организация ресурсов и экономия времени на написание однообразного кода, который создаётся автоматом в нормальной IDE за один клик. Значит я нашёл более эффективный инструмент.
Так что парадокс нихрена неуместен =)
«Парадокс Блаба» состоит в том, что программист, знающий некоторый язык (для него Грэм и вводит условное наименование «Блаб»), как правило, хорошо понимает, чем Блаб лучше, чем любой менее мощный язык, поскольку в состоянии назвать механизмы, имеющиеся в Блабе и отсутствующие в менее мощных языках и понимает, как именно эти механизмы облегчают программирование. В то же время он не в состоянии заметить разницу между Блабом и более мощными языками, поскольку «думает на Блабе» — решение любой задачи автоматически представляет на Блабе, естественно, ограничиваясь теми средствами, которые в Блабе есть. Имеющиеся в более мощном языке дополнительные средства в его глазах ничего не стоят, так как он не умеет их применять и, естественно, не понимает, что они облегчат ему жизнь. И лишь когда программист по каким-то причинам изучит более мощный язык, он получит возможность смотреть на Блаб «сверху вниз» и видеть его ограниченность. Ссылки на «Парадокс Блаба» можно нередко встретить в Интернете, в особенности — на ресурсах, посвящённых обсуждению новых и ограниченно популярных языков и механизмов программирования.
Золото́й молото́к (англ. Golden hammer) — анти-паттерн проектирования, заключающийся в использовании одного и того же решения везде.
Но вообще хорошим тоном было бы приводить свои аргументы напрямую. Мало ли какая Википедия как описывает тот или иной термин. В английской версии пишут про золотой молоток, что «golden hammer[a] is an over-reliance on a familiar tool», что уже немного другая мысль, более близкая к текущему обсуждению.
Вспомнилась цитата с баша:
Один вопрос — кто в здравом уме будет это делать-то?..
Что-то я Некроса вспомнил (нет, про стартапы не знаю, скорее всего к нему не относится). Ну, вы знаете, о ком я, господа ММВшники.
Проиграл.
У, это была целая былинная история.
Даже так.
Дичь.
Зависит от реализации.
Я намекаю на то, что эти абстракции невозможно адекватно изобразить, если сам язык их не предоставляет.
Опять это «чё-т я сомневаюсь в его полезности, мне ни разу не пригодилось».
Массивы – далеко не единственный вид коллекций, которые можно фурычить. Попробуй с i±1 обойти словарь, например. Вот в C++ для этого использовали пары итераторов, и выглядело монструозно, пока над ними range-based for не запилили, наконец.
P.S. Если у тебя эти соседние пиксели использовались для расчёта текущего, возможно, код бы упростился использованием матричных операций и сечений.
P.P.S. А итерироваться вручную действительно не стоит. Вот так это заполнение нового массива выглядело бы на хаски (и на любом другом языке с генераторами списков, хоть питоне; и на C# с LINQ это делается очень похоже):
P.P.P.S. Кстати, это наглядный пример превосходства декларативности – вместо длинной инструкции, как обойти массив и его заполнить, мы делаем кратенькое описание, что в нём должно лежать, а детали пусть компилятор решает.
Для словаря я использовал foreach, действительно. Использовал и забыл. Если словарь предполагается обходить только с этой конструкцией, чего её и запоминать-то.
Я не знаю что именно ты понимаешь под матричными операциями и сечениями. В смысле, я знаю как работают с матрицами, но куда это приткнуть тут — непонятно.
Это пример превосходства по длине кода, но мне лично не сильно понятно, что он делает. Точнее, понятно только потому что я писал тот код, с которого это взято. Какие именно детали тут решает компилятор, кстати?
Ах да. Производительность от этого ведь ещё может пострадать.
Насчёт матриц: вроде бы в подобных программах частенько бывают фрагменты типа «обойти все пиксели, взять у каждого левых и правых соседей пикселя, взять максимальную яркость, бла-бла», для чего действительно нужны i±1. Но часто эти операции можно выразить в виде короткого «взять сечение матрицы NxN, помножить на другую, сложить с третьей», и индексации тогда вообще не останется.
Насчёт деталей: компилятор решает, в каком порядке обойти коллекцию, что можно пропустить, что можно развернуть, распараллелить или векторизовать, так что производительность может даже выиграть. По крайней мере, такого рода оптимизации при прочих равных легче делаются как раз с более высокоуровневым, абстрактным кодом, потому что в случае низкоуровневого компилятору мало места для манёвров и требуется учесть гораздо больше мелочей.
Это в терминах математики. Сечение матрицы что-то плохо гуглится вообще в принципе.
Так вот да, порядок мне во многих случаях важен строго по очереди. Там где он не важен, я распараллеливаю свою программу сам, создавая M x N потоков. Согласен что там есть пространство для манёвра, но это только общая теория, опять же.
О матрицах свёртки идёт речь, по всей видимости. Или что-то типа того.
Читаю тут на досуге книжку по этой теме, очень интересная, советую.
Ну, на Хаскеле, например, 3D-шутан есть (там же неплохой документик по поводу программирования игр на функциональном языке).
Можт кто из разбирающихся в видах программирования подскажет, является ли Verilog декларативным языком?
Не является языком программирования вообще, но стиль самой разметки скорее декларативный, чем императивный.
Выходит, игру как программу написать на нём нельзя. Но что-то вроде этого создать можно.
Типа как HTML для гипертекста, так это для железа.
Ну, спор у нас довольно важный, потому что упирается он примерно в следующее: зачем программировать императивно (C#, GML, остальное), если можно проще программировать декларативно (Пролог, Хаскель, что-то ещё)? Описывать игровые состояния может оказаться проще, если конечно упростить работу с синтаксисом и забыть о том что в исходной математической задаче это предикаты, а не объекты игровой логики.
А игра, если и будет, то не в ближайшее время. Пока это тяжёлая академическая тема.
Впрочем, выше есть исходный код другой игры, но чтобы её запустить, нужно качать интерпретатор Пролога, который надо отыскать в Гугле.
Тогда уже спор может принять оборот «А действительно ли проще программировать игры декларативно?»
Но учитывая что ты уже мне столько раз толкал мысль «Это возможно я не буду делать т.к. слишком хлопотно», я думаю что ответ на этот вопрос будет отрицательным.
Ну так давай, программируй. Чего же ты ждёшь?
Займись делом тогда, а то что-то тут мямлишь «я не нерд», «много хлопот»...
Давай так — аналог квэйка к завтрешнему утру на прологе. Механика, один моб, одно ружие, обычные стены + тестовый уровень. С тебя ещё и редактор.
Ок. Только мне нужно знать для каких тебе целей. Для домашнего пользования или офиса.
От этого будет зависеть выбор модели — время работы, размер экрана, поддерживаемые форматы, qwerty клавиаутра в конце-концов! Это ведь очень ответственное дело!
А вообще уже утро. Гони аналог квэйка на прологе.
Да, а ещё лицензии на коммерческое её использование продаются с другим соглашением и по другой цене.
У меня не получилось открыть исходник на Хаскеле, пишет «ты не Юрри, пшёл вон отсюда».
Есть мнение, что в 2005 году (!) некто Mun Hon Cheong написал на Хаскеле простенький клон Квейка 3. По-моему я даже приводил этот пример тебе ещё тогда. Правда, совершенно не помню, что мне на это было отвечено. В любом случае, теперь ты уже от ответа уйти вряд ли сможешь, так что милости просим.
Тьфу ты, это тот же, что приведен выше qb60.
Да и было это всё для галочки — никакого применения не показали только говорили «используется для искусственного интеллекта»
Парни, давайте скорее писать игры, а не брезжить слюной с лямбдами и интерфейсами под мышками!
Всем до свидания!
Ты писал вручную экстрактор графики из ресурсов игры что ль?
Ну короче игра у тебя была не на Прологе, но этот пример нам не показывает ничего ни позитивного, ни негативного по сути темы.
А в дипломе у меня был не экстрактор, это была игра на С++, внутрь которой было встроено ядро с мозгами на Прологе. Visual Prolog dll'ки умеет формовать.
Но в любом случае, программируя прикладные вещи на Прологе от декларативности немного отходишь, представляешь каким образом интерпретатор проходит твой список правил и всё такое. Можно программировать на Прологе императивно, как того требуют задачи отрисовки картинок и прочего.Я понял, что у тебя было в дипломе. Значит, таки писал экстрактор — лови респект из нашей артели фанатских хако-переводчиков!
Не, экстрактор был сторонний — ресурсы из игры у меня были. Сложность была в том, что графические ресурсы там в своём формате, аналоге GIF'а, а полупрозрачные взрывы вообще в 256-цветной палитре интересно через квадратные картинки-матрицы реализовывалось. Короче, ресурсы были, но чтобы заставить их работать и собрать редактор карт, я потратил год подготовки диплома. :)
Вот, кстати, моя «игра» на Visual Prolog (её в официальный список демок поместили): http://www.visual-prolog.com/vip/example/userExample/alchemist/alchemist.htm
Там просто список цветных колбочек и их можно перемешивать между собой получая новые цвета. Колбу, помню, в Максе долго и упорно моделил. :)
Чел какой-то на Haskell'е 3D шутер запилил.
Не ожидал, что из поста, который выглядел, как повод к срачу (без обид) узнаю много новых штук. Комментарии дельные, спасибо.
Как пример, почитал про полиморфизм и понял некоторые свои ошибки. Пора уже учить ООП по-человечески.
А это и был повод к нему, который Хейзер заготовил ещё года три назад в нашем разговоре.
Правда, я не знаю, что полезного можно было извлечь из комментариев, какие именно ошибки понять.
ООП, если его знание не является требованием непосредственно по работе, нахрен не нужно. В ГМ я его использую просто потому что оно есть. На Паскале я писал без него, за 5-10 лет до того.
1) Ну, обычно, является.
2) Согласись если писать, следуя какой-то парадигме (ООП, ФП, неважно) код получится лучше, чем если писать совсем от балды.
UPD, 3) А Паскаль у меня ассоциируется со школьными годами и только. Ну, и опыт соответствующий (отрицательный).
Кстати, тут какой-то чел на Хаскеле 3Д шутер сделал.
Вот оно как бывает.
Ого, никогда не видел, вот это ты круто нашёл!
Вот видишь, а ты говорил — невозможно, невозможно!
Я не говорил такого. Просто решил приобщиться к Элите. К тем людям, которые привели в этом треде ссылку на эту игру если ты её ещё не видел.