- Inverse Sapir-Whorf không tập trung vào việc ngôn ngữ khiến ta khó nghĩ về điều gì, mà vào việc nó khiến ta khó không nói ra điều gì và buộc phải bộc lộ loại thông tin nào
- Thì hiện tại của tiếng Anh, đại từ theo giới tính, danh từ giống trong tiếng Pháp, và thì quá khứ mış trong tiếng Thổ Nhĩ Kỳ đều thúc ép người nói phải nói ra những thông tin như tính tạm thời, giới tính, hoặc nguồn gốc/mức độ tin cậy của thông tin
- Trong ngôn ngữ lập trình cũng vậy, nhiều khi chúng buộc lập trình viên phải đưa vào mã những chủ đề mà họ có thể không quan tâm, như thứ tự tính toán, có async hay không, cấp phát và giải phóng bộ nhớ, phạm vi, hay kiểu dữ liệu
async trong Python hoặc Javascript, quản lý bộ nhớ của C, lifetime của Rust, hay chú thích kiểu trong các ngôn ngữ kiểu tĩnh đều buộc phải làm rõ lựa chọn; trong khi Haskell với ngữ nghĩa không nghiêm ngặt và phân tích strictness có thể giao một phần lựa chọn đó cho ngôn ngữ
- Những ngôn ngữ lập trình dễ tiếp cận hơn có thể có rào cản Inverse Sapir-Whorf thấp hơn, tức là ít ép buộc người dùng phải nói về những chủ đề mà họ chưa hiểu rõ hoặc chưa có quan điểm
Inverse Sapir-Whorf có nghĩa là gì
- Giả thuyết Sapir-Whorf, nếu đơn giản hóa, là ý tưởng cho rằng ngôn ngữ ta dùng ảnh hưởng đến tư duy
- Dạng mạnh của Sapir-Whorf, đặc biệt là thuyết quyết định luận ngôn ngữ cho rằng ngôn ngữ kiểm soát tư duy hoặc cần một ngôn ngữ cụ thể mới có thể nghĩ được điều gì đó, ngày nay không còn được giới ngôn ngữ học nhìn nhận nghiêm túc một cách rộng rãi
- Việc một ngôn ngữ không có thì ngữ pháp không dẫn tới kết luận rằng người nói nó suy nghĩ hạn chế hơn về thời gian; luôn có những cách khác để biểu đạt thời gian
- Có khá nhiều bằng chứng rằng lời nói hằng ngày có thể ảnh hưởng đến nhận thức, kỹ năng và thái độ trong một số lĩnh vực, nhưng thường rất khó chứng minh những tác động trực tiếp lớn
- Inverse Sapir-Whorf không hỏi ngôn ngữ khiến điều gì khó nói hay khó nghĩ, mà hỏi điều gì trở nên khó không nói ra
- Theo góc nhìn này, cốt lõi là ngôn ngữ có thúc ép ta phải nói ra loại thông tin nào, hoặc khiến một số suy nghĩ trở nên khó tránh né hay không
Sự cưỡng ép bộc lộ trong ngôn ngữ tự nhiên
-
Tính tạm thời và lâu dài trong thì hiện tại tiếng Anh
- “I’m living in London” và “I live in London” đều có nghĩa là sống ở London, nhưng câu đầu bộc lộ thông tin rằng trạng thái đó là tạm thời
- Người không phải bản ngữ có thể không nhận ra khác biệt này, và ngay cả người bản ngữ cũng có thể chỉ tiếp nhận nó một cách vô thức
- Ý nghĩa “tạm thời” này đôi khi còn liên quan nhiều hơn đến việc người nói thích London đến mức nào, hơn là thời gian cư trú thực tế
- Trong tiếng Anh phải chọn thì, và vì thường chọn một cách vô thức nên ngôn ngữ đã khiến ta bộc lộ những thông tin như thời gian cư trú hay cảm xúc
-
Đại từ và danh từ theo giới tính trong tiếng Anh, tiếng Thổ Nhĩ Kỳ và tiếng Pháp
- Trong lời nói hằng ngày bằng tiếng Anh, khi chỉ một người cụ thể thì thường phải dùng “he” hoặc “she”
- “singular they” có tồn tại, nhưng khi nói về một người cụ thể mà ta biết hoặc đoán được giới tính thì nó vẫn không thật tự nhiên
- Tiếng Thổ Nhĩ Kỳ dùng một từ “o” cho he/she/it, và việc thiếu đại từ theo giới tính như vậy không ngăn con người nghĩ hay nói về giới tính của ai đó
- Ở điểm này khó mà dùng nó để ủng hộ Sapir-Whorf theo nghĩa thông thường, nhưng Inverse Sapir-Whorf lại rất rõ: đại từ tiếng Anh thúc ép ta phải nói ra giới tính dù muốn hay không
- Ngay cả khi muốn nói ẩn danh về một người quen, chỉ cần vô tình dùng “him” hay “her” là giới tính có thể lộ ra và khiến việc nhận diện dễ hơn
- Trong tiếng Pháp, danh từ có giống, nên khi dịch “my friend” phải chọn giữa “mon ami” và “mon amie”, hoặc “mon copain” và “ma copine”, từ đó làm lộ thêm thông tin
- Đại từ sở hữu trong cả tiếng Anh và tiếng Pháp đều có giới tính hóa, nhưng his/her trong tiếng Anh chỉ giới tính của người sở hữu, còn son/sa trong tiếng Pháp chỉ giới tính của vật/người được sở hữu, nên hai ngôn ngữ làm lộ những thông tin khác nhau
-
Thì quá khứ “mış” trong tiếng Thổ Nhĩ Kỳ
- Nói đơn giản, tiếng Thổ Nhĩ Kỳ có hai thì quá khứ chính: một dạng quá khứ chung tương tự simple past trong tiếng Anh, và dạng “mış”
- Dạng “mış” có nhiều chức năng, và khi nói về sự kiện trong quá khứ, nó được dùng khi thông tin là nghe kể lại hoặc có độ tin cậy thấp hơn
- Trước câu hỏi “Fred có đi làm hôm thứ Hai không?”, nếu trực tiếp nhìn thấy thì dùng dạng quá khứ thường “geldi”, còn nếu chỉ nghe lại thì dùng “gelmiş”
- Trong tiếng Anh, chỉ với simple past ta có thể nói mà không chỉ rõ nguồn thông tin hay mức độ tin cậy, nhưng trong tiếng Thổ Nhĩ Kỳ, ở một số tình huống, ta bị buộc phải kèm theo mức độ chắc chắn hoặc việc có trực tiếp chứng kiến hay không
- Vì có dạng “mış”, nên dạng quá khứ thường không còn là lựa chọn trung lập; khi cả hai lựa chọn đều không thật phù hợp thì câu sẽ trở nên gượng gạo
- Vì hậu tố “mış” trong tiếng Thổ Nhĩ Kỳ thường xuất hiện ở cuối từ cuối cùng của câu, nên người ta thậm chí có thể hình thành thói quen nói xong cả câu theo kiểu tiếng Anh rồi mới nhận ra rằng mình chưa gắn dấu hiệu “đây là thông tin nghe kể lại chứ không phải tự thấy”, và phải thêm “mış” vào cuối
- Trong tiếng Anh cũng có thể diễn đạt điều tương tự dễ dàng bằng các từ như “apparently”, nhưng tiếng Anh không bắt buộc phải nói rõ điều đó, còn tiếng Thổ Nhĩ Kỳ thì bắt buộc ở mức đáng kể
-
Sự cưỡng ép của ngôn ngữ mà người bản ngữ thường không nhìn thấy
- Những khác biệt như vậy thường khó nhận ra cho tới khi học một ngôn ngữ khác hoặc phải dạy tiếng mẹ đẻ của mình cho người nước ngoài
- Trong phần lớn các lần chọn giữa hiện tại đơn và hiện tại tiếp diễn, ta không chủ động nghĩ đến việc lựa chọn đó đang ngụ ý điều gì
- Khi ngôn ngữ ép buộc một cách diễn đạt nào đó, điều này không phải lúc nào cũng xuất hiện dưới dạng thêm một thứ gì vào; đôi khi nghĩa còn được cố định thông qua sự lược bỏ
- “I love cake” nói về bánh ngọt nói chung, còn “I love the cake” nói về một chiếc bánh cụ thể
- Chính vì không có “the” trong câu đầu nên ý nghĩa về bánh ngọt nói chung trở nên rõ ràng; nếu là một chiếc bánh cụ thể thì bắt buộc phải dùng dấu hiệu như “the” hoặc “this”
- Ở những ngôn ngữ khác có thể không có cách biểu đạt tương ứng trực tiếp với sự phân biệt này
Inverse Sapir-Whorf trong ngôn ngữ lập trình
- Trong ngôn ngữ lập trình, Sapir-Whorf theo nghĩa thông thường có thể đúng hơn đôi chút
- Trong các ngôn ngữ như Python hay Haskell, nói về cấp phát bộ nhớ là khó nhưng không phải không thể
- Giới hạn của ngôn ngữ lập trình thường được nói đến dưới góc độ những gì khó biểu đạt trong chính ngôn ngữ đó
- Bài Sapir-Whorf does not apply to Programming Languages của Hillel Wayne bàn kỹ hơn về chủ đề này
- Nhưng theo góc nhìn Inverse Sapir-Whorf, điều cốt lõi là liệu ngôn ngữ lập trình có buộc ta phải nói cả về những chủ đề mà thực ra ta không quan tâm hay không
- Kiểu cưỡng ép này thường chỉ dễ thấy khi học nhiều ngôn ngữ khác nhau, tức là có được góc nhìn giống người học ngoại ngữ
Các ví dụ chính trong ngôn ngữ lập trình
-
Thứ tự tính toán
- Phần lớn ngôn ngữ buộc ta phải biểu đạt thứ tự mà phép tính được thực hiện
x = some_func(y + 1, z + 2) trong Python nói rằng trước tiên tính y + 1, sau đó tính z + 2, rồi truyền hai giá trị đó làm đối số cho some_func
- Ta có thể không để ý đến thứ tự này, nhưng trong Python không có cách nào để biểu đạt phép tính trên mà lại không đồng thời chỉ ra thứ tự
- Đa số ngôn ngữ cũng tương tự, nhưng ở một số ngôn ngữ thì thứ tự đánh giá có thể rất phức tạp
- Cách viết tương đương trong Haskell như
some_func (y + 1) (z + 2) thì, nhờ ngữ nghĩa không nghiêm ngặt, hoàn toàn không chỉ định thứ tự đánh giá
- Đặc tính này cho phép những kỹ thuật như Tying the knot, nơi có thể tham chiếu đến giá trị chưa được định nghĩa xong
-
Màu của hàm async
- Màu của hàm async là một ví dụ điển hình
- Trong các ngôn ngữ có từ khóa
async tường minh như Javascript hay Python, ta buộc phải nói mã đó là đồng bộ hay bất đồng bộ
- Với hàm đồng bộ thì điều này được biểu đạt bằng cách lược bỏ từ khóa
async, nhưng về bản chất vẫn là chọn một trong hai phương án
- Không có cách nào để viết mã mà giữ thái độ nước đôi với chủ đề này
-
Cấp phát và giải phóng bộ nhớ
- Phần lớn ngôn ngữ không có garbage collection) đều buộc ta phải nói đến việc cấp phát và giải phóng bộ nhớ
- Trong các ngôn ngữ như C, chuyện này thường được xử lý khá tường minh, hoặc ngầm dùng cấp phát trên stack, nhưng dù cách nào cũng vẫn là phải chọn
- Ở những ngôn ngữ khác, vấn đề này có thể được che đi nhiều hơn nhưng không biến mất
- Trong Rust, nó chuyển thành câu chuyện về lifetime hoặc reference counting tường minh
- Lựa chọn kiểu “tôi không quan tâm bộ nhớ này được cấp phát và giải phóng khi nào, cứ tự xử lý đi” thực tế là không được cung cấp
- Việc không nói về cấp phát bộ nhớ cũng có cái giá của nó
- Những ngôn ngữ như vậy gần như chắc chắn sẽ đặt nhiều giá trị trên heap và cần một garbage collector lúc chạy
- Đổi lại, ngôn ngữ có thể có mức tự do lựa chọn lớn hơn nhiều, và Haskell chẳng hạn thường đưa ra các quyết định như vậy thông qua phân tích strictness
-
Phạm vi
- Mọi ngôn ngữ hiện đại đã biết đều khiến ta phải nghĩ về phạm vi
- Trong nhiều trường hợp, phạm vi được biểu đạt bằng vị trí vật lý nơi ta đặt biến, và nếu muốn hành vi khác thì phải dùng cú pháp bổ sung như global hoặc nonlocal trong Python
- Nếu hoàn toàn không muốn nghĩ về phạm vi, có lẽ bạn sẽ phải quay xuống assembly và chấp nhận một không gian địa chỉ toàn cục duy nhất
-
Kiểu dữ liệu
- Các ngôn ngữ kiểu tĩnh thường buộc ta phải nghĩ và nói về kiểu dữ liệu của mọi biến
- Suy luận kiểu giúp giảm gánh nặng này, giống như một người nghe thông minh hơn có thể hiểu thêm nhiều điều từ ngữ cảnh, nhưng cuộc đối thoại đó vẫn tồn tại
- Các ngôn ngữ thuần kiểu động cũng cho phép nói về kiểu, chẳng hạn kiểm tra
isinstance trong Python, nhưng điều đó kém tự nhiên hơn và về mặt kỹ thuật cũng là chuyện khác
- Một trong những sức hút của ngôn ngữ kiểu dần là nó thực sự tránh được vấn đề Inverse Sapir-Whorf, cho phép tự do nói hoặc không nói về kiểu tùy sở thích
- Tuy vậy, chưa rõ trên thực tế điều này hoạt động tốt đến đâu, vì quy ước của codebase sẵn có và linter đang dùng luôn tạo áp lực theo hướng nào đó
Ngôn ngữ dễ tiếp cận và rào cản thấp
- Nhiều đặc điểm của các ngôn ngữ lập trình “dễ tiếp cận” hoặc “dễ đọc” hơn có thể được phân tích dưới góc nhìn Inverse Sapir-Whorf
- Các ngôn ngữ như vậy có thể có rào cản Inverse Sapir-Whorf thấp hơn, tức là không ép người dùng phải nói về những điều mà họ chưa có quan điểm hoặc chưa hiểu
- Những chủ đề mà ngôn ngữ lập trình buộc phải nói ra có thể ảnh hưởng đến cách ta nhận thức và lựa chọn ngôn ngữ mình dùng
1 bình luận
Ý kiến trên Lobste.rs
Có thể xem việc thiết kế ngôn ngữ, dù là ngôn ngữ lập trình hay ngôn ngữ tự nhiên, là chuyện quyết định người dùng cần đặt sự chú ý vào đâu bằng cách chọn đưa yếu tố nào vào ngôn ngữ
C ngầm nói rằng “hãy để tâm đến quản lý bộ nhớ”, còn Haskell nói rằng “hãy để tâm đến kiểu mà biến và biểu thức có thể chứa”
Khi ngôn ngữ dẫn dắt tôi theo đúng hướng mà tôi thật sự muốn chú ý, nó giống như một công cụ rất hợp việc; còn nếu không, cảm giác như đang cố nghe một người nói nhỏ trong bữa tiệc cocktail trong khi có ai đó hét to từ đầu bên kia căn phòng
Sự chú ý là tài nguyên quý giá nhất, nên cần ý thức được công cụ dẫn dắt và định hình nó như thế nào
Trong tiếng Anh, việc nêu rõ hay lược bỏ “the” không trung lập đối với mức độ xác định của đối tượng, còn trong tiếng Thổ Nhĩ Kỳ, việc có dùng
mişhay không thì không trung lập đối với chuyện thông tin đó là tự mình biết được hay nghe kể lạiĐiều này có thể được xem là phía đối diện của giả thuyết Sapir-Whorf theo nghĩa tiêu chuẩn, tức tính trung lập của biểu đạt, vốn nói về “ngôn ngữ hạn chế những gì có thể nói”
Từ đó có thể giải thích liệu ngôn ngữ có trung lập hay không đối với một chủ đề nhất định, và với tư cách nhà thiết kế ngôn ngữ, có thể điều chỉnh để làm loãng hoặc tập trung sự chú ý của người dùng. Ví dụ, garbage collection làm cho biểu đạt trở nên trung lập với việc cấp phát heap, còn effect tracking làm cho biểu đạt trở nên không trung lập với tác dụng phụ và nhập/xuất
Không chắc mình đã nắm hoàn toàn ý chính của bài viết chưa, nhưng nó gợi lại một suy nghĩ mình lặp đi lặp lại từ lâu về Rust
Rust ở vào một vị trí khá lạ: nó cho phép xử lý tham chiếu, nhưng lại đặt ra những quy tắc nghiêm ngặt để đảm bảo an toàn bộ nhớ
Với C++, nếu nghĩ thứ gì đó nên là tham chiếu thì cứ biến nó thành tham chiếu rồi hy vọng không có vấn đề gì; còn với Python thì không có mức kiểm soát ấy nên cứ thoải mái sao chép dữ liệu
Nhưng trong Rust, bạn có thể rơi vào hố tối ưu hóa kiểu “sao chép thì kém hiệu quả, vậy dùng tham chiếu đi”, rồi khi borrow checker quát lên, dù vẫn tin rằng tham chiếu này là an toàn, bạn lại phải mất cả tiếng để refactor code
Các lập trình viên Rust giỏi thường bảo “cứ dùng
.clone,RC,Boxcác thứ đi”, và mình đồng ý, nhưng sự thật là tham chiếu vẫn ở ngay trước mắt và có vẻ như phải dùng an toàn đượcVì vậy vẫn còn lại một cảm giác kỳ lạ là mình quyết định làm mọi thứ tệ hơn chỉ để xoa dịu borrow checker, và cũng hiểu vì sao có người bỏ cuộc với suy nghĩ “borrow checker quá nặng tay với mình”
Chủ đề hay, và mình cũng vui khi thấy có nhắc sơ qua đến ngữ pháp tiếng Thổ Nhĩ Kỳ
Một ví dụ quen thuộc khác là, trong một số ngôn ngữ có thể lược bỏ những chi tiết như tính số nhiều, và tiếng Việt là một trường hợp như vậy
Thấy từ “exaggerated” có gắn link, mình đã nghĩ “ủa, có phải bài liên quan đến Arrival không?”, và đúng là vậy, khá thú vị
Nhiều người rất thích bộ phim này, nhưng cá nhân mình thấy khó mà tạm gác hoài nghi. Nó là khoa học viễn tưởng, nhưng phần “khoa học” lại giống một kiểu ngôn ngữ học mang màu sắc phép thuật hơn
Hầu hết ngôn ngữ lập trình ứng dụng lấy giá trị đơn lẻ làm nền tảng nguyên tử kiểu nào đó. Bạn có thể dựng list hay map lên trên, nhưng rồi chúng cũng chỉ là một vật đơn lẻ khác và thường không thật sự tương thích tinh tế với nhau
Trong Rust, bạn thường xuyên phải sao chép qua lại giữa các cấu trúc như vậy; còn trong SQL thì ít phải bận tâm chuyện đó hơn, đổi lại phải để tâm đến index và query plan, nhất là khi cơ sở dữ liệu vạch ra một kế hoạch rõ ràng ngớ ngẩn khiến điều bạn muốn hỏi trở nên phức tạp hơn, và thôi đừng đụng đến SQL NULL
Kết quả là phần lớn phần mềm của chúng ta bị đặc tả quá mức đến mức khó tin ngay từ cấp độ giá trị riêng lẻ, và dù hiệu năng PC đã tăng gấp 1000 lần, độ trễ UI tốt nhất lại còn tệ hơn xưa 10 lần
Chủ nghĩa giáo điều hướng đối tượng cũng chịu một phần trách nhiệm. Bất đồng bộ cũng đã được thử, nhưng quá dễ thoái hóa thành kiểu chỉ nhìn cây mà không thấy rừng,
awaittừng tác vụ độc lập mộthttps://www.uiua.org/ chắc phải được tưởng tượng là đang hạnh phúc
Toàn là những điểm rất hay. Mọi ngôn ngữ hiện đại đều buộc, hoặc ít nhất là thúc ép rất mạnh, lập trình viên phải xử lý chi tiết như chui vào một bãi cỏ dại
Các ngôn ngữ script có cung cấp phép toán trên những đối tượng bớt chi li hơn một chút, như chương trình hay trang web, nhưng vẫn không thể loại bỏ chi tiết
Chúng vẫn khiến bạn phải nghĩ và quản lý những chi tiết rất nhỏ như số, chuỗi, mã lỗi
Qua nhiều năm đào tạo và làm việc thực tế, chúng ta đã quá quen với việc quản lý chi tiết đến mức việc không suy nghĩ theo góc nhìn của chi tiết trở nên cực kỳ khó
Điều đầu tiên mình nghĩ tới là interface của object hay module
Trong ngôn ngữ lập trình, thứ này rất cụ thể, còn trong hội thoại ngôn ngữ tự nhiên thì mơ hồ hơn nhiều
Một ví dụ khác là sự khác biệt giữa generic trong C++ và generic trong Python. Trong C++ thì phải xử lý rất có chủ đích, còn trong Python thì nếu bỏ qua type hint, nó được xử lý khá ngầm định
Đoạn “inverse Sapir-Whorf làm ngôn ngữ hạn chế những gì khó nói ra, hoặc khiến việc không nói đến một thứ gì đó trở nên khó khăn, thậm chí khiến việc không nghĩ đến nó trở nên khó khăn” trông giống như một kim tự tháp ngữ pháp > thành ngữ/idiom > thư viện chuẩn > thư viện bên thứ ba > hệ sinh thái
Phần “khó mà không nghĩ đến” dường như tập trung vào các vấn đề khó biểu đạt hoặc có những ràng buộc quan trọng
Sự quen thuộc vận hành từ trên xuống dưới lẫn từ dưới lên trong, và mọi người bộc lộ nền tảng của mình qua cách họ viết code ở từng tầng
Dù đã đọc, viết và nói tiếng Anh hơn 15 năm, mình vẫn không biết “I live in London” và “I'm living in London” khác nhau
Giờ thì mình cũng không biết là mình sống ở London, hay là đang sống ở London nữa 😅
Nếu thay dạng hiện tại tiếp diễn ở đây bằng một tính từ bình thường và nói “I am cold”, bạn sẽ hiểu là tôi đang lạnh lúc này, chứ không phải theo nghĩa tôi lạnh lùng vĩnh viễn như một siêu phản diện nào đó
Tương tự, “I am living in London” hàm ý rằng hiện tại tôi sống ở London, nhưng tương lai có thể thay đổi
Nó cũng mang sắc thái rằng không phải lúc nào tôi cũng sống ở London. Cũng giống như “I am cold” phần nào hàm ý rằng ít nhất đã từng trải qua mức nhiệt đủ ấm để nhận ra trạng thái hiện tại không phải “bình thường” mà là “lạnh”