从分享文档的角度观察开源社区

国内的开源社区环境不咋地,朦朦胧胧的问题困扰着各个开源项目,而这个绝不是因为怀着开放理想的开源人做不出好的东西。

LOVE OPEN SOURCE尴尬的状态在持续着,脾气再好的人时间长了也会忍不住发发牢骚。

我也很费解,到底是为什么,我们到底应该怎么做?

有人说就算不参与提交代码,写些文字分享一下总可以的吧?有人就说没什么好分享的。
类似的争论总有发生的时候。这里不具体讨论这些观点,就从分享文档的角度来看看事情。

相信有许多人都有这样的经历,在使用某开源项目时遇到困难就 google,搜索结果中排名靠前的并不一定是官方的,特别是各种细致的问题,从摘要都可以看出来那个 post 所描述的问题正好就是自己遇到的,心中一乐,点开链接之后数秒,问题解决。

假设没有搜索引擎(天哪!),但是你只是知道有官方文档,然后你去查,发现写这个项目的文档写得非常特别,可能项目比较新,或者开发者就是这么特别,你只好开始刨那些文档。运气好的,能从 FAQ 里面找到你想要的,运气不好的,不太会觉得是自己运气不好,会认为这个项目开始不靠谱了,但是问题,还是得解决,于是想着既然开源的,就看看代码吧,正好自己也会哪门语言,强大的你下载了源码,不管 3721,连上调试尝试快速寻找突破口,经过 N ( >=1 ) 个循环之后,终于找到了问题,原来只是自己理解的问题,修改一下自己的代码即可轻松绕过。为了掩饰自己的“无知”,你可能选择了什么事情都没有发生。

另一个“强大的你”在地球的另外一个角度重温了一下刚才那一幕,也许太忙了,就忘了~~
还有另一个“强大的你”也遇到了,但是你也很特别,不会码字,然后就忘了~~
……
第 M 个人同样遇到个类似的问题,就会有 M 种理由当什么事情都没有发生过,就会有 M 个人开始对这个项目产生坏印象。使用的人开始减少,项目维护的热情在消减。

但情况非常之容易改善,只要中间有一个人为此记录下来,发布到网上,就会产生 P ( < M ) 个开心秒杀的情况。当中微妙的差别可以影响很多。这 M + 1 ( 1 是开发者 )个人是不是就可以形成开源社区,只要每个问题循环中有一人提交解决结果,其它人都可以直接读取这个缓存,看上去是不是非常简单而美妙。 现实中,情况可能复杂得多,只是可能,因为相对于每一个使用开源项目的个体,所要付出的和最大收益是不成比例的。整理成文字发表出去的成本非常低,网上有大量的免费服务可供选择。 开源社区可能不是以这种方式建立起来的。 只是开源社区对于开源项目是非常重要的,缺乏社区的支持,项目很难得到全面发展。 开源社区并不意味这固定的组织,任何人都可以作出贡献,比如只是一篇简单的分享,任何人都可以分享当中的喜悦。 非常简单的自然法则。

Baidu, 整个场面 hold 住

百度在场内作恶的传闻也不是一天半天的事了,突然连续 3 天上电视,不是在广告里,而是在广告中插播的节目里,突然有种事态严重的感觉。

不过,在网上这事还真没炒起来,除了前两天大连方面搞的全民健身和 google 买了部手机之外,真是相当的平静~~

百度把整个场面 hold 住了~~baidu logo

不知道 CCTV 策划的这次曝光还将持续多久呢?但如果百度一直这样 hold 住,效果就是单手拍掌。

单看报导本身,略显单薄的,来来去去就那几个案例,从材料到结论,某些案例背景交代“很有选择”,主观水分不少。专家鼓励的,用法律武器来保障自己,听起来不错,但怎么做呢,可以给些案例吗?场内局域网的游戏规则本身就不清不楚,光取证就已经够头大了,没相当的软硬实力就与垄断企业斗争,情况不容乐观。

大网站们自身影响力大自然排名就靠前的,给或者不给那点好处,对于它们来说,就像掉头发一样自然,但是对于许许多多的小企业来说,那就是割肉的问题了。而这里关键的问题并不是百度怎么作恶法,而是互联网整体缺乏有效的发展机制,无法培养出一个合理的对手。曾经有那么个声称自己不作恶的放在面前,不好好珍惜,现在没有如果了。作为网民也是有责任的,有责任指出不需要什么类型的服务,比如受人工干预的搜索结果,有责任选择和要求有更好的服务,比如选择 google。

百度不是一个人,树大容易有枯枝,大概不会期待现任领导者突然良心发现,即使真的良心发现了,又能控制得了多少呢?最后不一样钱照收,搜索结果照搞。当然事情也不能完全那么悲观,百度凭借目前的优势,只要思路拓宽,做好基础服务,是可以不作恶也赚到笑的。至少 CCTV 专门针对的假冒伪劣广告那部分是可以很好处理的。

互联网是时候需要有更多的关于 web 生态 的讨论了,需要明确下阶段究竟应该发展出什么样子的网络环境,明确具体的尺度和准则,网民的权利与义务,基本的游戏规则(不要告诉我是备案)和裁判守则,需要参与的企业具备怎么样的素质等等。

现在是百度 hold 住整个场面,究竟下一秒会变出什么惊喜呢?

百度知道你不知道~~

一路走好

世上本没有路,走的人多了,就有了。以前不明白,听起来挺形象直观,好像是那么回事。

突然之间想看《海上钢琴师》,看了。

人们看到的是孤儿,是天才,是目光聚焦的瞬间,然后,是孤独,如果是这么看,恐怕也只有“传奇”才可以形容 (The Legend of 1900)。因为就算是听了 1900 最后的内心独白,我也不能体会到那种感觉,不是理解,感觉到有差异,但不能感觉。就好像身着一身装备站在月球表面,隔着保护面罩看见,面前就有个人很自由地,只是穿着普通的衣服,舒服地活着。

如果,每个人都有自己的世界。

你跟我,或者他们,只是偶然遇上,那么那一切都说得通。差异是必然存在。

明白到自己和另外一个个体是存在差异,你可以选择接受或者不接受其他人的影响,消去或者保持差异。

世上本来就有路,一条属于自己的路,它像风,看不见摸不着,只能依靠树叶飘落,旗帜飞扬来反映风的存在一样,你走上去,而且只有在你走上去之后,人们才能发现,噢,那是一条路。那些曾经说过的计划,那些不给力的尝试并不能显示那条只有自己才能看见的路的存在。

所以,一路走好。

PS,如果能走到一起,是福气……

开始学习 Lisp

好吧,我是受到 《黑客与画家》 的催眠,去看 LISP 的,不过越看越清醒。

真的是好东西。之前看 Scala 的时候惊叹于它的 表达式 与 函数 之间的模糊边界,而且函数式编程使我从执着于模仿 Java 的编程方式中释放出来,对应该怎么样写代码有了更多新认识。虽然我了解的支持 FP 的首个语言不是 scala,是 JavaScript,只是很少人会把 FP 当成是一种特色,一种解决问题的方式。

学会了语法,了解了库,学会了设计模式,是能够让我开始编写代码解决问题了,但是不需要很长时间,就会发现“砖头”(构成代码的单元)不够用了。也就是自造砖头会成为一种常态,而怎么自制出跟你已经用惯了的那些基础砖头一样好用的砖头就成为一个问题——如何更好地表达问题,更好地抽象。而这个问题解决不好,它会以各种各样形式表现出来,我觉得是使我经常郁闷的重要来源。而且代码不仅仅是给自己用的,通常是一个开发小组里使用,它就成了像流行性感冒一样的不治之症,不时发作。在被各种头疼弄死之前,我觉得我还可以再抢救一下。

不是说 Lisp 本身多么的强大,也不是想要比较各种语言的强弱,程序猿要的不就是能够用好来表达自己解决问题的方式的语言么。其实我也说不准什么时候才会实战 Lisp ,更何况现在正受到 Nodejs 的感染……
但这个开始,给了我信心,带来了更多可能性。

传送门:
Lisp 之根源 (中文的,还有惊喜)
ANSI Common Lisp (第一、二章,也有中文的)

函数抽象

JavaScript 里 Array 非常常用。还记得当初是因为直接字符串拼接效率好差,但是用 […].join(”) 却神奇地快而使我印象深刻。

在 JavaScript 1.6 里还引入了一些新的方法,虽然有些看上去好像没什么特别,甚至会使人疑惑为什么需要多这么个方法。我很好奇这是基于什么设计出来的。

忘记了是从哪里看来的,说一些方法是为了可以支持函数式编程而引入的。比如 forEach, filter, every, map, reduce

实际使用过后,还真是尝到甜头了。最直接的感觉就是,代码变短了(不是字符数,而是独立的语法单位数量)。比如 every

如果没有它,你需要写这些代码

var arr = [15, 20, 30];
var isbigger = true;
for (var i = 0; i < arr.length; i++) {
    if (!(arr[i] > 10))  {
        isbigger = false;
        break;
    }
}
isbigger === true

有了它,你可以这样写

var arr = [15, 20, 30];
arr.every(function(it) {
    return it > 10;
}) === true;

少定义了一个变量 isbigger, 没有了 for 循环,自然也不需要考虑什么时候 break 了。需要做的判断可以非常清晰地用 it > 10 表达出来。真是简单明快。

或许想要表达的就是这种抽象方式,将某种特定过程抽象成一个 every,使用者可以只关心所需要的逻辑。而这个逻辑是用一个函数来表示的,作为参数传入到 every 当中去。由于 JavaScript 支持函数作为参数,使得使用函数来抽象非常的方便,不需要额外构建一些模式来进行胶连。如果从这个角度看,的确很符合函数式编程的模式。

再看看 every 的实现,和第一段代码的主体是非常的相像的。

/**
 * Copyright (c) Mozilla Foundation http://www.mozilla.org/
 * This code is available under the terms of the MIT License
 */
if (!Array.prototype.every) {
    Array.prototype.every = function(fun /*, thisp*/) {
        var len = this.length >>> 0;
        if (typeof fun != "function") {
            throw new TypeError();
        }

        var thisp = arguments[1];
        for (var i = 0; i < len; i++) {
            if (i in this && !fun.call(thisp, this[i], i, this)) {
                return false;
            }
        }

        return true;
    };
}

就这样一个独立功能的简单函数就可以实现关注点的分离。而且,分离之后,各自都可以很好地测试,关注点的单一,使得测试更加容易进行。功能变得简单(专注)了,少打了许多字,代码更加清晰易懂,出错的几率也相应地减少。出错少了,你会感觉是自己变聪明了(Ruby 创始人在一次演讲中说到的一个很有趣的观点)。

同样的原理,我觉得是可以很方便地应用到自己编写的代码当中去,仔细分析代码,分离不同的关注点,是实现自下而上的编程方式的重要一环。

也许看上去很简单,但是我觉得这种抽象方式作为一个很好的基础,可以帮助我们设计出更好的代码。

“cd -” 回到过去

在 linux,想 cd 到别的目录,运行个(比如) git pull,接着要回到原先的目录中去继续,是很常见的行为。
以前为了方便开两个 shell。但是毕竟是常用行为,我猜是会有捷径的。于是

man cd

Oops, ubuntu 里居然没有 cd 的 man page 的。
不过很快强大的 google 就知道下面这个正好就是干这事的。

cd -

这个看上去很怪的命令,因为 “-” 通常后面跟参数的,它实际上等于

cd "$OLDPWD" && pwd

从原理上看,它就只会回到 cd 之前所在的目录(我原先猜想会是个堆栈式的实现),于是不停的执行 “cd -” 就可以不停的来回切换于两个目录之间了。

真是简单而高效,我很喜欢。

没计划 != 不靠谱

最近在读 《黑客与画家》,里面写到了一个我一直以来都很困惑的地方,我们现在开发是没有所谓的长远计划的。一直以来所说的计划不过是一周,最长不超过两周的。正如他所说的,这事是不好随便公开的,因为几乎所有人都不理解,为此还不得不装出一个很有计划的样子。事实上,都不是这么回事。我觉得我们可能被传统的软件工程理论或者一些未经证实的推测给误导了。我觉得有必然在这个问题上重新思考,好好利用好这种短的开发周期,计划是另外一回事,是用来衔接的。

如果因缺乏详细计划而不能动手去做,那么什么时候才能得到这个详细的计划呢?

必须要对整体有全面的把握,然后才能做得好?

事实上,现在面临的对于我们来说都是全新的东西,基本上很难光靠脑海中的构想就能够把整体完全想通,即使能建立整体,但其中涉及到太多既可以这样又可以那样的细节做法,如果不把东西弄出来体验一番,是很难确定最终的模样。有时候过于纠缠一些搭建基础系统,现在看来基本都是鬼话,变动起来最痛苦的就是那些地方。如果想让产品更快一点与观众见面,就必须立刻就将想法实现出来。现实的感觉是,动手做了之后,计划才开始丰满起来。

改动不可怕,可怕在于长时间不去动它。

No.22 很冷

听说要下三天雪,还果真下了三天,天气预报也不是完全不靠谱的

有叶子的时候看着就是一堆,光了之后太细,加点雪,对比就出来了

人们在大树的庇护下行走,我也是其中一分子。这时候比较安心的是,如果有什么东西落头上了,可以猜想是积雪,而不是鸟粪 继续阅读“No.22 很冷”

No.21 冷

今年好像特别冷。

下雪前一天早上起来一看,发现玻璃都变成磨砂的了 ^..^

雪下了一天,依然未停,拉开窗帘,是这个样子的

因为下雪,大家裹得更加严实了,一路上,最忙碌的是情理积雪的人们,最快乐的是随便哪里都有雪玩的小孩子。
我,踏雪而行,在观赏这个似乎从来没见过的全新世界,做着不好意思说出来的事情……

于是,迟到了……