字幕列表 影片播放
Alright, welcome to category theory lectures
好的,歡迎收看範疇論的課程
So, are we all programmers here?
所以,在座的都是工程師嗎?
Is everyone a programmer, or are there people who are not programmers?
大家都是工程師,或者這邊有誰不是工程師嗎?
If you're not a programmer, please raise your hand
如果你不是工程師,請舉起手
Okay, thats means, like, you don't write any programs? > I kind of learn as a hobby
好的,這代表你並不寫程式? > 我只是為了興趣
Okay well that's good enough
好的,這樣夠好了
okay and how many people here have some little bit of knowledge of Haskell, okay
好的,這邊有多少人有些Haskell的經驗 好的,哇
Oh Lots, that's, that's, excellent because I might be giving some examples mostly
噢很多,這真的、真的很棒,因為大多數時候我可能會提供這方面例子
just like you know, declarations, functions or something like that
就像你知道的,宣告、函數之類的
I'll explain everything but it's it's good to have a little bit of
我會解釋一切,不過如果能有些
understanding. So I'm not really teaching a programming language, it will be about
概念是好的。所以我不真的會教一個程式語言,這會是關於
category theory and category theory is like this most abstract, or well maybe
範疇論。範疇論是最抽象的,或
almost the most abstract part of mathematics, right
可能幾乎是數學最抽象的部份
so the question is why are we here?
所以問題是,我們為什麼在這裡?
what does it have to do with programming, right?
是啊,這和寫程式有什麼關係呢?
and a lot of programmers they hate math
而且很多程式設計師討厭數學
they finished learning math at college and now they
他們在大學修習完數學然後現在他們
are really happy now "for the rest of my life I will not have to touch it"
非常開心。「在我的下半生不需要再碰它了」
"I hate math" and so on, and you guys here come for, I dunno, punishment?
「我討厭數學」之類的,然後你們為了,難道是,被懲罰而來?
Why do you think category theory might be important?
為什麼你們會覺得範疇論可能很重要?
What do you think, do we do functional programming?
你們怎麼想的,大家用函數式編程嗎?
Is category theory only relevant to functional programming or other branches
範疇論是只和函數式編程相關 還是也可能有助於
of programming would maybe profit from it too?
其它寫程式的方式?
is there something more to offer?
它能提供更多嗎?
Have you heard of functors, who's heard of functors?
你們聽過函子嗎,誰聽過函子?
yeah, and who knows what functors are?
好,那誰知道函子是什麼?
Uh huh, a few. That's good, that means i can actually explain stuff and you won't be totally
啊哈,有一些。 這很好,這代表我可以真的解釋些概念而你不會完全在
repeating what you already know
重複你已經會的
so I came to category theory through a long long twisted road
我沿著一條崎嶇小徑來到範疇論的世界
ok when I started programming I started programming in assembly language
我從組合語言開始學習程式
the lowest possible level, right, where you actually tell the computer exactly what to do
你在可能的最低階層詳盡的告訴電腦要做什麼
right down to "grab this thing from memory, put it into the register, use it as an
例如「從記憶體拿取這個東西,把它放進暫存器,把它當成
"address and then jump" and so on so this is very precisely telling the computer
位址然後跳轉」之類的。我非常精確地告訴電腦
what to do right this is this is a very imperative way of programming we start
要怎樣做,嗯。這是非常命令式的編程。我們
with this most imperative approach to programming and then sort of we drag
從最命令式的編程方法開始然後我們持續
this this approach to programming throughout our lives right and like we
一直這麼做,直到
have to unlearn at some point. And this approach to programming sort of in
某刻我們必須假裝忘記它。計算機科學中這樣的編程方式
computer science is related to Turing machines. A Turing machine is this kind of
和圖靈機有關。圖靈機是種
very primitive machine, it just stamps stuff on a paper tape, right
非常基本的機器,它只在一個紙帶上打印,是吧。
there is no high-level programming there it's just like this is
沒有高階編程,這就像是
the assembly language "read this number, put it back on tape, erase something from
組合語言: 「讀取這個數字,存回磁帶上,消除
the tape" and so on so this is this one approach towards programming
某些磁帶上的東西」等等。這是一種寫程式的方式
by the way, all these approaches to programming were invented before there were even
順帶一提,這些編程方式甚至在電腦出現之前就被發明了
computers, right and then there's the other approach to programming this came
然後有另一種編程方式,來自於
from mathematics the lambda calculus right, Alonzo Church and these guys
數學,即lambda演算,阿隆佐·邱奇和那些人
and that was like "what is possible to compute, right,
問「什麼是可計算的?」
"thinking about mathematics in terms of
「以東西會怎麼樣被實際被執行,變換,來
"how things can be actually executed in some way, transforming things", right
思考數學。」嗯
so these approaches to programming are not very practical
所以這些程式設計的技巧不是非常的實際
although people write programs in assembly language and it's possible but
雖然人們用組合語言寫程式而這是可行的但
they don't really scale, so this is why we came out with languages that offer higher levels of abstraction,
它們並不真正 是可擴展的,這是為什麼我們發明了提供更高層級抽象的語言
and so the next level abstraction was procedural programming
然後下個層級的抽象是程序式編程
what's characteristic of procedural programming is that you divide a big
程序式編程的特徵是你把一個大問題
problem into procedures and each procedure has its name, has a
分割程很多程序且每個程序都有名字、有
certain number of arguments
一定數量的參數
maybe it returns a value sometimes right
或者它可能傳回一個值,恩
not necessarily, maybe it's just for side effects and so on, but because you
也不一定,它可能只為了副作用之類的,但因為你
chop up your work into smaller pieces and you can like deal with bigger
把你的工作分成小片段 你可以處理更大的
problems right so this this kind of abstracting of things really helped in
問題。這樣的抽象對寫程式真的有幫助
in programming, right and then next people came up with this
然後接下來大家發現
idea of object-oriented programming right and that's even more abstract now you
物件導向這樣的點子。這甚至更抽象
have stuff that you are hiding inside objects and then you can compose these
現在你在物件內藏東西然後可以組合這些
objects right and once you program an object you don't have to look
物件對吧 然後一旦你寫了個物件你不必去探討物件
inside the object you can forget about the implementation right and and and
的內部 你可以忘了物件的實作然後
just look at the surface of the object which is the interface and then you can
只觀察物件的表面,介面 然後你可以
combine these objects without looking inside and you know you have the bigger picture
在不探討物件的內部下組合它們 然後你曉得你對整個程式有更深入了解了
and then you combine them into bigger objects and so you can see that there is
然後你再把它們組成更大的物件。所以你可以看到這裡有
a a certain idea there, right? and so it's a very important idea that if you
有個特定的點子,是吧?這是個非常重要的點子,如果你
want to deal with more complex problems you have to be able to
想處理更大的問題,你必須能
chop the bigger problem into smaller problems, right,
把大問題分割成更小的問題
solve them separately and then combine the solutions together
分別解決後把這些解組合起來
And there is a name for this, this is called composability, right.
這樣的行為有個詞:「可組合性」
So composability is something that really helps us in programming.
可組合性是一個大大地幫助我們寫程式的概念
What else helps us in programming? Abstraction, "abstraction" that comes from
還有什麼也是可以幫助我們寫程式的? 「抽象」。抽象這個詞來自
from a Greek word that means more or less the same as "subtraction", right which
一個或多或少代表「減法」的希臘文字
means "getting rid of details". If you want to hide details, you don't want them or you wanna say
意即「擺脫細節」。如果你想隱藏細節,你不想要它們或者你想說
"these things, they differ in some small details but for me they are the same"
「這些東西,它們在小細節上不同,但對我來說是他們一樣的」
"I don't care about the details" so, an object is in object-oriented programming
「我不在意細節」。所以,在物件導向中物件是
is something that hides the details, abstracts over some details right, and there are even these
用於隱藏細節、抽象於某些細節,甚至有這些
abstract data types that just expose the interface and you're not supposed to
只暴露介面的抽象資料型態而你不應該
know how they are implemented right?
知道它們是怎麼被實作的是吧
so when I first learned object-oriented programming I thought "this is like the best thing since sliced bread"
所以當我初次接觸到物件導向的時候覺得「這是開天闢地以來最棒的東西」
and I was a big proponent of object-oriented programming and together with this idea
然後我那時是個物件導向的擁護者,伴隨著
of abstracting things and and and composing things comes the idea of
抽象這樣點子和、和、和組合東西的是
reusabillity right so if i have these blocks that I have chopped up and
可重複使用性所以如果我有切割好的模塊
implemented, right, maybe I can rearrange them in different ways so once I
而且已被實作,或許我能用不同的方式排列它們
implemented something maybe I will use it in another problem to solve
一旦我實作了某個東西我以後可能會在不同的問題上用他
another problem I will have these building blocks, I will have lots of building
來解決那個問題。我會有這些模塊,我會有很多
blocks that hide their complexity and I will just juggle them and put them
隱藏複雜性的模塊然後我會把它們
in new constellations, right? so it seemed to me like this is really the promise of
揉合成不同形貌,對吧。所以當時我看來這真的是
object-oriented programming, I'm buying it! and I started programming object-oriented way
物件導向達到的承諾,我服了這套!我開始用 C++ 以物件導向的方式寫程式
using C++ and I became pretty good at C++ I think, you know, I wrote a lot of C++ code
然後我的 C++ 變得很強,我想。你知道的,我寫了很多 C++
and well it turns out that there is something wrong with this
但物件導向似乎有些地方不太對勁
object-oriented approach and it became more and more painfully obvious when people started
一旦人們開始撰寫並行和平行的程式,痛苦變得愈來愈明顯
writing concurrent code and parallel code, ok, so concurrency does not mix very well with
好的,所以並行並不能和
object-oriented programming. Why doesn't it? Because objects hide implementation
物件導向相處得很好。為什麼?因為物件導向隱藏了實作
and they hide exactly the wrong thing, which makes them not composable, ok?
而且它們正好隱藏了錯誤的東西,使得他們無法被組合,是吧。
They hide two things that are very important:
它們隱藏了兩件非常重要的事情:
They hide mutation – they mutate some state inside, right? And we don't know about it, they hide it
它們隱藏了改寫──它們改寫了某些內部狀態,對吧?而且我們不知道,它們隱藏了它
They don't say "I'm mutating something".
它們並不說它們改寫了什麼
And sharing these pointers right – they share data and they often share data between
還有分享──它們使用指標對吧,他們分享資料而且經常
each other you know between themselves they share data
在彼此之間分享。你知道的,在它們之間分享資料
And mixing, sharing and mutation has a name
然後分享、改變並混合 有個名字
It's called a data race, ok?
它被稱為資料競奪,好嗎?
So what the objects in object-oriented programming are abstracting over is the data races
所以物件導向中的物件對資料競奪進行抽象
and you are not supposed to abstract over data races
但你不該這麼做
because then when you start combining these objects you get data races for free, right.
因為一旦你開始組合它們,你就會有資料競奪
and it turns out that for some reason we don't like data races, ok?
而且因為某些原因我們不喜歡資料競奪
and so once you realize that you think
一旦你頓悟後你開始想
"okay, I know how to avoid data races, right, I'm going I'm going to use locks
「好,現在我知道怎麼避免資料競奪,我要使用數據鎖」
"and I'm going to hide locks too because I want to abstract over it"
而且我將也要隱藏它們因為我想要抽象於它們
so like in java where every object has its own lock, right?
所以像在Java裡所有物件都有它們自己的數據鎖對吧?
and unfortunately locks don't compose either, right.
不幸的是數據鎖也無法被組合
That's the problem with locks. I'm not going to talk about this too much
這是數據鎖的問題。我不再談更多
because that is like a different course about concurrent programming but I'm
因為這可以開另一堂並行編程的課程
just mentioning it that this kind of raising the levels of abstraction
我只蜻蜓點水:你必須特別注意這類抽象
you have to be careful what you're abstracting over
對什麼進行了抽象
what are the things that you are subtracting, throwing away and not exposing, right?
你減去、扔掉了什麼並不暴露它們?
So the next level of abstraction that came after that, well actually it came before
所以下一階段的抽象是,噢它其實更早出現
that but people realised that, "Hey, maybe we have to dig it out
但人們體會到「嘿,我們可能要重新找到它
"and start using this functional programming" when you abstract things into functions
並開始使用所謂「函數式編程」把東西抽象成函數
and especially in Haskell when, you know,
而且函數,特別是在Haskell裡面,你知道的
in a functional language you don't have mutations so you don't have this problem
在函數式語言裡你不需要可變變數所以你不會有
of hiding data races, and then you also have ways of composing
隱藏資料競奪的問題,然後你也有把
data structures into bigger data structures and that's also because everything is
資料結構組合成更大的資料結構的方法,也因為所有東西都是
immutable so you can safely compose and decompose things.
不可變的所以你可以安全組合和分解資料
Now every time I learned a new language I wanted to find where the boundaries of this language are
每次我學習一個新語言,我都想尋找語言的界線
like, "what are the hardest things to do in this language?", right?
例如,「這個語言最難做到什麼」?
So for instance in C++, right, what are the highest levels of abstraction that you can get?
例如在 C++ 中,你能達到的最高抽象是什麼?
Template metaprogramming, right? So I was really fascinated by template metaprogramming
模板元編程,是吧?我著迷於模板元編程
and I started reading these books about template metaprogramming
我開始閱讀了這些關於模板元編程的書
and was like "Wow, I would have never come up with these ideas, they are so complex", right?
那就像是「哇,我永遠想不出這些點子,他們太複雜了」,是吧?
So it turns out that these are very simple ideas
事實上它們是很單純的點子
it's just that the language is so awkward in expressing them
只是被用一個雞掰的語言表達
So I learned a little bit of Haskell and I said "Ok this huge template that was so complicated,
所以我學了些Haskell然後說「好,這些巨大的模板太複雜了
that's one line of code in Haskell", right? So there are languages in which
那只不過是一行Haskell。」對吧?所以存在某些
there was like a jump in the level of abstraction and made it much easier to
在抽象層級上大躍進的語言,它們讓
program at a higher level of abstraction, right.
你在更高抽象上寫程式簡單得多
And in every language you know there is this group of people who are writing
在每個語言中你都知道有一群人撰寫著
libraries right and they always stretch the language they always go to the highest
程式庫,他們總是延展著可能性
possible abstraction level and they and they hack, right? They hack at it
他們一路向上至最高的抽象層級。他們、他們是「駭客」。對吧?他們駭程式
as much as possible. So I thought "Okay I don't like hacking, I just wanted to
直至極限。所以我想,「好我不想駭程式,我只是想
"use a language that allows me to express myself at a high level of
使用一個讓我能在更高層次抽象上表達自己的語言
"abstraction and that lets me express new ideas that are much more interesting"
而且它讓我表達有趣得多的新點子」
you know, like, with template metaprogramming right you express this
你知道的,像模板元編程能讓你表達
idea that you might have lots of data structures that only differ by the type
一堆只差在它們包裝型別的資料結構這樣的點子
that they hide. Like you can a vector of integers and vector of
像你能有一個整數的列表和
booleans right? And there's just so much code to share, so if you abstract over the
一個布林值的列表對吧?而且它們之間有好多的共通代碼,所以如果你抽象於
data type that you are storing there, if you forget about it,
你儲存的資料型別,如果你忘了它
hide it, abstract over it, you can write code, abstract code, and in
隱藏它、對它進行抽象,你能撰寫代碼、抽象代碼
C++ you do this with templates right. And you get something new, you
在C++裡你用模板進行這樣的事情,對吧。豻且你得到了一些新的東西,你獲得了
program at a higher level – a higher abstraction level because you
在更高層次──更高抽象層次──寫程式的能力因為
disregard some of the details, so that was great.
你忽略了某些細節,而那真的很棒
Now it turns out that once I learned Haskell
再後來,我發現在學了Haskell後
(I'm still learning Haskell to some extent)
(某種程度上我還在學習Haskell)