4 ms·
Who gets to decide what qualifies as a "real alternative?" I have seen much larger applications written in Java than in C++; does that make Java a "real altern
by betterunix 14y ago
Who gets to decide what qualifies as a "real alternative?" I have seen much larger applications written in Java than in C++; does that make Java a "real alternative?" C++ does not really have any technical advantages over "true" high-level languages (i.e. languages that don't force the programmer to deal with low-level details and whose support for low-level operations does not constrain high-level features), but it has plenty of disadvantages. Meanwhile, I cannot think of anything people do in C++ that I am unable to do in Lisp, although I can think of plenty of things people do in C++ that are unnecessary in Lisp and that only serve to make code more complex and more error-prone.
So there, you have two "real alternatives:" Java and Lisp. I'll also throw in Scala (basically it's what Java should have been to begin with) and OCaml. So what are you doing in C++ that could not be done in any of these languages?
- cageface 14y agoNone of those languages give you the raw performance or low-level memory control of C++ and this is exactly why none of them are used to write things like Chrome, Firefox, Ableton Live, Photoshop, AutoCad, the JVM etc. If you can write your app in a higher level language than C++ then you'd be nuts to use it but there still isn't any real alternative for performance-critical native applications.
- betterunix 14y ago"None of those languages give you the raw performance or low-level memory control of C++" Really? That's funny, because entire OSes have been written in Lisp, and I am pretty sure that those systems needed low-level memory control. In fact, the Lisp compiler I use in my own work has support for low-level pointer operations and a form of inline assembly (which in the past was used to implement SSE intrinsics as an add-on library). I am not sure where people got this idea that all high-level languages were slow or robbed programmers of the ability to do low-level things. "why none of them are used to write things like Chrome, Firefox, Ableton Live, Photoshop, AutoCad, the JVM etc." I suspect that has more to do with the OSes that were targeted and the availability of C/C++ programmers who are familiar with programming for those OSes than with some hypothetical performance advantage of C or C++.
- cageface 14y agoWhich is more likely, billions of engineering dollars are being dumped into projects by people that just don't know any better or there are real, practical reasons why languages like Lisp and Java aren't suitable for these kinds of apps? I remember interviewing with ITA software when they were still tiny and was shocked to learn that even they had to write some of their software in C++ because Lisp didn't give them the speed or the control they needed. Extraordinary claims require extraordinary proof and the onus is on Lisp advocates to explain why there are so few real-world Lisp success stories. Calling everybody else stupid isn't good enough.
- betterunix 14y ago"Extraordinary claims require extraordinary proof and the onus is on Lisp advocates to explain why there are so few real-world Lisp success stories. Calling everybody else stupid isn't good enough." You seem to be suggesting that some technical shortcoming of Lisp held it back in the real world, while C and C++ had technical advantages that led to their success. I think the history of Lisp and the history of C tell a much different story. While C was becoming the language of choice for OSes that ran on low-end computers (especially Unix), Lisp was confined to very expensive computers that were being targeted at a market that ultimately failed to materialize. C became popular by riding on the coattails of Unix, not because it is a great language or because it could compete with other languages on technical features, and C++ road on the coattails of C (maintaining some amount of compatibility etc.). Lisp, meanwhile, was held back by bad business decisions; no amount of technical superiority could have saved Lisp from the AI winter. By the time you could really talk about Lisp running on PCs or cheap hardware, it was too late: C was already widely used and there was already an enormous volume of C code that people were working with. It is interesting that you mention ITA's use of C++. The big reason for that was the poor scalability of CMUCL's garbage collector, which they did not use at all, opting instead for memory-mapped arrays (hence C++, which was used to handle system calls and deal with pointers). Had ITA been developing for an OS written in Lisp (not unprecedented), C++ would never have entered the picture; but ITA was developing for an OS that exposed a C API and a C ABI, and using C or C++ to deal with system calls simply made the most sense. I suspect that if they were to try again today, they would use far less C++, if any; today's Lisp compilers come with (non-portable) extensions for POSIX system calls and for dealing with pointers, as well as disabling the garbage collector globally or on specific objects. It is not that Lisp itself was slow; just a specific feature of the Lisp systems they were using, and poor support for disabling or avoiding the use of that feature. So which is more likely: that C and C++ are the best languages ever developed for the kinds of programs they are used for, or that they were just in the right place at the right time?
- elliptic 14y agoAn analytic database like Vertica? A computer game with cutting-edge graphics? Etc.
- betterunix 14y agoBe careful about statements of the form, "That language is great, but it could not possibly be used for performance-critical code." There is nothing inherent to any of the languages I mentioned that makes them slow, and modern Lisp compilers can compete with C compilers on emitting fast code (and that is despite the fact that those compilers often lack some of the optimizations of C compilers; SBCL, for instance, has no peephole optimizer and it shows in the disassembly of compiled code). There is no reason why a Lisp program cannot access special hardware, use special CPU features via inline assembly, etc.
- elliptic 14y ago< here is nothing inherent to any of the languages I mentioned that makes them slow. I don't agree. The inability to explicitly allocate on the stack in Java and OCaml? The lack of threads in OCaml? Java GC pauses (by the time you're storing things off-heap you might as well be writing C++)? I don't know as much about Lisp, but when looking at a task X, I tend to give the benefit of the doubt to languages (or frameworks, or hardware, or people, for that matter) that have actually achieved a measure of success at X.
- gsg 14y agoYep, that's the price of simplicity and safety. People talk a lot about stack allocation, but the same issue of pointerful vs flat representation arises in arrays and records, where it presents even more of a performance issue. Some GCed languages allow a measure of control there: however, Java and OCaml are not among them. People have tried to marry flat representation and safety while allowing things like passing pointers to stack-allocated objects. The results are distinctly baroque (complex notions of region, etc).
- eropple 14y agoI have seen much larger applications written in Java than in C++; does that make Java a "real alternative?" I am a JVM fan and I dig Lisp, but for the purposes I use C++ for (game development, other high-perf code): no, Java is not a viable alternative and neither is Lisp. Two reasons for Java: generics and garbage collection. Generics are great for about 90% of what I do but templates provide similar flexibility and type-safety (better, really, than Java generics) while preserving fairly preposterous performance characteristics. And, generally speaking, I'm better at managing my memory than the runtime is in cases where I have a well-conceptualized object model[1] and a strong grasp of what's being done where; I can do without the overhead of stop-the-world garbage collection. Lisp has similar object-lifecycle issues and (this is a personal beef) at least Common Lisp lacks strong static typing, so it's a non-starter. Worse than Java for my purposes. Again, I dig these for where they're good, but C++ has a well-deserved stranglehold on its niche. It's not perfect--a project run by a friend of mine[2] is attempting to do it one better--but it hasn't become king of this area by accident. [1] - A "large application" does not always mean a large set of objects and interactions. Just a lot of interesting things with them. =) [2] - https://github.com/Ides-Language https://github.com/Ides-Language
- bcoates 14y ago> I cannot think of anything people do in C++ that I am unable to do in Lisp The biggest technical advantage I've noticed C++ having over other languages is that library performance characteristics are documented as part of the portable language spec. I really miss that when I switch to other languages and have no idea if the builtin list class acts like a linked list or a vector or a deque or what. Knowing that the algorithm you just built out of library components doesn't have a n^3 blowup on some platform is a correctness issue, not a premature optimization. I'm more comfortable that's not going to happen working in C++, and the culture and libraries around it than anywhere else. Does CL specify that, as part of the specification and not just by convention? I'm having a hard time finding docs to that effect but I don't use Lisp enough to know where to look.
- flyinRyan 14y agoActually, in CL a list is always a linked list. It's made of a "cons" which is a two celled part of memory for holding the head (usually data but can be anything) and the tail. A hash is also known to have hash behavior as opposed to, say, an rb tree. A vector is always what C++ would call an array though what CL calls an array might depend on convention (afaik it's often just a normal vector with the access calls changed to go to the correct location).
- betterunix 14y agoThat does not really answer the question. Consider, for example, this question: how efficient is append i.e. for two lists of N elements, how much work will append do? It is easy to assume this will be linear work in N since append will make a copy; but does CLTL2 actually say that append cannot do work in quadratic time, or cubic time, or even exponential time? It's a valid complaint, in my opinion, and I say this as the person who promotes Lisp as an alternative to C++. I would put it in the category of "things missing from the Common Lisp standard," lumping it together with undefined behavior. In practice, this issue rarely comes up; it is generally safe to assume that no Lisp implementation will have an asymptotically worse version of a standard function than the simplest version of that function. So, for example, although the standard is silent on the matter you can safely assume that no Lisp implementation would have an nconc that is asymptotically worse than the simple linear time implementation, and you should not rely on an implementation giving you something better than that. In the C++ standard, there are definitions of running times. So, for example, the stable_sort function is guaranteed to be no worse than O(N log(n) log(n)), and no better than O(n log(n)). That is one thing that is nice about C++, so I can concede that point, though with the note that the C++ standard has its own glaring omissions that are much more disturbing than the running times of algorithms.