On Mon, May 20, 2013 at 02:58:53PM +0100, Florian Rathgeber wrote: > On 20/05/13 14:49, Garth N. Wells wrote: > > On 20 May 2013 14:33, Anders Logg <l...@simula.no> wrote: > >> On Mon, May 20, 2013 at 01:09:20PM +0100, Garth N. Wells wrote: > >>> On 20 May 2013 12:44, David Ham <david....@imperial.ac.uk> wrote: > >>>> Hi all, > >>>> > >>>> I'm writing Dolfin-compatible wrappers for PyOP2 as previously > >>>> advertised at > >>>> FEniCS '13, which is causing me to bump into one of the "interesting" > >>>> quirks > >>>> of the Python Dolfin API. Lots of things which would appear to naturally > >>>> be > >>>> properties are actually methods and have to be called to be accessed. For > >>>> one among many, many examples, consider the value_size method of a > >>>> Function. > >>>> This is accessed with: > >>>> > >>>> f.value_size() > >>>> > >>>> while > >>>> > >>>> f.value_size > >>>> > >>>> would seem more natural. Given the existence of the @property decorator > >>>> in > >>>> standard Python which translates the former into the latter, this is > >>>> particularly mysterious. Is there a reason why this is done in Dolfin? > >>>> > >>> > >>> A few of us discussed this in January. I agree that the latter is > >>> cleaner. > >>> > >>> First point, the Python interface is largely generated automatically, > >>> so that's our starting position. We would save on C++ code and get the > >>> syntax ' f.value_size' in many cases by not accessing member data via > >>> functions. I like skipping the function, and have been doing so lately > >>> with new code. The issue we discussed in January was backwards > >>> compatibility - we could make a lot of C++ changes to get the syntax > >>> 'f.size', but users would have to update their code (this point > >>> bothers me less than it does others :)). > >>> > >>> In some cases we need a method, e.g. to get the size of a vector from > >>> a linear algebra backend. Storing the size in a wrapper is error > >>> prone. > >>> > >>> In summary, the reason for the interface in some parts is > >>> history/convention (with no technical reason), and in other cases it's > >>> a method for technical reasons. We could move more towards direct > >>> access to member data. > >> > >> I don't agree with these conlusions. > >> > >> The reasons for the use of methods are: > > I think David didn't argue for direct access to member data (as in > access to the C++ members), or in fact about changing the C++ layer at > all. Rather we would like the semantic attribute access on Python layer > provided by @property, which I think circumvents most of the issue > Anders raises (note again I'm only talking about the Python interface): > > >> 1. Tradition: following some C++ guidelines we read 10 years back that > >> member data should never be accessed directly. > > > > It's done at times in the STL, e.g std::pair. > > One reason of using @property is not accessing member data directly. > > >> 2. Safety: Being able to access member variables means they can be > >> changed from the outside (for a non-const object). This might lead to > >> all kinds of unwanted behavior. A member variable can rarely be > >> changed safely without changing a whole bunch of other data. > >> > > > > If the data must be hidden, then it can be hidden behind a function. > > Otherwise, if the object is const, then member data cannot be changed > > and only const functions can be called on the data. > > Something that would make things cleaner around the code would be to > > let more objects have immutable data (e.g., not allow Vector > > resizing), which allows some member data to be made const. > > > > At present we have annoying code duplication in numerous classes to > > provide const and non-const access functions. > > @property is read-only be default. You can also define a setter, which > would then be able to take care of changing all the other data. > > >> 3. Consistency: Sometimes, there is no member data to be accessed but > >> it gets computed or extracted by the accessor function. This means if > >> we moved to more access of member data, there would be mix of both and > >> it would be confusing and inconsistent. > > > > This is a major plus to accessing data directly. It makes explicit > > that accessing a data member involves no computation. > > With @property you would keep the accessor function as it is but access > it as if it were a property. In addition, if the access involves > expensive computation that would only need to be done once, it can be > cached directly on the attribute using e.g. cached_property: > http://www.toofishes.net/blog/python-cached-property-decorator/ > > >> On top of theses strong reasons (2 + 3), we would also break the > >> interface. > > > > Which is a drawback. > > Yes, also using @property would be an interface-breaking change.
I guess it's not possible to have both? -- Anders _______________________________________________ fenics mailing list fenics@fenicsproject.org http://fenicsproject.org/mailman/listinfo/fenics