Is it too late for me to bang my Go drum? http://play.golang.org/p/53jSv32wSF (You can't access the filesystem on the playground, so it doesn't run.) * Look at that error handling. Mmmmhmmm, clear and explicit. If something goes wrong, I'll know about it. * Apart from, of course, errors that I ignore, such as when converting the year from 4 chars to an int (line 54). I don't care if I can't parse that. * Note the dif…
C++11 and Boost - Succinct like Python
111–120 of 172 posts
Re: C++11 and Boost - Succinct like Python
#112Earlier quoted context omitted.
The extra syntax is not there for nothing. It's adding type information. Thus allowing error checking or dispatching by type or optimisations at compile time. It is a cost in terms of syntax and readability but it's not for nothing. So for correct programs the end result might be the same in terms of values. For buggy code and runtime speed that's not necessarily the case.
This is what caught my eye too as being really ugly and hard to read. const map > TagDataMap { {"title" , make_tuple( 3, 30, stripnulls)}, Why can't the compiler figure out the types involved in this map structure itself? The user-defined functions are declared above, make_tuple will be declared in some library, and the others are string/int literals.
I don't think C++ can figure out the map part simply because lots of things could have list initializers that accept lists of 2 item lists. C++'s overloading and implicit conversion conflicts with perfect type inferencing. This is an example of the kind of thing the FQA talks about, where several of C++'s issues collide to produce counter-intuitive behavior.
I do wonder if you could get away with this:
const map TagDataMap { ...
I don't have access to a C++11 compiler from where I am to find out though. I am particularly unclear on the interaction between `auto` and other aspects of a type declaration--I don't know if you can nest `auto` like this deep inside some other type declaration. I don't see why you couldn't, but wouldn't be shocked either.Re: C++11 and Boost - Succinct like Python
#113Is it too late for me to bang my Go drum? http://play.golang.org/p/53jSv32wSF (You can't access the filesystem on the playground, so it doesn't run.) * Look at that error handling. Mmmmhmmm, clear and explicit. If something goes wrong, I'll know about it. * Apart from, of course, errors that I ignore, such as when converting the year from 4 chars to an int (line 54). I don't care if I can't parse that. * Note the dif…
At the end after line 24 do we need another line of code that reads data into the newly created byte array? If so, that says a lot about the readability of the code since I'm not a Go developer...
Line 24 makes a byte slice, line 25 populates it with data read from the file.
Re: C++11 and Boost - Succinct like Python
#114Earlier quoted context omitted.
At the end after line 24 do we need another line of code that reads data into the newly created byte array? If so, that says a lot about the readability of the code since I'm not a Go developer...
I'm not sure what you mean. Could you be more specific? Line 24 makes a byte slice, line 25 populates it with data read from the file.
Re: C++11 and Boost - Succinct like Python
#115Earlier quoted context omitted.
And this is where I decide the language is too far developed on the wrong foundation. I cannot put up with type systems that don't have complete or near-complete type inference. I don't know why one would start a new project in a language that didn't support Hindley-Milner.
Just to elaborate on what danking00 is saying, the extra syntax in this case is not adding any extra information (to the compiler). The left hand type of the expression can be completely inferred at compile time, in this case. What that required syntax is adding is pain, but no gain (except for imperceptibly faster compile time). In Haskell this would look like: TagDataMap = [ ("title", ((3, 30, stripnulls)), ("artis…
vector items = {1,2,3,4};
int[] items = {1,2,3,4};
These have different types, so how would C++ know which one you meant if you instead wrote: auto items = {1,2,3,4};
Again, in Haskell this isn't a problem because literals have essentially a single type. (Edge cases around integers and strings notwithstanding).Edit: Just to clarify, in a Hindley-Milner system you could maybe get away with something like that, but everything you name in an HM system you must use, and that isn't the case in C++:
void foo() {
auto items = {1,2,3,4};
return;
}
I can then make two classes with list constructors: struct FooClass {
FooClass(std::initializer_list list) {
cout list) {
format_your_hard_disk();
}
};
Obviously there are consequences to choosing the right type, but the type of that value never leaks out of the function. Nevertheless, because side-effects can happen anywhere, even in a constructor, C++ cannot optimize that out.This might be a convoluted example, and it may be flawed, but conjuring up others is not hard and demonstrates that C++ simply cannot ever have true HM type inferencing. Since the "real deal" is not possible, the language is complex and the standard is large, I would not expect to be able to live without annotations in C++-land. (Again, the FQA makes the horror of multiple non-orthogonal solutions to the same problems quite clear).
Re: C++11 and Boost - Succinct like Python
#116I've been using both C++11 and Python lately. While the new C++11 features add a lot of value, I still find it frustratingly verbose for some things. For example, finding an element in a collection: std::string type = "foo"; auto it = std::find_if( channel_widgets.begin(), channel_widgets.end(), [type](const std::shared_ptr &w){ return (w->getType() == type); } ); if (it == channel_widgets.end()) { std::cerr target_w…
auto it = channel_widgets.begin();
while (it != channel_widgets.end())
if (it->getType() == type) goto found;
// error
found: // whatever
I kinda hate myself every time I write such for-loop, but it's still more succint than any variant of find_if. Generally, I use "trivial" STL algorithms (find, find_if, for_each, ...) only if I can reuse the functor several times. Otherwise it's not worth the hassle.PS: you can do it also without goto... use "break" after if, and after while you write
if (it == channel_widgets.end())
whatever; // not_foundRe: C++11 and Boost - Succinct like Python
#117Earlier quoted context omitted.
“C++11 idioms” include a preference for immutability, which leads to natural factorings. You don’t have to worry about things like iterator invalidation that way. #include #include #include #include using namespace std; template void print(const T& v) { copy(begin(v), end(v), ostream_iterator (cout, "\n")); } int main(int argc, char** argv) { vector v{"Hello", "there"}; print(v); } Also, Haskell is only so safe—at wo…
"const" doesn't help you in the presence of aliasing: #include #include template void print(const T& v, U& w) { for (auto ii = v.begin(), ie = v.end(); ii != ie; ++ii) { w.clear(); std::cout v; v.push_back(std::string("Hello")); v.push_back(std::string("there")); print(v, v); return 0; } In general there are lots of ways to get non-const access to const data. You'd need a sophisticated form of whole-program alias ana…
Re: C++11 and Boost - Succinct like Python
#118Earlier quoted context omitted.
“C++11 idioms” include a preference for immutability, which leads to natural factorings. You don’t have to worry about things like iterator invalidation that way. #include #include #include #include using namespace std; template void print(const T& v) { copy(begin(v), end(v), ostream_iterator (cout, "\n")); } int main(int argc, char** argv) { vector v{"Hello", "there"}; print(v); } Also, Haskell is only so safe—at wo…
"const" doesn't help you in the presence of aliasing: #include #include template void print(const T& v, U& w) { for (auto ii = v.begin(), ie = v.end(); ii != ie; ++ii) { w.clear(); std::cout v; v.push_back(std::string("Hello")); v.push_back(std::string("there")); print(v, v); return 0; } In general there are lots of ways to get non-const access to const data. You'd need a sophisticated form of whole-program alias ana…
Re: C++11 and Boost - Succinct like Python
#119Earlier quoted context omitted.
I call shenanigans. That's true of simple scripts, I'm sure. But you can't seriously claim to me that you can understand decorator idioms, iterables or list comprehensions without a deep understanding of the language. What you say might have been true for Python c. 1998, it certainly isn't true today. Broadly: reading code is just hard. It's much harder than writing code. There are no non-trivial codebases that can b…
Here's an example: A co-worker looked at a function I wrote that converts a table to a tree, and he said to me, "I thought Python was supposed to be readable, but I have no idea what this is doing." See for yourself: https://gist.github.com/3988350
Re: C++11 and Boost - Succinct like Python
#120I've been using both C++11 and Python lately. While the new C++11 features add a lot of value, I still find it frustratingly verbose for some things. For example, finding an element in a collection: std::string type = "foo"; auto it = std::find_if( channel_widgets.begin(), channel_widgets.end(), [type](const std::shared_ptr &w){ return (w->getType() == type); } ); if (it == channel_widgets.end()) { std::cerr target_w…
Can't comment on C++11 but the Python version is better written as: type = "foo" try: target_widget = (x for x in widgets if x.get_type() == type).next() print "widget found:",target_widget except StopIteration: print "widget not found"