Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Another python binding: python-sfml2  (Read 12595 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Another python binding: python-sfml2
« Reply #15 on: June 15, 2012, 07:54:09 am »
Quote
True, but it can be implemented to provide an exhaustive binding and its use discouraged at the same time
What's the point of implementing something and then discouraging its use? Confusing people? :P
I think it's important to stick to the native classes and functions, so that SFML code can interact nicely with the rest of the code, and not require type conversions and duplicated functions everywhere. A binding must look natural, as if it was directly developed in the target language.
Laurent Gomila - SFML developer

Sonkun

  • Full Member
  • ***
  • Posts: 241
    • View Profile
Re: Another python binding: python-sfml2
« Reply #16 on: June 25, 2012, 04:45:54 am »
Quote
What's the point of implementing something and then discouraging its use? Confusing people? :P

Maybe should I have said "preferred" instead" of "discouraged". I find more confusing not to have the sfml network module implemented than having it.

It allows you to port C++ projects more easily. With minor syntactic changes (all of which are documented), you can port your code without having to trod through the standard library's documentation. Later, you can replace bits and pieces you like with the standard Python's built-in equivalents.

Quote
I think it's important to stick to the native classes and functions, so that SFML code can interact nicely with the rest of the code, and not require type conversions and duplicated functions everywhere. A binding must look natural, as if it was directly developed in the target language.

That's exactly what my binding offer compared to the official's one, a more natural look and on many points:

1) Types
In Python, numeric types (integer, float, complex, long) are inferred. Users shouldn't care about the Vector's type or Rect's type.

In my binding, instead of writing:
sf.Vector2f()
sf.Vector2i()
sf.IntRect()
sf.FloatRect()

You write:
sf.Vector2()
sf.Rectangle()

2) Copy
In the official binding, there are plenty of copy() methods to make copies but in Python copies are done via the copy module.

In my binding instead of writing:
image = sf.Image.load_from_file("myimage.png")
image2 = image.copy()

You write:
from copy import copy, deepcopy

image = sf.Image.from_file("myimage.png")
image2 = copy(image)

3) C++ multiple definitions are not emulated

In Python, there are no multiple definitions. Instead of emulating this C++ feature and make Python functions take any argument then check whether they match a C++ function definition, I split functions.

For example, instead of writing this:
texture.update(window)
texture.update(image)

You write:
texture.update_from_window(window)
texture.update_from_image(image)

Another typical example is with multiple constructors. Here are the C++ Shader constructors.

bool loadFromFile (const std::string &filename, Type type
bool loadFromFile (const std::string &vertexShaderFilename, const std::string &fragmentShaderFilename)

Instead of writing this:
shader = sf.Shader.load_from_file("vertex.vert", "fragment.frag")
vertex = sf.Shader.load_from_file("vertex.vert", sf.Shader.VERTEX)
fragment = sf.Shader.load_from_file("fragment.frag", sf.Shader.FRAGMENT)

In my binding, you write:
shader = sf.Shader.from_file("vertex.vert", "fragment.frag")
vertex = sf.Shader.from_file(vertex="vertex.vert")
fragment = sf.Shader.from_file(fragment="fragment.frag")

4) Methods/function's name more pythonic.
The standard Python library traditionally uses from_foo() and to_bar() to respectively load/open and save objects. The binding does that as well.

music = sf.Music.from_file() # pythonic
music = sf.Music.open_from_file() # less pythonic

5) All of SFML's native classes are found.

You don't find Window, VertexArray and probably others in Bastien's binding.
« Last Edit: June 25, 2012, 07:18:07 am by Sonkun »
Interested in using SFML with Python ? Try out its Python binding!

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Re: Another python binding: python-sfml2
« Reply #17 on: June 25, 2012, 10:26:42 pm »
I guess I should give my opinion at some point. I find some of the changes in this binding interesting, and I will probably copy/adapt some of them. But overall, I find that your arguments actually don't support that such change is more pythonic, natural or makes more sense.

For example, you removed the copy() methods because “in Python copies are done via the copy module”. As it turns out, dict, one of the most basic classes in Python, has a copy() method.

Consider the following reasons not to use the copy module. The most obvious one is that operations on objects should be done via methods, as it's more natural in an object oriented language. Another one is that copy provides two kinds of copies, and it's not obvious which are supported. On the other hand, it's very easy to see if a copy() method exists, either via the documentation or the interpreter in interactive mode. I also think that making use of the copy module is overkill in the sense that deep copies don't seem to be needed.

In your third point, you don't give any reason why your design is better. You say that Python doesn't support multiple methods definitions, but that only matters to the implementer. I probably don't need to explain why emulating method overloading is often better for the users, especially those who come from C++ SFML.

I'm not sure what's the best way to implement vectors and rectangles. I think that they way they currently work is good enough, though. I think the way you describe Python's type system is misguided; there is a difference between, say, int and float, and Python enforces it. There is no static type checking, but that doesn't mean that any types can be mixed together. SFML also uses the different vectors and rectangles types for different purposes, which means that users should care what they are. It seems to me that the only question is whether or not these classes should be considered as generic containers.

As for missing classes, I'm open to suggestions. If there's a good reason to add them, I will do it. Streaming will be available soon(ish).

Overall, it seems that by “natural” and “pythonic”, you mean which that follows your opinion of how an API should look like, even when there are objective reasons to consider alternatives. I think that we should be rational when designing APIs, and recognize when the reasons that guided us are subjective. To be honest, it often seems to me that you're more interested in spreading slogans for your binding than having rational debates.
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

aspidites

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Another python binding: python-sfml2
« Reply #18 on: June 27, 2012, 04:58:16 am »
disclaimer: I'm a bit exhausted, so my replies might come off as curt. I certainly don't mean them to.

I guess I should give my opinion at some point. I find some of the changes in this binding interesting, and I will probably copy/adapt some of them. But overall, I find that your arguments actually don't support that such change is more pythonic, natural or makes more sense.
A rather subjective opinion (which I think was your overall point as well. Often it happens that we use the term 'pythonic' to mean that which seems more in-spirit with the nature of core pythonistas. Unfortunately, like any other philosophy, what is 'true to' or 'correctly adheres to' a particular philosophy quickly gets lost in translation. I hadn't realized this until I reflected on his reply of yours.

I'm not even sure it's fair to say that his binding is more 'idiomatic' than yours, since it could be argued that yours, more closely resembling the c++ api is as well. While I do like his binding better (and for other reasons), I'm not sure that pythonic is a proper adjective here. I'll continue to use it simply for lack of a better term.

For example, you removed the copy() methods because “in Python copies are done via the copy module”. As it turns out, dict, one of the most basic classes in Python, has a copy() method.

Paradoxically, that something exists in the standard library doesn't qualify it as "pythonic". A lot of things existed before this PEP or that was written. As for your dict example, the python standard library is (seemingly) inconsistent with respect to this. Sets and dicts have a copy method, but lists and tuples do not. Also, there still exists copy methods in Sonkun's binding, they are just not preferred.

Consider the following reasons not to use the copy module. The most obvious one is that operations on objects should be done via methods, as it's more natural in an object oriented language. Another one is that copy provides two kinds of copies, and it's not obvious which are supported. On the other hand, it's very easy to see if a copy() method exists, either via the documentation or the interpreter in interactive mode. I also think that making use of the copy module is overkill in the sense that deep copies don't seem to be needed.
I could argue that implementing __copy__ special methods is more object oriented because generic functions are then able to operate on those objects. Granted, I'm not stellar at c++, but in my case, its more natural to use these generic functions to operate on objects rather than have to hope that the object offers a copy method. Documentation isn't much of an argument, as anyone who is experienced with python will instantly recognize the significance of the existence of a __copy__ method. That, and they wouldn't be any worse documented than your copy method. As for overkill, just don't import deepcopy...

Again, the entire argument could be reversed (in fact, that's all I seem to have done, though it was done subconsciously).
In your third point, you don't give any reason why your design is better. You say that Python doesn't support multiple methods definitions, but that only matters to the implementer. I probably don't need to explain why emulating method overloading is often better for the users, especially those who come from C++ SFML.

Overall, it seems that by “natural” and “pythonic”, you mean which that follows your opinion of how an API should look like, even when there are objective reasons to consider alternatives. I think that we should be rational when designing APIs, and recognize when the reasons that guided us are subjective. To be honest, it often seems to me that you're more interested in spreading slogans for your binding than having rational debates.

As for rational, I've seen in occur a couple of times in your projects' issues system that a rational argument was given to implement a change yet still it wasn't. I guess my point in mentioning this is that either the kettle is calling the pot black, or what you view as rational is subjective. Beyond that, I fully agree with that notion.

There hasn't been any discussions on these forums which I suppose leads to your second assertion. However, I have found Sonkun rather receptive of constructive criticism. I've had meaningful conversations about the API, and have had plenty of my suggestions turned down with ample explanation. Ironically, the one time you turned down my pull request, it wasn't until he offered an explanation on an unrelated issue that I understood your logic for doing so (the request that allowed lists and tuples to be passed as an argument).

That isn't to say that you aren't generally responsive to user concerns (plenty of evidence in the main Python bindings forum). I just wanted to highlight that Sonkun isn't as irrational, argumentative, or haphazard as others seem to be suggesting here.

BTW, its rather difficult to have a 'rational debate' when the only response given is 'we already have one'. As far as I can gather, 'more pythonic' was an argument used when you first released your binding, wasn't it? The biggest difference here is that in addition to porting from 1.6 to 2.0, you also moved to cython (I think the original was using ctypes or swig; correct me if I'm mistaken).

Last few things:
  • I'm not speaking on his behalf, nor was I asked to. It could very well be the case that once he comes back from vacation, he reads this and chastise me for potentially (and unintentionally) misrepresenting him
  • I'm sure everyone here recognizes that without YOUR work, his wouldn't be here, and for that, we obviously owe you thanks.
  • The biggest appeal to his version over yours is that his comes without caveats. That is, I am able to compile it cleanly without errors for python 2 and 3 from one code base, which has subsequently made it a breeze to start implementing an sfml backend for kivy. Another was that his bindings seem to come with more complete documentation. For those coming directly from SFML this isn't an issue, but for me, this was the deal breaker.

After writing all of that, I'm not entirely convinced that my comments contributed positively to the discussion. I do hope my words are taken into consideration. Beyond that, I suppose I'll go back to lurking.