| Author | Topic |
Posts: 413
Registered: May 2004
|
|
List objects in language bindings
|
03 Jun '09 09:46
|
 |
|
Dear libSBML-users
We have an issue that we would value your opinion on - particularly
users of language bindings.
LibSBML C++ core has it's own List class which is used within the
remaining code to store
lists of ASTNodes, CVTerms, ModelCreators and Dates.
List class can add/get/remove arbitrary data type via functions with
void* type such as
"void List::add(void*)", "void* List::get(unsigned int)", and "void*
remove(unsigned int)".
In the C/C++ API it is possible to retrieve and directly manipulate
these List objects
and the functions.
Using CVTerms as an example there is a function on an SBase object
List* getCVTerms();
(example code) -------------------------------------------------
Model* m;
...
List* lst = m->getCVTerms();
CVTerm* cvt = static_cast<CVTerm*>(lst->get(0)); // needs a cast
----------------------------------------------------------------
However, the List class and these functions returning List* object are
not wrapped
by SWIG because the List's functions with void* type can't be directly
wrapped and
thus do not exist in the language bindings.
In looking at how to remedy this we ran into some issues.
Our first approach was to create a C++ ListWrapper template (proxy class
for the List
object) and then wrap each of the four Lists as individual classes by
SWIG. So we ended
up with four wrapped classes (ASTNodeList, CVTermList, ModelCreatorList,
and DateList).
This provided the same functionality as the C++ API - i.e. these XXXList
objects could be
retrieved and manipulated via get(..), add(..) and other functions.
However, this approach seems cumbersome. We are creating four artificial
objects that are
not at all in keeping with the style of the each language.
So we investigated reimplementing the code to use the generic list type
objects associated
with the target language. It is possible to do this but unfortunately
the "List" returned
is not synchronised with the underlying C++ layer; so it is essentially
read-only. Any
manipulation done directly to the object will NOT be reflected within
the containing model.
Hence our dilemma - and here we value your input :-)
1) We implement functionality that allows retrieval and manipulation of
a List object in
line with the C++ API BUT we do so in such a way that is even less
native than the rest of
the SWIG generated APIs.
OR
2) We implement more native solutions with allows retrieval but not
manipulation AND thus
create a mismatch in functionality between the C++ and bindings API
Please let us know what you think ?
Akiya, Mike & Sarah
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|
Posts: 97
Registered: November 2006
|
|
Re: List objects in language bindings
|
03 Jun '09 10:02

|
 |
|
Hello Sarah, All,
Why not instead either have a common base class for all list
elements or separate lists for different types?
Take care
Oliver
On Wed, Jun 3, 2009 at 12:46 PM, Sarah Keating <skeating@caltech.edu> wrote:
> Dear libSBML-users
>
> We have an issue that we would value your opinion on - particularly
> users of language bindings.
>
> LibSBML C++ core has it's own List class which is used within the
> remaining code to store
> lists of ASTNodes, CVTerms, ModelCreators and Dates.
> List class can add/get/remove arbitrary data type via functions with
> void* type such as
> "void List::add(void*)", "void* List::get(unsigned int)", and "void*
> remove(unsigned int)".
> In the C/C++ API it is possible to retrieve and directly manipulate
> these List objects
> and the functions.
>
> Using CVTerms as an example there is a function on an SBase object
>
> List* getCVTerms();
>
> (example code) -------------------------------------------------
>
> Model* m;
> ...
> List* lst = m->getCVTerms();
> CVTerm* cvt = static_cast<CVTerm*>(lst->get(0)); // needs a cast
> ----------------------------------------------------------------
>
> However, the List class and these functions returning List* object are
> not wrapped
> by SWIG because the List's functions with void* type can't be directly
> wrapped and
> thus do not exist in the language bindings.
>
> In looking at how to remedy this we ran into some issues.
>
> Our first approach was to create a C++ ListWrapper template (proxy class
> for the List
> object) and then wrap each of the four Lists as individual classes by
> SWIG. So we ended
> up with four wrapped classes (ASTNodeList, CVTermList, ModelCreatorList,
> and DateList).
> This provided the same functionality as the C++ API - i.e. these XXXList
> objects could be
> retrieved and manipulated via get(..), add(..) and other functions.
>
> However, this approach seems cumbersome. We are creating four artificial
> objects that are
> not at all in keeping with the style of the each language.
>
> So we investigated reimplementing the code to use the generic list type
> objects associated
> with the target language. It is possible to do this but unfortunately
> the "List" returned
> is not synchronised with the underlying C++ layer; so it is essentially
> read-only. Any
> manipulation done directly to the object will NOT be reflected within
> the containing model.
>
> Hence our dilemma - and here we value your input :-)
>
> 1) We implement functionality that allows retrieval and manipulation of
> a List object in
> line with the C++ API BUT we do so in such a way that is even less
> native than the rest of
> the SWIG generated APIs.
>
> OR
>
> 2) We implement more native solutions with allows retrieval but not
> manipulation AND thus
> create a mismatch in functionality between the C++ and bindings API
>
> Please let us know what you think ?
>
> Akiya, Mike & Sarah
>
> ____________________________________________________________
> To manage your libsbml-development list subscription, visit
> https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
>
> For a web interface to the libsbml-development mailing list, visit
> http://sbml.org/Forums/
>
> For questions or feedback about the libsbml-development list,
> contact sbml-team@caltech.edu
>
>
--
Oliver Ruebenacker, Computational Cell Biologist
BioPAX Integration at Virtual Cell (http://vcell.org/biopax)
Center for Cell Analysis and Modeling
http://www.oliver.curiousworld.org
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|
Posts: 183
Registered: July 2008
|
|
Re: List objects in language bindings
|
03 Jun '09 11:11

|
 |
|
Hmm, let's see. A couple opinions that may or may not be helpful, since
I'm one of your C++ users.
First of all, the List class itself is old and a bit scary. When I had a
question last month about using List or looping through the ASTNodes some
other way, the answer was 'do it some other way'. So if the List itself
goes away in favor of a more modern C++ approach, I don't think anyone
would shed any tears.
Secondly, I assume the issue here is that the list object itself is
'read-only', and that if it contains pointers, those pointers are indeed
manipulable. That's all I've needed thus far, so if so, the only
remaining task is manipulating the list itself (to add or delete members,
one presumes).
I think the simplest approach would be to provide these functions:
NativeListObject getListOfWhateverFrom(theThingItLivesIn, thisone);
returncode setListOfWhateverIn (theThingItGoesIn, thisone);
In other words, don't provide pointers to the list objects, provide actual
native lists. Then the user can manipulate it to their heart's content,
then save their manipulation with the 'set' function.
You'll have to do some heavy lifting in the 'set' function to make sure
you don't delete valid pointers and to make sure you do delete nonvalid
pointers, but however hairy that code, the user doesn't have to worry
about it.
This wouldn't have to mismatch the C++ API either--I for one would welcome
something that gave me a vector of ASTNodes or what have you. I wouldn't
hand out pointers to vectors, mind you, just actual vectors.
-Lucian
* Sarah Keating <skeating@caltech.edu> [2009-06-03 17:49] writes:
> Dear libSBML-users
>
> We have an issue that we would value your opinion on - particularly
> users of language bindings.
>
> LibSBML C++ core has it's own List class which is used within the
> remaining code to store
> lists of ASTNodes, CVTerms, ModelCreators and Dates.
> List class can add/get/remove arbitrary data type via functions with
> void* type such as
> "void List::add(void*)", "void* List::get(unsigned int)", and "void*
> remove(unsigned int)".
> In the C/C++ API it is possible to retrieve and directly manipulate
> these List objects
> and the functions.
>
> Using CVTerms as an example there is a function on an SBase object
>
> List* getCVTerms();
>
> (example code) -------------------------------------------------
>
> Model* m;
> ...
> List* lst = m->getCVTerms();
> CVTerm* cvt = static_cast<CVTerm*>(lst->get(0)); // needs a cast
> ----------------------------------------------------------------
>
> However, the List class and these functions returning List* object are
> not wrapped
> by SWIG because the List's functions with void* type can't be directly
> wrapped and
> thus do not exist in the language bindings.
>
> In looking at how to remedy this we ran into some issues.
>
> Our first approach was to create a C++ ListWrapper template (proxy class
> for the List
> object) and then wrap each of the four Lists as individual classes by
> SWIG. So we ended
> up with four wrapped classes (ASTNodeList, CVTermList, ModelCreatorList,
> and DateList).
> This provided the same functionality as the C++ API - i.e. these XXXList
> objects could be
> retrieved and manipulated via get(..), add(..) and other functions.
>
> However, this approach seems cumbersome. We are creating four artificial
> objects that are
> not at all in keeping with the style of the each language.
>
> So we investigated reimplementing the code to use the generic list type
> objects associated
> with the target language. It is possible to do this but unfortunately
> the "List" returned
> is not synchronised with the underlying C++ layer; so it is essentially
> read-only. Any
> manipulation done directly to the object will NOT be reflected within
> the containing model.
>
> Hence our dilemma - and here we value your input :-)
>
> 1) We implement functionality that allows retrieval and manipulation of
> a List object in
> line with the C++ API BUT we do so in such a way that is even less
> native than the rest of
> the SWIG generated APIs.
>
> OR
>
> 2) We implement more native solutions with allows retrieval but not
> manipulation AND thus
> create a mismatch in functionality between the C++ and bindings API
>
> Please let us know what you think ?
>
> Akiya, Mike & Sarah
>
> ____________________________________________________________
> To manage your libsbml-development list subscription, visit
> https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
>
> For a web interface to the libsbml-development mailing list, visit
> http://sbml.org/Forums/
>
> For questions or feedback about the libsbml-development list,
> contact sbml-team@caltech.edu
>
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|
Posts: 81
Registered: August 2005
|
|
Re: List objects in language bindings
|
03 Jun '09 13:03

|
 |
|
Hello given your options:
>
> 1) We implement functionality that allows retrieval and manipulation of
> a List object in
> line with the C++ API BUT we do so in such a way that is even less
> native than the rest of
> the SWIG generated APIs.
>
> OR
>
> 2) We implement more native solutions with allows retrieval but not
> manipulation AND thus
> create a mismatch in functionality between the C++ and bindings API
>
> Please let us know what you think ?
>
1) I'm not too sure what to do with this one as I don't see what you have
planned. Reading this I would imagine something along the lines of getting
rid of the 'list' object and make people use the getNumXXX and getXX()
functions of the model object.
2) will obviously cause more confusion, as people will invariably lose their
updates or wonder why they are not allowed to change things.
So I guess I would prefer 1), without knowing how it would look :) ... Or
how about
3) You could make swig loose the generic 'list' object, and generate a
couple of 'native lists', that would look like native lists, but the
underlying storage mechanisms would call back to the C++ getXXX functions.
In that case I would be able to use the languages native iterators for
example, and would still be free to modify objects. On the down side this
would involve some custom code, which would be easy to write for languages
like C# (and probably Java), but maybe more difficult for the Matlab
bindings :)
Cheers
Frank
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|
Posts: 57
Registered: May 2008
|
|
Re: List objects in language bindings
|
09 Jun '09 00:48

|
 |
|
Hello Oliver,
I'm sorry for my late reply and thanks for your comment.
Oliver Ruebenacker <curoli@gmail.com> wrote
> Hello Sarah, All,
>
> Why not instead either have a common base class for all list
> elements or separate lists for different types?
Implementing new separate C++ list classes (contained data type is explicitly defined)
instead of existing List class (contained data type is void* which can be casted to an arbitrary type)
and wrapping each new list class by SWIG for each language bindings could be one of solutions
for libSBML-4 or later.
(Another solution would be to replace the List class with one of STL container classes such as
std::vector.
For compatibility, List class can't be replaced in libSBML 3.x.)
Actually 1) (described in Sarah's last email) is based on this solution for wrapping the
following functions returning List* object (contained data type is different respectively)
for language bindings in libSBML 3.x :
- List* SBase::getCVTerms()
(CVTerm* is contained in the List*)
- List* ModelHistory::getListCreators()
(ModelCreator* is contained in the List*)
- List* ModelHistory::getListModifiedDates()
(Date* is contained in the List*)$B!!!!(B
- List* ASTNode::getListOfNodes(...)
(ASTNode* is contained in the List*)$B!!!!(B
By default, SWIG can wrap the List class for each language bindings BUT the
wrapped List class can't behave as expected (e.g. returned value of List::get(int)
function can't be casted to arbitrary data type in language bindings) because
void* data type, which can be casted to an arbitrary data type in C/C++, is wrapped
as a SWIG-specific proxy class (e.g. SWIGTYPE_p_void ) which can't be casted to
an arbitraty data type and thus useless in each language bindings (and thus List class
has not been wrapped for language bindings..).
To avoid this problem, the following technique is used in 1) :
(1) internally implementes ListWrapper<TYPENAME> (C++) class which is instantiated
for each class (i.e. ListWrpper<CVTerm*>, ListWrpper<ModelCreator*>, ListWrpper<Date*>
, and ListWrpper<ASTNode*>).
ListWrapper<TYPENAME> is a wrapper class for List* object and provides wrapper
functions with explicit data type such as "CVTerm* ListWrapper<CVTerm*>::get(int)"
and "void ListWrapper<CVTerm*>::set(CVTerm*)" which can be properly wrapped by SWIG.
(2) SWIG wraps the above 4 separates list classes as CVTermList, ModelCreatorList,
DateList, and ASTNodeList classes for each language bindings.
(3) SWIG wraps the above four functions returning List* object by internally
mapping List* (C++ layer) <-> XXXXList (language bindings layer).
For example, "List* SBase::getCVTerms()" function is wrapped as
"CVTermList SBase.getCVTerms()".
The strong point of this solution is that the return value of the above 4 functions
can be basically manipulated by the same interfaces of C++ List (e.g. get(), add(), remove())
for each language bindings.
Do you think the above solution is reasonable?
Thanks,
Akiya
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|
Posts: 57
Registered: May 2008
|
|
Re: List objects in language bindings
|
09 Jun '09 06:24

|
 |
|
Hello Lucian,
Thanks for your comment and sorry for my late reply.
Lucian Smith <lpsmith@spod-central.org> wrote
> Hmm, let's see. A couple opinions that may or may not be helpful, since
> I'm one of your C++ users.
>
> First of all, the List class itself is old and a bit scary. When I had a
> question last month about using List or looping through the ASTNodes some
> other way, the answer was 'do it some other way'. So if the List itself
> goes away in favor of a more modern C++ approach, I don't think anyone
> would shed any tears.
Regarding this, we'll consider replacing the List class with std::vector
class (or another container class) for libsbml-4 or later.
> Secondly, I assume the issue here is that the list object itself is
> 'read-only', and that if it contains pointers, those pointers are indeed
> manipulable. That's all I've needed thus far, so if so, the only
> remaining task is manipulating the list itself (to add or delete members,
> one presumes).
>
> I think the simplest approach would be to provide these functions:
>
> NativeListObject getListOfWhateverFrom(theThingItLivesIn, thisone);
> returncode setListOfWhateverIn (theThingItGoesIn, thisone);
>
> In other words, don't provide pointers to the list objects, provide actual
> native lists. Then the user can manipulate it to their heart's content,
> then save their manipulation with the 'set' function.
Thanks for your idea.
The following example interfaces are what you want?
vector<CVTerm*> SBase::getCVTerms();
int SBase::setCVTerms(vector<CVTerm*>&);
This seems to be one of consistent approaches for getting/setting list objects.
One of weak points may be that the granularity of the manipulation for list objects
is a bit coarse.
> You'll have to do some heavy lifting in the 'set' function to make sure
> you don't delete valid pointers and to make sure you do delete nonvalid
> pointers, but however hairy that code, the user doesn't have to worry
> about it.
This is a bit difficult problem.
Some restrictions such as
1) objects in the given list are cloned and copied like most of functions in
the current libSBML.
2) existing list objects contained in the target object (e.g. an SBase object
for the SBase::setCVTerms(..)) are deleted by the target object (i.e. pointers
or references to the existing list objects become invalid)
may make it easy to implement the set function but usability would be reduced.
Anyway, further consideration would be needed for this.
Thanks,
Akiya
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|
Posts: 57
Registered: May 2008
|
|
Re: List objects in language bindings
|
10 Jun '09 09:55
|
 |
|
Hello Frank,
Thanks for your comment and I'm sorry for my late reply.
"Frank Bergmann" <fbergman@u.washington.edu> wrote
> Hello given your options:
>
> >
> > 1) We implement functionality that allows retrieval and manipulation of
> > a List object in
> > line with the C++ API BUT we do so in such a way that is even less
> > native than the rest of
> > the SWIG generated APIs.
> >
> > OR
> >
> > 2) We implement more native solutions with allows retrieval but not
> > manipulation AND thus
> > create a mismatch in functionality between the C++ and bindings API
> >
> > Please let us know what you think ?
> >
>
> 1) I'm not too sure what to do with this one as I don't see what you have
> planned. Reading this I would imagine something along the lines of getting
> rid of the 'list' object and make people use the getNumXXX and getXX()
> functions of the model object.
The purpose of 1) is basically to wrap the following functions returning List*
object.
- List* SBase::getCVTerms()
- List* ModelHistory::getListCreators()
- List* ModelHistory::getListModifiedDates()
- List* ASTNode::getListOfNodes(...)
I described the detailed explanation in my privous post (reply to Oliver).
> 2) will obviously cause more confusion, as people will invariably lose their
> updates or wonder why they are not allowed to change things.
>
> So I guess I would prefer 1), without knowing how it would look :) ... Or
> how about
>
> 3) You could make swig loose the generic 'list' object, and generate a
> couple of 'native lists', that would look like native lists, but the
> underlying storage mechanisms would call back to the C++ getXXX functions.
> In that case I would be able to use the languages native iterators for
> example, and would still be free to modify objects. On the down side this
> would involve some custom code, which would be easy to write for languages
> like C# (and probably Java), but maybe more difficult for the Matlab
> bindings :)
This technique is great and I think this can be implemented in Java.
However, I'm not sure if this can be implemented in other language bindings
(Ruby, Python, and Perl).
Thanks,
Akiya
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|
|