49 comments

[ 0.27 ms ] story [ 88.0 ms ] thread
"digit separators to make for instance binary literals readable 0b1_0010_0010_0000_1000"

Nice. I first saw this in Rust, and it seemed like such an obviously good idea (allowing underscores in numeric literals) that I've wondered why more languages don't do it. Now I'm curious where it originated.

Not sure about the origin, but Ruby has them too.
Not sure of the origin either, but Ada has had that since 1983.
Aha, interesting. I was doing some quick scanning on Google-Books and other places to try to find the earliest usage, using variants of "numeric literal" and "underscore" as search terms, and couldn't find anything pre-1990s. Now I find the Ada stuff, and it wasn't coming up because all the '80s Ada documentation/discussion refers to them as underline characters, rather than underscore.

(Incidentally, one of the perils of trying to draw historical conclusions from text searches, or data sets like Google Ngrams: you could get completely wrong results if you miss a shift in spelling or word usage.)

Perl has had it for awhile, although there were probably languages that had it beforehand (awk or ADA maybe?)
(comment deleted)
(comment deleted)
That was in use in some assemblers back in the 80s and probably earlier.
It's very common in ML languages: SML and Ocaml both support it.
I think I saw it first in Perl.
But not much more readable than, say Hex e.g. 0x12204.
Indeed, but it's also useful in order to detect at a glance the order of magnitude of a literal. For instance, if I come across 10_000_000 in some code, I don't need to interrupt my train of thought to meticulously count the zeroes; I instantly know that's ten million. I couldn't say the same if it was instead written as 100000000.
It is if you're representing a flag word.
Verilog has that feature too
I saw it first in D. Doesn't mean it was invented there ;)
There's a Boost header with macros that provide this for C and C++.

  int i = BOOST_BINARY( 1 0010 0010 0000 1000 );
Upvoted, but I cry at the thought of all that extra typing.
This seems to me to be far more useful than user-defined literals (the conflicting feature). At least, I can think of many programs where digit separators would be nice - but for user-defined literals, I don't see them as providing much. We could already make invocations like "pixels(200)" and being able to say "200_pixels" doesn't add much to that, except complicating the parser.
The problem with this argument is that user-defined literals already exist in C++11, and use of the underscore character for a different purpose in a future standard has to be in such a way that it can be unambiguously distinguished from the user-defined literal usage. Backward-compatibility to the current standard has to be preserved.
Oh, absolutely, I just think it's a shame.
I am a big fan of adding digit separators where ever possible. I'm tired of staring at ls listings of terabyte filesystems and trying to figure out what order of magnitude the numbers are. And yes, I know about ls -lh.

I would like to see a universal format agreed on by everyone, so that numbers with separators (call them punctuated numbers) output by one program could be used as input for another, as is often done in Unix pipelines.

The languages that I know of that have punctuated numbers all use underscores. However, having thought about it a lot, I don't think this is a good choice. First, the underscore is often used, as in C, as an additional character in identifiers, but the semantics are different. An underscore in an identifier is significant, in a number it is not:

1_234_567 == 1234567, but

my_long_identifier != mylongidentifier

Also, the underscore is too "big". In a fixed width font, this is irrelevant, but in a variable width font, I think it makes numbers look ugly. The separator should be narrow. In some locales, the apostrophe is used:

1'234'567

I like the thinner character. I have at least one calculator that uses this convention in the display. Alas, this is probably unworkable in computers, since the apostrophe is used commonly for quoting. One option that might work is the back quote:

1`234`567

The back quote isn't used as much as the apostrophe, but it still might cause problems. On US keyboards, it's conveniently located right next to the 1.

Finally, I'd like to see both period and comma accepted as the decimal separator

1`234`567.89 == 1`234`567,89

but there are some obvious problems with that.

My bottom line is that, before C++, or any other language, adds underscores as thousands separators because that's what everyone else did, we should think more deeply about what's needed in a universal format for punctuated numbers.

Far better to use a character that's supposed to be part of an identifier like _ than a character that could have some other syntactical use in various languages. The fact that a number begins with a numeric character lets you distinguish it from other identifiers.
Digit separation might make long numbers more readable, but now they’re also more locale-dependent. Same goes for commas versus periods. Regardless, I think the grave accent is a poor choice here. Whitespace would be better, much like adjacent string literals in C. A compiler could warn by default about numeric literals crossing line boundaries in free-form languages, to catch missing punctuation. This also has the advantage of precedent in scientific literature.

Unfortunately it doesn’t work in languages without some redundancy, like many in the vector family. Is this a four-vector of one-digit numbers or a one-vector of a four-digit number?

    [1 2 3 4]
ruby was the first place i saw it used, but it's probably older than that.
One can only guess how the programming languages area will look like in 5 years, but C++ will get "runtime sized arrays" and "generic lambdas" in 2017 (add a year or two until it gets to mainstream compilers)? Makes you think that the criticism the language gets is a little justified.
There is no real need for runtime sized arrays, as one could already use vectors (which are more comfortable to use than C-style arrays anyway) and allocate them on the stack (that's one of the template parameters of std::vector, its allocator). If one were to be a masochist, one could also alloca and then use placement new, with all the shortcomings of alloca.

Granted, it's syntactically shorter to say int x[n], but it's the same behavior as above, and one would need to see what changes have to be made to the runtimes and the standard to allow for this, and how to report errors such as "There is no more space on the stack" (which is going to be much more frequent than running out of heap space).

As for "generic lambdas", I don't find that typing the type of your parameter is too annoying at the moment, though I haven't used the feature much. Perhaps this is a baby step in a move to make C++ a bit more Haskell-like: Strong typing, but also powerful type inference mechanism.

Other languages have more features, that's true. But C++ is still trying to advocate a blazingly fast speed, and pay-for-what-you-use mentality. That the language can still be the fastest, one of the most powerful, and achieve feature parity with current dynamic languages, I think reflects well on the language, not the opposite.

Your first two paragraphs here seem contradictory. If the feature can already be implemented, and the cost is merely some syntactic messiness, then there is no change necessary to the runtimes - all you need is a little syntactic sugar.

As an aside, there is a grand history of array notation being nothing more than syntax. Try building the following in gcc:

  int main() {
      int foo[] = {1, 2, 3};

      return 1[foo];
  }
The expression a[b] is simply translated into a + b, which commutes. There's some constraint applied that something there be a pointer (so 1[2] is rejected) but it's weaker than it "should" be...
Sorry, I misspoke - I didn't mean the runtime (what would that really be?) but the compilers. That is, I do not know, a priori, that the internal type system would deal equally well with constant sized arrays, as with variable based ones. Currently the size of all variables on stack is determined at compile time, and the compiler generates code for those offsets. If this now changes, one would have to see what needs to change in the compiler internally, and the executable that gets output by it. It can certainly "be done", but things need to change in order to accomodate it as part of the language.
> There is no real need for runtime sized arrays, as one could already use vectors [...] and allocate them on the stack

And how exactly would you do that? alloca() aside, there is no such thing as a stack allocator.

There's several projects that have seen the need to allocate variable length things on the stack, Chromium was one[1]. A quick googling sends me to [2] as well.

I haven't ever found myself in a situation where I _needed_ my stuff to be stack allocated, but then again I've never done really low level programming or embedded code, and I guess it could happen there.

[1] http://src.chromium.org/viewvc/chrome/trunk/src/base/stack_c...

[2] http://home.roadrunner.com/~hinnant/stack_alloc.html

These just allocate a fixed-sized stack buffer and overflow to the heap - no variable-length stack allocation happens.
Right, because alloca is the only thing (as far as I know) that can resize the stack. There is not going to be anything else that does the same thing. The best one can do is those stack allocators which overflow to heap, or an alloca-based stack allocator.

There's an interesting discussion[1] at comp.std.c++ about implementing VLAs in C++0x, and the issues with dynamic stack resizing.

[1] https://groups.google.com/forum/?fromgroups=#!topic/comp.std...

Runtime size arrays (VLAs) are already supported as an extension in GCC. But I'm actually an opponent of VLAs in the current form. There simply is no way to detect the stack size and prevent an overflow. Worst of all AFAIR GCC does not add any checks either and simply changes the stack pointer. There simply is no reasonable way to recover from an overflow.

If they really want to include VLAs then they have to take care of those issues. And in C++ we have std::vector as a safer alternative to raw handling of variable length data.

"There is now (thanks to CERN's presence :-) a working group on reflection in C++."

A few years ago I built an entire framework for automatic reflection in C++ - it worked by querying the export table of the executable or library. Eventually I lost interest and let the project slide, but I think this approach would be a good one to build on.

> Is there anything else you want to know?

Why are you doing this? C++ has no future, only past.

I just wish/hope it's true... that we ll finally get out of this dark age of byzantine languages that grow like cancer (just rembered the good ol "C is to C++ as Lung is to Lung Cancer" :) )... congrats for saying it out loud anyway!
If only there were alternatives which give similar control.
There's not. We are stuck in a C/C++ world for the time being. I had hopes for something like Oberon or D a couple of decades ago, but no one wants to go tilting at the windmills.
Shameless plug, but Rust is intended to be that. There's also Clay, etc.
I do believe most new projects today would be better off with a combination of a high level language for the logic, like Python or Perl, and a low level language like C or maybe Go for the plumbing, with clean interfaces between them. There really is no need for a behemoth like C++, with two dozen ways to do any single thing, half of them conflicting with each other and the other half subject to vigorous religious debates.
I think the key for effective use of C++ is to know what to do and what to use to do it. It's certain that relying on multiple inheritance for example is probably a bad idea.

After working with Ruby for some time, I realized that many co-developers don't have a slightest of a clue what they're doing with the language yet they do just about right with it - with C++ similar (careless) mindset and skill level would very soon end up in a terminated project.

In the end it's the domain which matters more than the languages - as I implied in my earlier comment, I outright require as much control over the hardware as possible - there are no alternatives for me. Rust comes close(and it's nice, I like it thus far!), but let's see in a few years.

Just curious, what is the alternative to C++ that has a "future"?
GCC 4.8 already adds support for return type deduction in normal functions.

> G++ now supports a -std=c++1y option for experimentation with features proposed for the next revision of the standard, expected around 2017. Currently the only difference from -std=c++11 is support for return type deduction in normal functions, as proposed in N3386.

http://gcc.gnu.org/gcc-4.8/changes.html

How much can be added to a programming language until it collapses?
I really would like a 'real' dependencies system.

But not until at least 2017 ... :(

I wonder whether the hexadecimal floating-point syntax 0x1.23p45 referred to in http://stackoverflow.com/a/11840637/139746 will qualify as “bug fixes and usability improvements”. This notation is very useful for the tiny fraction of programmers who need it.