14 ms·
C++ has become a scripting language
- Derpdiherp 13y agoMaybe 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 13y agoThe 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 13y agoA 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 13y agoWould 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 13y agoEh, 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.
- npsimons 13y agoAlready done: http://www.netfort.gr.jp/~dancer/software/binfmtc.html.en http://www.netfort.gr.jp/~dancer/software/binfmtc.html.en Also of note: does more than just C/C++: FORTRAN, Java, Pascal, even assembly; and includes a "realcsh" and "realksh" for that C and kernel REPL you've been craving. Just "apt-get install binfmtc". I test out quick little things in C++ with this all the time.
- zeugma 13y agoThere is a C++ REPL called Cling: http://root.cern.ch/drupal/content/cling http://root.cern.ch/drupal/content/cling It is made by Cern and based on Clang
- melling 13y agoI 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
- Derpdiherp 13y agoIt's proportional to the size and complexity of the code base really. Precompiled headers help.
- shubb 13y agoUsing 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.
- stinos 13y agoWould 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-namespace-std-considered-bad-practice http://stackoverflow.com/questions/1452721/why-is-using-name...
- praseodym 13y agoThe 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.
- drellem 13y agoI think that's the real point; c++ is becoming Java.
- alexchamberlain 13y agoEr... No! No GC and multi-paradigm.
- reirob 13y agoI'd like to add following criteria: * No static types * No need to compile * Having a REPL
- MichaelGG 13y agoF# 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 13y agoAgree 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.
- 13y ago
- moccajoghurt 13y agoIf 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.
- gubatron 13y agohigh-level general-purpose language != scripting language. the fact that the language provides a few new services doesn't mean it's become a 'scripting language' and I'm sure you probably know that and the title was just looking to stirr some s#it up. can you use it for scripting now? sure you always were able to do so, it's just a little more comfortable now to do so, you can use any programming language to script. however, you can't use a scripting language to do all the things (as well/efficient as) a real programming language can. i guess one of the main requisites to consider a language a "scripting language" is that you don't have to recompile it to run it, it's read as a script and executed by a runtime (that may perform some JIT compilation and what not), far from the case. I guess the right title to your post would've been "Now C++ can be used like a scripting language."
- yummyfajitas 13y agoJust 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 13y agofor(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 13y agoAh, 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; }
- deleted 13y ago[deleted]
- brian_cloutier 13y ago> 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.
- MereInterest 13y agoWell, if you want a REPL for C++, there is always ROOT. Though, for the love of all that is holy in this world, I don't know why they chose to have a REPL for C++. Or why they chose the profoundly ungoogleable name of "ROOT".
- natejenkins 13y agoIf you instead search for 'root CERN' the first result is the following: http://root.cern.ch/drupal/ http://root.cern.ch/drupal/
- pjmlp 13y agoIt is actually called CINT. http://root.cern.ch/drupal/content/cint http://root.cern.ch/drupal/content/cint
- reirob 13y agoIn Unix shell makes it in 2, with the bang line: #!/bin/sh sort < $1 > $2 My preferred scripting language ;)
- pestaa 13y agoAbsolutely yes, up to the point you're working with text. When objects (either implicit or explicit) start to interact with each other, shell scripting falls short quickly.
- deleted 13y ago[deleted]
- eXpl0it3r 13y agoQuite an odd definition/view of what a scripting language is, but yes I like C++11 and C++14 sounds even more promising!
- ytj 13y ago#Do the same thing in python from sys import argv open(argv[2], 'w').writelines(sorted(open(argv[1])))
- alexchamberlain 13y agoThat's not exactly a Pythonic example...
- shin_lao 13y agoExcept 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 13y agoAll 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 13y agoHell, in Linux, an OOM somewhere else on the system could terminate a properly written program with error handling.
- kossmoboleat 13y agoWikipedia 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 13y agoThe 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.
- glx4121_info 13y agoIMHO 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)
- 16s 13y agoIt's my favorite language. Python ranks a close second. With those two languages, I can do anything.
- roel_v 13y agoI 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).
- Derpdiherp 13y agoCompletely agreed - working in areas that I do char* style strings are still commonplace, and that does make you appreciate boost or std::string a great deal more. But it does not hold a candle to the ease of string manipulation in a lot of scripting languages.
- Pxtl 13y agoYup. 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 13y agoThe 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.
- oso2k 13y agoThe API that c0 [0] provides is closer (though still low-level) to what is provided by more modern languages. [0] http://c0.typesafety.net/ http://c0.typesafety.net/
- anirul 13y agoC++ is always the second best language for any task!
- aidos 13y agoevery 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.
- pdw 13y agoTraditional C++ would look something like this: for (vector<string>::const_iterator it = data.begin(); it != data.end(); ++it) { ofile << *it << endl; } But in this case we're dealing with a vector, so you don't need iterators: for (unsigned i = 0; i < data.size(); ++i) { ofile << data[i] << endl; }
- alexchamberlain 13y agoUgh, define need. If sanity is required, stick to iterators.
- mrich 13y agoIterators can get very ugly. I like this when there is a need to access elem a lot inside the loop: for (size_t i = 0, iEnd = elems.size(); i < iEnd; ++i) { Elem &elem = elems[i]; // deal with elem } Of course the new C++11 syntax is king.
- wowoc 13y agoI think that some amount of knowledge was assumed. You would have understood it if you had known Java. For-each loops in Java have a very similar syntax. You probably know something that is similar to Ruby, and that's why you understand it without ever learning it. I bet that you wouldn't understand it if you didn't know any programming language at all.
- bstamour 13y agoI 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.
- wldlyinaccurate 13y agoThe 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.
- ses4j 13y agoI 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 13y agoThinking 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 13y agoThis 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 13y agoThat'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.
- brudgers 13y agoA teddy bear cut lengthwise makes a good pair of house slippers. Must be bring your own garbage collector to work day.
- 6ren 13y agoI'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`).
- slug 13y agoC++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
- deleted 13y ago[deleted]
- segmondy 13y agowhy 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!
- jarjoura 13y agoI 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.
- ticviking 13y agoWhat 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.
- JanneVee 13y agoHow 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 13y agoYou are including way more lines of code... I don't get your point... sorry :(
- JanneVee 13y agoI 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.
- abelsson 13y agoHah, I was just about to post more or less exactly the same code. :) It's funny, had the author tweaked the problem just slightly to try make C++ look good by saying that the program should output sorted words instead of lines, you could have deleted the entire Line nonsense. Had the problem been to output sorted, unique words, you could have made the rather elegant: int main(int argc, const char* argv[]) { using input = istream_iterator<string>; using output = ostream_iterator<string>; ifstream inputfile(argv[1]); ofstream outputfile(argv[2]); set<string> words{input(inputfile), input()}; copy(words.begin(), words.end(), output(outputfile, "\n")); } But then again, it's not exactly in C++'s favor as a scripting language that copying words is easy, while lines is hard.
- YZF 13y agoI 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?
- pjmlp 13y agoThere are definitions well accepted by those that care to study programming languages in terms of Computer Science. The problem is that many discuss what they think a certain programming language is, without the proper bases to do so.
- YZF 13y agoWhat is the CS definition for "scripting language"?
- pjmlp 13y agoThey usually share a set of features in terms of typing, extensibility, ability to be used more as glue language than real applications, interactivity A well known paper that discusses those capabilities is the John Ousterhout's paper for the 1998 IEEE COMPUTER, "Scripting: Higher Level Programming for the 21st Century". http://www.stanford.edu/~ouster/cgi-bin/papers/scripting.pdf http://www.stanford.edu/~ouster/cgi-bin/papers/scripting.pdf
- judk 13y agoNice backpedal from "definitions".
- wowoc 13y agoC++ 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.
- michaelfeathers 13y agoIn some languages that 23 line program is one line. That's way more important than whether a language is a scripting language.
- zem 13y agothat 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".
- fijal 13y ago"faster than any non-JITted scripting language" <- why not JITted actually?
- vor_ 13y agoI 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.
- mrich 13y agoExcept for the iteration over the vector this would be the same in C++98.
- deleted 13y ago[deleted]
- newobj 13y agoI'm struggling to think of a scripting language that requires linker and binary compatibility with supporting modules.
- lttlrck 13y agoI'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.
- benhoyt 13y agoAgreed 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.
- Pitarou 13y agoI 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.
- deckiedan 13y agoNonsense. 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)