
C++ has become a scripting language - alexchamberlain
http://voices.canonical.com/jussi.pakkanen/2013/10/15/c-has-become-a-scripting-language/
======
brian_cloutier
> Ignoring include boilerplate and the like leaves us with roughly ten lines
> of code.

I'm not sure you get to claim a language is a scripting language and then
ignore the boilerplate.

The equivalent python is 4 lines, just one more than the number of steps
you're performing.

    
    
      import sys
      data = open(sys.argv[1]).readlines()
      lines = sorted(data)
      open(sys.argv[2], 'w').writelines(lines)
    

C++ is good at many things, but quickly creating readable scripts and live-
coding with a REPL are not among them.

~~~
reirob
In Unix shell makes it in 2, with the bang line:

    
    
      #!/bin/sh
      sort < $1 > $2
    

My preferred scripting language ;)

~~~
rofrol
you don't need hashbang if you run it the same like python:

    
    
      sh script.sh
      python script.py
    

So one line vs two lines

    
    
      import sys
      open(sys.argv[1],'w').writelines(sorted(open(sys.argv[2]).readlines()))
    

Yep, bash is more readable for small scripts

~~~
tyrion
> Yep, bash is more readable for small scripts

I don't agree with that, in my opinion bash is more _coincise_ while python is
far more _explicit_ and thus more understandable.

Python is not meant to be written in one line; the script could be rewritten
in a readable way like this:

    
    
      import sys
      
      inp = open(sys.argv[1], 'r')
      out = open(sys.argv[2], 'w')
      
      out.writelines(sorted(inp))

~~~
brian_cloutier
This is my favorite python implementation in this thread. I daresay it's
beautiful.

Including whitespace it's still half as long as the "11 line" core of the C++
script.

There's an unnecessary 'r'. Combined with the line rhythm established by
opening the files in consecutive lines you ensure readers who would have been
confused by the 'w' will quickly understand.

And the last line reads like programmer English; by which I mean English with
a SVO word order. Not intuitive to the average person but quite parsable by
anybody who's used a modern imperative language.

I can't even nitpick your choice of inp instead of input, the rhythm you setup
and the contrast with 'out' means it's quite obvious what you mean.

Have an upvote.

~~~
ksrm
English is usually SVO; I assume you meant OVS?

------
roel_v
I use C++ every day but I take objection to the following claim

"powerful string manipulation functions"

boost::algorithm::split (and the rest of algorithm, frankly) is unintuitive to
use. Regex requires looking up the syntax every time. No encoding/unicode
support. Literally 100's of popular string libraries, all incompatible, and
that's not even counting all the homebrew. char* everywhere so lots of copying
to work with string objects (which is what all of the algorithms work on).
Dozens of different and slightly different ways of converting other types and
object to/from strings. Poor string formatting functionality, and the
solutions that exist are verbose and cumbersome (strstream, boost::format,
...) .

I still love the combination of low-level power and high-level abstraction
that C++ provides, but string handling is one of the most problematic areas,
in my experience (which is of course colored by the type of work I do, but
still).

~~~
Pxtl
Yup. C++ isn't a terrible language for scripting, it's mostly the fact that it
lacks a single sleek standard library like C# or Python or whatnot offer for
normal shell-scripting tasks.

~~~
waps
The problem with that is that any such "sleek standard library" doesn't
translate the existing (massive) body of C++ code. Using QT is already much
better than the standard library though.

------
YZF
I think this is just helping perpetuate an artificial meaningless
classification of languages.

This entire "scripting language" vs. ? ("general purpose language"? "systems
programming language"?) is really not well defined in the first place.

What makes some language a scripting language? Is Python a scripting language
or a general purpose language? Scripting for a specific platform? "General"
scripting language?

I think most people think of "scripting languages" as languages used for
automating small tasks that aren't suitable (the languages, that is) for large
applications. By that definition any general purpose language is automatically
a "scripting" language but not the other way around.

And what does having a REPL vs. not or an interpreter vs. a compiler have to
do with any of this?

~~~
crazygringo
It isn't well defined? I always thought a scripting language was
evaluated/compiled at runtime (therefore slower, often allowing dynamically
generated code to be executed, no low-level memory management like pointers),
versus traditional languages which are compiled (either to assembly, or some
intermediate representation, but dynamically generated code in the original
language is necessarily out of the picture).

Obviously the _name_ "scripting" comes about from the fact that such langauges
are intended for "scripting" automating interaction with "objects"
(application scripting, HTML scripting, shell scripting, etc.), and that high-
level features and on-the-fly execution are more important than performance.

I've never met anyone who thought Python wasn't a scripting language -- I
mean, you run the Python interpreter on the script file. And I've never met
anyone who would call a compiled language (C, Java, etc.) a scripting
language. The distinction is pretty clear to me; maybe other people can think
of counterexamples?

~~~
YZF
Python is compiled into Python byte code. Is Scala compiled or interpreted?
(it has a REPL...)

[http://stackoverflow.com/questions/2998215/if-python-is-
inte...](http://stackoverflow.com/questions/2998215/if-python-is-interpreted-
what-are-pyc-files)

Do we need to compile to machine languages? What about a VM? What about the
Python VM is different than the Java VM or the .NET VM? Is C# therefore a
scripting language or a ______ language. (fill in the blank)

ActionScript? What about JIT compilers? JavaScript?

At any rate, I think you're trying to say scripting langugage == interpreted
language but there are probably interpreted languages (let's say Prolog) that
you wouldn't call scripting languages and there are compiled languages that
can be used for "scripting". I agree that _typically_ scripting languages are
interpreted. But I would call Python a general purpose language and not a
scripting language.

~~~
zanny
> Do we need to compile to machine languages

And then, everything always _eventually_ compiles to machine code, some just
do it at runtime!

------
praseodym
The four points on how "scripting languages differ from classical compiled
languages" would mean even Java qualifies as a scripting language, and I've
never seen anyone credibly claiming that.

Wikipedia is more clear on this:
[http://en.wikipedia.org/wiki/Scripting_language](http://en.wikipedia.org/wiki/Scripting_language)
"it is uncommon to use Java as a scripting language due to the lengthy syntax
and restrictive rules about which classes exist in which files" \-- I'd say
this applies to C++11 as well.

~~~
reirob
I'd like to add following criteria:

* No static types

* No need to compile

* Having a REPL

~~~
MichaelGG
F# has static types, but it feels pretty light for doing scripting. It's got a
REPL and a script mode to execute things without an explicit compile phase.
Perhaps "doesn't require heavy type annotations" is a better criteria than no
static typing.

~~~
reirob
Agree with you, without knowing F#. I guess F# is related to Haskell and in
Haskell you have static types, but you need them only where the
compiler/interpreter is not able to infer them.

~~~
MichaelGG
F# has some inheritance from OCaml and ML. Much older than Haskell. And type
inference can be done in many languages. There's no reason why, for instance,
Java and C# require type annotations all over the place. They could add in
type inference everywhere, although it'd probably mean a overhaul of the
compiler, and it wouldn't work in every case (overloading).

~~~
stonemetal
_There 's no reason why, for instance, Java and C# require type annotations
all over the place._

Wouldn't their type systems be a big reason why? ML and Haskell have type
systems very different from Java specifically because they went for systems
that were inferable. F# has an iffy "just assume it is int" step to make it
work with the C# type system. F#'s inference algorithm doesn't work as well,
and it impacts how the language gets used. For example people tend to overuse
the pipe operator because it helps the inference engine get the right type
without annotations.

~~~
MichaelGG
F#'s "assume it is int" is only for a few operators, such as +, as a
convenience. It has nothing to do with interop with C# at all.

F# inference is left-to-right, which is one reason to use the |> operator,
yes. F# had additional type inference, for instance, accessing members on a
binding would infer object types, but they removed that. Haskell has a more
complete type inference system.

I'm not seeing anything in C# that prohibits inference of types for fields,
methods return types, or parameters. The type system C# has is essentially a
subset of F#.

------
stinos
Would be great if somebody could post Python/Ruby/.. code here that achieves
the same, just to compare. Even with all the C++11 additions it never felt
like scripting to me, and I use it practically every day.

Small nitpcik to the author: please define variables when you're going to use
them, not C-style all at the beginning of the function. It makes code easier
to understand. It doesn't make the reader wonder 'hey what's this variable
going to be used for' then having to crawl through all code underneath it. It
creates code that's easier to refactor. Also, but more arguably for such a
small sample: [http://stackoverflow.com/questions/1452721/why-is-using-
name...](http://stackoverflow.com/questions/1452721/why-is-using-namespace-
std-considered-bad-practice)

~~~
danmaz74
Ruby:

    
    
      array = IO.readlines ARGV[0]
      array.sort!
      File.write ARGV[1], array.join("\n")
    

edit: get input and output file names from command line

~~~
ollysb
If we want to golf it, it would probably just be

    
    
      lines = IO.readlines ARGV[0]
      File.write ARGV[1], lines.sort.join('\n')
    

certainly more readable than the C++ even if you're unfamiliar with ruby.

~~~
danmaz74
Well, if you really want to golf it, you can just write:

    
    
      File.write ARGV[1], IO.readlines(ARGV[0]).sort.join('\n')
    

;)

~~~
Freaky
You're fired.

    
    
        IO.write(ARGV[1], ARGF.lines.sort.join)

~~~
danmaz74
Wow, this is really sweet and esoteric (didn't know about ARGF) - but, reading
the docs for ARGF, wouldn't it also try to ready from ARGV[1]?

Maybe this would fix it:

    
    
      IO.write(ARGV.pop, ARGF.lines.sort.join('\n'))

~~~
Freaky
Yes, good catch. join('\n') is wrong though - IO#lines preserves newlines, the
default join is the empty string, and you meant "\n" :)

~~~
danmaz74
:)

------
aidos
_every single line of code is clear, understandable and expressive_

It's been a while since I looked at C++ but that statement doesn't apply to
me. For example:

    
    
        for(const auto &i : data) {
          ofile << i << std::endl;
        }
    

I have no idea what that's doing or why it makes any sense. If I knew C++
better maybe that wouldn't be the case but, for example, the Ruby example
someone else provided is obvious to me (and I don't work with Ruby).

It feels there's a lot of telling the machine how you want to do something
going on in here (instead of what you want it to do).

I'd be really interested in hearing how this sample differs from a previous
C++ implementation.

~~~
minimax
I think people sometimes feel compelled to combine auto and the range based
for loop when they shouldn't. In this example the range based for loop adds
clarity but the use of auto doesn't. I would have written something like:

    
    
        for(const string &s : data) {
            ofile << s << std::endl;
        }
    

which is a lot more clear about what type of thing you're getting out of the
vector on each iteration.

~~~
jcl
Actually, the only thing this tells you about what you are getting out of the
vector is that it can be implicitly converted to a string.

If data is a vector of, for example, pointers to const char, on each iteration
this code will unnecessarily copy each item into a temporary string before
printing it. Using auto would avoid this step, regardless of data's type.

Note that the typical non-range-based for loop also omits the vector item
type... Is this that much less clear?:

    
    
      for (int i = 0; i < data.size(); ++i) {
          ofile << data[i] << std::endl;
      }

~~~
minimax
That's a good point, but when I think of the typical code for non-range-based
for loop it looks like:

    
    
        for (vector<string>::iterator i = data.begin(); i != data.end(); ++i) {
            ofile << *i << std::endl;
        
        }
    

which makes it pretty clear what types we're dealing with.

~~~
marshray
I think in C++1y we'll be able to define a function 'foreach' that we can use
like:

    
    
        foreach(data, []<class T>(const T & item) {
            ofile << item << std::endl;
        });
    

This should eliminate the potential implicit conversion to temp. But I'm not
sure it's seriously better than the original range based for with auto.

------
michaelfeathers
In some languages that 23 line program is one line. That's way more important
than whether a language is a scripting language.

------
Derpdiherp
Maybe it's true that C++ has become less verbose and more easily flexible than
it once was through some of the additions of the C++11 standard. I'd argue
that a scripting language is not defined by these criteria though, a scripting
language is not compiled down to a binary by definition - that's what defines
it.

Semantics though.

~~~
Millennium
The real differentiator is that there is no user-visible compile step.
Scripting languages can be compiled to binary, through a JIT or even AOT, but
when this happens, it's hidden from the user. Consider Python and Java: both
are compiled to binary formats, but Python hides this while Java does not. It
is common to call Python a scripting language, but it has been a long time
since anyone said that of Java (and even back when they did, it was intended
as an insult more than as a technical classification).

C++ is adopting some of the properties of scripting languages, but I'm not
aware of any implementations that have removed the explicit compile step. I
don't think it's really accurate to call C++ scripting as long as that step is
still required, and I haven't seen very much interest in taking it out.

~~~
adestefan
A little bit of command line foo would fix that. If you really wanted to go
gung-ho you could use Linux's binfmt_misc to do it directly to .cpp files for
you.

And before you complain it's not the same thing, that's basically all a
scripting language does. The compilation step is hidden inside the command
wrapper.

~~~
outworlder
Would it, though? C and C++ introduce a lot of complexity in the compilation
stage that are hard to hide without leaking much.

You have to import the headers, using include guards if your "script" spans
multiple files. Any external headers have to be in the header search path,
libraries have to be explicitly linked and also be in the linker path, you
have to have a makefile or similar in order to manage the compilation
complexity.

If you are using, say, python, all you have to do is add the shebang, "import"
the desired packages and you are good to go. One has to install the eggs,
packages, or whatever the name is beforehand, but after that you can just use
them.

~~~
npsimons
Eh, it's all semantics; nearly any language can be compiled or interpreted,
and while it is verbose, it's not insurmountable to make scriptable C++; I've
got some templates I tweaked with long enough to make them pretty
straightforward to cut and paste and use with binfmtc (see my other post) to
quickly test things (I may have to post those templates . . . ). I also have a
template for Python that does similar things, because in all honesty, while it
might slow down learning a bit, at least I'm learning the _correct_ way to do
things by always having warnings cranked to the max.

------
benhoyt
Agreed that C++11 is better than C++Original. But no. It's still 19 non-blank
lines, all of which you have to think about and maintain. Compare this to an
idiomatic version written in a "real" scripting language like Python.

    
    
       import fileinput, sys
       for line in sorted(fileinput.input()):
           sys.stdout.write(line)
    

Advantages over C++:

* Fewer import/using lines (5 lines in the C++ version).

* No variable declarations (4 lines in the C++ version).

* Automatic iteration over file or file-like objects is very nice. No need to build a list via getline() and the terribly-named "push_back()" function.

* No "data.begin(), data.end()" parameters to the sort function -- sane defaults, people.

* "for line in file" is so much easier to read than "for(const auto &i : data)".

* Return 0 is implicit. Explicit is better than implicit, I know, but this is a very sane default. If there's an exception, Python won't return 0.

* Better automatic error handling. What does the C++ version print if a file doesn't exist or if there's a read error?

* Thanks to Python's standard library (fileinput module), it automatically handles stdin, multiple input files, etc.

------
JanneVee
How about

    
    
        #include <iostream>
        #include <iterator>
        #include <algorithm>
        #include <fstream>
        #include <string>
        #include <vector>
    
        using namespace std;
    
        struct Line
        {
            string lineData;
            
            operator string() const
            {
                return lineData;
            }
        };
    
        std::istream& operator>>(std::istream& str,Line& data)
        {
            getline(str,data.lineData);
            return str;
        }
    
        int main(int argc, const char * argv[])
        {
            ifstream ifile(argv[1]);
            ofstream ofile(argv[2]);
            vector<string> data;
            copy(istream_iterator<Line>(ifile), istream_iterator<Line>(), back_inserter(data));
            sort(data.begin(), data.end());
            copy(data.begin(),data.end(), ostream_iterator<string>(ofile, "\n"));
            return 0;
        }
    

And to inform everyone. Cling as a C++ REPL exists.
[http://root.cern.ch/drupal/content/cling](http://root.cern.ch/drupal/content/cling)

~~~
pmelendez
You are including way more lines of code... I don't get your point... sorry :(

~~~
JanneVee
I eliminated the loops and did the processing with STL algorithms and
iterators. It is ugly as sin if you try to process lines like the original
code. Most scripting languages do rather well with lines but C++ does not.

------
deckiedan
Nonsense.

The thing which (to me) makes a scripting language /better/ for actual
scripting, is that it's run from sourcecode.

In unix terms, if the file starts with '#!'

Why? Because I can write a 4 line BASH script which I plonk into
/usr/local/bin and it just works. When I want to check why something happened
on the filesystem, I can open the script _in_ _place_ , and step through it in
the REPL.

No faffing around with trying to figure out where the source code is, no
compile/link/whatever...

Of course, while developing something a little more serious in a scripting
language, I use a linter+unittests in pretty much the same way as a
compiler... but that's besides the point.

Haskell is usually much more concise than C++, but I don't consider it a
scripting language. (OK, I could use an interpeted haskell, I suppose... Just
as you could use a BBC micro ASM interpreter in a VM... but whatever. It's
just silly)

------
brudgers
A teddy bear cut lengthwise makes a good pair of house slippers.

Must be bring your own garbage collector to work day.

------
yummyfajitas
Just curious, what C++11 features are used here? It's been a while since I
flexed my C++ muscles, but all of this looks like the standard C++.

Admittedly, even old style C++ with Boost does look a lot like a scripting
language (except for the segfaults).

~~~
Derpdiherp

      for(const auto &i : data) {
        ofile << i << std::endl;
      }
    

The for loop definition there with the auto keyword. The rest has been
standard for donkeys years.

~~~
yummyfajitas
Ah, nice to see that becoming mainstream. I glossed over it since it's so
similar to:

    
    
        BOOST_FOREACH(string i, data) {
          ofile << i << std::endl;
        }

------
shin_lao
Except the posted C++ code does not correctly handle memory errors or
exceptions thrown by the STL.

I love C++, but let's not make stupid claims.

~~~
ajross
All the posted python/ruby/etc... above has the same problem. A OOM condition
will terminate them all, which is generally the desired behavior (and thus the
reason that process termination is the default handler for OOM conditions in
all environments).

What error specifically are you looking to see handled that wouldn't be
exactly equivalent in your scripting language of choice?

~~~
angersock
Hell, in Linux, an OOM _somewhere else on the system_ could terminate a
properly written program with error handling.

------
ses4j
I disagree strongly with a couple of your points.

\- No need to manually manage memory.

That isn't true at all. You know enough memory management to avoid memory
issues in your example. C++11 didn't save you from needing to understand it --
you understand it so avoided needing it.

\- Compile time with -O3 is roughly the same as Python VM startup and has to
be done only once.

It still requires two separate steps. Also, compile gets slower as the program
gets larger, which isn't nearly as true for Python.

~~~
Pxtl
Thinking it over, memory management isn't really a good argument here. Even if
your program leaks, if we're talking about a job script? Who cares, the OS
will clean it up when the process closes. And either way, stack allocation and
references will do just fine for small jobs, you shouldn't need to be doing
lots of pointer stuff for a little script.

There are many sane subsets of C++ that save us from worrying about memory. If
you just keep everything on the stack or in an auto_ptr, you should do fine.

~~~
pcwalton
This is not true. auto_ptr (in C++11 unique_ptr) and stack discipline are not
memory safe. There is no sane subset of C++ that is memory-safe. I can provide
(and have provided—see my posting history) dozens of examples.

~~~
ajross
That's missing the point though. Broadly speaking, when people talk about
languages with automatic storage management being "safer" they are _not_
talking about a correctness proof of their memory handling. In fact some
languages, perl among them, _fail_ to be safe from leaks in all cases, yet no
one flips out about it.

The point is practical: is the language as typically used subject to routine
"accidental" memory leaks? That's surely true for C, and remains true for most
C++ idioms used up until the last few years or so.

It's _not_ true of the kind of RAII style being talked about in the linked
article. In that style it's routine to write large projects that literally
never call operator delete, and need to resort to an operator new only in rare
circumstances (often for compatibility with older APIs).

Modern C++ when used at this level[1] really does have the same kind of casual
robustness against leaks and free-memory issues that you expect to see from
garbage collected environments. And it's not even hard.

[1] Which is not to say that all contemporary C++ can be written in this
model. Obviously if you're doing syscall-level code you'll need to be touching
memory (and probably the heap) directly. But that's sort of the point.

~~~
pcwalton
> The point is practical: is the language as typically used subject to routine
> "accidental" memory leaks? That's surely true for C, and remains true for
> most C++ idioms used up until the last few years or so.

If this were true, we would expect to see large C++ codebases without memory-
related security vulnerabilities. But the security history of every large C++
codebase that I have seen or heard of says otherwise. I would love it to be
true, but I don't think it's a tenable position that C++, even "modern" C++,
is memory-safe in practice.

We can argue over whether the C++ deployed in practice is "real" modern C++,
but I think that enters into no true Scotsman territory really quickly. The
fact is that C++ is not memory-safe in theory and has not been shown to be
memory-safe in practice. For example, I know of real security bugs in Firefox
that were caused by issues that are _not_ fixed by any "modern" C++ idioms.

~~~
ajross
> _If this were true, we would expect to see large C++ codebases without
> memory-related security vulnerabilities._

OK, we're talking past each other. The linked article and my point was about
C++'s suitability for achieving software quality in tasks that are
traditionally done by "scripting" languages. Security analysis is an entirely
different world, and I tend to agree that other languages have a head start
there as far as memory safety.

But that said, "memory safety" is hardly a big contributor to the overall
vulnerability list. C++ is much less used on web backends, and it's likewise
true that almost no large web service codebase exists without non-memory-
related security vulnerabilities. I don't know if there are any deployed Rust
codebases of this size, but I'd expect them to have their share of whoppers
too.

~~~
pcwalton
I agree with you that C++ is often "safe enough" for tasks that aren't
security-critical: log processing or scientific computing, for example.

------
slug
C++11 is so 2 years ago, C++14 for the win ;) (
[https://en.wikipedia.org/wiki/C%2B%2B14](https://en.wikipedia.org/wiki/C%2B%2B14)
)

C++11 has many nice new things, if you are not familiar with it, I recommend
starting also on the wiki:
[https://en.wikipedia.org/wiki/C%2B%2B11](https://en.wikipedia.org/wiki/C%2B%2B11)

------
moccajoghurt
If the C++ code I have to deal with looked like the given example, I'd be very
glad. Too bad it usually looks way more complicated.

------
newobj
I'm struggling to think of a scripting language that requires linker and
binary compatibility with supporting modules.

------
ytj
#Do the same thing in python

from sys import argv

open(argv[2], 'w').writelines(sorted(open(argv[1])))

~~~
alexchamberlain
That's not exactly a Pythonic example...

------
mrich
Except for the iteration over the vector this would be the same in C++98.

------
kossmoboleat
Wikipedia claims that a scripting language should be interpreted and I would
argue that this means that you need a good interpreter program too. There is
actually a language called Ch
([http://en.wikipedia.org/wiki/Ch_(computer_programming)](http://en.wikipedia.org/wiki/Ch_\(computer_programming\)))
that tries to achieve just that and it work pretty nicely but it's not full-
blown C++.

~~~
LinaLauneBaer
The article mentions:

 _compile time with -O3 is roughly the same as Python VM startup and has to be
done only once_

So I think the OP argues that there is no need for a C++ interpreter because
compiling C++ code is as fast as starting a Python VM.

------
Pitarou
I disagree with the author's central claim (where's the REPL?), but he makes
an interesting point.

C++ has matured to the point where it has 95% of what a scripting language
needs. It wouldn't be hard to write a thin wrapper that provided the final 5%,
and it would come as a welcome convenience to programmer who are used to
working with the C++ libraries.

Oh. Wait a moment. It's already been done. It's called Lua. Ho hum.

------
bstamour
I wouldn't say it's gone into scripting language territory yet, but C++ is
becoming a much simpler language for everyday programming. It's still a large
complicated beast with sharp corners, but that only really occurs when you
delve into library-writing territory. Everyday C++ code, when written in a
modern style, is just cleaner, and C++14 is going to make it even better.

------
anirul
C++ is always the second best language for any task!

------
jarjoura
I think the OP is trying to blur the lines of "use the best tool for the job."
C/C++ are powerful languages but they usually require a build infrastructure
of some kind. (make, etc.)

If you need access to a native library that isn't exposed through any other
tool, sure, then writing a C++ tool is an acceptable route.

------
6ren
I'd expect part of the definition of "scripting language" to include being
interpreted. He addresses this as an extra:

    
    
      compile time with -O3 is roughly the same as Python VM startup and has to be done only once
    

It's a non-scripting language hassle to have to compile. Of course, you just
need a little front-end to automatically compile if needed for you. IIRC Perl
actually does this.

But I like his emphasis on large standard libraries, enabling compact scripts,
esp string processing, and memory managed. WHy couldn't you do this trick with
C (i.e. compile & run)? It's mainly libraries, though memory management isn't
natural. Actually, I could believe that many scripting languages actually
started like that, but shifted to their own syntax asap.

This trick can also be done with java, by keeping a server in the background
to run it to cheat the VM startup tax (and auto-compiling as needed). Java
verbosity is a problem, but you can write C-like code in Java. The biggest
problem is the detail of Java libraries - they give you a lot of control, but
a scripting language should give you less control, in return for quick
functionality (like unix `sort`).

------
wldlyinaccurate
The fact that C++ is a compiled language automatically removes it from my
"scripting toolbelt". Aside from that, I just don't find it to be anywhere
near as expressive as shell or Python, which is hugely important when you want
to understand a script you (or somebody else) wrote several years ago.

------
glx4121_info
IMHO this is a terrible example as you should never write this as it is just
unix' sort. Furthermore I think it is even complicated. First, I think it
should read from stdin and write to stdout and second this should be really
short not what c++ people consider short.

E.g.

import Data.List

main = interact (unlines . sort . lines)

------
melling
I haven't written much C++ in quite some time. Does it still suffer from slow
compilation? There's a module system in the works that should help a lot.

[http://clang.llvm.org/docs/Modules.html](http://clang.llvm.org/docs/Modules.html)

~~~
shubb
Using template heavy code can cause really slow compilation. If get really
liberal with nice things from Boost, a simple looking file can take a couple
minutes.

On the other hand, by modularizing the code down into libraries, and generally
using incremental compilation, after an initial 'full build', minor builds
during development are not too slow.

An example of my problem with C++ is, writing a function in a shared library,
which is meant to return a class from the standard library say vector<string>,
to the program that calls it is very unwise.

Can you imagine if your Python modules couldn't return objects from the
standard library?

This is because the shared library and calling program might have been
compiled against a different version of the standard library, and also because
the 'flattened names', used to refer to members of a class are not uniform
between compilers / compiler versions. You can often get away with stuff on
linux, because all the software is compiled in the same environment, but build
once run anywhere? No.

This is turning into a bit of a rant. I like C++, but it has so many
imperfect, jagged edges, enough to surprise programmers after 10 or 20 years.
There is still a lot left to fix.

------
wowoc
C++ is really great, but there are two major pains that I wish someone found
remedies for: compile time and compiler error messages.

Lack of tooling was another one, but with libclang tons of good tools are
coming.

------
vor_
I adhere to the traditional definition of a scripting language as being a
language used for automation; i.e., to control a host application or several
host applications.

------
segmondy
why would you ignore boilerplate? they count as well! that's why anyone would
skip C++ and use python. Because they don't want to write boilerplate code!

------
lttlrck
I'd be more inclined to agree if there was an example showing how to type
script.cpp in the terminal and have it automatically build with g++ and run.

------
eXpl0it3r
Quite an odd definition/view of what a scripting language is, but yes I like
C++11 and C++14 sounds even more promising!

------
16s
It's my favorite language. Python ranks a close second. With those two
languages, I can do anything.

------
fijal
"faster than any non-JITted scripting language" <\- why not JITted actually?

------
zem
that actually sounds precisely like D's sweet spot - a C++-like language, but
with decreased boilerplate and some high-level features that you'd expect from
a "scripting language".

------
ticviking
What does the compile time look like?

The biggest thing about a real scripting language is that I have one step to
go from edit to run.

