singalen: (portrait)
[personal profile] singalen
Хороший человек [livejournal.com profile] vbayda показал, как он использует boost::bind:
if (entityes_.end() == std::find_if(entityes_.begin(), entityes_.end(),
     boost::bind < bool > (&intersect < double >, c,
         boost::bind(&world::positions::entity::shape_,
            boost::bind(&world::entity::positions_, _1)
         )
     )
    ))

Как на меня, мягко выражаясь, выглядит не слишком читабельно.
Понял слова Алана Перлиса "избыток синтаксического сахара приводит к раку фигурных скобок" (переврал цитату, и ну его).
Не слишком-то C++ пригоден для функциональщины. Правда, синтаксис получился не намного хуже, чем у Lisp-а.

Попытался переписать это на Haskell. Не могу скомпилировать, хоть ты тресни. Хотя выглядит немного лучше.
Комментирую синтаксис "в стиле учебника" для тех, кто не знает языка.
module Main
  where

-- это описание типа данных - "записи" с конструктором и одним полем
data Entity = CreateEntity { position :: Position }

data Position = CreatePosition { circle :: Circle }

data Circle = CreateCircle { x, y, r :: Float }

-- указание типа функции (аргументов и параметров).
-- Обычно можно опустить, type inferrance его определяет.
circlesIntersect :: Circle -> Circle -> Bool
-- это собственно описание функции: имя, параметры, =, тело-выражение
circlesIntersect c1 c2 = sqr (r c1 + r c2) < sqr (x c1 - x c2) + sqr (y c1 - y c2)
  where sqr x = x*x

findIntersecting :: Circle -> [Entity] -> Entity
findIntersecting circle entities = 
-- это тот самый байнд одного (первого) параметра. Выглядит так: (имя функции) параметр.
  find ((entityMatches) circle) entities
  where
    entityMatches :: Circle -> Entity -> Bool
    entityMatches c e = circlesIntersect c (circle position e)
-- Оказывается, в Haskell обращение к полям структуры выглядит не как c.x, а как x(c).
-- Или x c, что в этом случае то же самое.

main = putStr "Hello\n"

Итого получается (получилось бы, если бы я лучше понимал синтаксис и типизацию)
findIntersecting circle entities = 
  find ((entityMatches) circle) entities where
    entityMatches c e = circlesIntersect c (circle position e)

или, без промежуточной "объясняющей" функции
findIntersecting circle entities = 
  find (((circlesIntersect) c (circle position e)) circle) entities

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

(no subject)

7/10/06 17:49 (UTC)
Posted by [identity profile] vbayda.livejournal.com
2. ну тут тоже самое что и с STL алгоритмами и контейнерами. Когда копировнаие невозможно или критично - используются указатели;
3. есть такое, но к этому привыкаешь. А еще гдето встречались скрипты, преобразующиее большой и сложный output с ошибками в нечто более простое, правда они сильно под STL заточены были;

(no subject)

7/10/06 18:32 (UTC)
Posted by [identity profile] nponeccop.livejournal.com
2. Подход с лишними указателями на ровном месте изначально ущербный - лишняя надстройка и лишние выделения памяти.

3. Привыкание ничего не меняет. Люди и при -60, и при +50 градусах живут, но я к такому привыкать не хочу.

С++ - реально калообразный язык. Нужно "что-то массовое, современное", но столь же быстрое. Я фанат скорости С++, а во всем остальном он полный отстой. STL и исключения использовать нельзя почти никогда - они сразу становятся ботлнеком. А если скорость некритична - можно какой язык попроще и погибче выбрать.