Live data from Hacker News

C++11 and Boost - Succinct like Python

fendrich.se

151–160 of 172 posts

Re: C++11 and Boost - Succinct like Python

#151

Earlier quoted context omitted.

"the extra syntax in this case is not adding any extra information (to the compiler)." This actually isn't true in C++, because there could be many classes in scope that could take a list initializer like this. In Haskell, no literal with [] can "turn into" something besides a list, but that can happen in C++: vector items = {1,2,3,4}; int[] items = {1,2,3,4}; These have different types, so how would C++ know which o…

Your example, void foo() { auto items = {1,2,3,4}; return; } is the case of poorly designed syntax, in a truly Hindley-Milner system there is no expression which doesn't have a type. Now, we could add some syntax that screws that up, say: let v = I-HAVE-AN-AMBIGUOUS-TYPE in 0 But that's rather silly, isn't it? If a value isn't used then I would, personally, like my language to optimize it away. So why not ditch such…

"Hell, stop programming in C++ and start using Rust!" I plan to try to do that, when Rust has become more stable.

Re: C++11 and Boost - Succinct like Python

#152
post #53

Earlier quoted context omitted.

Yes, to_string would have been better The C-style cast is shorter, but less safe, so you should not use it: http://stackoverflow.com/questions/1609163/what-is-the-diffe... Yeah, I couldn't quite decide if I should include const refs. On the one hand, it is idiomatic, but on the other hand I didn't want to clutter the code with something that is just an optimization on paper.

How can a C-style cast from char to unsigned possibly be "less safe", and how could a different style of cast be more safe?

In this case it obviously doesn't matter, but in the general case it is better to be explicit on which type of cast you are doing. That way the compiler can statically stop you from doing stupid things. Read the link I gave.

Re: C++11 and Boost - Succinct like Python

#153

Earlier quoted context omitted.

Your example, void foo() { auto items = {1,2,3,4}; return; } is the case of poorly designed syntax, in a truly Hindley-Milner system there is no expression which doesn't have a type. Now, we could add some syntax that screws that up, say: let v = I-HAVE-AN-AMBIGUOUS-TYPE in 0 But that's rather silly, isn't it? If a value isn't used then I would, personally, like my language to optimize it away. So why not ditch such…

Having programmed Haskell for the last seven years (and C++ for zero) I have a fairly decent handle on what HM is all about. If all you had said is that the foundations of C++ are too far gone, there wouldn't be anything to discuss. But the foundations of C++ being what they are, there's no point being offended when unfixable things go unfixed. I love HM, but you can't just throw it in any old language simply because…

Correct, I do not suggest adding HM to C++.

I suggest using a HM language when you start a new project.

Re: C++11 and Boost - Succinct like Python

#154
post #100

Earlier quoted context omitted.

In most programming languages the [] operator allows one to access elements in a container. In this case, we are accessing the position "two colons minus one". I refuse to believe this makes any sort of sense for someone that has no deep knowledge of Python.

Lots of languages use [] with colon separators for array slicing, e.g. F#, Perl, Ruby. The idea that this syntax involves "deep knowledge" is laughable. Your criticism is analogous to me looking at "int* foo = bar()" and saying, hey, we're multiplying a type by a name! How ridiculous!

The int pointer syntax is in fact ridiculous, so it does not support your point. Also s[x:y] is intuitively understandable compared to referencing two colons and minus one...

Re: C++11 and Boost - Succinct like Python

#155
post #129

Earlier quoted context omitted.

"the extra syntax in this case is not adding any extra information (to the compiler)." This actually isn't true in C++, because there could be many classes in scope that could take a list initializer like this. In Haskell, no literal with [] can "turn into" something besides a list, but that can happen in C++: vector items = {1,2,3,4}; int[] items = {1,2,3,4}; These have different types, so how would C++ know which o…

Integers and Strings aren't edge cases. Their literals are polymorphic and typed. C++ could also type its list initializers with some polymorphic type (similar to Haskell's Num) but didn't do so. This is not inherent.

They're not worth discussing because they're a counterintuitive mess rather than a case study of the glory of HM. Maybe edge case isn't the right word, but they're definitely not something I would hail as a perfect resounding success.

There are no polymorphic literals in ML, just polymorphic math operators, which is enough of a blight on the standard that OCaml discarded it and forces you to use different operators for real and integer arithmetic. And there's only one kind of string in both MLs.

Haskell's Num hierarchy is troublesome. They traded usability for + with complexity for /. It's extremely unlikely that you could write a program in Haskell that does much arithmetic and have it build correctly on the first try without any manifest typing. This is one reason students of Haskell find things so confusing: type declarations are necessary at the top level simply because the extensions and complexity of modern Haskell break HM if you try using it everywhere. Also, the class system in there is not especially mathematically correct, which leads to the numerous replacement Preludes that try to do a better job but haven't caught on.

Strings are edge cases because they are not polymorphic unless you enable OverloadedStrings. Once you do, you will either replace the built-in string with something else (ByteString or Text) or find yourself in the same kind of trouble you'd be in with Num.

Let me be clear: I'm not saying that these problems are showstoppers. They're really minor annoyances once you're experienced, though they contribute to confusion for beginners. The point I'm trying to make is that you can't just drop HM into any old language and expect it to work. A greater point would perhaps be that all languages have warts simply because they're large, complex beasts (Haskell and C++ especially) and it's unproductive to point to a missing feature in one and demand some sort of perfected version of the other's.

Re: C++11 and Boost - Succinct like Python

#156
post #147

Periodically throwing some new ingredients into old soup to freshen it up can only extend the life of leftovers so far. There comes a time when, even with a handful of fresh veggies, it's no longer good soup. You need to toss out the leftovers, scrub the kettle, and start a fresh batch. You will still need C++ for dealing with all the legacy C++ out there, but if you are starting a new project, you ought to be able t…

I keep wishing for this magical language to manifest, like a C++ compatible Boo. I only wish I were capable of building one myself.

Re: C++11 and Boost - Succinct like Python

#157
post #129

Earlier quoted context omitted.

Integers and Strings aren't edge cases. Their literals are polymorphic and typed. C++ could also type its list initializers with some polymorphic type (similar to Haskell's Num) but didn't do so. This is not inherent.

They're not worth discussing because they're a counterintuitive mess rather than a case study of the glory of HM. Maybe edge case isn't the right word, but they're definitely not something I would hail as a perfect resounding success. There are no polymorphic literals in ML, just polymorphic math operators, which is enough of a blight on the standard that OCaml discarded it and forces you to use different operators f…

> They're not worth discussing because they're a counterintuitive mess

Do you really believe Num overloading is a counterintuitive mess? I disagree completely.

> OCaml discarded it and forces you to use different operators for real and integer arithmetic

Which is pretty terrible.

> Haskell's Num hierarchy is troublesome.

Yes, but that's an orthogonal issue.

> This is one reason students of Haskell find things so confusing: type declarations are necessary at the top level simply because the extensions and complexity of modern Haskell break HM if you try using it everywhere

That sounds like FUD to me, a heavy Haskell user. Type declarations at the top-level are generally necessary to avoid the dreaded MR and for documentation purposes. Modern Haskell doesn't heavily use extensions that require type annotations on the top-level.

> Strings are edge cases because they are not polymorphic unless you enable OverloadedStrings. Once you do, you will either replace the built-in string with something else (ByteString or Text) or find yourself in the same kind of trouble you'd be in with Num.

It lets me use literals for Lazy Text, Strict Text, and String with the same syntax, which is nice.

My point is merely that giving a type to a polymorphic initializer is possible, and C++ chose not to.

Re: C++11 and Boost - Succinct like Python

#158

Earlier 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.

Wrong foundation? No. Foundation you don't want? Sure. Try to remember that Hindley-Milner is very hard to do outside of functional languages like ML and Haskell.

Yes type inference is harder with C++'s language design (OO comes to mind as a particular problem), thus my claim that it's the wrong foundation to build on. Of course, people like challenging problems and are working to bring more type inference to OO languages [1].

Furthermore, I assert that this truly is the wrong foundation. For new projects that must have OO, Scala provides local type inference and object orientation. If you're really hurting for some manual memory management, look at Rust [3] or Habit [2].

If we can recover the features we love on a new foundation that provides new features like type inference or memory-safety, then we've found a better foundation, IMHO.

[1] http://www.cs.ucla.edu/~palsberg/typeflow.html

[2] http://hasp.cs.pdx.edu/habit-report-Nov2010.pdf

[3] http://www.rust-lang.org/

Re: C++11 and Boost - Succinct like Python

#159
post #105

Earlier quoted context omitted.

Even in Hindley-Miller type systems it is considered good practice to add types as documentation to top-level constructs (see Haskell). In Python it is also considered good practice to add argument and return type info in the doc string. In a dynamic language you would also have to add a unit test or two for cases for some of the things that the compiler can catch for you. Looking at the complete picture makes a lang…

> it is considered good practice to add types as documentation to top-level constructs But with type inference your tools can do that for you (e.g. C-u C-c C-t in haskell-mode).

A good IDE can fill in the types in C++ too.

Re: C++11 and Boost - Succinct like Python

#160
post #131

Earlier quoted context omitted.

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

Manually capturing free variables via: def __init__(self, x, y, ..): self.x = x self.y = y Is so tedious and DRY-violating.

This is true. I'd prefer scala-style constructor syntax - though I'm not sure how you could retain python's wonderful symmetry between constructors and methods, and the distinction between allocation and initialization.
Post reply on HN