什么是最好的編程語言?(怎樣才能愛上編程呢?)

jopen 10年前發布 | 48K 次閱讀 編程語言
經常有人會寫點評論編程語言的文章,可能是一些很古老的快被遺忘的語言,也可能是正在流行的新語言。現在我也要寫點什么,寫出了我對編程語言的一些想法。

免責聲明:除非你精通三十門以上的語言并且能夠很好地用他們編程(或者是其中的絕大部分),否則你不能客觀地評價這些語言的好壞。是的,就像其他人寫的關于這方面的文章一樣,我也有自己的偏好。事實上,我認為如果你精通很多門語言,你就會認為這個話題是多么的荒誕可笑。

下面這些就是在我的博客中被評為最偉大的語言:

  • Assmbly:機器語言
  • C:形式化語言
  • Javascript:網編編程語言
  • Scheme:與C和Javascript相比,更輕巧,嵌入性更好,是極其靈活的編程語言

范例程序來自Rosetta Code

合適的語言

我不把這些語言稱之為合適的語言(reasonable languages)是因為他們是最好的語言(best languages)。他們是現在人們普遍使用的編程語言,人們用他們來編寫軟件。當然了,你可以避免這些爭論而是自己去做決定,如果那樣的話,進入下一 部分吧。

Ada

我總是對一種語言存儲安全的方面很好奇。大體來說這對于真實的操作系統和普通的一般的應用系統都是很有意義的。如果你有相關專業背景的話,并且使用這種語 言的話,你不需要讀下面的這一部分,但這是一種一旦你知道你需要用它來做什么,你就沒有什么選擇余地的語言。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;
看起來很安全,不是嗎!:)

Bourne (Again) Shell

我經常考慮,難道我真的需要用shell來寫Linux腳本嗎?真的有必要嗎?如果你不用shell寫script(腳本)也沒有關系,因為最終你要面對 面的處理這些script,并且你還要考慮怎樣在Bare Metal Age和pre-stackoverflow中處理這些問題。這種語言沒有什么令人吃驚的地方,也沒有什么可以擴展你的思維或讓你更有創造性的特性,也難 以從應用的業務角度去證明它是好的。也許僅在不知道什么情況中才可以體現出來吧。然而他在系統管理中是那么重要,并且沒有看起來那么糟糕。就像是 Javascript,你需要比其他語言更多的實踐練習。
為什么我要用Unix Shell呢?
  • 我是OSX/Linux/POSIX系統管理員
  • 為了實現自動化
  • 為了使用命令行的強大功能
一些Bourne Shell代碼。享受這些布爾表達式吧!
         #!/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

C

盡管你可能不喜歡C語言,但你必須要尊重它。他可能是最偉大的語言之一。他能真正地能編寫系統級代碼。它是UNIX的制造者,是所有語言的鼻祖,是通用的 系統級編程語言。它久經沙場,經歷時間的檢驗,廣泛傳播。太多的開發,調試,性能分析工具支持著C的發展,這也使得它減少了作為語言的缺陷(我看來,這些 缺陷不多)。這是一個真正實現了其目標的語言:成為通用的語言。今天,它甚至形成了最奇怪的一個體系結構,這也使得今天很難手寫出比C編輯器編譯出的代碼 更好的代碼。
盡管有這么強大的工具,但這是需要被人掌握的。這種語言很是冷酷無情,你需要懂它知道你自己在用它干什么。理解機器內部對C語言很重要,C語言可以控制機 器的底層。這一點很好,有積極的一面:如果沒有C語言這樣的底層語言,有些事情我們做不到。C語言程序員必須要徹底理解他們自己在干什么,這一點對于長時 間運行的可靠的軟件是極為重要的。如果有什么事物可以分開,C語言可以很好地支持并發。C語言編寫的程序運行時的效率和C語言的普遍性是一個神話!
Linux內核中的C語言代碼:
     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++的壞名聲是被一 些著名的程序員造成的,我完全同意。C++看起來仿佛是Bjarne Stoustrup把他能想到的所有的功能都加到C中。學習掌握它的負擔,使你的編程效率降低80%以上。這樣考慮:你的大腦容量是X,容量有限,不管你 有多少的能力,你想留下盡可能多的重要的事情。明智的做法是減少用于語言本身的腦力勞動,而是使用大腦和優化的算法。如果語言復雜,無論你有多聰明,你都 要用更多的腦力用于解決這語言的語法和語義上的問題,這會使你使用更少的時間用于優化你的代碼。
我認為C++是典型的例子,太復雜的事物沒什么意義。我同意,用C編寫大的程序是困難的(但是有例外,看Linux內核)。通過這些分析,Go,Rust和D語言似乎是更好的,但事實是C++在世界范圍內卻被廣泛地應用。
這是一個很好的C++使用模板,以下面的方式使用C++更容易理解,而不是使用template/classes來定義。
 #include
    #include
    #include
    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 class queue
          {
          public:
            queue();
            ~queue();
            void push(T const& t);
            T pop();
            bool empty();
          private:
            void drop();
            struct node;
            node* head;
            node* tail;
          };
          template struct queue::node
          {
            T data;
            node* next;
            node(T const& t): data(t), next(0) {}
          };
          template
           queue::queue():
            head(0)
          {
          }
          template
           inline void queue::drop()
          {
            node* n = head;
            head = head->next;
            delete n;
          }
          template
           queue::~queue()
          {
            while (!empty())
              drop();
          }
          template
           void queue::push(T const& t)
          {
            node*& next = head? tail->next : head;
            next = new node(t);
            tail = next;
          }
          template
           T queue::pop()
          {
            T tmp = head->data;
            drop();
            return tmp;
          }
          template
           bool queue::empty()
          {
            return head == 0;
          }
        }

C#

這 種語言旨在減少代碼,增加復用性,從而提高程序員的創造性。它是面對對象,具有靜態類型,有大量的庫函數。你能看出它是微軟由控制的。但點我不會擔心,它 不是一個糟糕的語言。它不是很吸引人,也許微軟真正想要的就是準確性吧。相比VB這是一個過于激進的改變吧。我能使用它來做的事:
  • windows編程
  • 游戲開發(大多數是由于微軟的強迫而使用它,我認為C/C++更好)
  • 這種語言能做大量的事情:Unity3D, Xamarin, .NET, XNA。
下面是一些代碼:
 using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    class Program
    {
        static SortedDictionary GetFrequencies(IEnumerable items)
        {
            var dictionary = new SortedDictionary();
            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很像呢!

Objective-C

相比C++和C#,對于Objective-C,我有更多的想法。他的語法很不好,但是作為語言我喜歡它。他有基于NextStep的一套很好的庫函數, 這些庫函數的增加,讓C有很大的進步。它沒有增加比其它父語言太多的難以控制模棱兩可的關鍵字。正如我說的,它的代碼有一點復雜并且很難閱讀,尤其是對于 嵌套函數更是如此。但在概念方面,有一些很好的東西,而不是其語法上。看這個代碼嵌套調用:
     char bytes[] = "some data";
        NSString *string = [[NSString alloc] initWithBytes:bytes length:9 encoding:NSASCIIStringEncoding];
對于C語言衍生出來的這個漂亮的代碼,利用了C語言的所謂的“block”。
         #import
        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;
        }   

Clojure

作為一個Scheme程序員我尊重Clojure:是所謂的現代Lisp,他有一些獨特的特性。我想說Clojure在編程方面的長處是和Java語言相 同的互操作性和并發實用程序。它與scaling是緊密相關的,但他們的特點是不同的:lisp是面向對象和面向過程的混合,Clojure有過多的括號 而使其沒有lisp流行。選擇這兩種語言中的哪一個進行編程取決每個人不同的風格,這是因為沒有長期的記錄說明哪一個在編程方面更成功一點,就像Java 與PHP相比,雖然他們都是運行在虛擬機上的。對于任何基于虛擬機運行的語言,另一件需要考慮的事情是運行時間:這與很小的小程序是不同的。這是一些我用 Clojure所要解決的問題:
  • 網絡編程。對于網絡編程,這是一個很好的選擇,在這個領域Clojure看起來是十分流行的。
  • 當你想使用JVM而沒有Java技術時。程序員的快樂程度和生產率都將提高。
  • 探索性的編程,編出的代碼能修改成產品代碼。這一部分Lisp也做的很好,但是Clojure是基于Java的,其有許多代碼時開源的。
  • 安卓程序開發?安卓程序開發的GUI模式很大程度是基于類繼承。(意味著你不僅僅確切地使用它作為一個插件庫,而是迫使你使用某些結構)。這個可以實現,但是這又不像Java繼承那樣自然。
經典的Clojure代碼:
     (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))))))
    Lisp形式的隊列的定義代碼:
        (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))
 

D

我以前很喜歡D,D恰好就像C++一樣做的很好。D1很像底層的Python。很像pythonized C或者是類似的東西。真是了不起:你感覺到了其發展迅速吧,他專注于算法而不是語言,但當你需要控制底層時,它又沒將這一部分去掉。D2帶來了C++的一 些復雜性,這是由于Andrei Alexandrescu的創新。這使得一部分人不高興了,雖然其確實在并發性方面做得更好了。D2再也不是一個純粹的語言了。盡管我喜歡它,但是我還是 感覺其不如C++普遍(一旦其復雜起來)。并且我認為現在Go正在吞并D的市場。盡管在語言方面真的能更快一些、更酷一點,但Walter和Andrei 不能與google競爭。你可能正如我一樣喜歡D,但是我不是很看好它。僅僅是追隨C++或者是按照GO語言更加支持本地并發開發呢。我什么時候會使用D 語言呢?
  • 從頭開發一個項目時,與C有接口或者是與C++有聯系時。你需要提前想好接口是什么樣子的。對于接口,我 不建議使用C++的GUI,因為其要從內部處理C++的繼承,這將使得其優勢發揮不出來。如果需要,就簡單做一個插件庫吧。(創建對象,使用其功能,而不 是模板或是C++的繼承)
  • 底層二進制的編程。就像一個獨立的部分,做自己的事情。
  • 如果希望能很好地支持并發。
讓我們看一些D2的慣用法,純函數,不可變的聲明。
     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++更具有表達性和更清潔的語言。

Erlang

這是一個有目的性的語言。Erlang的web界面是非常清晰的:構建大規模可伸縮軟實時的或可用的系統。它使用在電信、銀行、電子商務、計算機電話和即 時消息等方面。他的實時性也支持并發,分布和容錯。其在一些要求很高的應用程序中已經得到證明,例如WhatsApp。其代碼很有效,含義清晰,很可讀。
看一下簡單的并行程序的一個小例子:
     -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.

Go

我沒有親自使用過它。但很顯然的是,這是google做的,其將C與C++好的部分加在一起并且在并發方面比他們都好的語言。它比C++有更好的部分,它 形式簡單。他沒有不安全的指針,擁有包特性、函數和垃圾收集機制。未來Go可能成為服務器端語言。我什么時候要試試Go呢?
  • 對于服務器應用程序,需要非常高的可靠性和性能。這包括web應用程序。
  • 對于控制底層的高效率的代碼(然而,我更喜歡Erlang)
Go的并行程序代碼
     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)
            }
        }

Haskell

比起這個表單上的其他語言,這種語言更像是一種工具。幾乎在任何用代碼實現起來有困難的地方,都提供了函數庫。可以說這是一種很高門檻的語言。我看來,他 考驗你的大腦,在各種社區中有一群最聰明的人。我認為Haskll是很值得學習的,盡管你也許不能用它編寫任何程序。作為相對來說比較模糊的語言,我這樣 定義它是很合理的,并且在一些方面還是很有用的,例如金融方面。Haskell的代碼往往是非常緊湊的,但在某種意義上來說,雖然有點抽象,你需要很多的 函數,實際上是概念上的操作,而不是一步一步那樣去執行的。我個人不喜歡它的語法(我認為其語法太復雜),但至少它服務于一個目的,不覺得混亂。(我把你 看成了Perl!),這種語言看起來漂亮連貫,自己看吧:
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

Java

看起來很像是C#,但是他有虛擬機。它是第一個(C#仿照它)面向對象的語言。除了嵌入式設備不行和極其要求性能的地方不行,它幾乎什么都能干,web app到游戲。它是許多其他語言的基礎,尤其是虛擬機方面。看一個有趣的項目,它是為了教育、數學和藝術的而寫的程序。我什么時候要用Java呢:
  • 主要是當你想訪問一個非常大的開發商,即你想要別人維護你的軟件。
  • 當你需要在盡可能多的硬件上跑你的程序。
Java7的例子程序,看吧:
     import java.util.List;
        import java.nio.charset.Charset;
        import java.nio.file.*;
        public class ReadAll {
            public static List readAllLines(String filesname){
                Path file = Paths.get(filename);
                return Files.readAllLines(file, Charset.defaultCharset());
            }
           public static byte[] readAllBytes(String filename){
               Path file = Paths.get(filename);
               return Files.readAllBytes(file);
           }
        }
我才你已經寫過Java程序了,因此我不會解說類定義來煩你了。

Javascript

2010年代的通用網絡的語言。有趣的是,雖然此前被視為一個有缺陷的和功能有限的語言,但現在大量的程序員對其進行了良好的改造,現在已經成為一種偉大 的語言。特別是如果你看了它所有的庫,你會發現這些庫彌補Javascript的設計的缺陷(比如一個模塊系統)。最后要感謝這一點,現在我們甚至把 Javascript用在服務器端,這種前后端的對稱式編程給我們帶來了美好的生活。

有很多研究和努力投入到了改善Javascript的性能、優化Javascript的編譯器中。這實際上證明了社區是極其偉大的(如果不是最大的)語言 來支持者。有趣的是,你會看到無數的庫在做同樣的事情,這使得庫成為競爭最激烈的領域之一。看Grunt、Gulp等,真是太瘋狂了。
下面的代碼顯示了Javascript基于的原型類和繼承機制:
     function Car(brand, weight) {
          this.brand = brand;
          this.weight = weight || 1000;
        }
        Car.prototype.getPrice = function() {
          return this.price;
        }
        function Truck(brand, size) {
          this.constructor(brand, 2000);
          this.size = size;
        }
        Truck.prototype = new Car;
        var cars = [
          new Car("Mazda"),
          new Truck("Volvo", 2)
        ];
        for (var i=0; i
            console.log(cars[i]);
            console.log("brand: "+cars[i].brand+". weight: "+cars[i].weight+"." + (( cars[i].hasOwnProperty('size') ) ? " size: "+cars[i].size : ""));
            console.log("Car: %s. Truck: %s\n", cars[i] instanceof Car, cars[i] instanceof Truck);
        }
這顯示了使用Lo-dash庫的代碼:
     var characters = [
          { 'name': 'barney',  'age': 36 },
          { 'name': 'fred',    'age': 40 },
          { 'name': 'pebbles', 'age': 1 }
        ];
        var youngest = _.chain(characters)
            .sortBy('age')
            .map(function(chr) { return chr.name + ' is ' + chr.age; })
            .first()
            .value();

如果你是熟悉Javascript的細節的話(就像例子中一樣),你會我發現將兩種風格混合在一起很酷。

OCaml

它有幾分像Haskell,但更能滿足程序員的想法。如果需要的話,一些取舍會使問題更容易解決。面對對象的方法看起來更容易工作。有人使用他,我估計就是他在這一點上超過了Haskell。看下面的代碼:

let n_arrays_iter ~f = function | [] -> () | x::xs as al ->     let len = Array.length x in     let b = List.for_all (fun a -> Array.length a = len) xs in     if not b then invalid_arg "n_arrays_iter: arrays of different length";     for i = 0 to pred len do       let ai = List.map (fun a -> a.(i)) al in       f ai            done

看起來很像Haskell,對不對?

PHP

不要怕PHP,調整好看PHP的心態,如果你喜歡PHP編程,那你就成為了真正的程序員。這是一種代價小的語言。什么時候使用呢:
  • 如果想要大量的web開發人員一起工作
  • 就是它,沒什么原因
  • 下面是漂亮的PHP代碼。希望你喜歡。
     function hashJoin($table1, $index1, $table2, $index2) {
            foreach ($table1 as $s)
                $h[$s[$index1]][] = $s;
            foreach ($table2 as $r)
              foreach ($h[$r[$index2]] as $s)
                $result[] = array($s, $r);
            return $result;
        }
        $table1 = array(array(27, "Jonah"),
                   array(18, "Popeye"),
                   array(28, "Alan"));
        $table2 = array(array("Jonah", "Whales"),
                   array("Jonah", "Spiders"),
                   array("Alan", "Ghosts"),
                   array("Bob", "foo"));
        foreach (hashJoin($table1, 1, $table2, 0) as $row)
            print_r($row);

Python

這 是一種很好的語言,我很喜歡的它的塊結構:你不需要分號。我是如此地喜歡它以至于我打算以這種方式寫Javascript。但這也是不同于其他語言的地 方,因此許多人也因為這個原因不喜歡這種語言。這是一種清楚的語言,減輕了你肩上的語法的負擔。盡管在這一方面是很有爭議的,但是還是有大量的人堅決支持 這種語言。在很多情況在這兩種語言中選擇的是很難的,對于各種應用領域盡管Python似乎是更普遍的,更合理的選擇。那什么時候使用Python呢?
  • 網絡編程
  • 科學計算和數據分析
  • 系統管理和工具
  • 游戲或3D應用程序腳本
  • 跨平臺支持領域
很漂亮的Python代碼:
     from itertools import islice
        def hamming2():
            '''\
            A text documenting this function (stripped)
            '''
            h = 1
            _h=[h]    # memoized
            multipliers  = (2, 3, 5)
            multindeces  = [0 for i in multipliers] # index into _h for multipliers
            multvalues   = [x * _h[i] for x,i in zip(multipliers, multindeces)]
            yield h
            while True:
                h = min(multvalues)
                _h.append(h)
                for (n,(v,x,i)) in enumerate(zip(multvalues, multipliers, multindeces)):
                    if v == h:
                        i += 1
                        multindeces[n] = i
                        multvalues[n]  = x * _h[i]
                # cap the memoization
                mini = min(multindeces)
                if mini >= 1000:
                    del _h[:mini]
                    multindeces = [i - mini for i in multindeces]
                #
                yield h

Ruby

Ruby來自Rails。這個簡單的原因就可以使它不在這個列表中。當然了,現在可以看到許多其他的程序,但都是來自于Rails。在那以前,Ruby是一種來自日本的很難理解的語言。這是一個對于鼓勵快要消失的編程語言成為極其流行的語言的很好的例子。
我以前從許多Ruby程序員那里聽到,當然我也是一個很熟練的Ruby的程序員,他們說這是一個令人愉快的語言。換一句話說,這是一個絕不會令人沮喪的語言,我不知道這是來自語言或者是Rail本身。很早以前就被metasploit(一篇文章)指出來了。
這是用Python寫過的代碼,這里用Ruby再寫一遍。風格不同,體現出了Ruby更有“function”風格。
     hamming = Enumerator.new do |yielder|
          next_ham = 1
          queues = { 2 => [], 3 => [], 5 => [] }
          loop do
            yielder << next_ham   # or: yielder.yield(next_ham)
            [2,3,5].each {|m| queues[m]<< (next_ham * m)}
            next_ham = [2,3,5].collect {|m| queues[m][0]}.min
            [2,3,5].each {|m| queues[m].shift if queues[m][0]== next_ham}
          end
        end
        idx = 1
        hamming.each do |ham|
          case idx
          when (1..20), 1691
            p [idx, ham]
          when 1_000_000
            p [idx, ham]
            break
          end
          idx += 1
        end

Scala

似乎是在JVM方面很有優勢。我很確信,它突出的原因是與Clojure或其他大的流行的語言相比,它更是語法方面很簡單。這種語言也在這個列表中的原因是其可與Java很好地結合在一起。看下面的Hofstadter Q序列問題代碼:
     object HofstadterQseq extends App {
          val Q: Int => Int = n => {
            if (n <= 2) 1
            else Q(n-Q(n-1))+Q(n-Q(n-2))
          }
          (1 to 10).map(i=>(i,Q(i))).foreach(t=>println("Q("+t._1+") = "+t._2))
          println("Q("+1000+") = "+Q(1000))
        }

Scheme

這種語言在這個列表中,會有很多人對此有爭議,對此有三點理由:
  • 缺乏控制質量的方法
  • 很少有函數庫
  • 性能不佳
第一點是確實的,對于解決問題你有許多方法,但是沒有哪一個是首選的有效的方法。第二點也是真實的:有函數庫,但是都是分散的。語言方面的分散使得需要尋 找可供使用的代碼是很顯然的:你需要用你自己的方法實現。這也許不是十分困難或者是耗時的,如果你要使用帶有很好的FFI支持的Scheme實現,例如 Gambit或Chicken Scheme,你需要使用C語言的那些函數庫。這與你可能想的相反,我是這樣做的,并且能很好的工作。但最后,表現不佳。實際上這是完全錯誤的。像 Gambit那樣實現是非常快速的,并且你還能優化它。從算法優化,到全局模式編譯器聲明。當然了,C代碼可以很容易地在必要的時候組織代碼。
是的,我對于Scheme是狂熱的。但是,我承認它有一個致命的弱點:對于共享代碼,它太差了,只有一個不太好的社區。它是如此的靈活,以至于每一個程序 員都希望自己能對于問題提出完美的解決方案。Java在這方面是完全相反的:Java社區中有杰出的個人或小團隊,有試探形式的編程,未經證實的大型團 隊。但在這種情況下,是非常好的,你可以在一個非常快速和愉快的環境中發展。最后,語言的另一個非常有趣的特性:您可以很容易地用一個Scheme- to-Js編譯器編譯為Javascript,所以你可以享受在節點在服務器上編程的樂趣。以下是我使用這個語言具體的例子:
  • 需要快速編程且不需要只在像Python或Ruby中提供的庫
  • 在C或C++平臺的開發的腳本程序。
  • 為了構建一個需要從基礎代碼擴展出大部分代碼的應用程序
  • 對于游戲和OpenGL/ES-based多平臺的應用程序。
這是一個Scheme代碼示例。雖然有函數庫,但你需要自己去實現各部分功能代碼,因為沒有什么可用的。都要去實現:
     ;;! Recursive map that applies function to each node
        (define (map** f l)
          (cond
           ((null? l) '())
           ((not (pair? l)) (f l))
           (else
            (cons (f (map** f (car l))) (f (map** f (cdr l)))))))
        ;;! Explicit currying of an arbitrary function
        (define (curry fun arg1 . args)
          (if (pair? args)
              (let ((all-args (cons arg1 args)))
                (lambda x
                  (apply fun (append all-args x))))
              (lambda x
                (apply fun (cons arg1 x)))))
        ;;! Implementation of filter, with the match macro
        (define (filter p lst)
          (match lst
           ('() '())
           (((? p) . tl) (cons (car lst) (filter/match p tl)))
           ((hd . tl) (filter/match p tl))))
再看看" these other interesting examples"(一篇文章)吧!

Dinosaur languages

這種語言無所謂好壞。似乎我們僅僅是將其忘記了,沒有什么特別之處,也沒有什么理由吸引我們去使用這種語言。也許我們是錯誤的。

Assembly

事實上再也沒有人用Assembly(匯編)真正編程了,因為編譯器已經真的很好了,似乎也不用匯編來優化了。我認為總是有人可以用匯編寫出極其優秀的代碼,但那樣的人必須是足夠聰明的。
但是也有一個必須使用匯編的地方:終極編程。用SICP和Lisps對編程有特別好的啟發,但是我相信如果從語言的最基本的地方理解也能得到啟發:就像處 理器指令序列,抽象的語言結構,無論是在聲明,邏輯、功能或面向對象方面都有啟發。對程序員的大腦有好處。這是一種偉大的語言。什么時候使用呢:
  • 為了學習
  • 系統級編程需要使用的時候
  • ·當你需要手工實現某些功能時

Common Lisp

我過去使用Autolisp、AutoCAD,但需要在Lisp、Scheme、Clojure中做決定時,我選擇Scheme。對于我來說,在前面提到 的三種語言中,它排名第三。它感覺起來有些復雜,沒有了lisp中的美麗,優雅和簡單。我會用它來進行快速建模,但現在已經擁有的庫,使我們可以不用它解 決問題。并且我認為有擁有更好的庫的語言。

Perl

顯然是一個具有宗教性質的語言,這 種語言擁有自己的宗教團體。有這樣一個事實是語言學家Larry Wall將創造性加入到這種語言中。感覺Latin真的是很迷人呀。伙計們,一定是有某些原因才使仍有很多杰出的人在討論這種語言。這種語言的精髓被 Larry寫過的話描述了出來:匯編語言可以寫出一起東西。
總的來說,我對Perl語言的概念有很深刻的印象。但其有趣的語法也可以導致產生出很多的錯誤(Lisp中很多地方使用宏)。我認為這種語言的偉大的是在 解決小問題時非常方便:它有一個很全面的庫(CPAN),提供了幾乎任何你想要的方法,這使得解決問題很方便很簡單。使用Perl可能出現的最壞情況是, 為了改變你的系統,你要學習很多的東西。Ps:我已經被告知Perl的對對象支持是極其可怕的,但我認為這也是一個好處(我可能是偏激的),但我也懷疑這 種說法。
看看這兩大項目:POE(反應系統的框架、合作多任務處理和網絡應用程序),和一個實時web框架Mojolicious。

BASIC, COBOL, Fortran, Pascal, Visual Basic…

如果你需要使用這些語言中的任意一個,上帝都會保佑你的。他們應用在特定的領域(像Fortran應用在在天文學上和HPC應用在社區中),或 COBOL(在一些行業中的仍在使用的古老的系統),但它們幾乎都被社區的人們一致抨擊。但我給你一個很好的理由使用這些語言:當你維護別人代碼時按小時 收費。對于自己的代碼呢?不討論這些:)

Smalltalk

第一個面對對象的語言,但是對于我來說它似乎是被忘記了。

The Unreasonable languages

可能用于生產使用這種語言不太合理,但肯定會促使你讓你成為更優秀的程序員(這是完全合理的)。你的選擇是有價值的。我能說什么,我喜歡另類的觀點。

Array, J

我有許多的語言需要學習,我聽說他們是獨特的并且學習他們將在除了語言和語法方面擴展你的思維。

Factor, Forth

基于堆棧的語言是非常有能力的并且是非常值得學習的。很能擴展你的思維。所以就在這張列表中了。

F#

這是微軟想扮酷的想法。這是一個很好的語言,但是我們中有許多已經學會了遠離微軟了。我們有足夠的其他公司出資的語言了。

Oz

這是一種非常規范的有約束力和可分布式編程的語言。它擁有大部分主要編程語言的特點(懶惰和渴望),命令式和面向對象的。

Prolog/Datalog

聲明式邏輯語言大體上是非常具有學術性質的。不過也有一些例外,可以看到在this Stackoverflow question中被看到,并對與Scheme也是如此。

Rust

對于系統編程語言Mozilla的競爭者。它沒有像D一樣的歷史,也沒有像google這樣的大公司的支持,僅僅像Go一樣。不過,我仍然希望看到Rust在未來可作為系統開發的合理的選擇。

Shen

它在這個列表中,是因為對其類型相關的東西,我讀到了有趣的東西,一些非常基礎和有趣的東西是用Shen寫的。然而,它的實現是極其具有實驗意義的,并且這個語言有一個不可接接受的許可證。這個語言的創造者似乎生活在另一個年代。

TCL

我過去幾個月,這時我發現程序與數據由同樣的結構存儲并且它綁定到一個我需要了解的庫,這些是問題(BRL-CAD)。我想說的這是一種像其他很多語言一樣被低估的語言。它也沒有什么特別好的前途。

結論


我以我選擇的語言開始了這個漫長的帖子。編程是一個很美妙的藝術,我真心喜歡它,我承認我偏向于使用自己的經驗寫這篇文章。由于太多的不確定性,選擇一種語言來編程是一個很困難的事情。以我的觀點看,有三點很重要:
  • 這個工程的目的是為了創作出一個產品,還是屬于一個擁有文化底蘊的組織而偏向于某一種語言嗎?
  • 這項任務非常特殊而就是要求某一編程語言嗎?
  • 你喜歡或者是想要盡力用這種語言編程嗎?
盡管有時打破這個規則,但這就是我解決這類問題的方法。

你有更好的代碼片段顯示這些語言的特點嗎?

發布  renyuzhuo 3/9/2014   原文 blog.fourthbit.com
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!