The Future of Programming Languages

Talk about your skill passion! Ask questions, get feedback, post something cool!

Moderator: samw3

User avatar
Posts: 2760
Joined: Sun Dec 16, 2007 7:10 am
Location: Indiana, United States

The Future of Programming Languages

Postby Mene-Mene » Fri Jan 31, 2014 11:35 am

The auto-timeout caused me to lose my original post, so this one will be a bit shorter. (A good thing?)

Programming languages are a tool for a programmer to cause a computer to reach an intended result. I'd like to examine the outcome of an hypothetical world in which the programming community moves towards languages that enable faster prototyping, fewer bugs, and more useful programs. The essence of more powerful programming is being able to tell the computer to do more with less words. The way this has been achieved historically is by less "hand holding." In the days of ASM, people would tell the computer when to load a register, what registers to use, and tell the computer what to do every cycle of the way. When low-level languages came out, they abstracted common practices into ideas. Having a register hold a mutable value and checking it every few instructions became a while loop. No longer did we tell the computer how to do it, instead we told it what to do.

The most important feature of a programming language is readability. Debugging is an in-depth form of reading code. By supplying print statements, stepping through code, and experimenting with the smallest pieces of code possible and isolating the problem, we are doing a very methodical, deep reading of the sequence of instructions we've given to the computer. Code that does more with fewer instructions from the programmer has fewer points for error. In addition, by doing more with fewer and more descriptive instructions, it is possible to comprehend more of the program. Abstraction is the practice of not caring about the how and caring only about the what. That is to say, in the while loop, we no longer care about where the conditional is stored in memory but only about the idea of a conditional. OOP is intended to be an abstraction of a multitude of interacting objects that don't care about how they function, only the interface they expose.

I'll show two programs, one in golang and one in Clojure, where they both, using a sieve of Eratosthenes, generate the prime numbers from 2 to 200000.

Code: Select all

package main

import "fmt"

func getRange(min, max int) (nums []int) {
   size := max - min
   nums = make([]int, size)
   for i := 0; i < size; i++ {
      nums[i] = i + min

func sum(n []int) (sum uint64) {
   for i := 0; i < len(n); i++ {
      sum += uint64(n[i])

func ithN(nums []int, targetIx int) int {
   for numsFound, vecIx := 0, 0; vecIx < len(nums); vecIx++ {
      if nums[vecIx] != 0 {
         if numsFound == targetIx {
            return nums[vecIx]
   return 0

func sieveTo(max int) (primes []int) {
   primes = getRange(2, max)
   for i, p := 0, 2; p*p < max; i++ {
      for multIx := (p * p) - 2; multIx+2 < max; multIx += p {
         primes[multIx] = 0
      p = ithN(primes, i+1)

func main() {

Code: Select all

(defn multiple-of [n, x]
  (zero? (mod x n)))
(defn sieve-to [max]
  (loop [nums (range 2 max) primes []]
   (let [p (first nums)]
     (if (> (* p p) max) (concat primes nums)
      (recur (remove (partial multiple-of p) nums) (conj primes p))))))
(println (reduce + (sieve-to 200000)))

I realize that I'm implementing the sieve differently between the two programs. I tried to write the programs in the way most natural to the language. There is more here that's different than the size of the programs, the parentheses, or what functions are included with the language. The most important difference is that the imperative language describes the process for doing things in a step-by-step fashion, but the LISP-like language describes the process in a broad strokes fashion.

Using a simpler example, let's look at a switch-case statement in C++:

Code: Select all

#include <iostream>

int main() {
   int x = 3;
   switch (x) {
      case 0:
      std::cout << "x is 0";
      case 1:
      std::cout << "x is 1";
      std::cout << "x isn't binary";
   return 0;

The statement doesn't communicate how it will evaluate the argument, and it doesn't translate well into a sequence of instructions. Instead, it communicate what the programmer wants done and is much easier to read than the if statement equivalent. The compiler also has much more flexibility in optimizing the switch-case statement than it does if statements.

As a result, I see future programming languages specializing in communicating the intent of the programmer over the sequence of instructions. This will only work in systems languages if the compiler is sufficiently smart to translate intentions to imperatives as well as it does imperatives to instructions.

There are a variety of different features that are tremendously relevant as time goes on: libraries, performance, scalability, etc. Feel free to bring those up. This isn't about a language war on our current languages; it's about what makes our languages great.

I want to emphasize that I'm not saying that LISP is the future of programming. If it was, it would have won by now. I'm trying to say that the program I wrote in Clojure is nearer a better future than the program I wrote in golang because it communicates what the sieve does more succinctly and clearly than the other version. I'm trying to say that a switch-case statement communicates the idea of following a sequence of instructions based on a value better than a series of if statements.

Changing languages is obviously an expensive process, and if you have some code that implements the sieve of Eratosthenes clearly, feel free to share.
M^2 out-
It's Time to get Terminal!

Return to “Programming, Art, Design, Sound & Music!”

Who is online

Users browsing this forum: No registered users and 4 guests