原文:The Best Programming Language (or How to Stop Worrying and Love the Code) by A.
Castro-Castilla
每隔一段时间,就会有人觉得是时候再写一篇帖子讲讲什么编程语言最好,某个古老语言有什么强大的特性,或者哪个新语言做对了。现在,轮到我来写了。我终于能说说我对编程语言的看法了。
首先,免责声明:除非你用过30多种语言,而且受过他人写的所有这些语言(或者大部分)的代码的折磨,否则你就称不上是客观的。所以是的,我有偏向,就像讨论这个话题的大多数人一样。实际上我相信,一旦精通多种语言,这个话题就会显得荒诞。我一直对围绕存储安全设计软件这个概念感兴趣。对实时操作系统和各种关键系统中的应用程序而言,这都是个可行的概念。如果你在考虑使用这种语言,你很可能有相当的专业背景,不需要读这个帖子。这种语言是成为高手之后用的语言,而那时候也没有多少选择了。一些Ada代码:
function Best_Shuffle(S: String) return String is
T: String(S'Range) := S;
Tmp: Character;
begin
for I in S'Range loop
for J in S'Range loop
if I /= J and S(I) /= T(J) and S(J) /= T(I) then
Tmp := T(I);
T(I) := T(J);
T(J) := Tmp;
end if;
end loop;
end loop;
return T;
end Best_Shuffle;
看着就很安全,对吧?:)
#!/usr/bin/env sh
l="1"
while [ "$l" -le 5 ]
do
m="1"
while [ "$m" -le "$l" ]
do
printf "*"
m=`expr "$m" + 1`
done
echo
l=`expr "$l" + 1`
done
int next_pidmap(struct pid_namespace *pid_ns, unsigned int last)
{
int offset;
struct pidmap *map, *end;
if (last >= PID_MAX_LIMIT)
return -1;
offset = (last + 1) & BITS_PER_PAGE_MASK;
map = &pid_ns->pidmap[(last + 1)/BITS_PER_PAGE];
end = &pid_ns->pidmap[PIDMAP_ENTRIES];
for (; map < end; map++, offset = 0) {
if (unlikely(!map->page))
continue;
offset = find_next_bit((map)->page, BITS_PER_PAGE, offset);
if (offset < BITS_PER_PAGE)
return mk_pid(pid_ns, map, offset);
}
return -1;
}
怪物。它是我接触的第一种语言,直到尝试了许多其他语言后,我才明白它多么严重地影响我的效率,限制我的技术。一些著名的程序员对C++评价甚低,对此我完全赞同。C++像是Bjarne Stoustrup把他能想到的所有的功能都加到C中的成果。掌握C++耗费精力巨大,可能使编程效率降低80%以上。这样想吧:你的大脑容量是X,容量有限,不管你有多少的能力,都应该尽可能为重要的事情留出空间。明智的做法是少在语言本身上用脑力,大部分用来解决问题,编写算法。如果语言复杂,无论你有多聪明,都要在语法和语义上花费更多脑力,而不能专注于用代码实现你的想法。
我认为C++是高难度低收益的典型例子。我同意,用C语言编写大的程序很困难(但依然可能,看Linux内核)。从各方面看Go,Rust和D语言都更好,但事实是C++在世界范围内被广泛应用。
下面是一个优秀C++代码的例子,使用了模板。C++代码中像这样的用户代码段比模板或者类的定义好懂的多。
#include <fstream>
#include <string>
#include <iostream>
int main( int argc , char** argv )
{
int linecount = 0;
std::string line;
std::ifstream infile( argv[ 1 ] );
if( infile )
{
while( getline( infile , line ) )
{
std::cout << linecount << ": " << line << '\n';
linecount++;
}
}
infile.close();
return 0;
}namespace rosettacode
{
template<typename T> class queue
{
public:
queue();
~queue();
void push(T const& t);
T pop();
bool empty();
private:
void drop();
struct node;
node* head;
node* tail;
};
template<typename T> struct queue<T>::node
{
T data;
node* next;
node(T const& t): data(t), next(0) {}
};
template<typename T>
queue<T>::queue():
head(0)
{
}
template<typename T>
inline void queue<T>::drop()
{
node* n = head;
head = head->next;
delete n;
}
template<typename T>
queue<T>::~queue()
{
while (!empty())
drop();
}
template<typename T>
void queue<T>::push(T const& t)
{
node*& next = head? tail->next : head;
next = new node(t);
tail = next;
}
template<typename T>
T queue<T>::pop()
{
T tmp = head->data;
drop();
return tmp;
}
template<typename T>
bool queue<T>::empty()
{
return head == 0;
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Program
{
static SortedDictionary<TItem, int> GetFrequencies<TItem>(IEnumerable<TItem> items)
{
var dictionary = new SortedDictionary<TItem, int>();
foreach (var item in items)
{
if (dictionary.ContainsKey(item))
{
dictionary[item]++;
}
else
{
dictionary[item] = 1;
}
}
return dictionary;
}
static void Main(string[] arguments)
{
var file = arguments.FirstOrDefault();
if (File.Exists(file))
{
var text = File.ReadAllText(file);
foreach (var entry in GetFrequencies(text))
{
Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
}
}
}是不是很像Java?
char bytes[] = "some data"; NSString *string = [[NSString alloc] initWithBytes:bytes length:9 encoding:NSASCIIStringEncoding];
#import <Foundation/Foundation.h>
typedef NSArray *(^SOfN)(id);
SOfN s_of_n_creator(int n) {
NSMutableArray *sample = [[NSMutableArray alloc] initWithCapacity:n];
__block int i = 0;
return ^(id item) {
i++;
if (i <= n) {
[sample addObject:item];
} else if (rand() % i < n) {
sample[rand() % n] = item;
}
return sample;
};
}
int main(int argc, const char *argv[]) {
@autoreleasepool {
NSCountedSet *bin = [[NSCountedSet alloc] init];
for (int trial = 0; trial < 100000; trial++) {
SOfN s_of_n = s_of_n_creator(3);
NSArray *sample;
for (int i = 0; i < 10; i++) {
sample = s_of_n(@(i));
}
[bin addObjectsFromArray:sample];
}
NSLog(@"%@", bin);
}
return 0;
}(defn divides? [k n] (= (rem n k) 0))
(defn prime? [n]
(if (< n 2)
false
(empty? (filter #(divides? % n) (take-while #(<= (* % %) n) (range 2 n))))))(defn make-queue []
(atom []))
(defn enqueue [q x]
(swap! q conj x))
(defn dequeue [q]
(if (seq @q)
(let [x (first @q)]
(swap! q subvec 1)
x)
(throw (IllegalStateException. "Can't pop an empty queue."))))
(defn queue-empty? [q]
(empty? @q))uint grayEncode(in uint n) pure nothrow {
return n ^ (n >> 1);
}
uint grayDecode(uint n) pure nothrow {
auto p = n;
while (n >>= 1)
p ^= n;
return p;
}
void main() {
import std.stdio;
" N N2 enc dec2 dec".writeln;
foreach (immutable n; 0 .. 32) {
immutable g = n.grayEncode;
immutable d = g.grayDecode;
writefln("%2d: %5b => %5b => %5b: %2d", n, n, g, d, d);
assert(d == n);
}
}表的最大元素:
[9, 4, 3, 8, 5].reduce!max.writeln;它绝对比C++更简洁,更具表达力,差距不是一点点。
-module(hw).
-export([start/0]).
start() ->
[ spawn(fun() -> say(self(), X) end) || X <- ['Enjoy', 'Rosetta', 'Code'] ],
wait(2),
ok.
say(Pid,Str) ->
io:fwrite("~s~n",[Str]),
Pid ! done.
wait(N) ->
receive
done -> case N of
0 -> 0;
_N -> wait(N-1)
end
end.package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
words := []string{"Enjoy", "Rosetta", "Code"}
rand.Seed(time.Now().UnixNano())
q := make(chan string)
for _, w := range words {
go func(w string) {
time.Sleep(time.Duration(rand.Int63n(1e9)))
q <- w
}(w)
}
for i := 0; i < len(words); i++ {
fmt.Println(<-q)
}
}
binarySearch :: Integral a => (a -> Ordering) -> (a, a) -> Maybe a
binarySearch p (low,high)
| high < low = Nothing
| otherwise =
let mid = (low + high) `div` 2 in
case p mid of
LT -> binarySearch p (low, mid-1)
GT -> binarySearch p (mid+1, high)
EQ -> Just mid
后篇将于明天发布,敬请期待
本文经原作者许可翻译,未经许可禁止转载原文地址:http://blog.csdn.net/postd_cn/article/details/39551377