Heys guys,
at first: nice discussion. Like someone else said I'm happy to see that people around SFML are highly interested in core issues. It's one of the things I really love about SFML and its community.
Enough picnic, back to the serious side of life.
Exceptions, error codes or both: I'm with eXpl0it3r. SFML is a C++ library, so C++ techniques, practices and workflows should apply. If that requires CSFML to try/catch exceptions and forward them to the target-language's error mechanisms, then that's the way to go in my opinion.
Yes, this might be annoying for the binding writer (repeating code) and add another thin layer between the call and the execution in the library, but if that's required to reach a proper C++ way of doing things in a C++ library, well, then it's the cost. And unless someone can prove with a profiler and good tests that performance is really lacking, then I'm sure there are options that can be tried out.
Just look at how the bindings themselves are doing it: They change function names, implement event loops on top of SFML etc., just to make the binding fit to the target language. This is good, as nothing is worse than code that feels alien in a language (and does not make use of its security features especially!).
If your only argument against exceptions is that bindings are harder to do, then I guess that it's not valid. If SFML uses exceptions, then CSFML won't, because it's C. Since bindings are already using CSFML, I don't see any problems here. At least that's what my impression is, correct me if I'm wrong (it has been some time since I had been adjusting the Python binding).
It's not like exceptions are only a fancy way of doing error reporting. They greatly enhance security.
Splitting loading/saving routines: I like this. It's indeed an OOD thing mostly, but personally I think it's logical.
The biggest argument I can bring to the table (or: which is high priority for me) is modularity and security.
If sf::Image, for example, only contains the data, then the external loading mechanisms have to use the image's public interface, which makes sf::Image more robust due to encapsulation. Side effects are reduced, and transparency at the user increased.
Enhancing the image loading is easy as well: Just add another function/class that
uses sf::Image. And this will not look alien/confusing to the user. Just compare these:
sf::Image image;
// First version, using internal loading routines:
image.loadFromFile( "foo.png" );
image = PerlinNoiseImage::generate();
// Second version, using external loading routines:
image = sf::ImageAdapter::load( "foo.png" );
image = PerlinNoiseImage::generate();
The second version is more intuitive for extensions, because if you are using an extension or not, the handling is the same (in fact SFML's "built in" loading routines would behave like an extension as well).