paint-brush
A Look Ahead to Programming Languages in 2020by@richard-kenneth-eng
19,717 reads
19,717 reads

A Look Ahead to Programming Languages in 2020

by Richard Kenneth EngJanuary 1st, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Python and JavaScript are the two hottest programming languages today. However, they cannot remain on top forever. Eventually, they must fall out of favour, as all languages do. This is likely to happen within the next decade or so.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - A Look Ahead to Programming Languages in 2020
Richard Kenneth Eng HackerNoon profile picture

Python and JavaScript are the two hottest programming languages today. However, they cannot remain on top forever. Eventually, they must fall out of favour, as all languages do. This is likely to happen within the next decade or so.

What languages might come to replace them? Here’s my list of challengers…

Dart

Thanks to the Flutter framework and Google’s imprimatur, this language has quickly risen in popularity. It’s similar to the same driving force that made Ruby so popular: the Rails framework.

And if Google’s Fuchsia takes off, Dart will be in the centre of it.

Key advantage: it's a much better language than JavaScript.

Key disadvantage: it's up against JavaScript and its deluded hordes.

Mandelbrot set sample:

class Complex {
  double _r,_i;
 
  Complex(this._r,this._i);
  double get r => _r;
  double get i => _i;
  String toString() => "($r,$i)";
 
  Complex operator +(Complex other) => new Complex(r+other.r,i+other.i);
  Complex operator *(Complex other) =>
      new Complex(r*other.r-i*other.i,r*other.i+other.r*i);
  double abs() => r*r+i*i;
}
 
void main() {
  double start_x=-1.5;
  double start_y=-1.0;
  double step_x=0.03;
  double step_y=0.1;
 
  for(int y=0;y<20;y++) {
    String line="";
    for(int x=0;x<70;x++) {
      Complex c=new Complex(start_x+step_x*x,start_y+step_y*y);
      Complex z=new Complex(0.0, 0.0);
      for(int i=0;i<100;i++) {
        z=z*(z)+c;
        if(z.abs()>2) {
          break;
        }
      }
      line+=z.abs()>2 ? " " : "*";
    }
    print(line);
  }
}

Elixir

Elixir is an Erlang-derivative with an improved syntax and the same, amazing support for concurrency. As a pure functional language, it has a good likelihood of elevating this paradigm into the mainstream.

Key advantage: it makes functional programming exceptionally easy. And it's great for concurrency.

Key disadvantage: you need to understand the underlying OTP foundation which can be a daunting task.

Mandelbrot set sample:

defmodule Mandelbrot do
  def set do
    xsize = 59
    ysize = 21
    minIm = -1.0
    maxIm = 1.0
    minRe = -2.0
    maxRe = 1.0
    stepX = (maxRe - minRe) / xsize
    stepY = (maxIm - minIm) / ysize
    Enum.each(0..ysize, fn y ->
      im = minIm + stepY * y
      Enum.map(0..xsize, fn x ->
        re = minRe + stepX * x
        62 - loop(0, re, im, re, im, re*re+im*im)
      end) |> IO.puts
    end)
  end
 
  defp loop(n, _, _, _, _, _) when n>=30, do: n
  defp loop(n, _, _, _, _, v) when v>4.0, do: n-1
  defp loop(n, re, im, zr, zi, _) do
    a = zr * zr
    b = zi * zi
    loop(n+1, re, im, a-b+re, 2*zr*zi+im, a+b)
  end
end
 
Mandelbrot.set

Golang

Another Google-supported language, Golang has proven to be winner, thanks to its lightning-quick compilation speed, easy and efficient concurrency, and remarkable simplicity. The only thing missing is generics, and this feature is on the roadmap.

Key advantage: it's super-simple, and great for concurrency.

Key disadvantage: it lacks generics (for now).

Mandelbrot set sample:

package main
 
import (
    "fmt"
    "image"
    "image/color"
    "image/draw"
    "image/png"
    "math/cmplx"
    "os"
)
 
const (
    maxEsc = 100
    rMin   = -2.
    rMax   = .5
    iMin   = -1.
    iMax   = 1.
    width  = 750
    red    = 230
    green  = 235
    blue   = 255
)
 
func mandelbrot(a complex128) float64 {
    i := 0
    for z := a; cmplx.Abs(z) < 2 && i < maxEsc; i++ {
        z = z*z + a
    }
    return float64(maxEsc-i) / maxEsc
}
 
func main() {
    scale := width / (rMax - rMin)
    height := int(scale * (iMax - iMin))
    bounds := image.Rect(0, 0, width, height)
    b := image.NewNRGBA(bounds)
    draw.Draw(b, bounds, image.NewUniform(color.Black), image.ZP, draw.Src)
    for x := 0; x < width; x++ {
        for y := 0; y < height; y++ {
            fEsc := mandelbrot(complex(
                float64(x)/scale+rMin,
                float64(y)/scale+iMin))
            b.Set(x, y, color.NRGBA{uint8(red * fEsc),
                uint8(green * fEsc), uint8(blue * fEsc), 255})
 
        }
    }
    f, err := os.Create("mandelbrot.png")
    if err != nil {
        fmt.Println(err)
        return
    }
    if err = png.Encode(f, b); err != nil {
        fmt.Println(err)
    }
    if err = f.Close(); err != nil {
        fmt.Println(err)
    }
}

Julia

Julia’s strength is its excellent support for mathematical computation. The math-friendly syntax is great for data scientists. If any language can overthrow Python, this one is definitely a contender.

Key advantage: it's well-designed for scientists.

Key disadvantage: it's up against Python, the king of data science.

Mandelbrot set sample:

using Images
 
@inline function hsv2rgb(h, s, v)
    const c = v * s
    const x = c * (1 - abs(((h/60) % 2) - 1))
    const m = v - c
 
    const r,g,b =
        if h < 60
            (c, x, 0)
        elseif h < 120
            (x, c, 0)
        elseif h < 180
            (0, c, x)
        elseif h < 240
            (0, x, c)
        elseif h < 300
            (x, 0, c)
        else
            (c, 0, x)
        end
 
    (r + m), (b + m), (g + m)
end
 
function mandelbrot()
 
    const w, h = 1000, 1000
 
    const zoom  = 0.5
    const moveX = 0
    const moveY = 0
 
    const img = Array{RGB{Float64}}(h, w)
    const maxIter = 30
 
    for x in 1:w
        for y in 1:h
            i = maxIter
            const c = Complex(
                (2*x - w) / (w * zoom) + moveX,
                (2*y - h) / (h * zoom) + moveY
            )
            z = c
            while abs(z) < 2 && (i -= 1) > 0
                z = z^2 + c
            end
            const r,g,b = hsv2rgb(i / maxIter * 360, 1, i / maxIter)
            img[y,x] = RGB{Float64}(r, g, b)
        end
    end
 
    save("mandelbrot_set.png", img)
end
 
mandelbrot()

Kotlin

Kotlin is the better Java. In fact, it’s practically a drop-in replacement for Java. Google have already made it a first-class language for Android development.

Key advantage: it's a souped-up Java.

Key disadvantage: it's a very large language, even compared to Java.

Mandelbrot set sample:

import java.awt.Graphics
import java.awt.image.BufferedImage
import javax.swing.JFrame
 
class Mandelbrot: JFrame("Mandelbrot Set") {
    companion object {
        private const val MAX_ITER = 570
        private const val ZOOM = 150.0
    }
 
    private val img: BufferedImage
 
    init {
        setBounds(100, 100, 800, 600)
        isResizable = false
        defaultCloseOperation = EXIT_ON_CLOSE
        img = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
        for (y in 0 until height) {
            for (x in 0 until width) {
                var zx = 0.0
                var zy = 0.0
                val cX = (x - 400) / ZOOM
                val cY = (y - 300) / ZOOM
                var iter = MAX_ITER
                while (zx * zx + zy * zy < 4.0 && iter > 0) {
                    val tmp = zx * zx - zy * zy + cX
                    zy = 2.0 * zx * zy + cY
                    zx = tmp
                    iter--
                }
                img.setRGB(x, y, iter or (iter shl 7))
            }
        }
    }
 
    override fun paint(g: Graphics) {
        g.drawImage(img, 0, 0, this)
    }
}
 
fun main(args: Array<String>) {
    Mandelbrot().isVisible = true
}

Lua

Key advantage: Lua is a small, simple, fast, embeddable, portable, and flexible language.

Key disadvantage: it has been overlooked for 26 years. What's going to change now?

Mandelbrot set sample:

local maxIterations = 250
local minX, maxX, minY, maxY = -2.5, 2.5, -2.5, 2.5
local miX, mxX, miY, mxY
function remap( x, t1, t2, s1, s2 )
    local f = ( x - t1 ) / ( t2 - t1 )
    local g = f * ( s2 - s1 ) + s1
    return g;
end
function drawMandelbrot()
    local pts, a, as, za, b, bs, zb, cnt, clr = {}
    for j = 0, hei - 1 do
        for i = 0, wid - 1 do
            a = remap( i, 0, wid, minX, maxX )
            b = remap( j, 0, hei, minY, maxY )
            cnt = 0; za = a; zb = b
            while( cnt < maxIterations ) do
                as = a * a - b * b; bs = 2 * a * b
                a = za + as; b = zb + bs
                if math.abs( a ) + math.abs( b ) > 16 then break end
                cnt = cnt + 1
            end
            if cnt == maxIterations then clr = 0
            else clr = remap( cnt, 0, maxIterations, 0, 255 )
            end
            pts[1] = { i, j, clr, clr, 0, 255 }
            love.graphics.points( pts )
        end
    end
end
function startFractal()
    love.graphics.setCanvas( canvas ); love.graphics.clear()
    love.graphics.setColor( 255, 255, 255 )
    drawMandelbrot(); love.graphics.setCanvas()
end
function love.load()
    wid, hei = love.graphics.getWidth(), love.graphics.getHeight()
    canvas = love.graphics.newCanvas( wid, hei )
    startFractal()
end
function love.mousepressed( x, y, button, istouch )
    if button ==  1 then
        startDrag = true; miX = x; miY = y
    else
        minX = -2.5; maxX = 2.5; minY = minX; maxY = maxX
        startFractal()
        startDrag = false
    end
end
function love.mousereleased( x, y, button, istouch )
    if startDrag then
        local l
        if x > miX then mxX = x
        else l = x; mxX = miX; miX = l
        end
        if y > miY then mxY = y
        else l = y; mxY = miY; miY = l
        end
        miX = remap( miX, 0, wid, minX, maxX ) 
        mxX = remap( mxX, 0, wid, minX, maxX )
        miY = remap( miY, 0, hei, minY, maxY ) 
        mxY = remap( mxY, 0, hei, minY, maxY )
        minX = miX; maxX = mxX; minY = miY; maxY = mxY
        startFractal()
    end
end
function love.draw()
    love.graphics.draw( canvas )
end

Pharo

Pharo is a modern variant of Smalltalk, a remarkably productive object-oriented language. In fact, Smalltalk is the paragon of OOP and has inspired nearly every other OOP language on the planet. In the end, no language does OOP better than Smalltalk.

Pharo is also one of the simplest, most elegant languages in the world. You can actually learn the entire syntax of Smalltalk within 15 minutes!

Key advantage: it's super-productive, like 5X more productive!

Key disadvantage: it requires a different programming mindset. People are afraid of change.

Fractal tree sample (based on Squeak):

Object subclass: #FractalTree
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'RosettaCode'

"Methods for FractalTree class"

tree: aPoint length: aLength angle: anAngle
    | p a |
 
    (aLength > 10) ifTrue: [
        p := Pen new.
        p up.
        p goto: aPoint.
        p turn: anAngle.
        p down.
        5 timesRepeat: [
            p go: aLength / 5.
            p turn: 5.
        ].
        a := anAngle - 30.
        3 timesRepeat: [
            self tree: p location length: aLength * 0.7 angle: a.
            a := a + 30.
        ]
    ].
 
draw
    Display restoreAfter: [
        Display fillWhite.      
        self tree: 700@700 length: 200 angle: 0.
    ]

"Execute"

FractalTree new draw.

Rust

Rust has gained recognition for its memory safety feature: the borrow checker. This feature practically eliminates the entire class of memory-related programming errors. Rust promises much safer programming.

Key advantage: it helps make software much more reliable.

Key disadvantage: it's tough to learn, and the borrow checker can be complicated to understand.

Mandelbrot set sample:

extern crate image;
extern crate num_complex;
 
use std::fs::File;
use num_complex::Complex;
 
fn main() {
    let max_iterations = 256u16;
    let img_side = 800u32;
    let cxmin = -2f32;
    let cxmax = 1f32;
    let cymin = -1.5f32;
    let cymax = 1.5f32;
    let scalex = (cxmax - cxmin) / img_side as f32;
    let scaley = (cymax - cymin) / img_side as f32;
 
    // Create a new ImgBuf
    let mut imgbuf = image::ImageBuffer::new(img_side, img_side);
 
    // Calculate for each pixel
    for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
        let cx = cxmin + x as f32 * scalex;
        let cy = cymin + y as f32 * scaley;
 
        let c = Complex::new(cx, cy);
        let mut z = Complex::new(0f32, 0f32);
 
        let mut i = 0;
        for t in 0..max_iterations {
            if z.norm() > 2.0 {
                break;
            }
            z = z * z + c;
            i = t;
        }
 
        *pixel = image::Luma([i as u8]);
    }
 
    // Save image
    let fout = &mut File::create("fractal.png").unwrap();
    image::ImageLuma8(imgbuf).save(fout, image::PNG).unwrap();
}

TypeScript

TypeScript is JavaScript…with benefits. It primarily adds static typing. Compatibility with JavaScript makes it a favourite of front-end web developers because they already know JavaScript and they hardly need to alter their workflow.

Key advantage: it's JavaScript, so there's no big change for JavaScript developers.

Key disadvantage: it's still JavaScript, so you inherit all of its baggage.

Fractal tree sample:

// Set up canvas for drawing
var canvas: HTMLCanvasElement = document.createElement('canvas')
canvas.width = 600
canvas.height = 500
document.body.appendChild(canvas)
var ctx: CanvasRenderingContext2D = canvas.getContext('2d')
ctx.fillStyle = '#000'
ctx.lineWidth = 1
 
// constants
const degToRad: number = Math.PI / 180.0
const totalDepth: number = 9
 
/** Helper function that draws a line on the canvas */
function drawLine(x1: number, y1: number, x2: number, y2: number): void {
    ctx.moveTo(x1, y1)
    ctx.lineTo(x2, y2)
}
 
/** Draws a branch at the given point and angle and then calls itself twice */
function drawTree(x1: number, y1: number, angle: number, depth: number): void {
    if (depth !== 0) {
        let x2: number = x1 + (Math.cos(angle * degToRad) * depth * 10.0)
        let y2: number = y1 + (Math.sin(angle * degToRad) * depth * 10.0)
        drawLine(x1, y1, x2, y2)
        drawTree(x2, y2, angle - 20, depth - 1)
        drawTree(x2, y2, angle + 20, depth - 1)
    }
}
 
// actual drawing of tree
ctx.beginPath()
drawTree(300, 500, -90, totalDepth)
ctx.closePath()
ctx.stroke()

WebAssembly

WebAssembly is a dark horse. In the next decade or so, it could possibly spawn a number of languages that rise to the top. WebAssembly is only a compilation target, but there’s no reason it couldn’t spread far beyond the web domain. What WebAssembly-based language(s) could rise to the top? It’s anybody’s guess.