For the purposes of this question, OO is not necessary.
When you look through all it's trapings(sic), OO is just a way to organize code in a more readably(sic) way.
SQL is completly(sic) unnecessary.
Well, you're certainly entitled to your opinion. Not that I think it has any relationship to reality, but still.:-)
You know, one [object model] that is recognizable by your fellow programmers.
With regard to that, I'm the boss -- I own the company outright -- so it's my way or the highway.
Though I've learned a lot from some of our hires, I must say. But that's fine; just adds more to "my way" and gets them raises and bonuses and so on. Firm commitment with data to back you up is one thing; arbitrarily inflexible is just plain stupid.
Funny story; after an impassioned plea from a new guy with sterling credentials, I set him up with the task of porting from a stable phase of our primary app's C code to C++. Took him a little over a year. When he was done, the.EXE was 15 MB instead of 3.something, and enough slower on redraws that the engine layering was compromised on a then-current machine. Which I don't know to attribute to C++, probably just an implementation issue. The size, though, that seemed pretty clearly to be an issue with how MSVC5 was making code. Anyway, we had a few meetings whereby he got to point to what he thought were advantages of the new models for operators, area selections, movable timeline events and layers and field questions from us... no one was convinced (honestly, I think that might have even included him), and we shelved it. I still have the source archived, though it's now many revs behind the current C code; I thought it might come in useful some day. Guy still consults for me (it's been quite a few years now), but it's all pure C these days. I'll have to ask him what he thinks of all that, now that it's all water long under the bridge.
Well, an object class implementation (in C, specifically) might have a object=GimmeObject() that returns the allocated object (pointer to struct) which has all the methods, including destructor of course, and local variables set up. Easy enough to imagine, right? So that's the initial class. Presuming allocation and setup succeeds, of course.:-)
Now we might write a class that inherits the original object by making the original struct definition and init() the first part of the new structure, adding methods and variables as needed in the new extended area, overriding methods in the original as needed, even developing a super capability to run the original init as part of the new init by moving the original init to a private call, replacing the original with a new one. It also probably has a new destructor if it is anything more than overridden methods.
So now you call object=GimmeInheritedObject() and you get the original, with preexisting methods or overridden methods, preexisting init or super+ new init or new init, plus any new capabilities you care to glue on. When you're done, you call (*object->poof)(object) and it is properly disposed of.
There's nothing virtual about this, and no unusual casting involved. You simply get the functionality of the original object, including methods and etc, plus new stuff as you decide, overriding as you go. Syntax to use the new object is exactly like the old object except for the parts you override and extend,so -- if you're on the ball -- you might even be able to use the new class like the old class. You get it from somewhere else (after all, it's not the original object) but you dispose of it the same way, via its internal poof().
That's how I do it; I'm sure there are other ways, but this has worked very well for me.
Does that address your question? Or have I not understood what you were asking me? I could easily be answering the wrong things here, as I developed this stuff long ago in order to address specific needs I had at the time, and I've no great experience with C++ itself. Python, I've got some hours with, though, and to the extent that I use OO in python, it's pretty familiar to me in the terms I've laid out here.
...and in my experience of continuous programming since the early seventies, I have yet to encounter a wheel I *didn't* feel was entertaining the first time around (for me.) That, and I have a lot of hand-crafted wheels in my toolbox at this point.
Actually, if you packed it with the *goal* of being field readable, it'd be fine. Rather than go for max compression, I mean. Pack it in hexadecimal, for instance, and it'd be 100% editable, plus the reasonable database ops you'd like (equality, for instance) would work on it in string mode, and it'd be about as readable as any binary object ever is. It'd cost some storage space (you can get considerably more compression using base64, Ascii85 or e91) but the benefits could be competitive if flat's how you roll...
It has been my consistent experience that the more you depend on other people's APIs, the more...
...your project grows in distribution requirements and annoyances
...bytes your EXE consumes
...bugs you can't fix accumulate
...code accumulates which you don't actually understand
...subtle bugs creep in because you don't understand what you've included
...you have trouble making things portable
...legal coercion you are subject to
...obligations you have to 3rd parties increase
...you have trouble maintaining the code
...compatibility and functionality between different port targets diverges
Consequently, despite the dangling (and mostly illusory, IMHO) temptation of saving time, I'd just as soon write as much of an application as I can. After decades of writing my own stuff, I have a lot of things I can use, that I *designed* to be usable, in other projects that don't suffer from any of the above problems. I don't mind writing things, either, programming is sort of a zen thing for me. What I mind is not getting it to work correctly and being unable to fix it because some of it is out of my control. Now *that* tweaks my nose. Yes, I'm definitely a control freak.
And in that spirit, as well as a course with something decently OO and capable (Python!), a course on programming databases seems called for. Many science efforts involve collecting, and working with, huge amounts of data. Seems to me that a medium dip into SQL (PostgreSQL!) is called for here. Also courses on spreadsheets (not just Excel) and a solid whipping with Maple, Mathematica, etc.
The best carpenter in the world is crippled without a good set of chisels.
Most of the overhead I've observed has been in much larger executables. Not speed; compilers tend to be awesome at unrolling loops and all manner of other trickery that you wouldn't generally do by hand (because it'd be insanely ugly and hard to understand.)
On your other point, though, I find using functions inside structures (essentially objects) as methods to be so simple as to be absolutely painless. I wonder what you're running into with your virtual functions.
Definition:
struct foo
{
long l_foo;
float f_foo;
int (*function_foo)(struct *foo,int a,float b);
};
Use:
struct foo myfoo;
init_foo(&myfoo);// initialize foo, set function pointer, variables, etc...
(*myfoo.function_foo)(&myfoo,1,2.0f);// use method
Like as in, things that cause C "warnings" cause Ada to fail compilation until you fix it.
The source code for an image manipulation / FX application I work with every day consists of over a hundred megabytes of C source code. You can recompile the whole thing and, unless you just screwed up whatever you did, there will be no warnings. Not one.
If you came to my company and started writing code that generated warnings, you'd first be notified that wasn't acceptable (and handed back your code for rework), and if you persisted, you'd find yourself looking for another job.
As long as the compiler will warn us about things, there's no need for warnings to turn into errors. There's simply a need for discipline on the part of the programmer(s).
C is perfectly capable of many of the most useful object oriented techniques. Objects with methods and locals, classes (instantiating objects from models), inheritance -- all of these are easily and efficiently implemented in C without library or compiler-generated overhead. All the while, the programmer can remain in complete control, and the application can remain fast and lightweight. You can't do everything; there are some object-oriented paradigms that don't fit, but frankly, they're not critical. The important parts are easily managed.
You should imagine it because you are conflating the number of bits required to count things with the number of bits required to discriminate among things. The two are entirely disjoint.
Making dbtext handle arbitrarily packed fields would probably take me a couple hours at most. Perhaps not that long. I didn't do it because I had no need for it. The file format would remain editable at the field and record level by standard text editors because no characters above 127 would be present in any field. What it wouldn't remain is field-readable, which is probably what you meant to say anyway. Still, field readability is just one feature of many that makes the engine useful to me; wouldn't concern me if it wasn't available in the intra-record sense when used with non-ASCII character sets and binary data like images, etc. Presently I store binary objects in the filesystem and records about them in the database; I find that very convenient for a lot of reasons, but that's just the way I prefer to do things, means nothing for other people's applications of the class.
It still isn't big enough to do even a half decent job.
Imagine that a bit has a coherent meaning, such as "image contains a kitten." If the bit is zero, there is no kitten in the image; if it is one, there is at least one kitten in the image.
Now imagine that system extended for all types of animals. Going to go past a requirement for 1024 bits pretty fast, isn't it?
Now imagine that a bit represents "image contains a keyboard" in the same fashion.
Now imagine a bit for every type of macro and micro technological object there is. Going to require hundreds of millions of bits just for that.
Finally, imagine a bit that says "image contains person Rockoon." Now imagine a bit for every person on the planet -- about seven billion bits.
It is totally irrelevant if 2^1024 can represent all the atoms in the universe. It's still woefully small for the task we're talking about.
This means that either the information will be extremely general (and probably not correlate well with human interests) or it will be so narrow and specific as to only be of use to the entity that specified the analysis in the first place.
The only kind of approach that would really work is a system that allows unlimited storage for classification of each image, where classification is performed by multiple experts (a'la Amazon's "sell a task" method), where each required test ("Does image contain a kitten?") would require a complete pass through the image set by the experts.
Machine vision analysis isn't even close to being able to take on the role of expert in this sense, and you're not going to arrive at that state with a naive approach such as that suggested in this paper, either.
Seriously, it's amusing when people climb into the thread without understanding what its about, much less where it came from, and bitch because the ggp post that started it all remains relevant throughout. It's almost like reading... were a lost skill.
Go on, take yourself up to the top of the thread -- also the first post in the article, in this case -- and see what it's about. Oh, look... it's that "fyngyrz" dude with a post about... dbtext!!! Every other post that "fyngyrz" dude made was in the thread(s) that descend(s) from that post. Funny thing, eh? And why would that "fyngyrz" dude be posting? Why, because the responses, marvel of marvels, are weighing the merits of things like SQLite against... wait for it... dbtext!
It isn't so much that I'm responding to them, you see. They're actually responding to me at various levels. I'm just polite enough to answer, that's all.
You can (a) pack greater than 7-bit codes, or (b) request of the author the addition of greater than seven bit codes. Don't think either one is much of a show-stopper.
I honestly believe that if you put your code out there for someone to use you should try to get something for it. Your life, the time you spend writing the code, is valuable. Make it worth something.
It's my code; I chose to make it PD; and I do get something for it, I get to add a shoulder to the wheel, as it were, if anyone will accept my contribution... and I enjoy the idea that the time I spent saves someone else some of theirs, hopefully such that they can create something above and beyond what I already did. Sometimes that's enough. I've gotten lots of help off the net, no strings at all -- so I don't find it at all peculiar to offer something back likewise sans strings.
Some works we contribute; some things we ask a return for. I'm ok with both approaches, really, it is the ones in the middle (supposedly "free", but with substantial strings) that don't attract me either as a user or a contributor. That's just me. What seems to rile people up is if I talk about the reality of those strings. That's when we get these threadfests.
Well, you're certainly entitled to your opinion. Not that I think it has any relationship to reality, but still. :-)
Yeah, inheritance in C is a cast-iron bitch as well:
struct bar
{
struct foo;
}
By the way, I'm a huge fan of Python. It's my preferred interpreted language.
With regard to that, I'm the boss -- I own the company outright -- so it's my way or the highway.
Though I've learned a lot from some of our hires, I must say. But that's fine; just adds more to "my way" and gets them raises and bonuses and so on. Firm commitment with data to back you up is one thing; arbitrarily inflexible is just plain stupid.
Funny story; after an impassioned plea from a new guy with sterling credentials, I set him up with the task of porting from a stable phase of our primary app's C code to C++. Took him a little over a year. When he was done, the .EXE was 15 MB instead of 3.something, and enough slower on redraws that the engine layering was compromised on a then-current machine. Which I don't know to attribute to C++, probably just an implementation issue. The size, though, that seemed pretty clearly to be an issue with how MSVC5 was making code. Anyway, we had a few meetings whereby he got to point to what he thought were advantages of the new models for operators, area selections, movable timeline events and layers and field questions from us... no one was convinced (honestly, I think that might have even included him), and we shelved it. I still have the source archived, though it's now many revs behind the current C code; I thought it might come in useful some day. Guy still consults for me (it's been quite a few years now), but it's all pure C these days. I'll have to ask him what he thinks of all that, now that it's all water long under the bridge.
Well, an object class implementation (in C, specifically) might have a object=GimmeObject() that returns the allocated object (pointer to struct) which has all the methods, including destructor of course, and local variables set up. Easy enough to imagine, right? So that's the initial class. Presuming allocation and setup succeeds, of course. :-)
Now we might write a class that inherits the original object by making the original struct definition and init() the first part of the new structure, adding methods and variables as needed in the new extended area, overriding methods in the original as needed, even developing a super capability to run the original init as part of the new init by moving the original init to a private call, replacing the original with a new one. It also probably has a new destructor if it is anything more than overridden methods.
So now you call object=GimmeInheritedObject() and you get the original, with preexisting methods or overridden methods, preexisting init or super+ new init or new init, plus any new capabilities you care to glue on. When you're done, you call (*object->poof)(object) and it is properly disposed of.
There's nothing virtual about this, and no unusual casting involved. You simply get the functionality of the original object, including methods and etc, plus new stuff as you decide, overriding as you go. Syntax to use the new object is exactly like the old object except for the parts you override and extend,so -- if you're on the ball -- you might even be able to use the new class like the old class. You get it from somewhere else (after all, it's not the original object) but you dispose of it the same way, via its internal poof().
That's how I do it; I'm sure there are other ways, but this has worked very well for me.
Does that address your question? Or have I not understood what you were asking me? I could easily be answering the wrong things here, as I developed this stuff long ago in order to address specific needs I had at the time, and I've no great experience with C++ itself. Python, I've got some hours with, though, and to the extent that I use OO in python, it's pretty familiar to me in the terms I've laid out here.
Actually, if you packed it with the *goal* of being field readable, it'd be fine. Rather than go for max compression, I mean. Pack it in hexadecimal, for instance, and it'd be 100% editable, plus the reasonable database ops you'd like (equality, for instance) would work on it in string mode, and it'd be about as readable as any binary object ever is. It'd cost some storage space (you can get considerably more compression using base64, Ascii85 or e91) but the benefits could be competitive if flat's how you roll...
It has been my consistent experience that the more you depend on other people's APIs, the more...
Consequently, despite the dangling (and mostly illusory, IMHO) temptation of saving time, I'd just as soon write as much of an application as I can. After decades of writing my own stuff, I have a lot of things I can use, that I *designed* to be usable, in other projects that don't suffer from any of the above problems. I don't mind writing things, either, programming is sort of a zen thing for me. What I mind is not getting it to work correctly and being unable to fix it because some of it is out of my control. Now *that* tweaks my nose. Yes, I'm definitely a control freak.
YMMV, of course. This is just me.
And in that spirit, as well as a course with something decently OO and capable (Python!), a course on programming databases seems called for. Many science efforts involve collecting, and working with, huge amounts of data. Seems to me that a medium dip into SQL (PostgreSQL!) is called for here. Also courses on spreadsheets (not just Excel) and a solid whipping with Maple, Mathematica, etc.
The best carpenter in the world is crippled without a good set of chisels.
For code efficiency, yes; syntactically, it's identical though. These folks are arguing over syntax / writability.
Most of the overhead I've observed has been in much larger executables. Not speed; compilers tend to be awesome at unrolling loops and all manner of other trickery that you wouldn't generally do by hand (because it'd be insanely ugly and hard to understand.)
On your other point, though, I find using functions inside structures (essentially objects) as methods to be so simple as to be absolutely painless. I wonder what you're running into with your virtual functions.
Definition:
struct foo
{
long l_foo;
float f_foo;
int (*function_foo)(struct *foo,int a,float b);
};
Use:
// initialize foo, set function pointer, variables, etc ... // use method
struct foo myfoo;
init_foo(&myfoo);
(*myfoo.function_foo)(&myfoo,1,2.0f);
If it happens, just remember to #include "shyster.h", that's all.
The source code for an image manipulation / FX application I work with every day consists of over a hundred megabytes of C source code. You can recompile the whole thing and, unless you just screwed up whatever you did, there will be no warnings. Not one.
If you came to my company and started writing code that generated warnings, you'd first be notified that wasn't acceptable (and handed back your code for rework), and if you persisted, you'd find yourself looking for another job.
As long as the compiler will warn us about things, there's no need for warnings to turn into errors. There's simply a need for discipline on the part of the programmer(s).
Python:
for i in range(3): print "Hello World!"
and...
for i in range(ord('a'),ord('f')): print chr(i),
or, for explicit specifications...
for i in "abcde": print i,
C is perfectly capable of many of the most useful object oriented techniques. Objects with methods and locals, classes (instantiating objects from models), inheritance -- all of these are easily and efficiently implemented in C without library or compiler-generated overhead. All the while, the programmer can remain in complete control, and the application can remain fast and lightweight. You can't do everything; there are some object-oriented paradigms that don't fit, but frankly, they're not critical. The important parts are easily managed.
You should imagine it because you are conflating the number of bits required to count things with the number of bits required to discriminate among things. The two are entirely disjoint.
[!] ...and here I thought there was no reason in the entire world for me to support long copyright terms.
Just so you know, I am the author. :-)
Making dbtext handle arbitrarily packed fields would probably take me a couple hours at most. Perhaps not that long. I didn't do it because I had no need for it. The file format would remain editable at the field and record level by standard text editors because no characters above 127 would be present in any field. What it wouldn't remain is field-readable, which is probably what you meant to say anyway. Still, field readability is just one feature of many that makes the engine useful to me; wouldn't concern me if it wasn't available in the intra-record sense when used with non-ASCII character sets and binary data like images, etc. Presently I store binary objects in the filesystem and records about them in the database; I find that very convenient for a lot of reasons, but that's just the way I prefer to do things, means nothing for other people's applications of the class.
It still isn't big enough to do even a half decent job.
Imagine that a bit has a coherent meaning, such as "image contains a kitten." If the bit is zero, there is no kitten in the image; if it is one, there is at least one kitten in the image.
Now imagine that system extended for all types of animals. Going to go past a requirement for 1024 bits pretty fast, isn't it?
Now imagine that a bit represents "image contains a keyboard" in the same fashion.
Now imagine a bit for every type of macro and micro technological object there is. Going to require hundreds of millions of bits just for that.
Finally, imagine a bit that says "image contains person Rockoon." Now imagine a bit for every person on the planet -- about seven billion bits.
It is totally irrelevant if 2^1024 can represent all the atoms in the universe. It's still woefully small for the task we're talking about.
This means that either the information will be extremely general (and probably not correlate well with human interests) or it will be so narrow and specific as to only be of use to the entity that specified the analysis in the first place.
The only kind of approach that would really work is a system that allows unlimited storage for classification of each image, where classification is performed by multiple experts (a'la Amazon's "sell a task" method), where each required test ("Does image contain a kitten?") would require a complete pass through the image set by the experts.
Machine vision analysis isn't even close to being able to take on the role of expert in this sense, and you're not going to arrive at that state with a naive approach such as that suggested in this paper, either.
Everyone knows those are unstable. What were you thinking?
Seriously, it's amusing when people climb into the thread without understanding what its about, much less where it came from, and bitch because the ggp post that started it all remains relevant throughout. It's almost like reading... were a lost skill.
Go on, take yourself up to the top of the thread -- also the first post in the article, in this case -- and see what it's about. Oh, look... it's that "fyngyrz" dude with a post about... dbtext!!! Every other post that "fyngyrz" dude made was in the thread(s) that descend(s) from that post. Funny thing, eh? And why would that "fyngyrz" dude be posting? Why, because the responses, marvel of marvels, are weighing the merits of things like SQLite against... wait for it... dbtext!
It isn't so much that I'm responding to them, you see. They're actually responding to me at various levels. I'm just polite enough to answer, that's all.
You can (a) pack greater than 7-bit codes, or (b) request of the author the addition of greater than seven bit codes. Don't think either one is much of a show-stopper.
It's my code; I chose to make it PD; and I do get something for it, I get to add a shoulder to the wheel, as it were, if anyone will accept my contribution... and I enjoy the idea that the time I spent saves someone else some of theirs, hopefully such that they can create something above and beyond what I already did. Sometimes that's enough. I've gotten lots of help off the net, no strings at all -- so I don't find it at all peculiar to offer something back likewise sans strings.
Some works we contribute; some things we ask a return for. I'm ok with both approaches, really, it is the ones in the middle (supposedly "free", but with substantial strings) that don't attract me either as a user or a contributor. That's just me. What seems to rile people up is if I talk about the reality of those strings. That's when we get these threadfests.
You're most welcome. I am delighted that you might be able to use my dbtext project somehow. Cheers!
Works now -- thanks