Selecting a Programming Environment(williamaadams.wordpress.com)
williamaadams.wordpress.com
Selecting a Programming Environment
http://williamaadams.wordpress.com/2012/08/31/selecting-a-programming-environment/
19 comments
It's pretty normal these days to rely on GCC varargs. Among my people (the unix tribe), few care if Microsoft will ever support C99 or anything else for that matter.
You can use a macro to swap between varargs/stdarg.h if you want to be able to use the LLVM toolchain in addition to gcc.
MSVC++ can go suck fruit wax.
You can use a macro to swap between varargs/stdarg.h if you want to be able to use the LLVM toolchain in addition to gcc.
MSVC++ can go suck fruit wax.
"If you program long enough, you come to realize that there is no “one language to rule them all”"
Than you program some more and, if you're smart, you realize there's Common Lisp.
Than you program some more and, if you're smart, you realize there's Common Lisp.
Except that Common Lisp is a kludge, a relic, and a sad victim of 30-year–old compromises. It's also practically abandonware, with no new specification since 1994's ANSI Common Lisp. (Itself mainly clarifications to CLtL2.)
Modern Lisps — of which Clojure is currently the leader of the pack — would be a far better choice today.
Modern Lisps — of which Clojure is currently the leader of the pack — would be a far better choice today.
Not to start a Lisp-vs-Lisp side-conversation here, but if we're going to go with a 'modern' Lisp, I'd prefer one that doesn't add syntax and which supports proper tail-call elimination.
It's not like we have a lack of those, either - Racket's my personal favorite; aside from the robust standard library, the scoped languages give me hope that the 'Lisp curse' has finally been reversed.
It's not like we have a lack of those, either - Racket's my personal favorite; aside from the robust standard library, the scoped languages give me hope that the 'Lisp curse' has finally been reversed.
And then later you come across Haskell :P. Everything you could possibly want in a language, and far less wish-washy than the rest; a perfect testament to the fact that theory and practice are not at cross purposes.
Sure it's not perfect, but I posit that it's a local maximum for most tasks.
Sure it's not perfect, but I posit that it's a local maximum for most tasks.
And then you have to use javascript to do some front end web development.
>Than you program some more and, if you're smart, you realize there's Common Lisp.
And then you realize, oh, it was just "premature realisation", actually Common Lisp is not the one "to rule them all" after all.
E.g it's useless for most embedded work, a non started on the web client side, you cannot find many programmers to hire for your project, a lot of self proclaimed Lisp programmers are just dabblers, there are not enough available libs for lots of fields (, scientific computing, GUI, multimedia etc), and a thousand other reasons.
Oh, and no killer app was been made in Common Lisp, or any Lisp for that matter, with the exception of Emacs (but that one is targeted to developers anyway). In fact, the most famous example of Lisp "success" is a mid-nineties startup that was sold to Yahoo.
And then you realize, oh, it was just "premature realisation", actually Common Lisp is not the one "to rule them all" after all.
E.g it's useless for most embedded work, a non started on the web client side, you cannot find many programmers to hire for your project, a lot of self proclaimed Lisp programmers are just dabblers, there are not enough available libs for lots of fields (, scientific computing, GUI, multimedia etc), and a thousand other reasons.
Oh, and no killer app was been made in Common Lisp, or any Lisp for that matter, with the exception of Emacs (but that one is targeted to developers anyway). In fact, the most famous example of Lisp "success" is a mid-nineties startup that was sold to Yahoo.
Well, there's ITA Software. And arguably AutoCAD.
Well, as for AutoCAD:
The language was introduced in AutoCAD Version 2.18 in January 1986, and continued to be enhanced in successive releases up to Release 13 in February 1995.
_After that, its development was neglected by Autodesk in favor of more fashionable development environments like VBA, .NET and ObjectARX. However, it has remained AutoCAD's primary user customization language._
So it looks like it has been dead for 17 years.
The language was introduced in AutoCAD Version 2.18 in January 1986, and continued to be enhanced in successive releases up to Release 13 in February 1995.
_After that, its development was neglected by Autodesk in favor of more fashionable development environments like VBA, .NET and ObjectARX. However, it has remained AutoCAD's primary user customization language._
So it looks like it has been dead for 17 years.
musl & klib are great together if you're going to live in C land. I'd also add ``caffeine`` and ``libev`` if you're targeting a platform a Unix like platform and need to do network programming.
http://github.com/dmw/caffeine http://software.schmorp.de/pkg/libev.html
http://github.com/dmw/caffeine http://software.schmorp.de/pkg/libev.html
I glanced at klib and I noticed that a bunch of the implementations were straight up macros. This— this seems like crazy talk to me. But I am not a C programmer, and I've spent very little time in C++ until very recently.
Can someone shed some light on this? The trade-off may well be worth it, but I'm only aware of the negative trade-off, not the positive.
Can someone shed some light on this? The trade-off may well be worth it, but I'm only aware of the negative trade-off, not the positive.
I only saw the kind of macros you're probably thinking about (on the order of #define min(X, Y) ((X) < (Y) ? (X) : (Y))) in kbit.h, but I didn't look at the source to all the components. What klib does seem to use the preprocessor quite a bit for, however, is implementing generic functions and datatypes -- in other words, since the only significant difference between the implementation of a linked list whose nodes have "payloads" of 2 bytes, and one where the payloads are twice as large is, at the language level, the size of the respective payloads, we would ideally like some kind of code generating "function" that will take a datatype of some size and produce an appropriate linked list implementation. C++'s function templates exist for this sole purpose, but in C, we have to abuse its preprocessor to get a similar result.
If you take a look at the source of klist.h, the preprocessor stuff is a bit hairy, but it basically leaves you with a "compile time function", KLIST_INIT, that takes a datatype and generates, via simple textual substitution, an implementation of a linked list where each node of the list carries a payload of that datatype. klib_test.c includes a simple usage case.
Just to be clear, the preprocessor is generating real functions (inline ones, but functions nonetheless), not simply textually inserting the appropriate list code every time you use one of the macros like kl_next(iter) defined at the end of klist.h.
Check out the GCC docs on macros (and particularly, the section on concatenation) to get a better understanding of how klib implements this. http://gcc.gnu.org/onlinedocs/cpp/Macros.html
As for how "crazy" it is to do this with the preprocessor, it's just the most convenient alternative in C to manually copying and pasting a generic list implementation yourself and editing in the correct type information, so it's a fairly common practice. You'll know code that really abuses the preprocessor when you see it -- I would advise then to run.
If you take a look at the source of klist.h, the preprocessor stuff is a bit hairy, but it basically leaves you with a "compile time function", KLIST_INIT, that takes a datatype and generates, via simple textual substitution, an implementation of a linked list where each node of the list carries a payload of that datatype. klib_test.c includes a simple usage case.
Just to be clear, the preprocessor is generating real functions (inline ones, but functions nonetheless), not simply textually inserting the appropriate list code every time you use one of the macros like kl_next(iter) defined at the end of klist.h.
Check out the GCC docs on macros (and particularly, the section on concatenation) to get a better understanding of how klib implements this. http://gcc.gnu.org/onlinedocs/cpp/Macros.html
As for how "crazy" it is to do this with the preprocessor, it's just the most convenient alternative in C to manually copying and pasting a generic list implementation yourself and editing in the correct type information, so it's a fairly common practice. You'll know code that really abuses the preprocessor when you see it -- I would advise then to run.
They're mostly used to avoid the overhead of a function call. The inline keyword is a recent addition.
I saw some examples in the klib code where macros are used to generate boilerplate code, generating functions.
I saw some examples in the klib code where macros are used to generate boilerplate code, generating functions.
Selecting a single environment for all future software projects seems strange to me. Isn't it better to learn about changing parts of your environment depending on the context?
William is really talking more about selecting programming languages and Lua and C certainly cover a lot of programming use cases.
I have my own comfort zone (Clojure, JRuby, and Java with IntelliJ and RubyMine) and I am glad William has his.
I have my own comfort zone (Clojure, JRuby, and Java with IntelliJ and RubyMine) and I am glad William has his.
His Arduino callout limits the available practical options greatly. In his situation minus Arduino, I'd go with Go. It works really well on ARM devices like the Raspberry Pi and all the way up to Windows/Linux/Mac x64.
Go is my current first-choice language if I have the choice. Of course, in today's very segmented platform (web, desktop Windows, desktop Mac, desktop Linux, Android, iOS, WinPhone, et al) era, there's really no one language for everything. Even C falls down in some areas.
Go is my current first-choice language if I have the choice. Of course, in today's very segmented platform (web, desktop Windows, desktop Mac, desktop Linux, Android, iOS, WinPhone, et al) era, there's really no one language for everything. Even C falls down in some areas.
HaXe and HaXeNME come pretty close. Especially NME with which you can create GUIs and games compile to c++, compile to html5 using jeash, create native phone apps, and compile SWFs all from the same code. With HaXe itself the code usually needs a bit of modifying depending on the target. They added java recently to it which is not yet available for NME. If anything; it's fun to play with.
I like the web stack. I like CoffeeScript and Node.js with Chrome or Firefox. Doesn't cover everything, but does handle a lot of cases. If I have to have a native mobile then I might use something like Phonegap or Trigger.io. If I have need native desktop then I might use App.js. For Arduino I would use noduino if possible.
A similar approach applies to the standard library. Write to the language standard, and you are good to go everywhere.
Though, I'm also dubious about using C90 for multi-threaded stuff given that there is no concept of threads in the language until C2011.