This is the mail archive of the gsl-discuss@sourceware.org mailing list for the GSL project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: const gsl_vector *


The discussion seems to have died out, but I was glad for
the handful of replies that did come.


On 08/19/2014 04:33 PM, Patrick Alken wrote:

Also, the compiler should issue warnings/errors if you try to change anything else in the gsl_vector container. And since gsl_vector_set is the preferred way to set data elements, it will certainly detect a problem if you try to call gsl_vector_set on a const gsl_vector*

There is a (limited) sense in which this is the right answer.
Consider C++, where the access control happens by declaring
the accessor member functions with a 'const' attribute.
By analogy, controlling the "member" functions in C
gives some control over the access.

But this is not very satisfying, for two reasons. First, the
language does not provide compiler-enforced access control,
so there is never a guarantee. We just have to live with that.
Second, and more important, is that the current design is
an illusion.

  void   gsl_vector_set (gsl_vector * v, const size_t i, double x);
  double gsl_vector_get (const gsl_vector * v, const size_t i);

They look nice. And they seem to declare a contract with the
client, since one of them has the 'const' keyword and the
other one does not. As you say, the compiler can detect
something about this.

But as we have seen, it is an illusion. The fact that the 'const'
keywords are "sort of in the right place" is just misleading.
That the compiler can detect anything at all here is
basically an accident.

I think the main purpose of the current design was to abstract away all the details of gsl_vector, so in principle the user will never need to directly access the variables in v or directly access v->data. In practice, however, sometimes it is necessary to directly use those parameters.

Not necessarily. The abstraction is ok, up to a point. But the
current abstraction is too fat. It tries to do too much, notably
it balls up the memory management with the basic implementation,
making it impossible to separate the simple indexing semantics
from the more client-specific memory management.

This is where the gsl_vector discussion began some months ago,
with the need to factor the memory management out of the objects.

My first suggestion was to allow clients to pass alloc/free
functions to the initialization functions. But, after a little
thought, I realized this was not right. First, it smells bad,
because any sort of framework design is unworkable in the
long run. Second, because the containers should really be
lighter, not heavier with yet more memory management semantics.

So the right thing must be to lighten the containers, making
them essentially simple handles. They become "view" types,
which can be initialized along with allocation (as they are
now), or by simply wrapping existing storage.

All GSL interfaces should take the light-weight views as
arguments, since that is the most flexible choice. The
name 'gsl_vector' need not change, so there would appear
to be no need to change the prototypes for existing interfaces...
EXCEPT for the apparent need for a second 'const' type to get
the needed const-correctness for views initialized with
existing const storage.

This is where we are now. Const-correctness seems to require
a second type and therefore changes to existing interfaces.


I looked at the C interfaces for numpy ndarray objects, to
see what they do. It seems that const-ness is simply lost
through those interfaces. As long as you use them through
python, it doesn't matter. But if you try to export a
C array through the numpy C interfaces, somewhere the
constness must be discarded.

The ndarray struct (and the python type) carries a flag
called WRITEABLE, which is some kind of half-baked substitute
for mutability/immutability. It can generate runtime errors
under some circumstances, but does not constitute any form
of guarantee.

I looked at "typed memoryview" from cython. This is a good
thing, in its domain. But it seems like it is just a nicer
version of the python standard PEP 3118, which is the
basis for numpy ndarray.

Somebody also suggested I look at Datashape and Blaze. This
is not so clear to me. At least I didn't see how it could
help either.


So, none of these external designs seem to help much. The
only thing they seem to suggest is that constness is sort
of optional in that world...


Is const-correctness optional or not?


If clients choose to wrap existing data in a gsl_vector, are
they also willing to cast away any constness? It sounds
very wrong to me, but if you held a gun to my head...

--
G. Jungman


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]