By Linus Torvalds:
On Wed, 5 Sep 2007, Dmitry Kakurin wrote:
>
> When I first looked at Git source code two things struck me as odd:
>1. Pure C as opposed to C++. No idea why. Please don't talk about portability,
>it's BS.
*YOU* are full of bullshit.
C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it, to the point where it's much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out, that in itself would be a huge reason to use C.
In other words: the choice of C is the only sane choice. I know Miles Bader jokingly said "to piss you off", but it's actually true. I've come to the conclusion that any programmer that would prefer the project to be in C++ over C is likely a programmer that I really *would* prefer to piss off, so that he doesn't come and screw up any project I'm involved with.
C++ leads to really really bad design choices. You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap, that may "help" you program, but causes:
- infinite amounts of pain when they don't work (and anybody who tells me that STL and especially Boost are stable and portable is just so full of BS that it's not even funny)
- inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app.
In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C. And limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that do actually understand low-level issues and don't screw things up with any idiotic "object model" crap.
So I'm sorry, but for something like git, where efficiency was a primary objective, the "advantages" of C++ is just a huge mistake. The fact that we also piss off people who cannot see that is just a big additional
advantage.
If you want a VCS that is written in C++, go play with Monotone. Really. They use a "real database". They use "nice object-oriented libraries". They use "nice C++ abstractions". And quite frankly, as a result of all these design decisions that sound so appealing to some CS people, the end result is a horrible and unmaintainable mess.
But I'm sure you'd like it more than git.
Linus
=====
Heath Provost (galvanash@hotmail.com) on 6/5/10 wrote:
>
>As for C++ exceptions - the same thing really applies here.
>They are trying to write explicit code. Exceptions are the
>poster child for implicit magic...
Yes, exceptions is a good example. The Linux kernel actually does its own exception mechanism, exactly because that way we control what is going on (and do it much more targeted to the actual need in question while giving much better performance and avoiding the crazy unwinding issues).
And I really do dislike C++. It's a really bad language, in my opinion. It tries to solve all the wrong problems, and does not tackle the right ones. The things C++ "solves" are trivial things, almost purely syntactic extensions to C rather than fixing some true deep problem.
(The C++ objects, templates and function overloading are all just syntactic sugar. And generally bad syntax at that. And C++ actually makes the C type system actively worse.)
In non-systems programming, you should almost certainly use a language that offers garbage collection. That will possibly make a real difference in the complexity of your application. The C++ features? Largely useless, and just helps you screw up more.
And in systems programming, you're simply better off with C. You'll have a way easier time using all the existing code and libraries out there (re-using C++ code? Good luck). Fewer headaches, fewer opportunities to mess up the design and pick some unstable template library.
So in neither case is C++ likely the right choice.
Linus
June 5, 2013
June 4, 2013
excerpt from "effective c++"
Cpp is like some stubborn old man, who always says "i have lots of obscure habits, dealing with it"......
Lesson 4: the initialization is different from assignment, as well as their representations respectively. It is better to write the constructor as the form of initialization, named "initialization list", rather than just simply give the variables first assignment.
To avoid using objects before they're initialized, then, you need to do only three things. First, manually initialize non-member objects of built-in types. Second, use member initialization lists to initialize all parts of an object. Finally, design around the initialization order uncertainty that afflicts non-local static objects defined in separate translation units.
Lesson 7: declare destructors virtual in polymorphic base classes. C++ specifies that when a derived class object is deleted through a pointer to a base class with a non-virtual destructor, results are undefined. What typically happens at runtime is that the derived part of the object is never destroyed. Eliminating the problem is simple: give the base class a virtual destructor. Then deleting a derived class object will do exactly what you want. It will destroy the entire object, including all its derived class parts.
The purpose of virtual functions is to allow customization of derived class implementations. Any class with virtual functions should almost certainly have a virtual destructor. The implementation of virtual functions requires that objects carry information that can be used at runtime to determine which virtual functions should be invoked on the object. On the other hand, if a class does not contain virtual functions, that often indicates it is not meant to be used as a base class. When a class is not intended to be a base class, making the destructor virtual is usually a bad idea.
Lesson 9: Never call virtual functions during construction or destruction. Because during base class construction of a derived class object, the type of the object is that of the base class. Not only do virtual functions resolve to the base class, but the parts of the language using runtime type information (e.g., dynamic_cast (see Item 27) and typeid) treat the object as a base class type.
The same reasoning applies during destruction. Once a derived class destructor has run, the object's derived class data members assume undefined values, so C++ treats them as if they no longer exist. Upon entry to the base class destructor, the object becomes a base class object, and all parts of C++ treat it that way.
Since you can't use virtual functions to call down from base classes during construction, you can compensate by having derived classes pass necessary construction information up to base class constructors instead.
February 19, 2013
Set up Racket for Vim and mac Terminal
Racket is fairly great:), though the setting up procedure is kind of twisted. There is a .dmg installation file in the official website, which makes it quite straightforward to install in the Application folder. And, of course, the DrRacket app is awesome when I accidentally put mouse in one of the variables in the code, and then all its dependencies reveal via arrows.
But I am still used to writing code in vim and testing it in a parallel split window of iterm. I googled the solution, but cannot find a comprehensive one. So, I just list my solution here, which come from either stackoverflow or other persons' blogs.
1) vim syntax and highlight are out there ready for use.
2) Adding one command line to ~/.vimrc
au BufRead,BufNewFile *.rkt set filetype=racket3) Adding the path of executable racket to ~/.bach_profile.
export PATH=$PATH:/Applications/Racket\ v5.3.3/bin/4) If using the existing file, one should delete the first line of code "#lang racket" if existed.
5) Optional. Installing rlwrap to make the repl more user friendly.
That is much of it.
cheers,
February 14, 2013
1st update in 2013
The issue came from my question in stackoverflow. Basically, it was a misplaced question, because the reason why my program would hit the "RuntimeError: maximum recursion depth exceeded" was that I just passed the sorted array by the first scenario to the second scenario. This caused the second one hit the "worse case" and exceed the "maximum recursion depth". Well... it was embarrassing to admit that I forgot dereferencing the variable...
But, anyway, the question concerning recursion in Python has been in my head for a while, even since I started learning Scheme. This time, the kind answer below my question shed lights on how to solve this kind of problem. Then I dug a little deeper and find more about tail recursion in Python.
The following is an example with problematic way to implement a recursion function:
def fac(n):
return 1 if n < 2 else n * fac(n - 1)
> fac(3000)
> RuntimeError: maximum recursion depth exceeded
The right way to do this is to make a local helper function "tail recursive" with the help from anonymous function.
def fac(n):
def f(n, acc):
return acc if n < 2 else lambda: f(n - 1, acc * n)
t = f(n, 1)
while callable(t):
t = t()
return t
And an even elegant way is to use built-in function "reduce":
def fac3(n):
return reduce(lambda x,y:x*y, xrange(1,n))
The latter two could deal with any input number. Tada~A little extended reading about this topic:
Origins of Python's "Functional" Features
Tail Recursion Elimination
Tail Recursion Elimination in Python
Besides, studying Standard ML does give me much much more insights into both programming itself and programming in Python. Except the attractive tail recursion, Python has quite a few amazing features of functional programming. In retrospect, now I appreciate more about what was listed in the "progression path", and of course, cannot wait to progress to Haskell.
cheers,
October 4, 2012
Install opencv in mac osx
The most straightforward way is via homebrew.
Then, all of the dependencies will be install with opencv. The reason to use "sodu" is because there will be twice "brew link" used in the process which could not link certain libraries without permission.
Finally, the brew gave a wrong file to update. Instead of updating .profile, the correct destination should be .bash_profile. Add this line:
That is it.
cheers,
brew update
sudo brew install opencvThen, all of the dependencies will be install with opencv. The reason to use "sodu" is because there will be twice "brew link" used in the process which could not link certain libraries without permission.
Finally, the brew gave a wrong file to update. Instead of updating .profile, the correct destination should be .bash_profile. Add this line:
export PYTHONPATH=/usr/local/lib/python2.7/site-packages/:$PYTHONPATH<\code>That is it.
cheers,
September 17, 2012
missing you
小葛儿转眼安排好纽约面试就登飞机了。因为GPS的缘故,在机场周围转了好几圈,结果弄的再见都匆匆忙忙。送完她回到寝室——是的,没有了她,这里还是叫寝室合适——空荡荡的,安安静静。一分钟都不想多停留,背着书包就去了实验室。
晚上也不想回去,因为想到又是空空的房间就不自在。
一个人在这里。忽然一下安静了。多出了好多时间来想你,似乎一切记忆瞬间无比清晰,触手可及。你的肩膀软软的,抱在怀里的时候,还要告诉自己小心别把你弄疼了。你哭的时候,撅着嘴,鼻子里些许呜哝呜哝的声音,眼泪扑簌扑簌就落下来了。你笑的时候,眼睛眉毛嘴角都弯弯的,咯咯咯的,清脆悦耳。每到这个样的时候,我都在反问自己,为什么要和你吵架啊,有什么气好生呢。
可无论怎么吵架,我都还是爱你的,比每一次吵架前还要爱你,比每一次生气之前还要更想和你在一起。有时候会想,也许我太把你说的每句话当回事儿了,才会又好多的弄巧成拙。但翻回头来,我仍就欠你好多在一起的时光。
小葛儿啊。你的一举一动,一颦一笑,我都记在心里呢。欠你的那些时光,我也一定要都好好还你。快回来吧。有你在的地方,我就认为是家了。
我想你。
September 14, 2012
My August and a new beginning
八月份,是个开始的月份,来到了一个小屯子里,没有公交,没有市集,只是明晃晃的阳光,会照的人发晕。当真是个修行的地方。有关这里,想法都有关不要虚度光阴,要快些离开这里。
月中,和大瀾、乌龟、聪哥、温总一起去了黄石,西雅图,以及波特兰。这次旅行,如同酿酒发酵一般,越到后来越是留恋。
刚到Bozman的时候,大瀾看着大山都激动的手舞足蹈。然后进入黄石以后,各种臭泉以及异常干燥的气候弄的大家都越发烦躁起来。大瀾背着手,像居委会大妈一样视察颜色异常的泉水;也会二劲儿大发,摘下花来给每个人带上,拍个大头贴。大乌龟在走trail时候,被路上唯一的一个钉子扎破了后背。甩着舌头奔跑的牦牛,成群在树林里休息的大鹿,elk or moose。在大峡谷的晚上,八月间,大家竟然都被冻醒了,我迷迷糊糊间,看着大瀾给我盖被子,感动了好久。
三日后的大提顿满是惊喜。前一天晚上大瀾肚子疼的没吃好晚饭,扶她回房间后,我连吃饭的心思都没有了,更不要说后一天的提顿之旅。第二天早晨,大家也是有懒床的,有睡回笼觉的。只有唯一想去的温总,一肚子郁闷说不出口。而且刚启程,就发现没带门票,又折回。我开着车都能想到留守的聪哥似笑非笑的的得意样子。最终正午才进入大提顿,就遇见了满眼惊喜。厚厚的草甸,飘满小花的湖泊。大瀾拄着两人多长的树枝照相。在Jackson Lake租船的时候,旁边的小孩儿们兴奋的举着水瓶,炫耀捉住的水蛭。大瀾在船上,看不出任何身体异样,兴奋的拍水,尝试各种怪异的划船方法,几次都殃及到了坐在后面的我。但不管怎样,我俩划起船来,左右开工,还喊着号子,小船乘风破浪的指那儿打哪儿,相比而言,乌龟和温总的另一艘船大多就是在原地打转了。上岸之后,我们还在岸边的饭馆儿吃了进黄石以来最丰盛的一顿饭。在Jenny Lake,看着一湖清水,我和温总都脱到只剩内裤,跳进去玩水,结果上岸时候悲剧了,小石子们就像是锥子一样,走向岸边每一步都钻心的疼。。。大瀾在岸边,一边叹息着想游泳啊想游泳,一边带着乌龟和温总的俩单反,不断练习摄影技术。傍晚看日落,所有的山峰都一览无余,感慨自然壮丽。然后在把车开到山间处,再看一遍日落,再感慨一遍。晚上回程,看到了过马路的小狐狸,也许是被车灯照迷糊了,久久不离去,真想把它抱回来养。
晚上回到酒店,又出门,和大瀾并排躺在码头上,我第一次清楚看到了银河,像棉絮一样一团一团的,还看到了流星。拉着大瀾的手,看着奇妙的景色,时间就静止了。
到西雅图的第一天晚上,还有更多的惊喜。从倾斜的街道看到大海,身旁小酒馆门庭若市。城市真好。也是在这个时候,我们发现Yelp的预算对我们不适用。$的我们可以吃成$$$,$$的我们能吃成$$$$的。几个难民坐在日式料理最靠窗的桌子,烤肉、寿司、炒饭、拌面...,我们狼吞虎咽的样子,就是这家店最好的活体广告了。酒馆、小肥羊、牛逼的图书馆、大麻公园、面海公寓、满是鲜花的阳台,这就是我对西雅图的印象。
去波特兰是因为Grimm。精致的block,友好的大瀾校友,以及玫瑰花园。我们在市区停留只有半日。然后就是一个小时的公车,从二十几街坐到了245街。。作为这座庄园里唯一一队乘坐公车前来的客人,我们受到了主人的热情接待,安排我们住宿在一个墙上画着这个庄园某位109岁员工的房间里。庄园的晚饭不错,温总一时兴起喝了六七杯或者十来杯红酒,结果把大乌龟给喝醉了,嚷嚷着要脱衣服去游泳,又把聪哥紧张的如同被非礼了一样。。晚饭后我们还视察了庄园的绿化状况,并亲切会见了酒馆里的各种奇怪大叔大妈。
转眼相聚就要分离,回家的回家,旅行的继续上路,确实舍不得另外三位。昨天在豆瓣上读到马克吐温的一句话,“好友、好书,不轻易判断是非,这就是理想生活”。一路上颠簸,没读什么书,这生活却以足以让我留恋了。
在这里,开始学习工作快满一月了。老板人不错,几次问他有关研究的问题,他都很耐心的回答,给的方法也足够有操作性。今天一个师兄作报告被骂,也从另一个侧面证明老板足够聪明,不能唬弄。组里大家关系也很融洽,实验室、图书馆,资源也算充裕。新车也用的顺手。还是开始时的那个想法,不要浪费时间,早些离开这里。
Subscribe to:
Posts (Atom)
