Vì sao là F#?
(batsov.com)- F# là một ngôn ngữ hàm họ ML nhắm tới .NET, do Microsoft phát triển. So với C# vốn chủ yếu theo hướng lập trình hướng đối tượng, F# tập trung vào mô hình lập trình hàm
- Bài viết này tổng hợp các đặc điểm ngôn ngữ, hệ sinh thái, tình trạng tài liệu hóa, công cụ phát triển, trường hợp sử dụng, cộng đồng và so sánh F# với OCaml
F# là gì?
- F# là ngôn ngữ lập trình đa dụng để viết mã ngắn gọn, chắc chắn và hiệu năng tốt
- Được thiết kế để bạn có thể tập trung vào việc giải quyết vấn đề, thay vì bận tâm đến cú pháp phức tạp
- Mã nguồn mở, đa nền tảng và có khả năng tương thích rất cao với .NET
-
Đặc điểm
- Cú pháp gọn nhẹ và tính bất biến mặc định
- Suy luận kiểu và khái quát hóa
- Hàm hạng nhất, kiểu dữ liệu mạnh và pattern matching
- Hỗ trợ lập trình bất đồng bộ (Async)
- Là ngôn ngữ khai sinh ra toán tử pipeline (
|>) nổi tiếng
-
Ví dụ mã đơn giản
open System let names = [ "Peter"; "Julia"; "Xi" ] let getGreeting name = $"Hello, {name}" names |> List.map getGreeting |> List.iter (printfn "%s") - F# bắt đầu là một ngôn ngữ do Don Syme phát triển tại Microsoft Research vào năm 2005
- Khởi đầu từ dự án nghiên cứu chuyển OCaml sang nền tảng .NET (Caml.NET)
- Sau đó được đưa vào danh mục sản phẩm chính thức từ năm 2010, và đến năm 2024 thì F# 9.0 được phát hành
- Tính đến năm 2025, đây đã là một ngôn ngữ trưởng thành bước sang năm thứ 20
- Những lý do chính khiến tác giả thử nghiệm F#
- Xác nhận việc .NET đã tiến hóa thành nền tảng mã nguồn mở và đa nền tảng
- So sánh ưu và nhược điểm với OCaml
- Đánh giá tích cực về công cụ như Rider, Ionide
- Hứng thú đơn thuần với việc khám phá ngôn ngữ
F# với tư cách một ngôn ngữ
- F# là ngôn ngữ hàm họ ML, có cú pháp quen thuộc với người dùng OCaml
- Các lập trình viên từng dùng Haskell hoặc Lisp cũng có thể thích nghi dễ dàng
- Cấu trúc cú pháp dựa trên khoảng trắng, nên thụt lề quan trọng về mặt ngữ pháp giống như Python
- Được thiết kế để ngay cả người mới cũng có thể nhanh chóng nắm cú pháp cơ bản
-
Tóm tắt đặc điểm ngôn ngữ
- Định nghĩa và áp dụng hàm được biểu đạt ngắn gọn, tự nhiên
- Câu điều kiện, vòng lặp, tuple, xử lý list đều có thể dùng theo phong cách hàm một cách gọn gàng
- Record, discriminated union, pattern matching giúp xử lý cấu trúc dữ liệu phức tạp một cách súc tích
- Với toán tử pipeline (
|>), luồng dữ liệu có thể được tổ chức trực quan rõ ràng như chuỗi kết nối các hàm - F# rất phù hợp để viết script ad-hoc, có thể viết trong file
.fsxrồi chạy ngay bằngdotnet fsi - Cũng cung cấp môi trường REPL nên thuận lợi cho lập trình khám phá
-
Cú pháp thân thiện với người dùng
- Bao gồm các tính năng cú pháp thực dụng như chú thích một dòng và nhiều dòng, biến
mutable, list slice - Nhờ khả năng tương thích cao với C#, có thể dùng .NET API rất dễ dàng
- Cũng hỗ trợ tự nhiên việc nạp chồng toán tử cho nhiều kiểu khác nhau
printfngiúp in ra nhiều kiểu dữ liệu một cách dễ dàng, hữu ích cho debug và logging
- Bao gồm các tính năng cú pháp thực dụng như chú thích một dòng và nhiều dòng, biến
-
Người tiên phong của lập trình bất đồng bộ
- Nguồn gốc của mẫu
async/awaitlà F# 2.0, sau đó ảnh hưởng đến nhiều ngôn ngữ như C# và JavaScript - F# cung cấp cấu trúc giúp triển khai lập trình bất đồng bộ một cách trực quan mà không cần callback
- Luồng mã trông như đồng bộ nhưng thực tế lại chạy bất đồng bộ
- Nguồn gốc của mẫu
-
Sự đầu tư của Microsoft và tiến hóa của ngôn ngữ
- Microsoft từng phân bổ nguồn lực khá hạn chế cho F# trong thời gian dài, nhưng từ năm 2022 đã lập đội ngũ chuyên trách tại Prague và bắt đầu đầu tư nghiêm túc
- Qua các bản phát hành F# 8.0 và 9.0, ngôn ngữ và công cụ đang được cải thiện nhanh chóng
- Khi sự quan tâm nội bộ của Microsoft tăng lên, cũng có thể kỳ vọng vào tiềm năng phát triển trong tương lai
F# là một ngôn ngữ thực dụng, dễ học nhưng vẫn sở hữu hệ thống kiểu mạnh và mô hình lập trình hàm; đặc biệt, đây là lựa chọn rất hấp dẫn cho các lập trình viên muốn đưa cách tiếp cận hàm vào các dự án dựa trên .NET
Hệ sinh thái (Ecosystem)
- Sau một thời gian sử dụng tương đối ngắn, tác giả thấy rằng không có quá nhiều thư viện hay framework thuần F#
- Phần lớn người dùng vẫn phụ thuộc vào API mặc định của .NET và các thư viện bên thứ ba chủ yếu được thiết kế quanh C#
- Đây là hiện tượng thường thấy ở các ngôn ngữ chạy trên nền tảng chủ (hosted language) như Scala, Clojure, Groovy
-
Các thư viện chính cho phát triển web
- Giraffe: framework web nhẹ dựa trên ASP.NET Core, hướng tới phong cách hàm
- Suave: framework web server đơn giản theo phong cách combinator để định tuyến và tổ hợp tác vụ
- Saturn: framework phong cách MVC xây trên Giraffe, lấy cảm hứng từ Ruby on Rails và Phoenix
- Bolero: framework phát triển ứng dụng client dựa trên WebAssembly và Blazor
- Fable: transpile F# sang JavaScript để có thể tích hợp với hệ sinh thái JS như React, Node.js
- Elmish: framework UI dựa trên mẫu MVU (Model-View-Update), thường dùng cùng Fable
- SAFE Stack: stack phát triển web hàm end-to-end kết hợp Saturn, Fable, Elmish, Azure...
-
Các thư viện chính cho khoa học dữ liệu
- Deedle: thư viện phân tích và thao tác dữ liệu theo phong cách pandas
- DiffSharp: thư viện thiên về toán học, cung cấp machine learning và automatic differentiation
- FsLab: bộ công cụ khoa học dữ liệu tích hợp gồm trực quan hóa, phân tích thống kê...
Tình trạng tài liệu hóa
- Tài liệu chính thức nhìn chung được tổ chức tốt và có chất lượng cao
- Một phần nằm trên Microsoft Docs, phần khác nằm trên F# Software Foundation
- Cấu trúc tài liệu có thể hơi phân tán, nhưng style guide, tài liệu thiết kế và API thư viện chuẩn đều rất hữu ích
-
Các liên kết tài liệu được khuyến nghị
-
Tài liệu học tập từ cộng đồng
- F# for Fun and Profit: bộ sưu tập tutorial và bài luận (hơi cũ nhưng vẫn còn giá trị)
Công cụ phát triển (Dev Tooling)
- Hệ sinh thái công cụ phát triển của F# trước đây chủ yếu chỉ được tối ưu cho Visual Studio, còn hỗ trợ cho các trình soạn thảo khác thì khá yếu
- May mắn là trong 10 năm qua, môi trường công cụ đã được cải thiện đáng kể
-
Bước ngoặt kỹ thuật: FSharp.Compiler.Service (FCS)
- FCS là một thư viện thống nhất bao gồm compiler F#, tính năng hỗ trợ trình soạn thảo và scripting engine, cho phép dùng F# trên nhiều editor và môi trường tooling khác nhau
- Nhờ đó, hỗ trợ F# đã có thể xuất hiện trên VS Code, trình tạo tài liệu, backend thay thế... và thúc đẩy hệ sinh thái mở rộng
- Ví dụ tiêu biểu là Ionide, mang đến hỗ trợ F# phong phú trên VS Code và đã vượt mốc 1 triệu lượt tải
-
Các editor đã thử nghiệm
- Emacs (
fsharp-mode): cung cấp chức năng cơ bản, không hỗ trợ TreeSitter, hoạt động phát triển ít - Zed: hỗ trợ F# còn hạn chế
- Helix: có hỗ trợ cơ bản
- VS Code (plugin Ionide): một trong những môi trường hoàn thiện nhất
- JetBrains Rider: IDE thương mại nhưng hỗ trợ F# rất mạnh
Phần lớn tính năng hoạt động dựa trên F# language server (
fsautocomplete), nên mọi editor có hỗ trợ LSP tốt đều có thể dùng được - Emacs (
-
Điểm còn tiếc
fsharp-modedựa trên codebase cũ và phát triển chậm- Zed còn thiếu tính năng
- VS Code có một số tính năng (ví dụ: mở rộng/thu gọn vùng chọn) hoạt động chưa đúng
- Một số người dùng cũng thấy VS Code bất tiện do vấn đề keybinding/mô hình modal
-
Formatter và linter cho mã
- Fantomas: formatter mã chính thức của F#, được đa số người dùng và đội nhóm sử dụng
- FSharpLint: từng phổ biến nhưng hiện gần như đã ngừng phát triển
- Tuy nhiên, nhờ compiler rất mạnh, mức độ phụ thuộc vào linter là không cao
-
Công cụ khác
Trường hợp sử dụng (Use Cases)
- Nhờ hệ sinh thái rộng lớn của .NET, F# có tiềm năng được dùng trong nhiều lĩnh vực khác nhau
- Đặc biệt, nhờ tính năng Type Providers, F# rất phù hợp cho các tác vụ phân tích và thao tác dữ liệu
- Cũng phù hợp cho phát triển dịch vụ backend và ứng dụng full-stack; một số công cụ còn cho phép làm cả frontend
-
Các lĩnh vực sử dụng chính
- Phân tích dữ liệu: có thể thao tác dữ liệu dựa trên kiểu tĩnh nhờ Type Providers của F#
- Dịch vụ backend: có thể dùng F# cùng các framework web mạnh mẽ của .NET
- Ứng dụng frontend: thông qua Fable và Elmish, có thể phát triển UI tích hợp với hệ sinh thái JS
- Từ
Fable 4, còn có thể transpile sang nhiều ngôn ngữ như TypeScript, Rust, Python
- Từ
-
Ví dụ Fable (lệnh transpile đơn giản)
- JavaScript:
dotnet fable - TypeScript:
dotnet fable --lang typescript - Python:
dotnet fable --lang python
- JavaScript:
Tình hình cộng đồng
- Nhìn chung cộng đồng không lớn và có thể còn nhỏ hơn cả OCaml
- Reddit và Discord là hai không gian giao tiếp sôi động nhất
- Cộng đồng Slack cũng tồn tại nhưng khó tiếp cận do vấn đề với hệ thống tự động gửi lời mời
- Vai trò của Microsoft trong cộng đồng không thật sự rõ ràng, và cộng đồng có xu hướng tự dẫn dắt khá mạnh
-
Các nguồn lực chính đang được cộng đồng vận hành
- Amplifying F#: thúc đẩy phổ biến F# và khuyến khích doanh nghiệp tham gia
- F# for Fun and Profit: kho lưu trữ tutorial và bài luận
- F# Lab: bộ công cụ cộng đồng F# cho khoa học dữ liệu
- F# Weekly: bản tin tổng hợp tin tức F# mới nhất
Mức độ phổ biến và thực tế (The Popularity Contest)
- F# không nằm ở thứ hạng cao trên hầu hết các thước đo độ phổ biến như TIOBE, StackOverflow hay tin tuyển dụng
- Nhưng đây cũng là thực tế chung của phần lớn các ngôn ngữ hàm, không phải vấn đề riêng của F#
- Dù chưa phải dòng chính, nó vẫn có nhóm người dùng ở quy mô tương đương với các ngôn ngữ hàm khác như Clojure, OCaml, Emacs Lisp
-
Vì sao dùng F#?
- Có nhiều lý do để chọn một ngôn ngữ lập trình ngoài khả năng xin việc
- Vì vui (cũng có câu nói chữ F trong F# là “Fun”)
- Học các mô hình và ý tưởng mới
- Rèn luyện cách suy nghĩ khác với tư duy quen thuộc
- Có nhiều lý do để chọn một ngôn ngữ lập trình ngoài khả năng xin việc
-
Tài liệu liên quan
So sánh F# với OCaml
Mục tiêu ban đầu của F# là mang những ưu điểm của OCaml sang .NET, và mang những ưu điểm của .NET sang OCaml
– Don Syme, người tạo ra F#
- F# được phát triển với cảm hứng từ OCaml, và thời kỳ đầu còn tương đồng đến mức hỗ trợ cả phần mở rộng file
.ml,.mli - Theo thời gian, nó dần tiến hóa thành một ngôn ngữ độc lập, và giờ đây mỗi bên phát triển theo hướng riêng
-
Ưu điểm của F#
- Dựa trên nền tảng .NET
- Có thể tận dụng số lượng thư viện khổng lồ
- Có sự hỗ trợ của Microsoft
- Thân thiện với người mới
- Cú pháp quen thuộc với những ai từng dùng ngôn ngữ hướng đối tượng (như C#)
- Thông báo lỗi của compiler tương đối rõ ràng
- Trải nghiệm debug trực quan hơn
- Hỗ trợ lập trình bất đồng bộ rất mạnh
- Cung cấp những tính năng mà OCaml không có
- Anonymous record
- Active pattern
- Computational expressions
- Sequence comprehension
- Type providers
- Units of measure
- Dựa trên nền tảng .NET
-
Nhược điểm của F#
- Dựa trên nền tảng .NET
- Có nhiều thỏa hiệp trong thiết kế ngôn ngữ để tương tác với
.NET(nullđược cho phép, v.v.)
- Có nhiều thỏa hiệp trong thiết kế ngôn ngữ để tương tác với
- Thuộc sở hữu của Microsoft
- Mức độ yêu thích Microsoft khác nhau giữa từng người
- Nguồn lực phân bổ cho F# vẫn tương đối ít
- Về dài hạn, mức độ Microsoft sẽ hỗ trợ F# đến đâu vẫn còn chưa chắc chắn
- Vấn đề liên quan đến tên gọi
- Những ai không thích quy ước đặt tên
PascalCase,camelCasecó thể thấy bất tiện - Cái tên F# có thể gây vấn đề khi tìm kiếm hoặc đặt tên file (vì vậy cũng thường được viết là FSharp)
- Những ai không thích quy ước đặt tên
- Thiếu một số tính năng nâng cao có trong OCaml
- First-class module, functor
- Hỗ trợ GADT còn thiếu
- Không có mascot, cũng không có lạc đà
- Dựa trên nền tảng .NET
-
Điểm chung và so sánh qua lại
- Cả hai ngôn ngữ đều có thể nhắm tới runtime JavaScript
- F#: Fable
- OCaml: js_of_ocaml, Melange
- Hiện tại Fable cho cảm giác trưởng thành hơn, nhưng vẫn cần thêm trải nghiệm sử dụng thực tế
- Cả hai đều mạnh nhưng là ngôn ngữ ngách, và trong tương lai gần khó có khả năng trở thành ngôn ngữ đại chúng rộng rãi
- F# có tính thực dụng là có thể len dần vào các codebase C# sẵn có
- Một nhược điểm là dự án F# vẫn dùng file project dựa trên XML và phải chỉ định thứ tự biên dịch thủ công
- Điều này có thể gây cảm giác phiền hơn khi so với hệ thống build
Dunecủa OCaml
- Điều này có thể gây cảm giác phiền hơn khi so với hệ thống build
- Với mục đích giáo dục hoặc học cấu trúc ngôn ngữ, OCaml có thể phù hợp hơn
- Nếu mục tiêu là phát triển dịch vụ web hoặc backend thực dụng, F# có thể là lựa chọn tốt hơn
- Đặc biệt, với tư cách một ngôn ngữ tích hợp tốt với
.NETnhưng vẫn giữ được phong cách hàm, F# là một công cụ rất mạnh
- Cả hai ngôn ngữ đều có thể nhắm tới runtime JavaScript
Cảm nhận kết lại
- Tác giả cảm thấy F# là một ngôn ngữ thú vị và thực dụng hơn rất nhiều so với kỳ vọng
- Tác giả nói cảm giác này giống như lần đầu tiên tiếp xúc với Clojure trước đây
- Đặc biệt nhớ lại việc Clojure từng là Lisp thực dụng nhất nhờ khả năng tương tác xuất sắc với Java
- Nếu ngay từ đầu .NET đã là mã nguồn mở và portable,
- ClojureCLR có thể đã phổ biến hơn hiện tại
- Và cộng đồng cùng hệ sinh thái F# cũng có thể đã phát triển mạnh hơn
- Việc F# không phải mã nguồn mở cho đến năm 2010 cũng đã cản trở việc được chấp nhận trong giai đoạn đầu
".NET và F# đều không phải mã nguồn mở trong giai đoạn đầu là sai lầm lớn nhất, và điều đó đã khiến nhiều cơ hội bị bỏ lỡ" – Don Syme
- OCaml cũng không khó học, nhưng với người lần đầu học ngôn ngữ họ ML thì F# có thể dễ hơn
- Rào cản để đi đến production cũng thấp hơn
- Tác giả đặc biệt nhấn mạnh rằng nếu bạn đã có kinh nghiệm với .NET thì rất đáng để nhất định thử F#
- F# không chỉ là một ngôn ngữ tuyệt vời theo đúng nghĩa độc lập, mà còn mở ra cơ hội tận dụng hệ sinh thái mạnh mẽ của .NET
- Thông qua các công cụ như Fable, có thể transpile mã F# sang JavaScript, Dart, Rust, Python...
- Trong cộng đồng F# có câu nói rằng "chữ F trong F# là Fun"
- Sau khi tự tay dùng thử, tác giả cũng thấy câu này là thật, và nhấn mạnh rằng nó không chỉ vui mà còn thực dụng
- Cuối cùng, bài viết cũng nhắc đến độ ổn định và độ tin cậy của F# qua câu "nếu biên dịch thành công thì phần lớn mọi thứ sẽ chạy tốt"
In sane type systems we trust!
1 bình luận
Ý kiến Hacker News
F# là ngôn ngữ hàm tốt nhất khi viết lại một ứng dụng Ruby on Rails
Đã thử F# nhưng còn mới với hệ sinh thái .NET
Công ty chúng tôi đã chuyển từ C# sang F# cách đây 6 năm
Lý do việc tiếp nhận F# bị đình trệ là do hệ thống build kém
Đã học F# vào năm 2013 và thấy rất vui
F# là một trường hợp hiếm khi mọi người dùng đều rất hài lòng
Khi C# có được nhiều tính năng của F#, lợi thế của F# đang giảm dần
Có một SaaS có lãi được viết hoàn toàn bằng F#
F# là một ngôn ngữ tuyệt vời
F# đẹp nhưng khó dùng một cách thành thạo