访谈嘉宾:

(Adit自画像)

Adit Bhargava, 软件工程师,兼具计算机科学和美术方面的教育背景,在adit.io撰写编程方面的博客。

因为爱好,Adit踏入了编程殿堂。Visual Basic 6 for Dummies教会了他很多基础知识,但始终对算法没搞明白。直到遇到一位优秀的算法教授后,他才认识到这些概念是多么地简单且优雅。

几年前,他开始在adit.io上撰写图解式博文,介绍函数式编程、Git、机器学习和并发。图解式写作风趣幽默、化繁为简、清晰明确,受到大量读者的喜爱。


我们主要聊了些:

  • 为什么要写这样一本萌萌的算法入门书
  • 封面插画背后的故事
  • Adit神秘的算法导师
  • Adit最喜欢的算法
  • 评判算法的重要指标
  • 编程学习低龄化

Chinese Version

Why would you like to write such an introductory book, which is full of fascinating scenarios and cute illustrations drawn by hand?

I usually take notes for myself when I learn something, because it helps me learn. For example here are the notes I'm taking as I read "A Book Of Abstract Algebra" (attached). So this was a technique I had used in the past, and I thought others might find it useful also. So I wrote this blog post. People liked it and it made me think that a book with the same style would probably do pretty well too.

(Let's enjoy Adit's explanation of Monad in pictures!)

学习 Monad的渠道:

  • 取得计算机科学专业的博士学位。
  • 压根儿不学。这里根本用不到那些条条框框!

Functor 将一个普通函数应用到被封装的值上:

enter image description here

Applicative 将一个封装的函数应用到封装的值上:

enter image description here

Monad 将一个 “接受普通值并回传一个被封装值” 的函数应用到一个被封装的值上,这一任务由函数 >>=(读作 bind)完成。听起来似乎很拗口,让我们来看个例子吧,还是熟悉的 Maybe

enter image description here

假设 half 是只对偶数感兴趣的函数:

half x = if even x
     then Just (x `div` 2)
     else Nothing

enter image description here

如果扔给 half 一个封装的值会怎样?

enter image description here

这时,我们需要用 >>= 把被封装的值挤到 half中。猜猜>>= 的照片:

enter image description here

再看看它的效果:

> Just 3 >>= half
Nothing
> Just 4 >>= half
Just 2
> Nothing >>= half
Nothing

这其中究竟发生了什么?Monad 是另一种类型类,这是它定义的一部分:

class Monad m where
    (>>=) :: m a -> (a -> m b) -> m b

下图展示了 >>= 各个参数的意义:

enter image description here

下面的定义让 Maybe 成了 Monad:

instance Monad Maybe where
    Nothing >>= func = Nothing
    Just val >>= func  = func val

来看看执行 Just 3 时发生了什么:

enter image description here

如果传入 Nothing 就更容易了:

enter image description here

你还可以把这些调用过程连起来,比如执行 Just 20 >>= half >>= half >>= half 会得到 Nothing

enter image description here

enter image description here

太棒啦!

(Taken from Adit's articleFunctors, Applicatives, And Monads In Pictures

From the book cover, I thought it might be full of hand-drawn illustrations about mice. It seems not, for there’re other images like sheep, birds, rabbits, diagrams. Why would you put that picture in front of the book?

I wish I had a good answer for you! The people at Manning chose the picture on the cover. Manning was generally good about giving me a lot of control over the book, but for the cover, they really fell in love with this image and chose to use it.

A whole bunch of readers are really curious about your algorithmic teacher mentioned in author's introduction part who made tough concepts become simple but elegant. Could you share some of his/her teaching methods?

Sure! Her most effective teaching method was stepping through an algorithm line by line. When something is hard, it is easier skip over it. But in order to learn, it is important to slow down at the hard parts. So for each algorithm she taught, she would slow down and go through the code line by line and explain what each line did. I tried to do the same thing in my book. In the section on recursion, for example, I walk through each line and show how the stack changes. I think having that level of detail is really important.

What's your favorite algorithm? Why does it give you such a deep impression?

I've mentioned how much I love graph algorithms a few times in the book. Graphs are a really amazing structure that show up absolutely everywhere. I feel like I'm able to solve so many problems just using graph algorithms. I recently went to lunch with a friend and someone at the lunch said "I bet I can teach you Category Theory in 15 minutes". I didn't know anything about Category Theory, but I knew graphs and abstract algebra, so it actually took him less than five minutes to explain Category Theory to me. At work, I've been able to automate some tedious tasks, all because I know how topological sort and breadth-first search work.

Sometimes, short operational time does not necessarily mean good performances. Except time, are there any other dimensions to judge algorithm?

Yes! I think ease of use is a pretty important metric. For example, there are plenty of machine learning techniques more advanced than KNN, but if you are just starting out with a problem, you might want to start with KNN even if you are a machine learning expert. If an algorithm is easy to think about, there are fewer places for bugs to hide. Once you start getting into more complicated algorithms like neural networks, if you run into a bug, it will take more time to figure out the cause because there are so many more moving parts, so more places for the bug to hide. When picking an algorithm and considering performance time, it is important to think about the performance of the programmer also! Easy to understand code is more maintainable and more likely to be bug-free.

There are actually a few teenagers who are reading your book. What do you think of learning algorithm from very early ages, like primary school ages or even earlier?

I think that makes a lot of sense. Programming is a way to be creative, just like painting or music. I learned programming pretty early and made video games and animations. The earlier you learn, the sooner you can work on your own projects!

Will you keep this up with a "Grokking" series covering other CS/Dev topics? Because we all love it.

I hope so! I need to think hard about what else I can write about :)


——See More


更多精彩,加入图灵访谈微信!