Categories
程式開發

未來有望幹掉 Python 和 JavaScript 的編程語言


本文最初發表 Hacker Noon 博客,經原作者 Richard Kenneth Eng 授權,InfoQ 中文站翻譯並分享。

導讀: Python 和 JavaScript 是兩門非常有影響力的編程語言,二者都是我們在打造跨平台應用時會用到的主流語言。由於Python 和JavaScript 都是腳本語言,因此它們有很多共同的特性,都需要解釋器來運行,都是動態類型,都支持自動內存管理,都可以調用eval()來執行腳本等等腳本語言所共有的特性。在過去這些年來,Python 和 JavaScript 佔據著主導型地位,但有句話說得好,長江後浪推前浪,青出於藍勝於藍。如果將來有一天,Python 和 JavaScript 被打敗趕下榜單,那這個挑戰者會是誰呢?退休的軟件工程師 Richard Kenneth Eng 為我們分享了他的看法,羅列了那些他認為有望打敗 Python 和 JavaScript 的編程語言。

Python 和 JavaScript 是當今最熱門的兩種編程語言。但是,它們不可能永遠位居榜首。最終,它們一定會失寵,就像所有的編程語言一樣。這很可能在未來十年內就會發生。

哪些編程語言有望取代它們呢?下面就是我列出的挑戰者名單。

Dart

未來有望幹掉 Python 和 JavaScript 的編程語言 1

由於 Flutter 框架和 Google 的認可,這門語言迅速流行起來。它與使 Ruby 如此流行的驅動力相似:Rails 框架。

如果 Google 的新操作系統 Fuchsia 取得成功的話,Dart 將會成為其中心。

主要優勢:它是一種比 JavaScript 更優秀的編程語言。

主要缺點:它面對來自 JavaScript 及其迷惑的群體的對抗。

曼德勃羅分形圖(Mandelbrot set)示例代碼:

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;i2) {
          break;
        }
      }
      line+=z.abs()>2 ? " " : "*";
    }
    print(line);
  }
}

Elixir

未來有望幹掉 Python 和 JavaScript 的編程語言 2

Elixir 是 Erlang 的派生語言,具有改進的語法,以及與 Erlang 相同的、驚人的並發性支持。作為一種純函數式語言,它很有可能將這一範式提升為主流。

主要優點:它使函數式編程變得異常簡單。它非常適合併發性。

主要缺點:需要了解潛在的一次性可編程基礎知識,這可能是一項艱鉅的任務。

曼德勃羅分形圖(Mandelbrot set)示例代碼:

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

未來有望幹掉 Python 和 JavaScript 的編程語言 3

另一種 Google 支持的語言 Golang,得益於其閃電般的編譯速度、簡單高效的並發性以及非凡的簡單性,它被證明是贏家。唯一缺少的就是泛型,不過,這個特性已經在路線圖上了。

主要優點:超級簡單,對並發性支持非常好。

主要缺點:它(目前)缺少泛型。

曼德勃羅分形圖(Mandelbrot set)示例代碼:

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

未來有望幹掉 Python 和 JavaScript 的編程語言 4

Julia 的優勢在於它對數學計算的出色支持。數學友好的語法對數學家來說非常有用。如果有哪種語言可以推翻 Python,那麼 Julia 肯定是一個競爭者。

主要優點:這門語言是為科學家精心設計的。

主要缺點:這門語言面臨數據科學之王 Python 的挑戰。

曼德勃羅分形圖(Mandelbrot set)示例代碼:

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)  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

未來有望幹掉 Python 和 JavaScript 的編程語言 5

Kotlin 是更好的 Java。事實上,它實際上就是 Java 的一個可以立即使用的替代品。 Google 已經將其打造成 Android 開發的一流語言。

主要優點:它是一種升級版的 Java。

主要缺點:它是一種非常龐大的語言,即使與 Java 相比也是如此。

曼德勃羅分形圖(Mandelbrot set)示例代碼:

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  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) {
    Mandelbrot().isVisible = true
}

Lua

未來有望幹掉 Python 和 JavaScript 的編程語言 6

主要優點:Lua 是一種小巧、簡單、快速、可嵌入、可移植的靈活的語言。

主要缺點:它已經被人們忽視了 26 年,現在會有什麼改變呢?

曼德勃羅分形圖(Mandelbrot set)示例代碼:

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  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

未來有望幹掉 Python 和 JavaScript 的編程語言 7

Pharo 是 Smalltalk 的現代變體,Smalltalk 是一種非常高效的面向對象編程語言。實際上,Smalltalk 是面向對象編程的典範,它幾乎啟發了地球上所有其他面向對象編程語言的靈感。最後,沒有一種語言比 Smalltalk 更適合面向對象編程了。

Pharo 還是世界上最簡單、最優雅的語言之一。你可以在 15 分鐘內學會 Smalltalk 的全部語法

主要優點:它的工作效率非常高效,就像工作效率提高了 5 倍一樣!

主要缺點:掌握這種語言,需要一種不同的編程思維。但人們往往害怕改變。

分形樹示例代碼:

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: [email protected] length: 200 angle: 0.
    )

"Execute"

FractalTree new draw.

Rust

未來有望幹掉 Python 和 JavaScript 的編程語言 8

Rust 因其內存安全特性:借位檢查器而得到了廣泛的認可。這個特性實際上消除了所有與內存相關的編程錯誤。 Rust 保證了編程的安全性。

主要優點:它有助於使軟件更可靠。

主要缺點:這門語言很難學習,而且借位檢查器可能也很難理解。

曼德勃羅分形圖(Mandelbrot set)示例代碼:

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

未來有望幹掉 Python 和 JavaScript 的編程語言 9

TypeScript 是 JavaScript……帶來了好處。它主要是添加了靜態類型。與 JavaScript 的兼容性使它成為前端 Web 開發人員的最愛,因為他們已經了解 JavaScript,而且幾乎不需要改變他們的工作流程。

主要優點:它就是 JavaScript,因此對 JavaScript 開發人員來說沒有什麼太大的變化。

主要缺點:它仍然是 JavaScript,所以仍然繼承了 JavaScript 的所有包袱。

分形樹示例代碼:

// 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

未來有望幹掉 Python 和 JavaScript 的編程語言 10

WebAssembly 是一匹黑馬。在未來十年左右的時間裡,它可能會衍生出一系列的語言,這些語言有望最終登上榜首。 WebAssembly 只是一個編譯目標,但沒有理由說它不能擴展到 Web 領域以外的地方。至於哪些基於 WebAssembly 的語言可以登上榜首?現在誰也說不准。

作者介紹:

Richard Kenneth Eng,博主。 Smalltalk 佈道師。退休的軟件工程師。 《復仇者聯盟》粉絲。

原文鏈接:

https://hackernoon.com/programming-languages-of-the-future-b61332kd