What is “modern” programming?

As a young teenager, I dabbled with basic and some assembly. Things got serious when I learned Turbo Pascal. “Now we are talking”, I thought. Turbo Pascal offered one of the earliest examples of Integrated Development Environment (IDE). In effect, an IDE is a program that lets you conveniently write, compile, debug and run code, all within a friendly environment. Turbo Pascal did not have much in the way of graphics (it was text-based), but it had menus and windows. You could enter a debugging mode, track the value of variables, and so forth.

Then I moved on to Delphi (a graphical Turbo Pascal) and it had a superb IDE that would still look good today. I played with Visual Basic, designing a “talking clock” that I published on Bulletin Board Systems at the time (with Windows 3.1). Then I found out about Visual Studio… For years, my reference for C++ programming was Visual Studio. So it was all IDEs, all the time.

Smalltalk famously had powerful graphical IDEs back in the early 1980s.

Chris Wellon wrote about Borland C++, an IDE from the 1990s:

To test drive the IDE, I made a couple of test projects, built and ran them with different options, and poked around with the debugger. The debugger is actually pretty decent, especially for the 1990s. It can be operated via the IDE or standalone, so I could use it without firing up the IDE and making a project. (…) The toolchain includes an assembler, and I can inspect the compiler’s assembly output. (…) Imagining myself as a software developer in the mid 1990s, this means I can see exactly what the compiler’s doing as well as write some of the performance sensitive parts in assembly if necessary.

My point is that using an IDE is not “modern”. The present is very much like the past. What we program has changed, but, in many instances, how we program has not changed. I have the latest Visual Studio on my Dell laptop. The man I was 20 years ago would be perfectly at ease with it. Debugging, code completion, code execution… it is much like it was. In fact, Visual Studio was never very different from Turbo Pascal. And I find this deeply depressing. I think we should make much faster progress than we are.

I submit to you that modern programming has little to do with the look of your desktop. Graphical user interfaces are only skin deep. Modern programming techniques are all about processes and actual tools, not the skin on top of them. I don’t care whether you are using Eclipse or Emacs… this tells me nothing about how modern you are.

So what is “modern”?

  • Coding is social. Twenty years ago, it was sensible to require everyone in your organization to use the exact same IDE and to depend uniquely on your IDE to build, test, deploy code… But there are lots of smart people outside of your organization and they often do not use your IDE. And today you can reach them. This means that you must be wise regarding the tools and processes you adopt.

    If you mock people who program using the Atom text editor, Visual Studio or Emacs, you are not being social. You need to be as inclusive as possible, or pay the price.

  • The Go language comes with its own formatting tool. I don’t care whether you reformat your code automagically as you save, or whether click a button, or whether you type go fmt, it is all the same… and it is definitively a great, modern idea. It is progress. All programming languages should force upon the users a unique code format. No more bikeshedding.

    And so we are clear, Java had guidelines, but guidelines are insufficient. We need a tool that takes the code as an input and generates a uniquely defined output where everything is dealt with, from line length to spaces.

    The goals are that there is never any possible argument as to how the code should be formatted and that the correct format is produced without effort. I cannot tell you how important that is.

  • Programming languages like Rust, Go, Swift… come with their own package management system. So, in Swift, for example, I can create a small text file called Package.swift and put it at the root of my project, where I declare my dependencies…
    import PackageDescription
    let package = Package(
        name: "SwiftBitsetBenchmark",
        dependencies: [
       .Package(url: "https://github.com/lemire/SwiftBitset.git",  
              majorVersion: 0),
       .Package(url: "https://github.com/lemire/Swimsuit.git",  
              majorVersion: 0)

    (Source example.)

    Then I can type swift build and the software will automatically grab the dependencies and build my program. And this works everywhere Swift runs. It does not matter which text editor or IDE you are using.

    You don’t want to use text editor, and you prefer to use a graphical interface? Fine. It makes no difference.

    Why is that modern? Because automatically resolving dependencies with so little effort would have looked like magic to me 20 years ago. And it is immensely important to resolve dependencies automatically and systematically. I do not want to ever have to manually install and deploy a dependency. I want other people to be able to add my library to their project in seconds, not minutes or hours.

    Yes, you can add it to existing languages (e.g., as Maven or IDEs do with Java), but there needs to be a unique approach that just works.

  • Programming languages like Go, Swift and Rust support unit testing from the start. In Go, for example, create a file myproject_test.go and add functions like func TestMyStuff(t *testing.T), then type go test and that is all. Twenty years ago, hardly anyone tested their code, today it is an absolute requirement and it needs to be done in a unique manner so you can move from project to project and always know how the tests are done.

    If I cannot spot sane unit tests in your code right away, I will assume that your code is badly broken.

  • Continuous integration: as code changes, you want a remote tool to grab the new code and test it… so that a regression can be stopped early. It is not enough that people can run tests on your code, they also need to see the results of automated testing and check the eventual failures for themselves.

    Continuous integration is part of a larger scheme: you must automate like crazy when you program. Manual labor should be minimized. And sometimes that means that you really ought to only click on a button, but what it should never mean is that you repeatedly need to follow a complicated sequence of commands, whether through a graphical user interface or through a command shell.

  • Version control. Twenty years ago, it made sense to write your code on your desktop and send the new code (as patches) by email. But this only makes sense when the pace of collaboration is slow. Today, this would be insane. Anything less than Git is backward. Note that even Microsoft builds Windows using Git today.

So what happens when you work with smart students who never learned about modern programming? They look at a command like go get and they only see the skin (a command line). They think it is backward. Where are the flashy graphics?

They work within a nice-looking IDE like Visual Studio or Eclipse and they are convinced that they are “modern”, totally oblivious to the fact that IDEs go back decades. And then instead of using the IDE for its strengths, such as better affordance and faster operations, and adopting modern programming techniques elsewhere… they stick with old-school programming:

  • No test. At least, no automated and systematic test.
  • Hard dependencies on a specific setup.
  • No automation. No continuous integration. No automated deployment.

They are programming just like I did when I started out decades ago with Turbo Pascal. It is very much old school, despite the graphical user interfaces.

Daniel Lemire, "What is “modern” programming?," in Daniel Lemire's blog, July 15, 2017.

Published by

Daniel Lemire

A computer science professor at the University of Quebec (TELUQ).

23 thoughts on “What is “modern” programming?”

  1. The use of container technology also helps. My code is developed into a Docker container and on passing all tests gets added to a repository of Docker images. That image is deployed to any post development environment and we can absolutely guarantee that the app will behave identically in all environments.
    For me having consistent environments has revolutionised what we do.

  2. You wrote, ‘Visual Studio is not modern, this is what a modern dev environment should do,’ and then listed a ton of things that VS does pretty well within its target stack. Granted, I only use VS for full-stack enterprise-level asp.net, but I just figured I’d point out that it supports:

    – auto formatting
    – node and other flavors of build tools
    – unit testing
    – nuget in asp.net at least, which means fewer ‘hard dependencies’
    – continuous integration
    – containerization (or will soon)

    That said, I generally step out of the full IDE and recommend VS Code, Atom etc when it comes to working outside of the asp.net stack (and soon even for asp.net core) and using Git, ci, and Docker.

    My only point is that all the editors have their pros, and you can use them all in an antiquated fashion, but I don’t agree with blaming VS for that, and in fact I think recent iterations of VS have really kept up with a modern dev environment for its stack. (stepping into 2010 for some projects though… Ugh).

    But I agree in that we should be educating new devs on the proper build pipeline regardless of the stack and editor they use, because ftp ugh.

    1. You wrote, ‘Visual Studio is not modern, this is what a modern dev environment should do,’

      That’s not what I wrote.

      What I am saying is that if you go back 20, 30 years ago… there were things that looked like modern-day Visual Studio. The graphical interface is very much old school. So, using Visual Studio in 2017 does not make you “modern”.

      Regarding Microsoft in general, they are definitively embracing best practices and helping to move the field in the right direction.

      1. There are several other features worth notting for modern IDE’s like InteliJ:
        – refactoring, extracting methods, subclasses, crateing interfaces from implementations and vice versa…
        – hinting – not only syntax highlighting but performance tips ets, predicted compilation and runtime errors
        – database connections, persistance, ER diagrams to/from entities and classes
        – automatic code generaion: test cases, surrounding, wrapping with loops/try-catch and so on

  3. To be fair, this part seems unusual to me:

    > So what happens when you work with smart students who never learned about modern programming?
    > They look at a command like go get and they only see the skin (a command line).
    > They think it is backward. Where are the flashy graphics?

    My experience is that most students (here I mean post-secondary students) are well-accustomed to the command line, and are (initially) tied very little to IDEs, or at least understand very well how to use their favored IDE to develop against most projects. Indeed, though my entire post-secondary education IDEs were basically invisible. The religions of recent students seem to be more about languages, licenses and development philosophies than specific IDE choies.

    In the real world, including “students” who self-learn and perhaps students of schools that actually include IDEs in the curriculum (which?), I think you really want to do two things: make your code portably compilable with the standard platform capabilities, and at least ensure it isn’t hostile to IDE use. On unix-like platforms that generally means a make, autotools or cmake build (or at least something that boils down to the same thing) and at least fixing bug reports from IDE users that don’t otherwise compromise the software.

    On Windows platforms, it’s a bit tougher because of the large gulf in functionality between approximately POSIX-compliant software and Windows, but you can get pretty close with MinGW and cmake, or even cmake alone (depending on the source).

  4. The problem with all these general advice about programming is that you never show what you have accomplished. Point to a successful software project where your methods were employed so we can have some verifiable proof that you are actually a productive programmer and not an ivory tower professor with no experience in the real world. Have you ever worked in a real company?

    Kind regards,
    John Smith

  5. Started programming in 1980, with extended basic on a Ti99, with 16k of memory, 13K USABLE FOR PROGRAM., Moved up to a Osborne, with64k memory, and an about 4 inch green screen built in, Z80 cpu. 8080/z80 assembly, basic, forth, and yuck, Cobal.. verbose, Fortran.. Then Compaq Deskpro, 640k mem, 20meg hardrive, TI LISP, ICON,C, TURBO PASCAL, FORTH. I still use Unicon-lang and Icon. Many boxes later, Added: C,PHP, Prolog, … then around 2002, Haskell. That has been the most mind expanding/busting, ever since, along with still using Icon/Unicon for scripting, and utilities. Not a fan of object oriented langs. Elixir is one that I will be Trying in earnest soon. That could be I think a super addition, love what I’ve seen so far.. was put off with the Erlang syntax, but elixir has put a clean face on the great erlang run-time. Cheers, gene

  6. “Modern programming” is very easy:
    You just need to be politically correct in your programming and voila! you’re modern 😀

  7. One key aspect around go is that it’s spec is about 1/6 of the size of Java. This makes training and ramping up significantly faster and cheaper.
    Also modern programming is much more functional/ immutable/ stream – closure based than it used to be ( leads to more reliable concurrent code).

    To me powerful ide’s are often a sticking plaster for a language/framework’s deficiencies.

  8. Very nice post Prof. Daniel. In my opinion “Modern Programming” is a paradigm shift that goes hand in hand with “Modern Applications” e.g. Mobile and cloud based applications. In fact, for some legacy applications (e.g. packaged application), which already have their own dev/deployment processes a and frameworks, its hard to introduce and sell the modern programming approach to the project decision makers.

  9. How about adding stackoverflow.com to the list?

    20 years ago we used offline API documentation describing function parameters. Today we google complete, ready to use code fragments for all common tasks.

    1. How about adding stackoverflow.com to the list?

      I think that this is closely related to “programming is social”. We used to program in closed silos, with reference books and limited teams. This is no longer true.

  10. A key commonality of all the aspects that are described as “modern programming” is that they are relatively recent (not over 20 years old) as “best practice”. I would put “Learning on the job” (or Just in Time) as the key attribute for a modern programmer.

    I have been at it for 30 years, and I learn something new at least every year. In the last 10 I added git, jenkins, docker, snap, vscode on linux, boost::test, agile (scrum), Raspberry Pi, Arduino, Python and many others to my arsenal, and I look forward (with some trepidation) to the next (r)evolution.

  11. What majority of supposed graduates of whatever programming related education you care to cite are basically ignorant of the importance and qualities of a stack?

  12. IMNSHO, modern programming is exactly the same as “old” programming. Exactly like 20 years ago (when I started my architectural career as a co-architect of a stock exchange) programming is all about getting things done.

    Everything else is just a tool in a toolbox to achieve that task. Moreover – whatever-fans-of-specific-technology-will-tell-you – most of the modern tools may be a blessing or a curse depending on specifics. Examples are numerous, including but not limited to: (a) automated deployment button being devastating if it gets to wrong hands; (b) over-reliance on IDE debugger which becomes a detriment for a wide class of debugging problems (people spend too much time trying to follow the code, when logging shows the problem much better); (c) over-reliance on IDE class browsers – which leads to crappy source file organization and reduces code readability (and to make things worse – it supports a misunderstanding that design is about classes, while way too often class is way too small unit for thinking about the code); (d) over-reliance on automated testing (especially on automated _unit_ testing) leads to false sense of security – and unit testing is known to be of extremely little value at least in real-world interactive systems (=”if you want to avoid regressions, code review – in addition to automated testing – is a MUST”). And so on, and so forth.

    Looking at the very same thing from a bit different perspective – we can say exactly as 30 years ago, the real art of programming has nothing with the book by Knuth (it is a really good book, but it is about science, not art); rather – the real art of programming is all about finding what out of all those shiny-things-in-the-toolbox is applicable to your specific project, and what is not.

  13. Prof,

    Your Student.

    In modernisation let talk cloud, git, etc. There is the question of security issues.

    Second, 5 gl or 6 gl languages or ide make no smart effort to build your own tool but you’ll be dependable on others.

    An opinion from you master’s degree student.

    Kind regards

    H. Sahyoun

  14. hi Professor Daniel,

    can I ask your permission to translate this blog post to Chinese and publish in my blog with reference and citation?


Leave a Reply to Junjia Cancel reply

Your email address will not be published.

You may subscribe to this blog by email.