本文由 简悦SimpRead 转码,原文地址 www.freecodecamp.org
原文罗塞塔石碑,通过History.com [www.history.com/s3static/vi…......
最初的罗塞塔石碑,通过History.com
科技界被一个相对较小的编程语言库所支配,这已不是什么秘密。虽然准确的数字很难获得(而且毫无疑问会随着时间的推移而变化),但你可能会说出少数几种语言,它们在一定时期内构成了所有编程产出的绝大部分。
我在研究这篇文章时访问了两个有趣的网站,可以让你按流行程度直观地了解编程语言。IEEE Spectrum可以让你互动地调整各种指标的权重,而PYPL则提供了一个整洁的表格,根据过去12个月的谷歌趋势数据,给出了实际的百分比份额。
现在,我拒绝被卷入任何关于什么是编程语言流行度的最佳指标的争论中(以及无论如何这是否是一个重要的统计数字)。以下只是一个草率的分析,以说明一个问题(任何借口都可以使用R-Fiddle!)
使用PYPL的数据,我们可以看到几个明显的趋势。
图表产生于R-Fiddle.org;,数据来自PYPL
1) - 前10种语言几乎占了谷歌趋势数据的90%份额
按照顺序,这些是 Java, Python, PHP, C#, JavaScript, C, C++, Objective-C, R和Swift。它们加在一起,在谷歌趋势中的份额为87.1%。
2) -语言流行度遵循幂律分布
使用我最喜欢的R包,'igraph',为其可靠的power.law.fit()函数,我发现编程语言的流行程度遵循幂律分布。
> pL = power.law.fit(shares)> pL$KS.p$KS.p[1] 0.9873141
$KS.p
值为0.987,是与Kolmogorov-Smirnov测试统计量相关的p值,它告诉我们,我们可以非常确定人气分布(如PYPL所定义)确实遵循幂律分布。
像许多其他现象一样,编程语言的相对受欢迎程度是不均匀分布的。这通常可以用正反馈(或 "雪球效应")机制来解释--一个简单的版本可能是,一种语言越受欢迎,它的工作机会就越多,所以更多的人被激励去学习它,从而增加它的受欢迎程度。
那么,什么是新的?
有些编程语言比其他语言更受欢迎,这其实并不奇怪。每个人都已经知道,Java、C、C++、C#、Python 等 是迄今为止使用最多的语言。
在我看来,更有趣的是,对于每一种巨大的编程语言,肯定有几十种更小、更利基的语言在荒野中。
抛开纯粹的好奇心,我们有充分的理由对此感兴趣。任何涉足过少数几种编程语言的人都知道,不同的语言适合不同的用途。JavaScript用于网页开发,PHP用于服务器端编程,R用于统计,Matlab用于完全的数学。对于编程语言来说,多样性是一件好事。在那里,可能有一种语言非常适合于解决你甚至不知道存在的问题。
但在哪里可以找到它们呢?有一个地方可以找,那就是Rosetta Code。
一个编程之旅
我不记得我到底是怎么遇到Rosetta Code的,但是一旦我找到它,我就被迷住了。它把自己描述成一个编程知识网站,在它的档案中,有647种编程语言,令人印象深刻。去看看吧。
真正令人敬畏的是,Rosetta Code不仅仅是为每种语言提供一个通用的 "Hello World!"的例子。不,相反,它收集了800多个各种各样的编程任务,从一些简单的 "奇数或偶数",到更高级的问题,如解决迷宫和网络刮削。每个任务页面都描述了要解决的问题,然后给出一系列编程语言的解决方案。
在这里,声誉并不重要。除了C、C++、Java等语言外,你还会发现一些你从未听说过的语言的解决方案。有些是复古的,有些是现代的;有些看起来很熟悉,而有些则深奥得令人难以置信。你可以花比你愿意承认的更多的时间来浏览所有的例子--但为了帮助你开始,我已经汇编了一份引起我注意的一些不太知名和/或更有趣的语言的清单。激活书呆子模式,并潜入其中吧!
过去的爆炸事件
有些语言是永远存在的,或者说看起来是这样。和C语言一样,Lisp和Fortran的后代语言已经存在了几十年,其他语言如BASIC和Pascal可能已经过时了,但在大众的记忆中仍然存在。
不过,时间对其他语言就不那么友好了。这里列出了一些在Rosetta上有代码样本的语言,从某种程度上说,这些语言不太可能在短期内让你被雇用。
EDSAC订单代码
EDSAC是一台著名的早期计算机,由Maurice Wilkes的团队在20世纪40年代末在剑桥大学设计和建造。EDSAC的建造使大卫-惠勒在1951年获得了有史以来第一个计算机科学博士学位。在此过程中,他还发明了 "惠勒跳",即封闭子程序--我们今天通常称之为 "函数"。
尽管EDSAC在历史上有不可动摇的地位,但它从1958年起就停止了活动,所以不要急于学习它的自定义编程语言。这里有一个来自Rosetta Code的例子。这是 "空程序",或最短的合法程序。它根本就没有做什么。
T64K [ set load point ]
GK [ set base address ]
ZF [ stop ]
EZPF [ begin at load point ]
GEORGE
这种语言发明于1957年,是一种通过打孔磁带输入到一个房间大小的机器中的语言。尽管如此,它还是充满了特色,包括循环、条件语句、子程序和矩阵数据结构。它甚至读起来有点像一种更现代的语言。
60年过去了,GEORGE已经不在我们身边。下面是计算数列之和的方法。
0 (s)
1, 1000 rep (i)
s 1 i dup × / + (s) ;
]
P
BCPL
“基本组合编程语言”,即BCPL,在计算机历史上是当之无愧的地位。BCPL是第一个引入大括号"{"作为定义代码块的方式的语言--这一惯例仍然用于今天许多最重要的语言。作为遗产,这很好。
下面是一个用BCPL编写的 "Hello World "程序。
GET "libhdr"
LET start() = VALOF
{ writef("Hello world!")
RESULTIS 0
}
PL/I
由IBM在60年代初开发的PL/I(Programming Language One)在其全盛时期被广泛使用,但从未完全取代其竞争对手Fortran和COBOL。PL/I主要是一种大型机语言,随着PC的出现以及C++和Java等语言的流行,PL/I逐渐失去了地位。
在Rosetta Code上有PL/I的许多例子;这里是生成斐波那契数列。
/* Form the n-th Fibonacci number, n > 1. */
get list(n);
f1 = 0; f2 = 1;
do i = 2 to n;
f3 = f1 + f2;
put skip edit('fibo(',i,')=',f3)(a,f(5),a,f(5));
f1 = f2;
f2 = f3;
end;
SNOBOL4
SNOBOL开发于20世纪60年代初,在随后的十年中成为一种流行的教学语言。然而,它在整个20世纪80年代和90年代失去了活力,但在它能够影响Lua的设计之前,它在我们先前看到的PYPL排名中出现了前20名。
这里有一个SNOBOL4程序,可以输出一个字符串的长度。
output = "Byte length: " size(trim(input))
end
FOCAL
FOCAL ('Formulating On-Line Calculations in Algebraic Language', since you asked) 于1968年推出,是一种高效的语言,可以在内存有限的系统上运行。该语言的一个特别的怪癖是它对字符串有明显的恐惧感。输入字符串 "HELLO "会被解释为要求计算机计算8 ^ "LLO"
,FOCAL在吐出一个巨大的数字答案之前努力地计算。
尽管FOCAL有其怪癖,但在70年代和80年代,它被广泛使用。可口可乐公司甚至使用了他们自己的版本,他们富有想象力地称之为COKE。
这个例子来自Rosetta Code,显示了一个在不同单位之间转换温度的FOCAL程序。
01.10 ASK "TEMPERATURE IN KELVIN", K
01.20 TYPE "K ", %6.02, K, !
01.30 TYPE "C ", %6.02, K - 273.15, !
01.40 TYPE "F ", %6.02, K * 1.8 - 459.67, !
01.50 TYPE "R ", %6.02, K * 1.8, !
SETL
SETL发明于20世纪60年代末,主要基于集合理论,这是数学的一个分支,涉及对象的集合。最近的稳定版本是在2005年,尽管SETL的使用率下降了,但它还是有一些名气的。
由美国国防部开发的第一个Ada编译器就是用SETL编写的。另外,据说它还影响了ABC语言--该语言后来启发了Python的设计。
下面是SETL如何计算两个整数的最大公除数。看到与Python的任何相似之处了吗?
proc gcd (u, v);
return if v = 0 then abs u else gcd (v, u mod v) end;
end;
MUMPS
这种不幸的语言自1966年以来一直存在,也被称为M。一个关键特征是内置的数据库系统,它允许对存储的数据进行超级有效的访问。
虽然不再被普遍使用,但MUMPS以GT.M和InterSystems_Cache的形式存在--它们在医院和金融数据库系统中有一定的地位。欧洲航天局也将InterSystems_Cache用于其最近的盖亚任务。
这就是MUMPS如何被用来反转字符串。
REVERSE
;Take in a string and reverse it using the built in function $REVERSE
NEW S
READ:30 "Enter a string: ",S
WRITE !,$REVERSE(S)
QUIT
故意混淆视听
一个成功的编程语言的标志是什么?速度?多功能性?可读性?不,忘掉这些吧--让我们来看看外面的编程语言的一个分支,它们是故意的困难和/或不直观的使用。
神秘语言,或称 "esolangs",是一种编程语言,有时用于实验,有时用于挑战,有时只是作为最终的书呆子玩笑。如果你不太明白,那也没关系--事实上,这通常就是重点。
比较有名的例子包括Brainf***、Befunge和特别容易引起偏头痛的Malbolge。这里还有一些其他的列表,从有趣的到有趣的,再到完全愚钝的,不一而足。在你的简历/履历中包括这些内容,风险自负。
INTERCAL
最初的神秘编程语言是在1972年发明的,这使得它和C语言一样古老。它是作为对当时流行的编程实践的模仿而推出的,但它持续生存到今天表明它仍然和以前一样重要。
除了晦涩难懂的语法,INTERCAL还要求用户经常使用关键字PLEASE
,否则程序就会拒绝运行,这让用户更加困惑。然而,过分的礼貌会适得其反--过于频繁的说 "请 "也会导致错误。当然,这种怪癖并没有被正式记录下来,因为那实在是太有用了。
下面是一个无限循环,用INTERCAL写的。
NOTE THIS IS INTERCAL
PLEASE ,1 <- #5
DO ,1 SUB #1 <- #54
DO ,1 SUB #2 <- #192
DO ,1 SUB #3 <- #136
PLEASE ,1 SUB #4 <- #208
DO ,1 SUB #5 <- #98
DO COME FROM (1)
DO READ OUT ,1
(2) DO ,1 SUB #1 <- #134
(1) PLEASE ABSTAIN FROM (2)
Beeswax
这是一种概念上有趣的语言,它以蜜蜂在蜂巢中的运动为灵感,在指令中移动指针。
Beeswax能够进行算术,读/写文件,甚至修改自己的源代码。下面是一个计算用户输入的整数的n-factorial (n!)的程序。
p <
_>1FT"pF>M"p~.~d
>Pd >~{Np
d <
Chef
这也许是我在Rosetta Code上发现的语言中最喜欢的。我以前在其他地方读过它,但没有看到像这里提供的例子范围那样的东西。
与大多数编程语言不同,Chef几乎是完全自然地阅读,因为每个程序的格式都很像菜谱(因此得名!)。为了完整起见,它还用与烹饪有关的名称来指代变量、指令和数据结构,如 "搅拌碗"、"冰箱"、"混合"、"切碎 "等。为什么不呢?
下面是一个计算数组的和与积的示例程序。
Sum and Product of Numbers as a Piece of Cake.
This recipe sums N given numbers.
Ingredients.
1 N
0 sum
1 product
1 number
Method.
Put sum into 1st mixing bowl.
Put product into 2nd mixing bowl.
Take N from refrigerator.
Chop N.
Take number from refrigerator.
Add number into 1st mixing bowl.
Combine number into 2nd mixing bowl.
Chop N until choped.
Pour contents of 2nd mixing bowl into the baking dish.
Pour contents of 1st mixing bowl into the baking dish.
Serves 1.
Golfscript
对于代码高尔夫(一种奇特的极客爱好,参与者试图用尽可能少的代码字节解决编程难题)的爱好者来说,Golfscript是一种旨在以小博大的语言。
它确实实现了这一目标,并使其用户能够非常简洁地解决复杂的难题。它的网站告诉我们,这种简洁是通过 "使用单一符号来表示高级操作 "来实现的。
你会在生产环境中使用它吗?也许吧,如果你是一个经验丰富的代码高尔夫球手,并且不考虑你的项目的任何继承者的理智。否则...可能不会。
Rosetta Code有几个很好的Golfscript例子,由于它非常简明,我在这里包括了其中的三个例子。
#对一个整数阵列进行排序
[2 4 3 1 2]$
#99绿瓶歌词
[296,{3/)}%-1%["No more"]+[" bottles":b]294*[b-1<]2*+[b]+[" of beer on the wall\n".8<"\nTake one down, pass it around\n"+1$n+]99*]zip
#100道门挑战
100:c;[{0}c*]:d;
c,{.c,>\)%{.d<\.d=1^\)d>++:d;}/}/
[c,{)"door "\+" is"+}%d{{"open"}{"closed"}if}%]zip
{" "*puts}/
Hoon
Hoon的迷人之处在于,尽管有些人将其归类为esolang,但它实际上是有实际用途的。它可以用来为Urbit上的网络服务编程,Urbit将自己描述为 "安全的个人服务器点对点网络"。
看看下面的'最大元素'例子。
Hoon被描述为Lisp-y,注意每行开头的两个字符符号。这些'符文'被用来代替保留的关键字,这是一个很好的概念,但对于那些不熟悉其逻辑的人来说,确实影响了可读性,而且可能使Hoon有一些深奥的资格。
:- %say
|= [^ [a=(list ,@) ~] ~]
:- %noun
(snag 0 (sort a gte))
> +max [1 2 3 ~]3
Piet
到目前为止,我遇到的最独特的语言是Piet,以20世纪荷兰艺术家Piet Mondrian命名。
它遵循一个非常不寻常的设计原则。程序代码应该采用抽象艺术的形式。这一点是如何实现的呢?这个解决方案简直就是天才。
整数由一个连续的色块中的 "代码 "的数量来表示。指针从左上角开始,在图像上移动。每当它遇到一个颜色变化,就会执行一条指令。确切的指令是由色调和亮度的变化来指定的。
心灵 = 吹响。
"Hello World "通过Rosetta Code
玩转数组
引起我注意的一件事是有很多基于数组的语言存在。基于数组的编程自20世纪60年代初随着APL的发明而出现,尽管它们并不完全是主流,但有很多分支至今仍在不同程度上使用。这些语言都有很多共同点,所以我就不多说了,但它们的有趣之处在于它们可以如此简洁。
J
J是由Kenneth Iverson发明的,他也是APL的发明者。J是一种非常简洁的语言,让你用很少的几行代码就能完成很多事情。
下面是一个K-means聚类算法。作为比较,同样的例子在C语言中只有184行。
NB. Selection of initial centroids, per K-means++
initialCentroids =: (] , randomCentroid)^:(<:@:]`(,:@:seedCentroid@:[))~
seedCentroid =: {~ ?@#
randomCentroid =: [ {~ [: wghtProb [: <./ distance/~
distance =: +/&.:*:@:-"1 NB. Extra credit #3 (N-dimensional is the same as 2-dimensional in J)
wghtProb =: 1&$: : ((%{:)@:(+/\)@:] I. [ ?@$ 0:)"0 1 NB. Due to Roger Hui http://j.mp/lj5Pnt
NB. Having selected the initial centroids, the standard K-means algo follows
centroids =: ([ mean/.~ closestCentroid)^:(]`_:`initialCentroids)
closestCentroid =: [: (i.<./)"1 distance/
mean =: +/ % #
K, q
这两种语言都是由Kx Systems商业化开发的。两者都是类似APL的、基于数组的语言,在金融和大数据领域都有应用。q包裹着K,并提供了增强的可读性。
我在下面列出了两种语言的例子。这些都是超级简洁的语言,如果你喜欢的话,无疑是打一轮代码高尔夫的好选择。
/ 1-D Cellular automata in Kf:{2=+/(0,x,0)@(!#x)+/:!3}
/ Anagrams in K{x@&a=|/a:#:'x}{x g@&1<#:'g:={x@<x}'x}0::`unixdict.txt
/ Pascal's Triangle in qpascal:{(x-1){0+':x,0}\1}
/ 100 Doors Challenge in q`closed`open (1+til 100) in `int$xexp[;2] 1+til 10
Klong
Klong与K和q类似,但它的网站声称它不那么含糊。自己判断吧--下面是一个用Klong写的"中间三位数"解决方案。
items::[123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0]
mid3::{[d k];:[3>k::#$#x;"small":|0=k!2;"even";(-d)_(d::_(k%2)-1)_$#x]}
.p(mid3'items)
IDL
再给你一个基于数组的语言。IDL(交互式数据语言),从1977年开始出现,已经被包括NASA和ESA在内的组织使用。事实上,IDL在太空研究中找到了自己的位置,它曾经被用来帮助技术人员修理哈勃太空望远镜。
一个更接地气的应用是这个函数,它可以生成一个Sierpinski三角形。
pro sierp,n
s = (t = bytarr(3+2^(n+1))+32b)
t[2^n+1] = 42b
for lines = 1,2^n do begin
print,string( (s = t) )
for i=1,n_elements(t)-2 do if s[i-1] eq s[i+1] then t[i]=32b else t[i]=42b
end
end
向上和未来?
当然,有些语言的使用量不大,只是因为它们出现的时间不长。它们是否流行取决于各种因素,而现实是,绝大多数语言不会被广泛采用。但你总得从某个地方开始,对吗?
下面是Rosetta档案中的一些语言,它们都是相对较新的语言。
Crystal
这个项目仍在阿尔法测试中,所以现在还不要转而使用它--但请留意。受Ruby的写作效率和C的运行效率的影响,Crystal的作者们似乎决心要创造一种全方位的两全其美的语言。时间会告诉我们他们是否能成功做到这一点。
下面是一个用Crystal编写的"快速排序 "算法--为什么不试试自己运行?
def quick_sort(a : Array(Int32)) : Array(Int32)
return a if a.size <= 1
p = a[0]
lt, rt = a[1 .. -1].partition { |x| x < p }
return quick_sort(lt) + [p] + quick_sort(rt)
end
a = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
puts quick_sort(a) # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Frege
函数式编程是新的大事件,而Frege是2011年首次推出的纯函数式语言。它被描述为 "Java虚拟机上的Haskell"。以数理逻辑学家Gottlob Frege的名字命名,这种语言可以编译成Java,也可以在线试用。
下面是一个"99瓶 "挑战的解决方案。它与Haskell中的相同解决方案几乎完全相同,这是可以预期的。
module Beer where
main = mapM_ (putStrLn . beer) [99, 98 .. 0]
beer 1 = "1 bottle of beer on the wall\n1 bottle of beer\nTake one down, pass it around"
beer 0 = "better go to the store and buy some more."
beer v = show v ++ " bottles of beer on the wall\n"
++ show v
++ " bottles of beer\nTake one down, pass it around\n"
++ head (lines $ beer $ v-1) ++ "\n"
Futhark
虽然缺乏全面的文档,但Futhark项目似乎是一个有前途的研究方向。其目的是编译成高性能的图形处理单元(GPU)代码--但不是为了产生图形输出。
相反,Futhark的目标是利用GPU的力量来执行计算密集型程序,而这些程序使用更传统的语言通常会花费更多时间。下面是一个用于计算几何平均值的函数的例子。
include futlib.numeric
import "futlib/math"
fun agm(a: f64, g: f64): f64 =
let eps = 1.0E-16
loop ((a,g)) = while f64.abs(a-g) > eps do
((a+g) / 2.0,
f64.sqrt (a*g))
in a
fun main(x: f64, y: f64): f64 =
agm(x,y)
Sidef
Sidef在2013年3月作为一个项目开始,已经接近其活跃发展的第四年。它看起来很先进,而且文档非常完善,在Rosetta Code上有600多个编码解决方案的例子。
Sidef主要用于研究目的,并期待着探索OOP和函数式编程。就个人而言,我非常喜欢它的外观。下面的例子显示了它在寻找两行的交点的行动。
func det(a, b, c, d) { a*d - b*c }
func intersection(ax, ay, bx, by,
cx, cy, dx, dy) {
var detAB = det(ax,ay, bx,by)
var detCD = det(cx,cy, dx,dy)
var ΔxAB = (ax - bx)
var ΔyAB = (ay - by)
var ΔxCD = (cx - dx)
var ΔyCD = (cy - dy)
var x_numerator = det(detAB, ΔxAB, detCD, ΔxCD)
var y_numerator = det(detAB, ΔyAB, detCD, ΔyCD)
var denominator = det( ΔxAB, ΔyAB, ΔxCD, ΔyCD)
denominator == 0 && return 'lines are parallel'
[x_numerator / denominator, y_numerator / denominator]
}
say ('Intersection point: ', intersection(4,0, 6,10, 0,3, 10,7))
> Intersection point: [5, 5]
Sparkling
和Sidef一样,这种语言也是在2013年开始的。它的设计灵感来自于C、Python和Lua的特点--以及对JavaScript的几个特点的不屑。
它的目标是成为一种轻量级和可扩展的脚本语言,几乎可以在任何地方运行。下面是一个数字猜测游戏,你可以尝试在你的浏览器中运行这里。
printf("Lower bound: ");
let lowerBound = toint(getline());
printf("Upper bound: ");
let upperBound = toint(getline());
assert(upperBound > lowerBound, "upper bound must be greater than lower bound");
seed(time());
let n = floor(random() * (upperBound - lowerBound) + lowerBound);
var guess;
print();
while true {
printf("Your guess: ");
guess = toint(getline());
if guess < n {
print("too low");
} else if guess > n {
print("too high");
} else {
print("You guessed it!");
break;
}
}
诺亚方舟
还有一个类别是给你的--有很多潜在的语言,我不可能把它们全部看完,挑出每个有趣的例子。如果你发现我可能遗漏了什么,请在下面留言回复!
我注意到的一件事是,很多语言都是以动物命名的。这有什么解释吗?
我就不细说了,但这里有一个快速浏览的过程,可以作为结束。
Cat, Kitten
Cat被描述为一种功能性语言,但似乎已经不存在了。然而,Kitten似乎目前正在开发中,并称自己是Cat的继承者。受Haskell的影响很大,但目标是更容易理解。
"Hello world!" writeln //Cat
"Hello world!" say //Kitten
Cobra
OOP语言,受Python、C#、Eiffel和Objective-C的影响。
class Hello
def main
print 'Hello world!'
>> ("Fish")
另一个多维的esolang,如果你喜欢这种东西。
!v "Hello world!"r! >l?!;o
Heron
受到C++、Python和Pascal的启发,但自2012年以来没有提交,所以似乎不再处于积极开发中。它在Rosetta上的唯一样本是一个冗长的N-queens问题的解决方案。为了简洁起见,我推断了一个简单的 "Hello world!"程序来代替。
Main() {
WriteLine("Hello world!");
}
Lobster
一种游戏编程语言,旨在实现跨平台移植。似乎正在进行积极开发。
print "Hello world!"
熊猫
网站指出,熊猫的目标是简单到一个熊猫人都可以编程。我不知道熊猫的编码能力如何,所以我对这个问题仍然一无所知......
say("Hello world!")
Pony
从C++到Erlang都有影响,Pony看起来是一个有趣的项目,有详尽的教程。
actor Main new create(env: Env) => env.out.print("Hello world!")
Salmon
Salmon旨在将低级代码和高级代码的编写混合在一起。
"Hello world!"!
print("Hello world!\n");
standard_output.print("Hello world!\n")。
Squirrel
Squirrel是一种轻量级的脚本语言,已经被嵌入到_Left 4 Dead 2_、_Portal 2_和_CS:GO_等游戏中。
print("Hello world!")。
唷!
这是个口哨式的旅行! 如果你已经走到了这一步,并且喜欢上了这个旅程(或者发现了一个明显的明显的错误),请在下面留言--我会尽快回复的 谢谢你的阅读!
如果你想更深入地研究。
谢谢你的阅读!
免费学习代码。freeCodeCamp的开源课程已经帮助超过40,000人找到了作为开发者的工作。开始吧