Re: [dev] Suckless design in Games

From: Szabolcs Nagy <nsz_AT_port70.net>
Date: Wed, 11 Aug 2010 14:05:41 +0200

* Chidambaram Annamalai <quantumelixir_AT_gmail.com> [2010-08-11 13:12:46 +0530]:
> Have you even bothered to look through the sources? You really have
yes
although it was a couple of years ago last time i used bgl

> to decouple the storage schemes from the algorithms so that you can write
> O(M + N) code to support O(M*N) template instances. And there is no point if
> this abstraction had a severe penalty on the runtime performance. BGL
> exactly knows which algorithm to use for a particular storage mode because
> intelligence is built into it using traits. The hierarchial design (which is
this is a misconception about bgl and c++ generic programming in general

you can treat certain aspects of the algorithms but not everything
genericity is only available where the designers thought about it
(eg you cannot reuse a stack in dfs graph traversals of various graphs
because it is hardcoded in boost)

this usually ends up in a lot of configurability where users don't
need it, but the result is still not flexible enough for practical
problems

that's why everyone ends up implementing their own containers instead
of using stl in a bigger c++ project
(eg by adding concurrency support or using different tradeoffs in the
algorithm design, so eventhough stl is very generic it is still not
flexible enough)

intuition tells that generic code allows easy replacement of components
but this is a fallacy:
- the designer must know how the code will be used in advance
and decompose the algorithms that way
- the users need to know a lot more about the internal implementation,
how an abstract component interacts with others
(the more fine grained the generic code the more difficult to use it)
(it's not true that you can easily write your own graph represantation
to use it with boost you need to know a lot of details)
(from the docs a lot of semantic detail is not clear, eg can you modify
a graph from a visitor? boost uses iterators and in many datastructure
modifications invalidates them)
- when an algorithm is used in the most simple and usual way, genericity
causes a lot of unnecessary boilerplate, confusion about the api, and
cryptic compiler error messages
(to find the shortest path in a simple directed graph with int edge
weights, i still have to fill the template arguments
http://www.boost.org/doc/libs/1_43_0/libs/graph/example/dijkstra-example.cpp
this is not elegant code)

i experimented with various types of genericity for algorithms
here is one approach:
implement the algorithm in the simplest way for the most useful types
etc. then when you need it for a specific task then copy the code and
apply appropriate modifications in the source (often s/type1/type2/g)

it turns out that with this approach it's often easier to change
a component without screwing things up than by understanding all
the gory details of a generic api like boost

adapting an algorithm for your usecase usually takes less than an hour
and the result is readable customized code, easy to debug, easy to edit

> Template metaprogramming uses static polymorphism which is an entirely
> different beast from OO inheritance that uses dynamic polymorphism.
yes, each of them has quirks and the user of the library should deal
them
(using various concepts together the complexity of the result is the
product of the complexity of each part, not the sum)

my argument is that this amount of abstraction just not worth the effort
(at least in c++)
Received on Wed Aug 11 2010 - 14:05:41 CEST

This archive was generated by hypermail 2.2.0 : Wed Aug 11 2010 - 14:12:02 CEST