19 điểm bởi GN⁺ 2025-07-10 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trong lập trình, cách nói “gọi hàm” có nguồn gốc tương tự với khái niệm “yêu cầu” hoặc “gọi” một cuốn sách trong thư viện
  • Ở giai đoạn đầu của ngành điện toán, xu hướng chủ đạo là triệu gọi, gọi các subroutine từ thư viện
  • Khi Fortran II đưa vào lệnh CALL, cách nói “gọi hàm” nhanh chóng trở nên phổ biến
  • Sau đó, các ngôn ngữ như Algol và JOVIAL cũng tiếp nhận cách dùng này và sử dụng danh từ “call”
  • Ý nghĩa của “call” dần được mở rộng và cố định quanh trước, trong và sau khi chuyển điều khiển lúc runtime

Vì sao lập trình viên nói là “gọi (call)” một hàm?

  • Trên StackExchange đã có câu hỏi về nguồn gốc của cách nói “gọi (call) một hàm”
  • Có nhiều phép so sánh khác nhau, nhưng thực tế, từ “call” bắt nguồn từ nghĩa triệu gọi (summon) hoặc gọi đến
    • Tương tự như việc “yêu cầu” một cuốn sách trong thư viện, khái niệm này bắt đầu từ việc “yêu cầu” một subroutine để sử dụng
    • “call number” là ký hiệu dùng để chỉ vị trí của sách trong thư viện

Lịch sử của “call” trong thuật ngữ thư viện

  • Theo OED, Melvil Dewey là người đầu tiên dùng “call number” như một thuật ngữ khoa học thư viện vào năm 1876
    • “call number” là ký hiệu dùng cho vị trí của sách hoặc cho yêu cầu lấy sách
  • Trong Library Journal năm 1888, các thuật ngữ như “call blank”, “call slip”, “call number” đã được dùng thường xuyên
  • Theo giải thích của Joudrey & Taylor, “call number” là tên gọi xuất phát từ hành động gọi tài liệu trong các kho sách đóng
    • Các hệ thống như Cutter number được đưa vào để phục vụ việc phân loại

Những cách dùng ban đầu của “call” trong khoa học máy tính

  • Trong bài báo năm 1947 của John W. Mauchly, đã xuất hiện trường hợp dùng “called in” để lấy subroutine từ thư viện subroutine
    • Trong ngữ cảnh này, nó mang nghĩa tham chiếu nhanh và sử dụng thông qua số hiệu đã được ghi lại
  • Routine assembly của MANIAC II (1956) cũng áp dụng khái niệm gán “call number” cho từng subroutine để có thể gọi ra khi cần
    • Trong ngôn ngữ assembly thực tế, hành động này được gọi là “transfer control”
  • Ở giai đoạn này, trọng tâm vẫn là khái niệm gọi mã từ lúc biên dịch hoặc liên kết, hơn là “lời gọi” ở runtime

Sự xuất hiện của lệnh “CALL” trong ngôn ngữ lập trình

  • Fortran II (1958) đưa vào các lệnh CALLRETURN
    • Đây là hành động “call for” một subroutine để chuyển quyền điều khiển thực thi sang đó
    • Bản thân lệnh CALL chỉ rõ hành vi cú pháp của việc “gọi”
  • Dần dần, việc “transfer control” ở runtime và hành vi “gọi” ở thời điểm liên kết/lắp ráp bắt đầu hòa lẫn một cách mơ hồ

Sự mở rộng và định hình nghĩa của “call” trong thập niên 1960

  • Trong từ điển của Sarbacher (1959), “call in” được định nghĩa là việc chuyển điều khiển từ routine chính sang subroutine
    • Đồng thời cũng giải thích “call number” và “call word” như định danh và mã gọi
  • Trong JOVIAL (1960), các cách nói như “procedure call”, “calls” đã chính thức được dùng như danh từ
    • Về sau, chúng còn được dùng với các lớp nghĩa như vị trí gọi (site), đối số (argument), tham số (parameter)
  • Algol (1959~1960) cũng dùng nhiều cách diễn đạt như “procedure call”, “called procedure”, “during the call”
    • Trong báo cáo Algol 60 của Peter Naur, còn xuất hiện sự phân biệt về mặt thời gian giữa “call for” và “during the call”
  • Trong Burroughs Algebraic Compiler (1961), dạng động từ “to call” xuất hiện rõ ràng lần đầu tiên
  • Từ Corbató và cộng sự (1963) trở đi, cách dùng hiện đại “to call a subroutine” trở nên phổ biến

Kết luận

  • Lệnh CALL X của Fortran II đã giúp cách diễn đạt “call” bám rễ vào khái niệm gọi hàm/subroutine
    • Nó được gợi ý từ khái niệm thư viện trước đó (gọi bằng số hiệu), nhưng đã được mở rộng nghĩa mới trong ngôn ngữ lập trình
  • Sau đó, Algol, JOVIAL và nhiều ngôn ngữ khác tiếp nhận các thuật ngữ như “call”, “call site”
  • Từ khoảng năm 1961, cách nói “to call X” bắt đầu được định hình trong các tài liệu lập trình chính thức và cộng đồng
  • Ngày nay, gọi hàm chỉ toàn bộ chuỗi thao tác tạm thời chuyển quyền điều khiển, nhận kết quả rồi quay lại, và “call” trở thành thuật ngữ tiêu chuẩn cho quá trình đó

1 bình luận

 
GN⁺ 2025-07-10
Ý kiến trên Hacker News
  • Grace Hopper giải thích rằng nghĩa gốc của từ call (bắt nguồn từ call number, dùng để sắp xếp tài liệu trong thư viện vật lý) cũng đã ảnh hưởng đến sự ra đời của thuật ngữ compiler. Mỗi chương trình con được gán một call word, và khái niệm tạo nên chương trình bắt nguồn từ việc lấy tài liệu ra khỏi thư viện rồi kết hợp chúng lại
    • Tôi thực sự dùng những thuật ngữ này
    • Giờ mới thấy mọi mảnh ghép khớp lại với nhau. Các con số định danh trong hệ phân loại thập phân Dewey được gọi là call number
  • Tôi nghĩ ngành khoa học thư viện đã đóng góp cho lĩnh vực máy tính hiện đại nhiều hơn rất nhiều so với chúng ta tưởng tượng. Ví dụ, khi giải thích chỉ mục cơ sở dữ liệu, tôi thường mang hình ảnh mục lục thẻ ra nói. Chỉ cần nhìn tủ ngăn kéo gỗ cho phép tra theo tên tác giả, thập phân Dewey, hoặc chủ đề là ai cũng hiểu ngay. Tham khảo khái niệm mục lục thư viện
    • Tôi thuộc thế hệ từng dùng các tủ ngăn kéo gỗ ở thư viện địa phương và cả từ điển giấy. Khi lần đầu tiếp xúc với hash map hay IDictionary cách đây 25 năm, chính hình ảnh đó giúp tôi nắm được ngay. Nhưng bây giờ ẩn dụ này không còn hữu ích như trước. Không ít lần tôi phải giải thích trực tiếp thẻ mục lục hay từ điển trông như thế nào, và người trẻ thì nói: "À, vậy tức là một hash map analog"
    • Mới vài tháng trước tôi còn thắc mắc vì sao chiều rộng tiêu chuẩn của terminal lại là 80 ký tự. Tôi cứ nghĩ là vì kích thước màn hình PC ngày xưa. Hóa ra là vì thẻ đục lỗ có 80 ký tự, mà nguồn gốc của thẻ đục lỗ rốt cuộc lại là thẻ chỉ mục. Lại thêm một lần phải nghiêng mình trước ngành khoa học thư viện. Kiểu lịch sử máy tính này giống như chuyện bề rộng ô tô bắt nguồn từ kích thước hai mông ngựa vậy
    • Khoảng 1–2 năm trước tôi từng giải thích cơ sở dữ liệu bằng cách ví nó với một tủ ngăn kéo gỗ phủ bụi nằm trong góc thư viện. Bối cảnh và hiểu biết nền thực sự rất quan trọng
    • Tôi luôn nghĩ từ index trong thuật ngữ máy tính bắt nguồn từ phần mục lục ở cuối sách. Tôi chưa từng nối nó với index cards
    • Thế hệ trẻ ngày nay có thể chưa từng nhìn thấy mục lục thẻ. Tôi thường giải thích rằng ổ cứng là một danh sách các số 0 và 1, và để tìm được thứ gì đó thì cần có cấu trúc
  • Tôi là người Phần Lan. Trong tiếng Phần Lan, từ tương ứng với "gọi hàm" là kutsua, nếu dịch ngược sang tiếng Anh thì là invite hoặc summon. Tức là nó mang nghĩa "gọi" như "mẹ gọi con từ ngoài sân vào", chứ không phải kiểu call như "Joe gọi điện cho bạn" hay "gọi màu này là gì". Chỉ muốn chia sẻ vậy thôi
    • Trong tiếng Đức người ta dùng aufrufen, nếu dịch từng mảnh thì gần như là "gọi lên". Khi dùng với tân ngữ trực tiếp, như lúc giáo viên điểm danh học sinh ở trường, nó có nghĩa là gọi ai đó bằng tên hoặc số. Từ tương ứng với gọi điện là anrufen
    • summon đôi khi cũng rất hợp, vì có lúc nó tạo cảm giác như đang gọi ra một nỗi kinh hoàng huyền thuật trong mã nguồn. invite thì đôi khi khiến tôi nghĩ đến việc mời quỷ dữ hoặc ma cà rồng vào nhà
    • Ở Na Uy người ta dùng funksjonskall, dịch sát nghĩa là function call. Nó đơn giản là nghĩa gọi một cái gì đó
    • Trong tiếng Nga cũng tương tự, nếu dịch ngược thì sẽ là "gọi bằng điện thoại", "triệu hồi", "mời" v.v.
    • Không trực tiếp liên quan đến chủ đề, nhưng nếu bạn ở Helsinki thì có thể tham gia buổi meetup Hacker News tại địa phương
  • Trong cuốn sách Wilkes, Wheeler, Gill (1951), cụm call in được dùng cho việc thực thi chương trình con. Ở trang 31 có các câu như "nếu chương trình con không được gọi đúng cách thì máy sẽ dừng" và "có thể tự do gọi chương trình con trong bất kỳ chương trình nào". Trong báo cáo ban đầu về EDSAC năm 1950 cũng có chú thích call in auxiliary sub-routine, có thể thấy trong bài thuyết trình này
  • Thỉnh thoảng người ta cũng dùng invoke hoặc execute thay cho call, nhưng đó là các thuật ngữ dài hơn và mang tính chung chung hơn. Tuy vậy, tôi thường nghe sinh viên CS không phải người bản ngữ dùng sai từ call trong những ngữ cảnh như "calling a command" hay "calling a button", và điều đó hơi gây khó chịu
    • invoke bắt nguồn từ tiếng Latin invocō, invocāre (gọi ra), nên không phải là sai mà chỉ là cách nói rút gọn
    • Ví dụ dùng sai mà tôi nghe thấy nhiều nhất (hoặc ghét nhất) là đi cùng với return. Tôi từng nghe câu kiểu: "bây giờ gọi từ khóa return thì hàm sẽ kết thúc"
    • C# hay dùng Invoke ở những chỗ như delegate hoặc reflection, trong khi debugger lại dùng Call Stack
    • Theo kinh nghiệm của tôi, ngay cả người bản ngữ mới học lập trình cũng dùng tương tự. Họ còn gọi cả những thứ không phải lệnh là command
    • Người mới bắt đầu đôi khi còn gọi cả statement hoặc toàn bộ khai báo hàm là command
  • Đây không phải lý thuyết khoa học gì, chỉ là một quan sát. Thuật ngữ mới lan truyền tốt khi nó có một điểm gì đó dễ bắt nhịp. Thường thì nó ngắn, dễ gợi nghĩa hoặc gợi hình nên được nhớ và lan đi nhanh. Đôi khi cần giải thích, nhưng chỉ từ ngữ cảnh thôi người ta cũng học được rồi truyền lại. Ví dụ như từ salty, và call cũng vậy. Nó ngắn, dùng thường xuyên nên rất thuận miệng; các sắc thái như call up/call in/summon/invoke (kiểu như câu thần chú) đều cho cảm giác khá khớp. Khi đó điện thoại cũng là một công nghệ mới mẻ và thú vị, nên hình ảnh gọi điện cho người khác hẳn đã được liên hệ rất dễ với việc gọi chương trình con. Những từ như jump thì đã được dùng theo nghĩa khác rồi, nên tôi nghĩ call mới có thể phổ biến rộng rãi
    • Với tôi salty chẳng liên quan mấy đến nước mắt. Trong thói quen ngôn ngữ của tôi, ai đó salty không có nghĩa là buồn mà là đang cáu kỉnh hoặc khó chịu. Tức là ẩn dụ đến từ hình ảnh vị mặn như thứ gì đó gắt và mạnh. Nói cách khác, dù cách diễn giải khác nhau thì ẩn dụ vẫn hoạt động tốt, và điều đó cho thấy call cũng có thể lan truyền theo cách như vậy
  • Trong câu "... những thứ phức tạp nên nằm trong library, tức là một bộ băng từ (nơi lưu trữ các bài toán có giá trị đã được viết từ trước)", tôi chưa từng nghĩ rằng từ library thực sự bắt nguồn từ những giá tài liệu có dán nhãn ngoài đời
  • Tôi vẫn luôn nghĩ hàm không nhất thiết phải cần từ khóa call. Hàm thường trả về giá trị nên có thể dùng ngay trong câu lệnh gán. Thứ cần call là subroutine (thực chất là một địa chỉ/nhãn có tên). Thực ra cũng có thể nhảy trực tiếp đến địa chỉ đó bằng GOTO rồi quay lại. Từ khóa CALL giúp luồng thực thi trông rõ ràng hơn. Giống như sếp giao Sam xử lý việc tính toán rồi lại giao Bill in báo cáo TPS, luồng công việc cứ thế tiếp diễn. Rồi cuối cùng mọi thứ đều biến thành function và subroutine thì bị gán biệt danh là spaghetti. Nhưng tôi vẫn thắc mắc vì sao lại có cả hai thuật ngữ routine (chương trình) và subroutine
    • Theo một tài liệu năm 1947 của Goldstine và von Neumann, nguồn gốc của từ routine được ghi rõ là: "Chúng tôi gọi chuỗi chỉ thị đã mã hóa của một bài toán là routine" (tham khảo)
  • Trong âm nhạc cũng có khái niệm "call and response". Tôi nghĩ nó cũng có thể liên hệ với khái niệm return value
  • Algol 60 cũng dùng từ call không chỉ cho hàm mà còn cho cả tham số. Ví dụ như call by value, call by name; ở mục 4.7.5.3 có cấu trúc như "trong trường hợp call by value". Ngày nay người ta nói procedure/function/subroutine thì được call, còn argument/parameter thì được pass, nên pass by value/reference/name rõ ràng hơn. Tuy vậy, các thuật ngữ cũ như call by value vẫn còn tồn tại trong một số ngữ cảnh. Khái niệm gọi (call) argument hay parameter thì đã biến mất, nhưng những thuật ngữ legacy như vậy vẫn còn tồn tại