Discussion:
New version of the C containers library
(too old to reply)
jacobnavia
2017-07-07 09:26:03 UTC
Permalink
It is just not true that you need to go to C++ to use a container library.

The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)

You can download it from:

https://github.com/jacob-navia/ccl.git

There are no strings attached, use it as you wish.
Reinhardt Behm
2017-07-07 09:50:32 UTC
Permalink
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
Your containers have no strings? ;-)
--
Reinhardt
jacobnavia
2017-07-07 10:32:46 UTC
Permalink
Post by Reinhardt Behm
Post by jacobnavia
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
Your containers have no strings? ;-)
They are not attached! :-)
Melzzzzz
2017-07-07 10:08:50 UTC
Permalink
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
What is the license? Can I use it for commercial development?
--
press any key to continue or any other to quit...
Ben Bacarisse
2017-07-07 10:15:05 UTC
Permalink
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
A note about language. The form "you do not need to go to C++ to use a
container library", would be used to state a fact. But saying "it is
just not true that..." means you are rebutting someone who has said that
it is true and I'm not aware of anyone who has. The effect is to be
confrontational and argumentative rather than simply informative. That
may have been your intent, but I mention it in case it was not.
Post by jacobnavia
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
This suggests that there is no down-side at all. I suspect that because
C's type system is simpler, the user code (for a similar task) ends up
being more complicated. In effect you /loose/ some of the associated
simplifications associated with the complexities! I think a more
persuasive case is made when both sides are presented.

<snip>
--
Ben.
Malcolm McLean
2017-07-07 11:40:37 UTC
Permalink
Post by Ben Bacarisse
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
A note about language. The form "you do not need to go to C++ to use a
container library", would be used to state a fact. But saying "it is
just not true that..." means you are rebutting someone who has said that
it is true and I'm not aware of anyone who has. The effect is to be
confrontational and argumentative rather than simply informative. That
may have been your intent, but I mention it in case it was not.
I don't think so. Obviously Jacob is arguing for use of his library. But it's
objectively the case that STL has gained wide acceptance in the C++
community - everyone knows about it, most people use it, it is accepted
into the standard namespace, whilst can't say the same thing about any C
library designed to achieve similar things. In fact Jacob is acknowledging
the fact that the C container library remains a minor project (he's got six
stars on github, which is three for than for my binary image processing
library).
Post by Ben Bacarisse
Post by jacobnavia
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
This suggests that there is no down-side at all. I suspect that because
C's type system is simpler, the user code (for a similar task) ends up
being more complicated. In effect you /loose/ some of the associated
simplifications associated with the complexities! I think a more
persuasive case is made when both sides are presented.
The typical case with C++ is that fairly complex coding is used to create
something which is superficially simple and straightforwards to use,
however when things go wrong, it can be very difficult to understand or
trace the error. Even with modern C++ compiler, the error messages generated
by templated types can be too convoluted to be easily understandable.
Kenny McCormack
2017-07-07 12:39:24 UTC
Permalink
In article <69bc30e5-357b-4172-b2ea-***@googlegroups.com>,
Malcolm McLean <***@gmail.com> wrote:
...
In fact Jacob is acknowledging the fact that the C container library
remains a minor project (he's got six stars on github, which is three for
than for my binary image processing library).
s/three for/three more/
--
Debating creationists on the topic of evolution is rather like trying to
play chess with a pigeon --- it knocks the pieces over, craps on the
board, and flies back to its flock to claim victory.
Ben Bacarisse
2017-07-07 13:32:53 UTC
Permalink
Post by Malcolm McLean
Post by Ben Bacarisse
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
A note about language. The form "you do not need to go to C++ to use a
container library", would be used to state a fact. But saying "it is
just not true that..." means you are rebutting someone who has said that
it is true and I'm not aware of anyone who has. The effect is to be
confrontational and argumentative rather than simply informative. That
may have been your intent, but I mention it in case it was not.
I don't think so. Obviously Jacob is arguing for use of his library. But it's
objectively the case that STL has gained wide acceptance in the C++
community - everyone knows about it, most people use it, it is accepted
into the standard namespace, whilst can't say the same thing about any C
library designed to achieve similar things. In fact Jacob is acknowledging
the fact that the C container library remains a minor project (he's got six
stars on github, which is three for than for my binary image processing
library).
I'm not sure what it is you don't think. I agree with everything you
said after "I don't think so". Are you saying that something being
"just not true" is not argumentative? OK. I seems that way to me, but
I'm only one of many readers.
Post by Malcolm McLean
Post by Ben Bacarisse
Post by jacobnavia
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
This suggests that there is no down-side at all. I suspect that because
C's type system is simpler, the user code (for a similar task) ends up
being more complicated. In effect you /loose/ some of the associated
simplifications associated with the complexities! I think a more
persuasive case is made when both sides are presented.
The typical case with C++ is that fairly complex coding is used to create
something which is superficially simple and straightforwards to use,
however when things go wrong, it can be very difficult to understand or
trace the error. Even with modern C++ compiler, the error messages generated
by templated types can be too convoluted to be easily understandable.
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
--
Ben.
Malcolm McLean
2017-07-07 13:50:35 UTC
Permalink
Post by Ben Bacarisse
Post by Malcolm McLean
The typical case with C++ is that fairly complex coding is used to create
something which is superficially simple and straightforwards to use,
however when things go wrong, it can be very difficult to understand or
trace the error. Even with modern C++ compiler, the error messages generated
by templated types can be too convoluted to be easily understandable.
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
I find that's not true.

A reasonably good C++ programmer will usually try to write code so that callers
have the ideal environment. But he then uses various templates and other tricks
to achieve that, so the cost of giving caller a good environment is that the code
itself is difficult to read. But caller is simply the next level up, he adopts a similar
policy. The result is two things, firstly a lot of hard to read code, secondly a lot
of one line wrapping or adapter functions which wrap a generic with a specific
or hide other ugliness. The one line functions are also confusing, because
the function itself contains almost no information except the name of its
subroutine.
Ben Bacarisse
2017-07-07 16:04:32 UTC
Permalink
Post by Malcolm McLean
Post by Ben Bacarisse
Post by Malcolm McLean
The typical case with C++ is that fairly complex coding is used to create
something which is superficially simple and straightforwards to use,
however when things go wrong, it can be very difficult to understand or
trace the error. Even with modern C++ compiler, the error messages generated
by templated types can be too convoluted to be easily understandable.
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
I find that's not true.
A reasonably good C++ programmer will usually try to write code so
that callers have the ideal environment. But he then uses various
templates and other tricks to achieve that, so the cost of giving
caller a good environment is that the code itself is difficult to
read. But caller is simply the next level up, he adopts a similar
policy. The result is two things, firstly a lot of hard to read code,
secondly a lot of one line wrapping or adapter functions which wrap a
generic with a specific or hide other ugliness. The one line functions
are also confusing, because the function itself contains almost no
information except the name of its subroutine.
I don't find that (unless I've misunderstood). Here's one way to write
the program that was used as illustration before:

#include <fstream>
#include <iostream>
#include <string>
#include <map>
#include <vector>

int main(int argc, char **argv)
{
if (argc == 2) {
std::map<std::string, std::vector<size_t>> positions;

std::ifstream fin(argv[1]);
std::string word;
while (fin >> word)
positions[word].push_back((size_t)fin.tellg() - word.length());
fin.close();

for (auto &pair : positions) {
std::cout << pair.first;
for (auto &pos : pair.second)
std::cout << " " << pos;
std::cout << "\n";
}
}
}

I don't recognise any of the problems you describe here and I seem to
remember the C version was not as clear (to me at least).
--
Ben.
Malcolm McLean
2017-07-08 11:04:31 UTC
Permalink
Post by Ben Bacarisse
Post by Malcolm McLean
Post by Ben Bacarisse
Post by Malcolm McLean
The typical case with C++ is that fairly complex coding is used to create
something which is superficially simple and straightforwards to use,
however when things go wrong, it can be very difficult to understand or
trace the error. Even with modern C++ compiler, the error messages generated
by templated types can be too convoluted to be easily understandable.
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
I find that's not true.
A reasonably good C++ programmer will usually try to write code so
that callers have the ideal environment. But he then uses various
templates and other tricks to achieve that, so the cost of giving
caller a good environment is that the code itself is difficult to
read. But caller is simply the next level up, he adopts a similar
policy. The result is two things, firstly a lot of hard to read code,
secondly a lot of one line wrapping or adapter functions which wrap a
generic with a specific or hide other ugliness. The one line functions
are also confusing, because the function itself contains almost no
information except the name of its subroutine.
I don't find that (unless I've misunderstood). Here's one way to write
#include <fstream>
#include <iostream>
#include <string>
#include <map>
#include <vector>
int main(int argc, char **argv)
{
if (argc == 2) {
std::map<std::string, std::vector<size_t>> positions;
std::ifstream fin(argv[1]);
std::string word;
while (fin >> word)
positions[word].push_back((size_t)fin.tellg() - word.length());
fin.close();
for (auto &pair : positions) {
std::cout << pair.first;
for (auto &pos : pair.second)
std::cout << " " << pos;
std::cout << "\n";
}
}
}
I don't recognise any of the problems you describe here and I seem to
remember the C version was not as clear (to me at least).
--
Ben.
The idea is that we've got a hierarchy of functions, caller and callee,
and each function is written with the needs of caller in mind. So
it sacrifices its own clarity for that of its caller. If all functions
do that, the result is that nothing is clear. With the exception of
programs with only two levels or hierarchy. (In fact main is usually
a mess for other reasons).

But compare the first significant lines

C++
std::map<std::string, std::vector<size_t>> positions;

ccl:
strCollection *text = istrCollection.CreateFromFile(fileName);

Now admittedly with C++ there's a bit of confusing name choice for
historical reasons. No-one would expect a "vector" to be an array
or "size_t" to be the type for an index variable. And pretty much
every function or data structure is a "map" of some description,
it doesn't carry the mind to a binary search tree.

But it's not obvious whether code is being called or not with the C++
version. With Jacob's, it's a clear RAII model. Then the strings are
in fact sorted alphabetically, but where do you tell the program that?
With Jacob's, it's a string type, so it's clearly built into the
function. With the generic, in fact it's because you overload the '<'
operator. But to know that requires a fairly deep familiarity with C++.
Ben Bacarisse
2017-07-08 11:57:02 UTC
Permalink
Post by Malcolm McLean
Post by Ben Bacarisse
Post by Malcolm McLean
Post by Ben Bacarisse
Post by Malcolm McLean
The typical case with C++ is that fairly complex coding is used to create
something which is superficially simple and straightforwards to use,
however when things go wrong, it can be very difficult to understand or
trace the error. Even with modern C++ compiler, the error messages generated
by templated types can be too convoluted to be easily understandable.
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
I find that's not true.
A reasonably good C++ programmer will usually try to write code so
that callers have the ideal environment. But he then uses various
templates and other tricks to achieve that, so the cost of giving
caller a good environment is that the code itself is difficult to
read. But caller is simply the next level up, he adopts a similar
policy. The result is two things, firstly a lot of hard to read code,
secondly a lot of one line wrapping or adapter functions which wrap a
generic with a specific or hide other ugliness. The one line functions
are also confusing, because the function itself contains almost no
information except the name of its subroutine.
I don't find that (unless I've misunderstood). Here's one way to write
#include <fstream>
#include <iostream>
#include <string>
#include <map>
#include <vector>
int main(int argc, char **argv)
{
if (argc == 2) {
std::map<std::string, std::vector<size_t>> positions;
std::ifstream fin(argv[1]);
std::string word;
while (fin >> word)
positions[word].push_back((size_t)fin.tellg() - word.length());
fin.close();
for (auto &pair : positions) {
std::cout << pair.first;
for (auto &pos : pair.second)
std::cout << " " << pos;
std::cout << "\n";
}
}
}
I don't recognise any of the problems you describe here and I seem to
remember the C version was not as clear (to me at least).
The idea is that we've got a hierarchy of functions, caller and callee,
and each function is written with the needs of caller in mind.
This is probably another case of your using words in a way I don't
understand because that sounds like a terrible idea. The best functions
are generic and have no entanglements with the caller. In high level
languages, functions often do very general things which can be combined
to get the desired effects.
Post by Malcolm McLean
So
it sacrifices its own clarity for that of its caller. If all functions
do that, the result is that nothing is clear. With the exception of
programs with only two levels or hierarchy. (In fact main is usually
a mess for other reasons).
Ah. So when you say "the idea is..." you are descibing a bad idea? One
that should be avoided? If so, I agree.
Post by Malcolm McLean
But compare the first significant lines
C++
std::map<std::string, std::vector<size_t>> positions;
strCollection *text = istrCollection.CreateFromFile(fileName);
Why are you comparing these? The programs do entirely different things.
(For one thing, Jacob's CCL has this peculiarly specialised container
and a specialised function for reading strings from a file. It suits
the program he chose to post but not the program in question here.)
Post by Malcolm McLean
Now admittedly with C++ there's a bit of confusing name choice for
historical reasons. No-one would expect a "vector" to be an array
or "size_t" to be the type for an index variable.
size_t is not used as an index variable in this example. But use long
if you'd rather. If Jacob had posted a program solving this problem,
I'd have used whatever type he used. That way the compassion would
focus on the issue at hand -- the containers -- rather than your dislike
of size_t which applies equally to both languages.

Many you could post a CCL version of this program so we can actually
compare the code?
Post by Malcolm McLean
And pretty much
every function or data structure is a "map" of some description,
it doesn't carry the mind to a binary search tree.
Indeed. I wonder what name the CCL uses that is free from this sort of
criticism.
Post by Malcolm McLean
But it's not obvious whether code is being called or not with the C++
version. With Jacob's, it's a clear RAII model.
There's no RAII in the C code -- there is simply explicit allocation and
deallocation. If you prefer that, that's fine, but it's not RAII.
Post by Malcolm McLean
Then the strings are
in fact sorted alphabetically, but where do you tell the program that?
We need to see equivalent CCL code. Maybe it, too, will show something
about the way maps are stored that you could complain about?
Post by Malcolm McLean
With Jacob's, it's a string type, so it's clearly built into the
function. With the generic, in fact it's because you overload the '<'
operator. But to know that requires a fairly deep familiarity with C++.
You need to know some C++ to understand the code, yes. (For example,
neither I nor anyone else has overloaded the '<' operator in this case.)
But you would need to know the CLL to follow the CLL example. If you
wrote such an thing, we could have an actual comparison. As it is, the
C++ is simply there to be sniped at when many of the same points might
apply to a CCL version of the same program.
--
Ben.
jacobnavia
2017-07-07 14:17:43 UTC
Permalink
Le 07/07/2017 à 15:32, Ben Bacarisse a écrit :

<quote>
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
<end quote>

--------------------------------------------------------------------
#include <containers.h>

static void grep(char *word,char *fileName)
{
strCollection *text = istrCollection.CreateFromFile(fileName);
Iterator *it;
int lineNumber = 1;
char *line;
if (text == NULL) {
fprintf(stderr,"Unable to open '%s'\n",fileName);
return;
}
it = istrCollection.NewIterator(text);
for (line = it->GetFirst(it); line!= NULL;
line = it->GetNext(it),lineNumber++) {
char *p = strstr(line,word);
if (p) {
printf("[%4d] %s\n",lineNumber,line);
}
}
istrCollection.DeleteIterator(it);
istrCollection.Finalize(text);
}

int main(int argc,char *argv[])
{
if (argc < 3) {
fprintf(stderr,"Usage: grep <word> <file>\n");
return EXIT_FAILURE;
}
grep(argv[1],argv[2]);
}
Richard Heathfield
2017-07-07 15:15:59 UTC
Permalink
Post by jacobnavia
<quote>
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
<end quote>
--------------------------------------------------------------------
#include <containers.h>
static void grep(char *word,char *fileName)
{
strCollection *text = istrCollection.CreateFromFile(fileName);
Iterator *it;
int lineNumber = 1;
char *line;
if (text == NULL) {
fprintf(stderr,"Unable to open '%s'\n",fileName);
return;
}
it = istrCollection.NewIterator(text);
for (line = it->GetFirst(it); line!= NULL;
line = it->GetNext(it),lineNumber++) {
char *p = strstr(line,word);
if (p) {
printf("[%4d] %s\n",lineNumber,line);
}
}
istrCollection.DeleteIterator(it);
istrCollection.Finalize(text);
}
int main(int argc,char *argv[])
{
if (argc < 3) {
fprintf(stderr,"Usage: grep <word> <file>\n");
return EXIT_FAILURE;
}
grep(argv[1],argv[2]);
}
Although I have no particular use for Jacob's library (I'm quite happy
with the STL when using C++ and prefer to use my own containers when
using C), I have to say that the above code looks to me to be about as
clean as you could reasonably hope for in a low-level language. I
suppose it's possible that a C++ version might be cleaner, but I don't
quite see how.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
Ben Bacarisse
2017-07-07 15:50:25 UTC
Permalink
Post by jacobnavia
<quote>
It's reasonable in a C group to stick the knife into C++ but I don't
think there is much doubt that C++'s containers generate simpler code
than any C library is likely to be able to do. There was an example not
so long ago of listing the positions in a file at which each "word"
appears.
<end quote>
The example was chosen to illustrate nested containers. The output was
each "word" in the file followed by the list of file offsets at which it
occurs.
Post by jacobnavia
--------------------------------------------------------------------
#include <containers.h>
static void grep(char *word,char *fileName)
{
strCollection *text = istrCollection.CreateFromFile(fileName);
Why use a container to write grep?
Post by jacobnavia
Iterator *it;
int lineNumber = 1;
char *line;
if (text == NULL) {
fprintf(stderr,"Unable to open '%s'\n",fileName);
return;
}
it = istrCollection.NewIterator(text);
for (line = it->GetFirst(it); line!= NULL;
line = it->GetNext(it),lineNumber++) {
I don't like to repeat code. I'd write

while (line = it->GetFirst(it)) {
...
lineNumber++;
}

<snip>
--
Ben.
Richard Heathfield
2017-07-07 15:57:17 UTC
Permalink
<snip>
Post by Ben Bacarisse
Post by jacobnavia
it = istrCollection.NewIterator(text);
for (line = it->GetFirst(it); line!= NULL;
line = it->GetNext(it),lineNumber++) {
I don't like to repeat code.
Fair enough, except that...
Post by Ben Bacarisse
I'd write
while (line = it->GetFirst(it)) {
...
lineNumber++;
}
...this doesn't do the same thing. You can perhaps rewrite it like this:

int first = 1;
while(line = first ? it->GetFirst(it) : it->GetNext(it))
{
first = 0;
...
lineNumber++;
}

but I'm not convinced that it's cleaner.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
Ben Bacarisse
2017-07-07 17:13:00 UTC
Permalink
Post by Ben Bacarisse
<snip>
Post by Ben Bacarisse
Post by jacobnavia
it = istrCollection.NewIterator(text);
for (line = it->GetFirst(it); line!= NULL;
line = it->GetNext(it),lineNumber++) {
I don't like to repeat code.
Fair enough, except that...
Ah, right. In fact it's not repeated code.
Post by Ben Bacarisse
Post by Ben Bacarisse
I'd write
while (line = it->GetFirst(it)) {
...
lineNumber++;
}
What I'd do is change the API so that GetNext works like GetFirst!
There's a strong argument for making iterators work that way.
Post by Ben Bacarisse
int first = 1;
while(line = first ? it->GetFirst(it) : it->GetNext(it))
{
first = 0;
...
lineNumber++;
}
but I'm not convinced that it's cleaner.
No, indeed. Given the API you have to do something a little messy. I
think that's shame.

What do you think Jacob?
--
Ben.
jacobnavia
2017-07-07 17:54:39 UTC
Permalink
Post by Ben Bacarisse
What do you think Jacob?
Well, this is an interesting idea. As it is now, GetFirst will return
the first (i.e. the zero position) element of a container (lists,
vectors, etc).

This way you can reset an iterator (for a second pass for instance) just
by calling GetFirst again.

It could be better to adapt GetFirst so that it returns a sequence
increasing from the zeroeth to the number of elements but I do not see
why it would be useful since it replicates GetNext(). What use cases do
you have?

Besides, it is a bit of a stretch to see GetFirst() return the 23rd
element, say, isn't it?

Another problem is that a container would need to store the index of the
element to be returned by the next GetFirst(). If you pass a container
as an argument to a function, that function would have no means to know
what will GetFirst() return, so that before calling GetFirst you would
have to ensure that it returns indeed the first element. New APIs would
be needed to read that index and to reset it, complexifying the interface.


Thanks for your input Ben, Richard.

jacob
Ben Bacarisse
2017-07-07 18:41:13 UTC
Permalink
Post by jacobnavia
Post by Ben Bacarisse
What do you think Jacob?
Well, this is an interesting idea. As it is now, GetFirst will return
the first (i.e. the zero position) element of a container (lists,
vectors, etc).
This way you can reset an iterator (for a second pass for instance)
just by calling GetFirst again.
Yes, you need a way to reset the iterator, but the "next" operation
should work from the start -- right after initialisation or reset.
Post by jacobnavia
It could be better to adapt GetFirst so that it returns a sequence
increasing from the zeroeth to the number of elements but I do not see
why it would be useful since it replicates GetNext(). What use cases
do you have?
I was thinking simple loops like this:

while ((x = iterator.next()) != NULL) ...

It's idiomatic in C to write loops like that.
Post by jacobnavia
Besides, it is a bit of a stretch to see GetFirst() return the 23rd
element, say, isn't it?
Quite. I meant to write GetNext. I did not even see that there where
two functions, so when I wrote the example loop in my reply to you I
used GetFirst when I meant (or would have meant if I'd see it) GetNext.
Post by jacobnavia
Another problem is that a container would need to store the index of
the element to be returned by the next GetFirst(). If you pass a
container as an argument to a function, that function would have no
means to know what will GetFirst() return, so that before calling
GetFirst you would have to ensure that it returns indeed the first
element. New APIs would be needed to read that index and to reset it,
complexifying the interface.
I think maybe I've confused matters by writing GetFirst. My point was
that they should be one uniform way to access all the elements, from the
first to the last, via the iterator. I don't think this implies any
extra storage in a container.

Just be 100% clear, I would have expect the loop to look like this:

while (line = it->GetNext(it))
if (strstr(line, word))
printf("[%4d] %s\n", lineNumber++, line);

<snip>
--
Ben.
Stefan Ram
2017-07-07 16:01:37 UTC
Permalink
Post by jacobnavia
it = istrCollection.NewIterator(text);
for (line = it->GetFirst(it); line!= NULL;
I imagine that it is possible that »NewIterator«
will fail (for example, due to lack of memory).

There does not seem to be code for this in the client.
Kenny McCormack
2017-07-07 13:25:53 UTC
Permalink
In article <***@bsb.me.uk>,
Ben Bacarisse <***@bsb.me.uk> wrote:
...
The effect is to be confrontational and argumentative rather than simply
informative.
Now you're being confrontational.

(And so am I...)
...
In effect you /loose/ some of the associated
simplifications associated with the complexities!
It never ceases to amaze me how computer people simply cannot figure out
that the word is "lose", not "loose". I've seen this wordo/think (not a
typo) in online posts for decades. They just can't figure it out!

One might even think that they've got a screw loose here.
--
Trump has normalized hate.

The media has normalized Trump.
GOTHIER Nathan
2017-07-07 16:03:35 UTC
Permalink
On Fri, 7 Jul 2017 13:25:53 +0000 (UTC)
Post by Kenny McCormack
It never ceases to amaze me how computer people simply cannot figure out
that the word is "lose", not "loose". I've seen this wordo/think (not a
typo) in online posts for decades. They just can't figure it out!
One might even think that they've got a screw loose here.
It's a pretty common mistake made by french writers relying on the "choose"
model. There are also many french language exceptions which non french writer
could badly write such as the plural for "carnaval" relying on the "animaux"
model.
Noob
2017-07-07 21:35:36 UTC
Permalink
Post by GOTHIER Nathan
Post by Kenny McCormack
It never ceases to amaze me how computer people simply cannot figure out
that the word is "lose", not "loose". I've seen this wordo/think (not a
typo) in online posts for decades. They just can't figure it out!
One might even think that they've got a screw loose here.
It's a pretty common mistake made by french writers
FWIW, it was Ben who wrote "loose". He's not francophone AFAIK.

Regards.
Kenny McCormack
2017-07-07 21:54:01 UTC
Permalink
Post by Noob
Post by GOTHIER Nathan
Post by Kenny McCormack
It never ceases to amaze me how computer people simply cannot figure out
that the word is "lose", not "loose". I've seen this wordo/think (not a
typo) in online posts for decades. They just can't figure it out!
One might even think that they've got a screw loose here.
It's a pretty common mistake made by french writers
FWIW, it was Ben who wrote "loose". He's not francophone AFAIK.
I think the possibility of this being related to being a french native was
just raised in the abstract. I don't think there was any implication (or
that anyone thought) that this applied specifically to Ben.

No, this error is common and goes back to (at least) the early 80s, where
for whatever reason, otherwise literate computer people decided to misspell
this particular word. And, like a virus, it just keeps spreading.
--
If Jeb is Charlie Brown kicking a football-pulled-away, Mitt is a '50s
housewife with a black eye who insists to her friends the roast wasn't
dry.
GOTHIER Nathan
2017-07-07 23:52:25 UTC
Permalink
On Fri, 7 Jul 2017 21:54:01 +0000 (UTC)
Post by Kenny McCormack
No, this error is common and goes back to (at least) the early 80s, where
for whatever reason, otherwise literate computer people decided to misspell
this particular word. And, like a virus, it just keeps spreading.
I suspect french natives from being the source of this virus since I noticed
this common mistake in my early school days.
Ben Bacarisse
2017-07-07 22:41:03 UTC
Permalink
<snip>
Post by Noob
Post by GOTHIER Nathan
It's a pretty common mistake made by french writers
FWIW, it was Ben who wrote "loose". He's not francophone AFAIK.
As it happens, I am -- at least in the sense that I speak French (and my
name is French as is one side of my family) -- but my troubles with
spelling come from being dyslexic. There is no linguistic impetus
behind the error, I am simply blind to it unless I proof-read in a way
that is too onerous for Usenet posts (and is, even then, not 100%
reliable).
--
Ben.
Tim Rentsch
2017-07-10 19:44:30 UTC
Permalink
Post by Ben Bacarisse
<snip>
Post by GOTHIER Nathan
It's a pretty common mistake made by french writers
FWIW, it was Ben who wrote "loose". He's not francophone AFAIK.
As it happens, I am -- at least in the sense that I speak French (and my
name is French as is one side of my family) -- but my troubles with
spelling come from being dyslexic. There is no linguistic impetus
behind the error, I am simply blind to it unless I proof-read in a way
that is too onerous for Usenet posts (and is, even then, not 100%
reliable).
Thank you for explaining - I didn't realize you are dyslexic. I have a
nearly autonomic reflex to misspellings and incorrect grammar (for which
we may either thank or blame my being raised by a grammarian). I know
better, at a conscious level, than to let those things bother me, but
they still do subconsciously and I'm sure that leaks out from time to
time. My apologies for that.

Incidentally, one of the best programmers I ever met is dyslexic. His
spelling was (by my standards) absolutely terrible, but he sure could
write code.
David Brown
2017-07-11 19:46:15 UTC
Permalink
Post by Tim Rentsch
Post by Ben Bacarisse
<snip>
Post by GOTHIER Nathan
It's a pretty common mistake made by french writers
FWIW, it was Ben who wrote "loose". He's not francophone AFAIK.
As it happens, I am -- at least in the sense that I speak French (and my
name is French as is one side of my family) -- but my troubles with
spelling come from being dyslexic. There is no linguistic impetus
behind the error, I am simply blind to it unless I proof-read in a way
that is too onerous for Usenet posts (and is, even then, not 100%
reliable).
Thank you for explaining - I didn't realize you are dyslexic. I have a
nearly autonomic reflex to misspellings and incorrect grammar (for which
we may either thank or blame my being raised by a grammarian). I know
better, at a conscious level, than to let those things bother me, but
they still do subconsciously and I'm sure that leaks out from time to
time. My apologies for that.
Incidentally, one of the best programmers I ever met is dyslexic. His
spelling was (by my standards) absolutely terrible, but he sure could
write code.
The thing many people fail to understand about dyslexia is that it is
not an all-or-nothing issue. A great many people (including me, as it
happens) are slightly dyslexic - but fortunately few are serious
affected. I don't know about Ben, but my spelling is terrible and I
rely a lot on automatic spell checking - and of course that is not very
helpful with cases like lose/loose :-)

Being dyslexic seldom affects grammar (except in cases like this).
Jerry Stuckle
2017-07-10 23:17:47 UTC
Permalink
Post by Ben Bacarisse
<snip>
Post by Noob
Post by GOTHIER Nathan
It's a pretty common mistake made by french writers
FWIW, it was Ben who wrote "loose". He's not francophone AFAIK.
As it happens, I am -- at least in the sense that I speak French (and my
name is French as is one side of my family) -- but my troubles with
spelling come from being dyslexic. There is no linguistic impetus
behind the error, I am simply blind to it unless I proof-read in a way
that is too onerous for Usenet posts (and is, even then, not 100%
reliable).
But the big question is - do you believe in dog? :)

I also have met some programmers who are dyslexic. Without exception
they have worked hard to overcome their disadvantage and become
excellent programmers.
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
Tim Rentsch
2017-07-10 19:57:37 UTC
Permalink
Post by Kenny McCormack
...
The effect is to be confrontational and argumentative rather than simply
informative.
Now you're being confrontational.
As I read Ben's posting, his comments are written in a neutral
and informative tone, and sound like they were meant to be
helpful. I guess someone could read them as confrontational
but they don't strike me that way at all.
Thiago Adams
2017-07-07 13:24:49 UTC
Permalink
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
I have read some of your design decisions. (1.1.6 Design choices)

"Another design decision is to hide or not the container access within macros.
Instead of writing:

iList.Add(myList,&mydata);
iVector.Add(myVector,&mydata)

// that would be replaced by
#define CCL_ListAdd(myList,mydata) iList.Add(myList,&mydata)
#define CCL_VectorAdd(myVector,mydata) iVector.Add(myVector,&mydata)
// ... etc

"

Have you considered to have some code generator?

Particularly, I think this design

iVector.Add

has a big impact on performance.
jacobnavia
2017-07-07 14:20:41 UTC
Permalink
Post by Thiago Adams
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
I have read some of your design decisions. (1.1.6 Design choices)
"Another design decision is to hide or not the container access within macros.
iList.Add(myList,&mydata);
iVector.Add(myVector,&mydata)
// that would be replaced by
#define CCL_ListAdd(myList,mydata) iList.Add(myList,&mydata)
#define CCL_VectorAdd(myVector,mydata) iVector.Add(myVector,&mydata)
// ... etc
"
Have you considered to have some code generator?
Particularly, I think this design
iVector.Add
has a big impact on performance.
And how would you add an element to a list?
By inlining the "Add" function all over the place?
Keith Thompson
2017-07-07 16:11:10 UTC
Permalink
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
I suggest you add a LICENSE file, or update the README file, to be
more explicit about permitted use. Copyright law is complicated,
and I'm not qualified to give concrete advice, but as I understand it
anything that's published is copyrighted by default. Publishing on
GitHub might have some legal effect.

If you want to release it to the public domain (which means you
disclaim any copyright), you need to say so explicitly. sqlite3 is
public domain; it might provide a good example. (That would imply
that someone could grab a copy, remove your name, and redistribute
it.) There are a number of permissive open source licenses.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Rick C. Hodgin
2017-07-07 20:11:39 UTC
Permalink
Post by Keith Thompson
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
I suggest you add a LICENSE file, or update the README file, to be
more explicit about permitted use. Copyright law is complicated,
and I'm not qualified to give concrete advice, but as I understand it
anything that's published is copyrighted by default.
I believe Jacob Navia is in France, so this may not apply, but in
the United States, there is a natural copyright which falls to the
author of any published work:

https://en.wikipedia.org/wiki/Common_law_copyright

FWIW, I disagree with this philosophy, by the way, as I do not
believe any person should be entitled to monopoly rights on their
ideas or their inventions. I believe all ideas and inventions were
given through people by God for all people to use and enjoy equally,
and not just for the exclusive benefit of a few.

I also believe this has not always been this way, in that before
Jesus came we (mankind) were yet under the Law of Moses, and Grace
had not yet come. Grace levels the playing field as God reaches
out to all people now, whereas before Jesus came to the Earth, only
Israel was God's chosen nation. But since Jesus has come to the
Earth, all people worldwide are able to be saved, and His Kingdom
has come to all who will receive it.

I believe that since Jesus' death, burial, and resurrection, that
was when the issue of personal legal copyright would've been done
away with in God's own sight, as He calls each of us to love our
neighbors as ourselves, and we would not withhold behind money
barriers (or other barriers) those things which are beneficial.

I urge each of you to consider this in your life. We live in the
age of the Grace of God poured out unto man through Jesus Christ.
Because of what He has done to save us, we no longer are pinned
down as we were before He came. Now we are freed from sin, freed
from the yoke of oppression of sin and the evil lures and draws
of our sinful flesh. We are now able to be born spiritually,
which sets us free from the explicit and only ties to our flesh,
for now our spirit also gives us input, and is able to overcome
the weak flesh.

It's not just a belief. It truly is real, and it can truly give
even you new life, new hope, and a changed perspective on all
things from within.
Post by Keith Thompson
If you want to release it to the public domain (which means you
disclaim any copyright), you need to say so explicitly. sqlite3 is
public domain; it might provide a good example. (That would imply
that someone could grab a copy, remove your name, and redistribute
it.) There are a number of permissive open source licenses.
I recommend the Public Benefit License by LibSF:

http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/pbl_v1.txt

-----
An excerpt from the license:

This license releases the software and digital work into the
Public Domain forever, with the following consideration:

It is the intention of the LibSF authors that all of our work
remain open. We ask you to honor that request and always
maintain the digital content you have received from us (source
code, multimedia, and all other forms) in an open manner...

We at LibSF offer this content into the Public Domain knowing
that it can also be taken and usurped for purposes other than
those the authors desire and state above, so in addition we
include this warning, a reminder of accountability:

Each of us was created by God for a purpose. We have been
assembled here upon this planet to live and work together for
the benefit and betterment of all. God has doled out unique
and special skills, talents, and abilities, as He has done,
severally, to each of us. It must therefore be recognized
that each of us is part of the full gift of giving unto man,
and as a body is comprised of many members, each with their
part, so too are we part of this body of man.

We have a responsibility and accountability to God for how we
operate in this world. We will be judged by that which He's
given us, and how we chose to use His free gifts...

These are truly important issues. They are fundamental to our own
soul's state, and the encouragement of right things here in this
world as per the teachings of Jesus Christ.

To be clear: Labor is to be paid for. Our ideas and inventions are
not, except whereby we labor to produce and perfect the materials of
our idea or invention. It is not Biblical to continue to earn revenue
from a prior labor effort that no longer requires commensurate labor,
such as writing a software program and selling it a billion times,
bringing in revenue and profit for each when it required no additional
effort to sell the second product over the first. A recovery of the
initial labor expense is one thing, but after that it becomes a sin
against God ... unless there is ongoing labor involved which must be
paid for.

Thank you,
Rick C. Hodgin
Noob
2017-07-07 22:26:29 UTC
Permalink
Post by Keith Thompson
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
I suggest you add a LICENSE file, or update the README file, to be
more explicit about permitted use. Copyright law is complicated,
and I'm not qualified to give concrete advice, but as I understand it
anything that's published is copyrighted by default. Publishing on
GitHub might have some legal effect.
If you want to release it to the public domain (which means you
disclaim any copyright), you need to say so explicitly. sqlite3 is
public domain; it might provide a good example. (That would imply
that someone could grab a copy, remove your name, and redistribute
it.) There are a number of permissive open source licenses.
As you say, copyright law, and - more broadly - various
international "intellectual property" regimes, can be
very quirky.

For example, the GPL has some awkward corner cases in France
(Jacob's country of residence) which led some to create a
compatible license: CeCILL.

https://en.wikipedia.org/wiki/CeCILL
https://fr.wikipedia.org/wiki/Licence_CeCILL

Also, I don't think it is legal to strip attributions or
even to waive attribution requirements, in French law,
even for public domain works (so-called "paternity rights").

https://fr.wikipedia.org/wiki/Droit_de_paternit%C3%A9

IANAL but I play one on Usenet :-)

For franco-phones, this might be of interest:
http://www.maitre-eolas.fr/post/2009/02/20/1321-les-droits-d-auteur-pour-les-nuls

("Author's rights for dummies")

Regards.
David Brown
2017-07-11 19:54:26 UTC
Permalink
Post by Noob
Post by Keith Thompson
Post by jacobnavia
It is just not true that you need to go to C++ to use a container library.
The C Containers library provides with the most popular containers of
C++ without all the associated complexities since it is plain C (1989
standard)
https://github.com/jacob-navia/ccl.git
There are no strings attached, use it as you wish.
I suggest you add a LICENSE file, or update the README file, to be
more explicit about permitted use. Copyright law is complicated,
and I'm not qualified to give concrete advice, but as I understand it
anything that's published is copyrighted by default. Publishing on
GitHub might have some legal effect.
If you want to release it to the public domain (which means you
disclaim any copyright), you need to say so explicitly. sqlite3 is
public domain; it might provide a good example. (That would imply
that someone could grab a copy, remove your name, and redistribute
it.) There are a number of permissive open source licenses.
As you say, copyright law, and - more broadly - various
international "intellectual property" regimes, can be
very quirky.
For example, the GPL has some awkward corner cases in France
(Jacob's country of residence) which led some to create a
compatible license: CeCILL.
https://en.wikipedia.org/wiki/CeCILL
https://fr.wikipedia.org/wiki/Licence_CeCILL
Also, I don't think it is legal to strip attributions or
even to waive attribution requirements, in French law,
even for public domain works (so-called "paternity rights").
As I understand it, in Germany there is no such thing as "public domain"
for similar reasons.

I would recommend Jacob looks at the "creative commons" licenses and see
if there is one of these that fits. Other common choices for a project
like this would be the BSD licence ("you can use the software as you
want, but can't claim copyright") or the Mozilla Public licence ("you
can mix these files with anything of your own, but any changes you make
to /our/ files need to be published").

Certainly a lack of clear licensing makes the software unusable for
professional use, as would some sort of "home made" license -
international laws are far too complicated.
Post by Noob
https://fr.wikipedia.org/wiki/Droit_de_paternit%C3%A9
IANAL but I play one on Usenet :-)
http://www.maitre-eolas.fr/post/2009/02/20/1321-les-droits-d-auteur-pour-les-nuls
("Author's rights for dummies")
Regards.
Loading...