Earlier quoted context omitted.
I'm very glad that virtual is not the default. Most of the classes I write are simply value classes and do not use inheritance at all. Once you start using virtual, you really have to embrace traditional inheritance idioms whole hog, and then you've got std::vector > instead of std::vector . If anything, the performance difference between std::vector > and std::vector is even greater today than it was twenty years ag…
On the flipside, if you are not using inheritance then you could have solved the same problem with abstract data types. The only big problem is that in C++ the method call syntax is much more convenient to use: foo.frob() vs Foo::frob(foo). IMO, the correct way to fix this is by adding syntax sugar to the language, not by making methods non virtual by default.
We have C++14
311–320 of 353 posts
Re: We have C++14
#312Earlier quoted context omitted.
Right. So while UTF-16 is a terrible encoding and there is very little reason to use it, UTF-32 is little better. Use UTF-8.
Like I said, I'm very lonely. My only consolation is that every project I've seen that says "use UTF-8 and be careful not to do goofy things (like running a string through the encoder twice, or passing a string to old C string functions that aren't Unicode aware, or assuming each character takes one byte), without exception, constantly finds those goofy mistakes in their code. Being careful is not enough. UTF-8 for s…
A language where the "String" data type is as follows:
A rope of "logical characters" (One or more code points, such that they are logically one character. So an accent is combined with the previous character, that sort of thing.)
With the additional "restriction" (read: implementation detail) that within a single node all logical characters must have the same width. (You can, for example, store a single one-byte character in a run of two-byte characters as an overlong-encoded two-byte character, but this is just an optimization.)
Short ropes degenerate to a flat array.
(You have to do a workaround for single code points that encode multiple logical characters. You split them into N parts encoded in the private unicode range or something similar, and when displaying them recombine them if they are in the correct order, otherwise normalize them. Although I'm up in the air about this. Should reverse("st") be "st"? Or "ts"? (That's the single unicode character "st", for those that are confused.))
Ideally, you put character encoding directly within nodes.
That way most things "just work". Running a string through the encoder twice doesn't do anything, as it detects the encoding is the same as the target encoding and doesn't do anything. Reversing a string "just works". Indexing a string is sub-linear time, but gives decent results. (Indexing a string and getting invalid unicode as a result is never fun!) Concatenating strings takes sublinear time even. This works really well with immutable data structures, or quasi-immutable data structures. (there's some tricks with rewriting ropes to take maximal advantage of structure-sharing that preserve the illusion of an immutable data structure without actually being immutable.)
And if you really want you can start doing fancy things like allowing lazy generators within strings, or lazily decompressing / reading data from disk.
To store on disk? Yeah, go with UTF-8. (Or my personal favorite pet encoding: compressed UTF-32.)
Re: We have C++14
#313Earlier quoted context omitted.
Like I said, I'm very lonely. My only consolation is that every project I've seen that says "use UTF-8 and be careful not to do goofy things (like running a string through the encoder twice, or passing a string to old C string functions that aren't Unicode aware, or assuming each character takes one byte), without exception, constantly finds those goofy mistakes in their code. Being careful is not enough. UTF-8 for s…
> Being careful is not enough. UTF32 will not help you much with that, save that you've got a separate type for "strings" and "bunch of bytes" Which you can have anyway, so do that, it's a good idea which doesn't require using UTF32. > But UTF-8 for in-memory strings has a long track record of being much harder to actually do correctly. As if other in-memory encodings had a better track record.
Yes, people forget to normalize their UTF-32, UTF-16 and UTF-8 strings before comparing for equality. Yes, people forget that whether a code point is a letter depends on who's asking the question (I usually don't consider Greek letter pi a letter, but Greeks do). Yes, it's true that reversing a Unicode string in any encoding requires more than simply reversing the individual elements (because of combining characters).
So, yes, it's possible to get things wrong in any encoding. But UTF-8 has more ways to screw up than the alternatives. And UTF-16 has a few more than UTF-32; but I can accept UTF-16 if there are external reasons to (e.g., working on Windows).
Re: We have C++14
#314Earlier quoted context omitted.
That's the problem I have with C++. It is a mish-mash of paradigms, features and techniques. It is not consistent in use-cases and philosophy (unless you count "all and everything" as use cases and philosophy). As much as I try to find "my" general purpose language of choice, and forr all of my inertia in learning yet another programming language, I believe languages should have narrower scopes. And there should be m…
I thought much like that (and was a huge Python fan) until I found Scala. There are cases people cite as "more than one way to do it", but they're usually superficial syntax differences. You do have to choose between passing around objects and passing around functions, but that's a choice you make in Python as well. It can handle high-performance calculation or high-level scripting, but it never feels like these are…
This seems to be the curse of any powerful core language (Scala, Haskell, ...) - on the one hand they allow you to make all kinds of useful abstractions that you can't make with e.g. Java. On the other hand, their abstractions are so powerful that they create seemingly different languages.
One could apply the same rule as C++ - stick to a subset of the language/abstractions. However, if you look at e.g. Haskell, a large number of libraries now depend on a library such as lens [1], so often it's not that much of a choice.
Re: We have C++14
#315Earlier quoted context omitted.
I agree that using exception is hardly noteworthy these days, but consider that in the context of a codebase that has evolved for more than a decade. I guess, ten years ago, "let's not use exceptions; they aren't worth it" was more justifiable. In any case, the decision was made, and we have millions of LOC where every single API is built with the assumption "No exceptions here." In that context, introducing exceptio…
This is of course a valid reasoning to forbid the use of some features at this particular company. However, it renders advocating the Google C++ style guide as an ubiquitous style guide for all C++ programming rather moot.
Re: We have C++14
#316Earlier quoted context omitted.
> Being careful is not enough. UTF32 will not help you much with that, save that you've got a separate type for "strings" and "bunch of bytes" Which you can have anyway, so do that, it's a good idea which doesn't require using UTF32. > But UTF-8 for in-memory strings has a long track record of being much harder to actually do correctly. As if other in-memory encodings had a better track record.
Nobody's ever accidentally tried to uppercase a UTF-32 string by passing each code point to C's toupper() function; but that constantly shows up in projects using UTF-8 for in-memory strings. And it's not always caught by unit tests. People never accidentally pass a UTF-32 string to a legacy API that expects char*'s in Latin1 encoding. I when I say "never" I don't mean "almost never happens"; I mean literally "anybod…
But you can still copy only parts of a grapheme cluster. If you want to do Unicode right, you have to treat even UTF-32 as a variable-length coding.
Re: We have C++14
#317Earlier quoted context omitted.
>"To the point - you could ensure that compiler can de-virtualize your usage of structure (or class if you will) by adding "nonvirtual" to every method it implements or derives." Think it in this way. Many respectable people has been making a case to avoid inheritance[1][2]. What you are proposing would actually be an incentive to them. I don't know about you but the amount of functions that I actually override in my…
I agree with "composition over inheritance", but I disagree with "inheritance is evil". Composition over inheritance means you divide you classes into parts that ALSO use inheritance and virtual methods, you just don't make the hierarchy deep and don't mix many different subdivisions into one hierarchy. The problem isn't virtual methods, it's too many divisions and responsibilities in one class hierarchy. And you do…
The override keyword was added in C++11 to help prevent the sort of mistake you were trying to show. Any methods you mark with it will result in a compile error if they are not actually overriding anything.
For example, if B::g were marked as override, it would fail to compile because A::g is not virtual.
Re: We have C++14
#318Earlier quoted context omitted.
> Have you ever tried building GCC? I've wasted days on it and in the end still failed to make it work. I've hand-built GCC for half a dozen of different target architectures over the years and it's perhaps one of the most stable pieces of software when it comes to building it. I've only had one build failure over the years and that was unstable from git (even that usually works no problem). To build GCC, follow the…
I don't know how you manage it, but I can tell you it is not reasonable to expect people to compile every compiler they want to use on every system they want to use it.
Re: We have C++14
#319Earlier quoted context omitted.
Exactly. I only write greenfield C++ and I dig it a whole bunch.
Good for you. It would be harder to dig if you had to do some maintenance like less lucky lifeforms.
Re: We have C++14
#320Earlier quoted context omitted.
Meh, breaking backwards compatibility isn't all that bad. It will be a bit rough for a few years, but it's worth it to clean things up for a brighter future.
The weird thing is, why not just call it something new? I've always wondered if they called Perl 6 "Smeebly" or something would it get a better reception? C+++ ? My personal taste is that if you break backwards compatibility that is when you have a 'new' language and you just just name it as such.
With this argument, every release that adds a new keyword (for example) would have to be given a new name, since it will very likely break some code. Question that remains is how much must the changes be before the thing deserves a new name.