12

C++ is a great language in many ways, but some things in particular are cumbersome to write without an IDE. As a VIM user, it would be very interesting if I had access to a higher level language which enabled me to write C++ with S-Expressions and possibly with Lisp-like macros, allowing for the generation of clean code while avoiding rewriting the same patters over and over again.

I've asked on freenode and tested several ideas, such as compiling Lisp->C with compilers such as ECL and Bigloo, but none of those generated particularly clean C code.

Are there any works on this issue?

MaiaVictor
  • 5,820
  • 7
  • 27
  • 45
  • 3
    Why not write your code in a lisp with macros such that it's all C++ and then those features that you want but are hard to cleanly do just get expanded by a LISP macro from a simple syntax to the more complex C++. Better yet, you could just write your code in LISP. :) – Jimmy Hoffa Aug 29 '13 at 18:51
  • 2
    Are you expecting the Lisp -> C++ translation to produce clean C++ code, when the (arguably simpler) C++ -> Assembly produces unreadable (a matter of opinion) assembly? Who is the target of compilation meant for anyways? –  Aug 29 '13 at 18:51
  • Could you please point to the definition of "higher level language"? The only thing in common in all languages which I've seen so characterized is the presence of a garbage collection. – AProgrammer Aug 29 '13 at 18:58
  • @JimmyHoffa I particularly don't prefer to bloat my vim with remediating tools than having a proper, proven macro system. But I like the suggestions and I will definitely try them if I don't get what I want. Thanks. – MaiaVictor Aug 29 '13 at 19:14
  • @JimmyHoffa because somebody probably has already done that and I don't want to reinvent the wheel. Other than that, this is probably what I'm gonna do! Ah, and *just writing in lisp* is not an option as I have to ship C++ code. Sucks to be on my skin! ): – MaiaVictor Aug 29 '13 at 19:14
  • 1
    Somehow I'm not totally convinced anybody has already written the macros to expand exactly what you want expanded, but as a rule macros are surprisingly simple to write, they're just list processing methods, you shouldn't have much difficulty just writing it all inside of a single s-expression which you delimit when you want the macro expander to pay attention, then just simply print the list to get your C++ code with expansion. – Jimmy Hoffa Aug 29 '13 at 19:19
  • @JimmyHoffa Fair enough! – MaiaVictor Aug 29 '13 at 19:30
  • 2
    I agree that Lisp can do certain things that are hard in C++ (like closures). Do you need to do those things? Then since they are hard to do in C++, no matter how you get them into C++, automatically or manually, it will not be pretty. My suggestion: If you don't really really truly need those difficult things that Lisp can do, don't use Lisp. Get good at C++. If you must use those things, but you must code in C++, then figure out how to do it in C++. That's what separates the adults from the children in this business. – Mike Dunlavey Aug 29 '13 at 20:02
  • Particularly I really enjoy using closures on my code and my source is pretty much a collection of small anonymous functions piped together. It is obviously unrealistic to expect to translate anything like that to readable C. But a simple S-Expression syntax with powerful macros would do great on the C world, I guess. In theory there is nothing stating you need to go functional to code in SExps, after all. – MaiaVictor Aug 29 '13 at 20:17
  • 3
    There are several languages having compilers that emit C code, so I don't see why this isn't feasible, even if it's C-like C++ code. If your question is "can I get canonical, best-practice C++ code using all of the available features in C++," that might be a little harder. – Robert Harvey Aug 29 '13 at 21:18
  • @RobertHarvey feasible you mean as in "possible", but probably not done, right? – MaiaVictor Aug 29 '13 at 21:36
  • @MikeDunlavey: C++11 does have closures. Yes, they still have manual object lifetime control, but they are good closures. And C++ was really used as functional language even before that. – Jan Hudec Sep 02 '13 at 08:06
  • @Jan: I'm sure you're right. The problem I see all the time is people using features because they're "cool", not because they're needed, necessarily. – Mike Dunlavey Sep 02 '13 at 12:11
  • @MikeDunlavey: School assignment (according to comments we are talking about one) is however a good place to try the features out and see what they are worth without screwing up something that will have to be maintained next 10 years. – Jan Hudec Sep 02 '13 at 12:54
  • @Jan: Good point. I wonder if teachers could say "In situation X, the options are Y or Z, and these are the pros and cons" so we minimize the situation where if you've got a hammer everything looks like a nail. – Mike Dunlavey Sep 02 '13 at 14:23
  • 1
    Vote to close: Good question, but not sure this is a valid question for SE. Its open to much opinion ("readable C++"), its asking for a tool recommendation, or its too broad, or a bit of all of these. – mattnz Sep 23 '13 at 01:09

3 Answers3

13

Compiling higher level languages to lower level ones is cake. There's countless examples of it being done. Without going off on much of a tangent, we can point to early C++ compilers that compiled down to C.

When you start throwing "clean" and "readable" into the mix, however, things get really tough. Clean, readable code expresses the meaning and intent of what you were writing. Computers are notoriously bad at interpreting & creating meaning. You're more likely to end up with variables named int_147 than input_buffer_length. Sure, if you really wanted to make this project work, you could engage in a massive AI project to handle converting your Lisp to some sort of decently readable C++ but, to be perfectly honest, Common Lisp compilers are pretty fucking good at what they do.

More important than the difficulty of generating C++ from a Lisp is the usefulness of this. What purpose would it serve for the generated C++ to be readable? If the Lisp is your source code, intermediate representations should be irrelevant. If you want to be able to hand the C++ over to programmers that don't understand your original Lisp, you've now got another problem. What happens when they want to modify your generated C++? What happens if they write things in C++ that don't cleanly translate to your Lisp?

Let's say we've solved that. It's a decade later and, after burning through hundreds of millions of dollars of DoD grant money, we've build this massive, complex (but flawless) language translation engine that can turn Lisp into idiomatic C++ and vice versa. What have we really gained that wouldn't be better accomplished by either teaching people a new programming language or just developing a new compiler that lets us link the two languages?

Oh, right. Your boss wants you to write C++ and you'd rather not. Update your resume & find a new job.

Sean McSomething
  • 3,781
  • 17
  • 25
  • I wish I could update my resume and find another job. Unfortunately that is not so straightforward when job="student" and boss="professor". And most unfortunately, I am supposed to have a diploma. Regardless of the fact I don't go to the classes, but learn it myself home. Of the fact I am already working on the industry and make more money than most graduates I know. That is just how it works. Sadly. Happily my prof accepted to pass me if I write something complicate in C++. I already know C++. So I'd rather take the chance to learn something different (; Rant aside, great answer. Thanks. – MaiaVictor Sep 02 '13 at 03:47
  • @Dokkat: I don't believe you know C++. Can you write templates with special implementations depending on whether the parameter has some method or function? Have you done compile-time computations using Boost.MPL? Do you understand how Boost.ForEach works? If you have to do it in C++, take it as opportunity to learn more advanced C++. It will be more usable for your work too. – Jan Hudec Sep 02 '13 at 08:04
  • 1
    Well I have done some pretty complicated templates when I worked with C++ those sad years. Yea I used Boost.ForEach a lot, I remember defining a lot of macros to get it more useful though. Anyway I was a kid, that was not a fun experience. I don't get the point in learning any further, when Lisp provides such a much more solid, less painful macro system, that accomplishes exactly that kind of metaprogramming that C++ requires guruish skills. – MaiaVictor Sep 02 '13 at 09:14
3

Short answer, there is nothing out there currently that will help you convert Lisp to READABLE C++. Sure you can convert anything to C++ or C but readable code is written by humans, not programs. Sure you can output C++ code with proper formatting, indents, nice class names, and maybe even somehow get perfect translation from Lisp class objects to C++ classes. Maybe you can get your library dependencies linked just right, and maybe you can compile binaries that are very close to what the C language would have produced had you written the whole thing in C. But ultimately, readable code is a beauty that is not understood by anyone, at least not just yet, and possibly never considering that the term readable is quite subjective to begin with and what might be considered readable among one group of developers may be considered atrocious by others.

To make C++ readable, you have to write in C++, not in Lisp. You also have to be able to change your coding style according to what the people who will read your code will best understand. Just like books, programs are written with a specific audience in mind and can be beautiful and touching if written well, and obfuscated and tedious if not. And if we can't come up with a program to write beautiful fiction novels for us, then we won't be able to come up with something to convert to readable C++.

  • I guess you are overreading what I mean with "readable"! It does not have to be really beautiful. Just enough so you can read it and understand what is going on. I guess I'll go with some Lisp macros for a direct translation, as JimmyHoffa suggested on the comments. – MaiaVictor Sep 02 '13 at 04:24
3

ViM is a great IDE for C++. It has the best completion I've ever seen so far too, though it gets a little slow if you pull in a lot of headers, the clang complete. And for compilation I found all IDEs lacking anyway; you end up writing build system in CMake or something anyway. And I have not seen anything to provide any help for lisp, period.

True, C++ does not have lisp-style macros, but templates can do everything scheme's hygienic macros can and some more, because you can implement them differently based on types and based on their capabilities. True, it's lack of garbage collector makes closures a bit more tedious, but the RAII idiom used for resource management instead has it's own advantages and interesting properties.

If you are a student, do you really know all the advanced C++? From algorithms library over writing templates with alternate implementations based on properties of argument types, compile time calculations using template meta-programming (using Boost.MPL) to understanding how Boost works under the hood? If not, I recommend taking this as opportunity to learn some advanced C++. School assignment won't need to be maintained, so you can play with the language to see what the features are worth where in production code you'd have to be careful about readability.


And to answer the final direct question: C++ has so many more idioms under it's belt that there is no way to generate idiomatic C++ from anything. Simply because there will be no way to express most of those idioms in anything else. Starting from the fact that anything will garbage collection will allocate everything on heap while in C++ it is idiomatic to take advantage of the stack.

Jan Hudec
  • 18,250
  • 1
  • 39
  • 62
  • Agree on VIM. It fits like a glove for C development. I am a Vim user but for Lisp I use Emacs in evil-mode with SLIME and Paredit. There is some support for Lisping in vim with basic REPL hooks but they do not come close to SLIME. – mike30 Sep 02 '13 at 14:00