西西河

主题:【原创】介绍一下Go语言(1)之前的话 -- zllwy

共:💬92 🌺231
分页树展主题 · 全看首页 上页
/ 7
下页 末页
  • 家园 【原创】介绍一下Go语言(1)之前的话

    我知道会有很多争议的。就当一家之言来看吧。欢迎讨论。

    先说说我入门的经历。最早知道Go是还在Android的时候,坐我对面的一位资深老程序员(以前是xbox team做graphics的)跟我介绍了Google内部在开发的新语言。新的语言这年头也层出不穷,我也没注意。后来到了现在的公司,开始做web service,主要用Java。特别讨厌netty的异步编程方式(netty本身还是好同志,对了,如果你没听说过,netty是一个基于Java nio的一个网络编程库),所以就开始想到coroutine,因为coroutine是非常轻的,可以大量创建,这样可以同时保证并行性和代码的顺序性。不过coroutine在C里面比较容易实现,利用gcc的特殊feature可以实现,有专门的库可以用。在Java里面,没有直接的实现。只好退一步,考虑continuation,利用continuation可以实现coroutine。continuation其实是个非常强大的概念。函数调用返回其实是continuation的一种特殊形式(参考google吧)。Java里面说了好久要支持continuation,因为它是实现generator的必需。曾经进了Java 7的draft,但后来被JCP砍了。有一些专门的库,比如RIFE和apache commons的Javaflow,实现了continuation,不过因为没有JVM支持,效率比较低。后来发现了Cambridge(UK那个)一个印度人的博士论文,他写了一个系统叫Kilim,在Google还有个tech talk。Kilim在Java上实现了一套最基本的Actor/Message的实现。他的办法是用一个"Pausable" exception来标志有可能主动pause的函数,然后在编译后经过一道特殊的Java class的binary rewriting,在所有的pausable的函数前后插入维持continuation状态的代码。这样就可以实现类似coroutine那样的合作式并发,或者称为轻量级的thread,和windows上的fiber比较像。实际上Kilim也把它的并发单元叫做fiber。Kilim还实现了基本的消息传递的机制。Kilim是看来最完整最高效的在Java里面actor的实现。不过Kilim的问题是它要多一道工序,改写class file。另外所有的I/O代码其实也要重写来支持fiber。这些好在也不是太大的问题,实际上有人已经开始用kilim了。

    随着我对Actor模型的兴趣,go再一次重新进入我的视野(scala什么的就不提了)。这次,我发现Go正式我期盼已久的语言。

    元宝推荐:铁手, 通宝推:博客南,zczxyz,
    • 家园 Simplicity of Go

      A simple web server:

      package main
      import (
         "fmt"
         "http"
      )
      func handler(c *http.Conn, r *http.Request) { 
         fmt.Fprintf(c, "Hello, %s.", r.URL.Path[1:]) 
      }
      func main() {
         http.ListenAndServe(":8080",
                             http.HandlerFunc(handler))
      }
      
      • 家园 Mere syntactic sugar

        Frankly, I don't see much "simplicity" in this snippet of code. Any decently flexible descendant language of ALGOL60 can wrap up and give apparent simplicity like this.

        The real "simplicity" only becomes evident when it can handle otherwise complicated programming tasks with clearly and cleverly crafted model.

        Don't get me wrong, I am not saying Go is not a decent language, just this example you gave is not convincing at all.

        • 家园 你说得也没错

          不过我在这里想说明的是,只用语言本身和语言提供的库,来实现这么一个web server,Go的代码量可能是在最少的那端。而且并不像你说的是syntax sugar,这里面没有任何花里胡哨的东西,完全是任何看得懂C的人,不需要学习Go都能看懂的程序。

          我更想说的是,程序语言就是应该这么简单。其他很多语言要写更多代码,就是因为搞复杂了。写一个简单的web server,实际上就只需要这么些代码。

          对了,这个例子不是我提的,是Go team在一个talk的slides里面的一页。我想还是说明很多问题的。

          • 家园 You didn't get my point

            The short length of the code that implements a dummy webserver does not proof anything. With enough wrapping code underneath, one can write a C++ library that eventually allows a beginner to implement a dummy webserver with same LOC, or maybe shorter. Node.js can do the same short implementation for a simple web server.

            The point is that the shortness of implementing things like this does not illustrate the inherent succinctness of the Go language. There should be better examples in aspects such as the easy control / expression of concurrency, etc.

            For instance, in Haskell, a good example is that you can implement complex constructs such as transactional memory in insanely small LOC while that is not possible in any ALGOL60 family languages. That's the true demonstration of the power / simplicity of a language.

            All in all, Go is a promising language, but not that outstandingly impressive. Or, maybe not yet.

            • 家园 Haskell

              再说一下Haskell,之所以STM在Haskell上容易实现,正是因为Haskell作为functional language本身的约束(没有side-effect)导致的结果。在传统有side-effect的语言里面,实现STM是一件很难的事情,到现在Microsoft和Intel也都只有research project(比如STM.NET),而没有产品,虽然都已经说了好多年了。关键是STM的性能问题,以后可能要靠硬件解决。

              • 家园 Bingo

                "正是因为Haskell作为functional language本身的约束(没有side-effect)导致的结果"

                That's exactly what I meant by saying "inherent succinctness". This is precisely what matters for simplicity: the nature of a language's power by design. Now you've got it, yet you dismissed it as a trivium, what a pity.

                PS: Simplicity of a language is not measured by how many keywords it has or does it use symbol-table during the compilation process, these are true trivia. Otherwise, one would argue LISP is the simplest language there ever is.

                Well, much confused by your introduction, I went ahead reading the tutorial and specification of the Go language, and wrote a couple of small programs myself, I can see the power of this new language clearly resides in the go-routine concept, which makes the concurrency much easier to handle than most of other languages.

                If I would evangelize the simplicity of this language, I would've chosen the example of goroutines, which is a heck lot better demonstration.

                • Bingo
                  家园 看来我写得很烂

                  That's exactly what I meant by saying "inherent succinctness". This is precisely what matters for simplicity: the nature of a language's power by design. Now you've got it, yet you dismissed it as a trivium, what a pity.

                  No side-effect到底是好还是不好仁者见仁。从某种程度上来说也是导致haskell流行不起来的原因。即使是functional language本身,也不完全抛弃side effect。目前的趋势是在procedural language里面加入functional的元素。我可没有dismiss这个design,只是觉得对大多数程序员来说,这是更是一种约束。而通过增加限制条件来simplify在我看来并不是真正的simplicity。

                  PS: Simplicity of a language is not measured by how many keywords it has or does it use symbol-table during the compilation process, these are true trivia. Otherwise, one would argue LISP is the simplest language there ever is.

                  当然不是,只是从一个侧面来衡量。No symbol table也不是true trivia,而是为了简化compiler,提高编译速度考虑的。

                  Well, much confused by your introduction, I went ahead reading the tutorial and specification of the Go language, and wrote a couple of small programs myself, I can see the power of this new language clearly resides in the go-routine concept, which makes the concurrency much easier to handle than most of other languages.

                  If I would evangelize the simplicity of this language, I would've chosen the example of goroutines, which is a heck lot better demonstration.

                  goroutine正是我选择go的最主要原因。我在第1部分写得很详细了。另外我在第4部分里面重点写了goroutine。web server只是一个简单的小例子。如果你觉得不好,为什么不再补充一篇呢?

                  也许我是写得不怎么样。不过能引起你的兴趣,我的目的也达到了。就算抛砖引玉吧。

                  • 家园 写得完全不烂,但是也许可以展得更开

                    你写的这些关于Go的帖子我很感兴趣,都认真看了,我还跑网上找了一些教程等看,还顺便看了看Lua的资料。就象吹西门的雪兄说的,Go的让我最感兴趣的地方是goroutine(另一个是duck typing和对继承的处理)。引起我的兴趣,这个目的你的确是达到了,但是你的第4部分里写的,让我这个对这方面不熟悉的人,感到心痒痒,但是又有没有搔到痒的感觉,不太好受。主要就是术语比较多,但是缺少解释,也许有基础的朋友看了没问题,但是对我来说却是有点懵。所以希望能进一步讲讲这方面的内容。

                    有两个问题想请教一下:为什么goroutine能比线程轻得多?通过channel来通信为什么比通过内存分享来通信要可靠?

                    对后一个问题我的理解是,通过内存分享来通信,得时时刻刻注意着race condition的问题,因为这有可能在程序的任何一点发生,编译器的优化使得理解和控制race condition更为困难。但事实上同一个程序中那些并行的部分并不需要这样时时刻刻保持通信的状态,它们之间是合作的,只需要在大家都知道的特定的点为特定的目的而通信,所以channel就大大简化了这种状况。还有比如java中,即便两个methods都是synchronized,如果顺次呼叫这两个methods,有可能还是得在放在一个synchronized的块里,也就是说java的synchronized机制是局部(不知应该用什么词)的。而channel的通信却天生是全局的,一个message只可能给收听这个channel的若干goroutines中的一个,于是在一个goroutine里面完全不用考虑其他并行的goroutine的影响。但我不知道是不是还有其他的用channel通信的优点。

                    • 家园 谢谢

                      先解释一下为什么goroutine比thread要轻。goroutine是用户空间的,所以切换goroutine要比thread的花费要小。thread的初始堆栈比较大(几个MB),而goroutine初始堆栈比较小(20KB),而且是动态缩放的。所以可以同时创建比thread可以大得多的数量的goroutine。

                      我觉得你对channel的理解是对的。本质上通过share memory来通信使得程序引入了非确定性。两个并行的程序如何访问一块共享的内存,其执行过程是不确定的。但如果通过channel,那就很明确什么时候要通信。至于性能,不是最主要的。因为channel很可能就是利用mutex来实现的。channel是比buffer/mutex更高一层的抽象。主要的目的还是使程序逻辑本身更加清晰,减少发生错误的可能性,尽量把非确定性缩小到可控的范围(比如channel底层的实现)。有时候为了性能需要,mutex也还是可能需要用到。比如在go的mailing list讨论过goroutine的barrier的问题。如果同时生成一组goroutines,需要等他们都运行结束然后取所有的结果。这个barrier的实现可以用channel,但效率比较低。Go还没有一个好的抽象来解决这个问题。最高效的方案还是用mutex来实现。

                    • 家园 有没有接触过Lua的河友。可否简单介绍一下

                      最近在考虑一个包含数据库的系统框架,所以非常关注系统内部应用层的编程语言。希望一定是一个脚本语言,以得到好的开发效率,以及在今后的应用中 real time deploy。因为系统时常有大量运算(文本及数值负载都很重)所以计算速度也很重要。又考虑系统的构成有很多部件,开发资源,维护资源(人力,财力)有限,希望尽量采用开源软件.python本是一个不错的选择,可是在速度上有短板,特别是GIL限制了多线程,现在看不出来在重新写过cPython的垃圾处理机制前有什魔希望解决,最近Google限制内部使用python的谣言让我但心JIT项目不会太顺利。

                      Lua在速度(JIT),内存效率,多线程上有巨大的优势。可是有如下缺点

                      1) 社区没有python发达,库资源的丰富程度及文档支持远没有python丰富。

                      2)语言没有Python丰富,对我来说特别是缺乏OOP的原生支持和缺乏装饰模式的原生支持最恼火。(我们希望用装饰模式实现对原语言特色进行非侵入扩展,本来改Lua及LuaJIT的内核也可以加入额外的语言特色,但这样就可能在用其他Lua库时有风险,并且不能自动支持Lua升级)

                      希望得到熟悉Lua的河友指教。特别在如下方面:

                      1) Lua在构建大型系统时有何缺点。

                      2)介绍一下成功的Lua开源库,如:数值运算,网络支持,web应用,图形界面,2D-3D绘图,分布远程运算,日期时间时区。

                      3)LuaJIT在运行实际大型系统时的效率如何

                      4)Lua的程序量比相应的python差多少,比C好多少(代码的表达效率:如python可以用C 1/6.5的代码量实现同样功能)。

                      如果能像zllwy河友一样,系统介绍一下就更好了。

                      谢谢

            • 家园 【商榷】我想你也没有明白我的意思

              我们在争论不同的东西。我只想说:

              “Go很简单,只用自己的库就可以写很短的一个web server程序。”

              你非要说

              “Go不是最出色的,其他的程序语言包装一下也可以这么短。”

              完全是南辕北辙。网络上的争论,往往就是陷于这样的意气之争。哈哈。

              还有啊,你说程序长短不说明问题,我完全不同意。你去试试用Java/C/C++/python/javascript写同样的程序,只准用自己的标准库。

              • 家园 这么说就没劲了

                python -m SimpleHTTPServer 8000

                这可也是用自己的标准库,而且干的事情比你的还实用些呢,呵呵

                • 家园 还争这个哪

                  我承认python也很简单(虽然其实你要实现我例子中的代码的话,python的code其实也不比Go少。哈哈)。不过这个跟我说Go写代码很简单不矛盾吧?其实公平比较应该是static language和static language比。Go就是个better C,或者C + python。Go的source code感觉冗余比较少。就像Java的public static void main(),实在是太罗嗦了。:-)

              • 家园 我觉得Simplicity不是这个意思

                一般而言,我们说到Simplicity,很少指标准库的丰富强大。

                自问还没有能力很好的定义对于一个编程语言来说,simplicity是啥,但是我觉得有些例子,

                比如ruby的meta programming,比如python的 generator,再比如C#的delegate。

分页树展主题 · 全看首页 上页
/ 7
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河