Giữ một ngôn ngữ lập trình tương thích ngược với sửa lỗi sai của nó


56

Đầu tiên, một số bối cảnh (thứ mà hầu hết các bạn đều biết):

Mọi ngôn ngữ lập trình phổ biến đều có sự phát triển rõ ràng, hầu hết thời gian được đánh dấu bởi phiên bản của nó: bạn có Java 5, 6, 7, v.v., PHP 5.1, 5.2, 5.3, v.v. Phát hành phiên bản mới giúp API mới có sẵn, sửa lỗi, thêm tính năng mới, khung công tác mới, v.v ... Vì vậy, tất cả trong tất cả: nó tốt.

Nhưng còn vấn đề của ngôn ngữ (hoặc nền tảng) thì sao? Nếu và khi có điều gì đó sai trong ngôn ngữ, các nhà phát triển sẽ tránh nó (nếu có thể) hoặc họ học cách sống với ngôn ngữ đó.

Bây giờ, các nhà phát triển của những ngôn ngữ đó nhận được rất nhiều phản hồi từ các lập trình viên sử dụng chúng. Vì vậy, thật hợp lý khi thời gian (và số phiên bản) trôi qua, các vấn đề trong các ngôn ngữ đó sẽ chậm nhưng chắc chắn sẽ biến mất. Vâng, không thực sự. Tại sao? Khả năng tương thích ngược, đó là lý do tại sao. Nhưng tại sao nó lại như thế? Đọc dưới đây cho một tình huống cụ thể hơn.


Cách tốt nhất tôi có thể giải thích câu hỏi của mình là sử dụng PHP làm ví dụ:

PHP được yêu thích và ghét bởi hàng ngàn người. Tất cả các ngôn ngữ đều có sai sót, nhưng rõ ràng PHP là đặc biệt. Kiểm tra bài blog này . Nó có một danh sách rất dài về cái gọi là lỗ hổng trong PHP. Bây giờ, tôi không phải là nhà phát triển PHP (chưa), nhưng tôi đã đọc qua tất cả và tôi chắc chắn rằng một phần lớn của danh sách đó thực sự là vấn đề. (Không phải tất cả, vì nó có khả năng chủ quan).

Bây giờ, nếu tôi là một trong những người tích cực phát triển PHP, tôi chắc chắn sẽ muốn khắc phục từng vấn đề đó. Tuy nhiên, nếu tôi làm điều đó, thì mã dựa trên một hành vi cụ thể của ngôn ngữ sẽ bị phá vỡ nếu nó chạy trên phiên bản mới. Tóm tắt trong 2 từ: tương thích ngược.

Điều tôi không hiểu là: tại sao tôi phải giữ PHP tương thích ngược? Nếu tôi phát hành phiên bản PHP 8 với tất cả các vấn đề đã được sửa, tôi không thể đưa ra một cảnh báo lớn cho nó: "Đừng chạy mã cũ trên phiên bản này!"?

Có một thứ gọi là sự phản đối. Chúng tôi đã có nó trong nhiều năm và nó hoạt động. Trong ngữ cảnh của PHP: hãy xem cách những ngày này mọi người chủ động không khuyến khích việc sử dụng các mysql_*hàm (và thay vào đó là khuyến nghị mysqli_*và PDO). Khấu hao công trình. Chúng ta có thể sử dụng nó. Chúng ta nên sử dụng nó. Nếu nó hoạt động cho các chức năng, tại sao nó không hoạt động cho toàn bộ ngôn ngữ?

Giả sử tôi (nhà phát triển PHP) làm điều này:

  • Khởi chạy một phiên bản PHP mới (giả sử 8) với tất cả các lỗi đó đã được sửa
  • Các dự án mới sẽ bắt đầu sử dụng phiên bản đó, vì nó tốt hơn, rõ ràng hơn, an toàn hơn, v.v.
  • Tuy nhiên, để không từ bỏ các phiên bản PHP cũ hơn, tôi tiếp tục phát hành các bản cập nhật cho nó, sửa các vấn đề bảo mật, lỗi, v.v ... Điều này hợp lý vì những lý do mà tôi không liệt kê ở đây. Đó là cách làm phổ biến: tìm ví dụ về cách Oracle tiếp tục cập nhật phiên bản 5.1.x của MySQL, mặc dù nó chủ yếu tập trung vào phiên bản 5.5.x.
  • Sau khoảng 3 hoặc 4 năm, tôi ngừng cập nhật các phiên bản PHP cũ và khiến chúng chết. Điều này là tốt, vì trong 3 hoặc 4 năm đó, hầu hết các dự án sẽ chuyển sang PHP 8.

Câu hỏi của tôi là: Tất cả các bước này có ý nghĩa? Nó sẽ rất khó để làm? Nếu nó có thể được thực hiện, thì tại sao nó không được thực hiện?

Có, nhược điểm là bạn phá vỡ tính tương thích ngược. Nhưng đó không phải là một cái giá phải trả? Như một ưu điểm, trong 3 hoặc 4 năm nữa, bạn sẽ có một ngôn ngữ có 90% vấn đề được khắc phục .... một ngôn ngữ dễ chịu hơn rất nhiều khi làm việc. Tên của nó sẽ đảm bảo sự phổ biến của nó.

EDIT : OK, vì vậy tôi đã không thể hiện chính xác khi tôi nói rằng trong 3 hoặc 4 năm nữa mọi người sẽ chuyển sang PHP giả thuyết 8. Ý tôi là: trong 3 hoặc 4 năm, mọi người sẽ sử dụng PHP 8 nếu họ bắt đầu dự án mới.


31
PHP là một ví dụ tồi cho câu hỏi cụ thể này, bởi vì thường xuyên hơn là bạn không được chọn phiên bản bạn sẽ làm việc cùng. Phần lớn các trang web PHP được triển khai trên các máy chủ dùng chung và chủ sở hữu máy chủ đang chọn phiên bản, không phải bạn. Rất nhiều và rất nhiều thứ được sửa với mỗi phiên bản mới ( mysql_*chẳng hạn như đã bị loại bỏ trong 5.5), nhưng điều đó không liên quan nếu phần lớn các nhà cung cấp dịch vụ lưu trữ ngoài đó có một hoặc thậm chí hai phiên bản trở lại (5.3 là - không may - vẫn là phần lớn nhà cung cấp cung cấp).
yannis

5
... Tôi cũng nghĩ rằng bạn đánh giá thấp số lượng mã cần được chuyển, số lượng thứ sẽ bị phá vỡ, số lượng phụ thuộc của bên thứ ba để thích nghi, v.v.
dagnelies 25/03/13

12
Bài đăng trên blog tuyệt vời này joelonsoftware.com/items/2008/03/17.html của Joel Spolsky về "tai nghe sao Hỏa" nên là bắt buộc đối với mọi nhà phát triển đánh giá thấp tầm quan trọng của khả năng tương thích ngược.
Doc Brown

3
Ngoài ra, PHP đã dần dần mất chức năng với mỗi bản phát hành - và kết quả là RẤT NHIỀU công cụ bị phá vỡ. Thật không may, PHP bị mắc kẹt ở một vị trí khó khăn, nơi họ có một thời gian khó khăn thậm chí tạo ra các cảnh báo về sự phản đối theo cách mà các nhà phát triển sẽ thấy rằng cuối cùng họ sẽ không phá vỡ các trang web.
lông tơ

20
python 2.x => python 3.x là một thay đổi đột phá từ một ngôn ngữ được thiết kế tốt sang ngôn ngữ khác, được thiết kế tốt hơn một chút, có sự hỗ trợ của bên thứ nhất để tự động thay đổi nhiều cấu trúc không tương thích. Chuyển mã giữa chúng dễ dàng như bạn có thể thay đổi giữa hai ngôn ngữ. Py3k vẫn đang rất chậm đạt được chỗ đứng.
Phoshi

Câu trả lời:


25

Nghe có vẻ tốt, nhưng hiếm khi hoạt động trong thực tế; mọi người rất miễn cưỡng thay đổi mã đang chạy và ngay cả đối với các dự án mới, lĩnh vực xanh, họ rất miễn cưỡng chuyển đổi từ ngôn ngữ / phiên bản mà họ đã biết.

Thay đổi mã đang chạy, "hoạt động tốt" không phải là thứ được xếp hạng cao trong danh sách ưu tiên của bất kỳ dự án nào. Thay vì áp dụng nỗ lực vào những thứ mà các nhà quản lý nghĩ đã được trả tiền, chỉ để có thể nâng cấp lên phiên bản mới hơn của ngôn ngữ hoặc nền tảng, họ sẽ đồng ý rằng các nhà phát triển nên tiếp tục phát hành cũ "ngay bây giờ". Bạn có thể cố gắng lôi kéo người dùng của mình bằng các tính năng tuyệt vời chỉ có trong bản phát hành mới, nhưng đó là một canh bạc khi bạn có nguy cơ giảm cơ sở người dùng của mình để không đạt được ngôn ngữ rõ ràng; Các tính năng hiện đại, mát mẻ không thể dễ dàng bị cân nhắc so với giá của cơ sở lắp đặt bị phân mảnh theo quan điểm phổ biến và bạn có nguy cơ bị mang tiếng là "máy chạy bộ nâng cấp"

(Rõ ràng, hầu hết những điều này không áp dụng cho các dự án được viết bởi những người có sở thích chỉ vì niềm vui của riêng họ. Tuy nhiên (ở đây là flamebait ...) PHP hiếm khi được tin tặc chọn bởi vì đó là một niềm vui để viết ngay từ đầu. )


65

Bạn đang đánh giá thấp tác động của khả năng tương thích ngược; ước tính của bạn rằng tất cả các dự án đang hoạt động sẽ di chuyển trong 3 hoặc 4 năm là quá lạc quan.

Giả sử tôi là một nhà phát triển PHP. PHP có những sai sót, nhưng tôi biết cách khắc phục những lỗi đó - đó là một phần lý do tôi được trả tiền khi là nhà phát triển PHP. Bây giờ giả sử rằng PHP 8 xuất hiện và sửa các lỗi đó, nhưng nó không tương thích ngược. Kết quả là:

  • Tôi phải dành thời gian cập nhật mã cho PHP 8. Đó là thời gian mà tôi có thể dành để đáp ứng các yêu cầu của khách hàng, thực hiện các tính năng mới, theo kịp sự cạnh tranh.
  • Ngay cả sau khi tôi đã làm điều này , rất có thể tôi đã bỏ lỡ một số trường hợp góc hoặc vấn đề tương thích không lường trước được, giới thiệu các lỗi trong mã của tôi.

Vì điều này, có một động lực mạnh mẽ để không bao giờ chuyển sang PHP 8, ngay cả khi nó "tốt hơn, rõ ràng hơn, an toàn hơn, v.v." Người ta ước tính rằng vẫn còn hàng tỷ dòng COBOL (!) - mặc dù rõ ràng có sẵn các công nghệ tốt hơn nhiều, chi phí cho một bản cập nhật, kết hợp với rủi ro của các lỗi, chỉ là nó không xứng đáng.

Thứ hai, ngay cả khi tôi quyết định di chuyển mã của riêng mình, bất kỳ ứng dụng không cần thiết nào cũng phụ thuộc vào thư viện của bên thứ ba và không có gì đảm bảo rằng các thư viện của bên thứ ba sẽ di chuyển. Ví dụ, Python 3 đã được phát hành vào tháng 12 năm 2008, nhưng Django (có lẽ là khung web Python hàng đầu) đã không hỗ trợ Python 3 ổn định, sẵn sàng sản xuất trong gần năm năm (xem tại đâytại đây ).


8
Có một số lượng lớn các vị trí COBOL đáng ngạc nhiên mở ra, đặc biệt là với các công ty bảo hiểm cũ Oo
Chad Harrison

1
@Josh Kelley: Tôi đồng ý với bạn nhưng tôi nghĩ rằng những vấn đề này chỉ ảnh hưởng đến các ngôn ngữ mà bạn không thể tách biệt rõ ràng mã kế thừa khỏi mã mới, ví dụ Python, PHP vì bạn cần bao gồm các thư viện và C ++ (mẫu). Các ngôn ngữ có mô hình biên dịch khác nhau (ví dụ Java, Scala, Clojure) cho thấy có thể thêm mã mới (ví dụ: trong Clojure) vào mã kế thừa (ví dụ như trong Java) mặc dù hai ngôn ngữ không tương thích ở cấp mã nguồn.
Giorgio

2
Tôi không biết liệu tôi nên đăng bài này dưới dạng câu hỏi riêng biệt hoặc dưới dạng nhận xét. Nhưng tại sao họ không thể tạo ra một ngôn ngữ lập trình nâng mức di chuyển mã lên một khái niệm hạng nhất? Trong java, có một chú thích @Deprecated chỉ đưa ra cảnh báo cho bạn. Có lẽ một ngôn ngữ khác thực sự có thể cung cấp một macro thay thế mã cũ bằng mã mới chính xác. Nếu bạn đang sử dụng phiên bản mới nhất, sẽ không có lỗi khi gọi mã không dùng nữa, nhưng mã cũ được chuyển đổi sang sử dụng mã mới không được dùng nữa. Chỉ cần spitballin '
Daniel Kaplan

7
@tieTYT - Một số ngôn ngữ lập trình thực hiện điều này - xem gofix 2to3 hoặc Go's gofix ( talk.golang.org/2012/Station.slide#68 ). Nó chắc chắn sẽ giúp loại bỏ các tính năng cũ, nhưng có giới hạn về việc phần mềm có thể hiểu và cập nhật phần mềm khác tốt như thế nào khi ngữ nghĩa ngôn ngữ thay đổi.
Josh Kelley

3
@hydroparadise Dì tôi làm việc với tư cách là nhà phát triển với các ngân hàng và công ty bảo hiểm, và trong những ngày khủng hoảng này, một số khách hàng của công ty bà đã quyết định quay lại với COBOL vì phần mềm rẻ hơn! Vì vậy, ngay cả nền kinh tế cũng có thể ảnh hưởng đến tốc độ các công ty chuyển sang các ngôn ngữ / phiên bản mới hơn.
Bakuriu

17

Bạn đang đưa ra rất nhiều giả định về hành vi của con người. Nếu bạn thay đổi nó quá nhiều, mọi người sẽ đánh giá đối thủ của bạn, vì dù sao họ cũng sẽ phải bỏ ra công sức đáng kể để chuyển đổi. Đối với các ngôn ngữ nguồn mở, mọi người sẽ chỉ rẽ nhánh phiên bản cũ.

Nhìn vào con trăn cho một ví dụ. 3.x đã có sẵn trong bốn năm, và vẫn chưa được áp dụng rộng rãi. Mọi người cố gắng sử dụng nó cho các dự án hoàn toàn mới, nhưng tôi nghĩ rằng bạn đang đánh giá thấp công việc bảo trì mã.

Tất nhiên, hầu hết mọi người đã không coi python 2.x là "thiếu sót". Họ không có khiếu nại như người dùng php. Php ở một vị trí bấp bênh hơn nhiều, bởi vì rất nhiều người chỉ gắn bó với nó vì cơ sở mã lớn hiện có của nó. Nếu bạn mất khả năng tương thích ngược, rất nhiều người sẽ nắm lấy cơ hội mà họ đã chờ đợi để chuyển sang python.


Tôi nghĩ rằng bạn có một điểm tốt ở đây (+1). Tôi nghĩ khả năng tương thích ngược là một vấn đề sai, đặc biệt đối với các ngôn ngữ được biên dịch trong đó bạn có thể sử dụng trình biên dịch riêng biệt (xem cách bạn có thể tích hợp Scala và Clojure với Java hoặc C # với C ++). Nhưng giữ cho cảm giác rằng ngôn ngữ mới, rốt cuộc, chỉ là một phiên bản cập nhật của ngôn ngữ cũ là rất quan trọng để tránh một ngã ba hoặc mọi người chỉ đơn giản chuyển sang ngôn ngữ khác. Tôi nghĩ những lý do này mạnh hơn nhiều so với việc xử lý mã kế thừa.
Giorgio

1
@Giorgio Vấn đề sai? Nói với tất cả các nhà văn thư viện, những người phải hỗ trợ nhiều phiên bản ngôn ngữ hơn cùng một lúc.
Svick

@svick: Với trình biên dịch riêng biệt, bạn không cần phải hỗ trợ các phiên bản ngôn ngữ khác nhau. Xem ví dụ về cách Scala có thể sử dụng các thư viện Java không được biên dịch cho Scala.
Giorgio

9

Đối với bất kỳ ngôn ngữ nào khác ngoài PHP tôi muốn nói, ừ, điều đó hoàn toàn có ý nghĩa! Đó chính xác là những gì Python đang làm với việc chuyển sang Python 3.

Tuy nhiên, vấn đề với PHP là có quá nhiều lỗ hổng với chính thiết kế ngôn ngữ, do đó, cái mà bạn gọi là "PHP 8" sẽ là một ngôn ngữ hoàn toàn khác. Và nếu bạn phải chuyển sang ngôn ngữ khác, tại sao bạn lại gắn bó với PHP mới, thay vì bất kỳ giải pháp thay thế hiện tại và ổn định nào?

Cộng đồng PHP cực kỳ chậm để thích nghi với mọi thứ mới. Chỉ cần nhìn bao lâu để thoát khỏi register_globals. Nó được biết đến là một rủi ro bảo mật kể từ năm 2000. Cuối cùng, nó chỉ được gỡ bỏ 12 năm sau đó. Một ví dụ khác, khi PHP5 được giới thiệu, đó là một cải tiến lớn so với PHP4, nhưng cộng đồng đã không thích ứng với nó. Tôi mất 4 năm và những hành động lớn như GoPHP5 để bắt đầu nhận con nuôi. Và điều đó thậm chí không có lượng thay đổi không tương thích ngược đáng kể.


5

Tuyên bố miễn trừ trách nhiệm: Tôi quản lý nhóm người dùng ColdFusion.

ColdFusion bị những vấn đề tương tự: được nhiều người yêu thích, bị nhiều người coi thường. Ngoài ra, hàng tấn và tấn FUD dựa trên các phiên bản tiền Java. ColdFusion 10 đã xuất hiện vào năm ngoái, là một người bán khổng lồ và tuần trước tôi đã đăng ký để thử nghiệm phiên bản tiền phát hành 11. Ngoài ra, có hai lựa chọn thay thế nguồn mở lớn, một được hỗ trợ bởi JBoss.

Có rất nhiều chức năng mới trong CF10 mà tôi muốn triển khai, nhưng việc di chuyển từ CF 7 hoặc 8 có thể khó khăn tùy thuộc vào quy mô cơ sở mã của bạn, số lượng dự án sắp tới và tài nguyên bạn phải kiểm tra hồi quy mọi thứ một khi bạn Phiên bản mới nhất. Tôi đã gặp phải một số khác biệt nhỏ về cú pháp giữa 8 và 9, cũng như các trường hợp cạnh trong đó mã không biên dịch theo cùng một cách. Khi được tìm thấy, tôi đã ghi lại chúng vào Tiêu chuẩn mã hóa của chúng để chúng không được sử dụng trong các dự án trong tương lai hoặc bởi các nhà phát triển mới.

Điều đó nói rằng, nếu ColdFusion 11 (hoặc bất kỳ ngôn ngữ lập trình nào) không hoàn toàn phản đối một số chức năng và cú pháp nhất định, thì mức độ nỗ lực để tìm và thay thế chức năng có thể là rất lớn. Những nỗ lực thử nghiệm có thể là rất lớn. Các công ty sẽ trả cho các nhà phát triển, QA và người quản lý dự án của họ để tìm, thay thế và kiểm tra tất cả những thứ không dùng nữa? Nghi ngờ.

Nếu phiên bản mới nhất của ngôn ngữ tương thích ngược, nhưng giới thiệu hiệu suất tăng mà không thay đổi mã (CF9 nhanh hơn khoảng 30% so với CF8 và CF10 nhanh hơn CF9), ai quan tâm đến việc thay đổi chức năng gọi nếu chúng vẫn hoạt động?

Là một công ty, chúng tôi phải lo lắng về việc làm hài lòng khách hàng và cung cấp nhu cầu của họ để lập hóa đơn dịch vụ, xây dựng doanh nghiệp và tuyển dụng thêm khách hàng.

FWIW, tôi rất muốn đưa chúng tôi lên phiên bản jQuery mới nhất vào một lúc nào đó, nhưng vì một số chức năng đã bị từ chối một vài phiên bản sau những gì chúng tôi sử dụng và đưa ra khối lượng JavaScript chúng tôi có trong hệ thống, tôi không biết làm thế nào chúng ta sẽ thực hiện điều đó


4

Có một sự đánh đổi ở đây; một số lỗi THỰC SỰ cần sửa, nhưng một số thứ không thể thay đổi mà không vi phạm mã của ai đó. Tôi dường như nhớ ai đó nói rằng "quy tắc" rằng mọi lỗi sẽ phá vỡ dự án của ai đó, bất kể lỗi đó rõ ràng hay bị phá vỡ như thế nào, ai đó sẽ sử dụng nó cho mục đích gì đó. Đó là bản chất của lập trình viên.

Đây là (theo suy nghĩ của tôi) sự khác biệt giữa các bản phát hành chính, bản phát hành nhỏ và bản sửa đổi. Theo nguyên tắc chung:

  • Các bản phát hành chính được cho là có chứa các thay đổi vi phạm.
  • Phát hành nhỏ có thể thay đổi hành vi một chút.
  • Các phiên bản nên tương thích chéo khá nhiều.

Ví dụ: nếu tôi đang viết một cái gì đó trong v2.3 của một ngôn ngữ, tôi sẽ không nhận thấy bất kỳ sự khác biệt nào nếu tôi nâng cấp lên v2.3.2. Nếu tôi nâng cấp lên v2.4, thì một vài thứ có thể thay đổi - các cú pháp cú pháp nhỏ, một số chức năng hoạt động hơi khác một chút nên tôi phải điều chỉnh logic, v.v. Nếu tôi nâng cấp lên v3.0, tôi sẽ không ngạc nhiên nếu nó bị hỏng hoàn toàn - các chức năng không được chấp nhận hoặc bị thiếu, các hoạt động không được hỗ trợ hoặc thay đổi nhiều đến mức tôi không thể điều chỉnh lại thành dòng, tôi thực sự phải viết lại một số chức năng để tính đến các thay đổi mới.

Biên tập:

Chiến lược phân nhánh SCM nâng cao của Steve Vance có ý nghĩa như sau:

Thông thường, có hai đến ba cấp phát hành, được đặt tên theo các số được kết nối với các dấu chấm (ví dụ: 1.2.3). [...] Trong cấu trúc này, số đầu tiên được liên kết với một phiên bản chính, chỉ ra rằng nó có các cải tiến về tính năng và chức năng quan trọng so với trước đó; cũng có thể có sự không tương thích đáng kể yêu cầu di chuyển. Số thứ hai đại diện cho một phiên bản nhỏ, chứa các cải tiến về tính năng và chức năng ít hơn, một số lượng đáng kể các sửa lỗi và không có sự không tương thích. Số thứ ba đề cập đến một mức độ vá lỗi, biểu thị gần như độc quyền một bộ sưu tập các bản sửa lỗi; không cải tiến tính năng hoặc chức năng và không cho phép không tương thích giữa các cấp độ bản vá.

Sự thay đổi duy nhất tôi thực hiện cho điều này là nguyên tắc đã nói ở trên mà các lập trình viên thường tìm cách "sử dụng" các lỗi, do đó, một phiên bản nhỏ với "một số lượng sửa lỗi đáng kể và không tương thích" có thể khó khăn, bởi vì đó có thể là những lỗi đó lỗi sẽ phá vỡ thứ gì đó đã sử dụng chúng hoặc sẽ khiến cách giải quyết trở nên không cần thiết và bắt đầu gây ra sự cố.


Tôi mong đợi 2.3-> 2.4 để thêm chức năng, nhưng không xóa nó.
Donal Fellows

1
Thật trùng hợp, tôi đã bắt gặp một trích dẫn có liên quan gần đây. Nó hơi dài cho một nhận xét, vì vậy tôi sẽ chỉnh sửa câu trả lời của mình.
anaximander

2

Nó thực sự phụ thuộc vào mục tiêu của ngôn ngữ - loại ứng dụng nào được dự định xây dựng bằng ngôn ngữ.

Ví dụ, bỏ qua Android, Java chủ yếu được sử dụng trong các hệ thống doanh nghiệp lớn và kho trung gian; những loại ứng dụng này có xu hướng trở nên rất lớn cả về kích thước và thời gian. Điều này có một số hàm ý; hãy tưởng tượng một hệ thống với 500K + LoC mà công nhân 50+ kỹ sư đang trong giai đoạn phát triển. Thông thường, loại hệ thống này được bảo trì sau đó với 10 nhà phát triển; bây giờ nếu ngôn ngữ thay đổi và thay đổi không tương thích ngược, dự án không thể dễ dàng chuyển sang phiên bản mới vì các lập trình viên đã viết một số phần đã biến mất và không ai muốn chạm vào nó. Đây là vấn đề nhỏ hơn, vấn đề lớn hơn bao gồm thực tế là rất tốn kém để thích ứng ứng dụng 500 LoC với các ràng buộc ngôn ngữ mới. Ví dụ: nếu thuốc generic không được thực hiện với kiểu xóa vàList list = new List(); sẽ không biên dịch hàng triệu dòng mã sẽ cần phải viết lại - đó là một chi phí lớn.

Mặt khác, PHP có xu hướng được sử dụng trên web cho các ứng dụng đơn giản hơn; thông thường nó được phát triển bởi một lập trình viên duy nhất hoặc một nhóm nhỏ. Ý tưởng là loại nhà phát triển biết toàn bộ dự án khá tốt có thể tích hợp thay đổi ngôn ngữ dễ dàng hơn. Ngoài ra, mục đích của nó là xây dựng một trang web rất nhanh, và càng nhanh thì càng tốt vì vậy nếu một tính năng ngôn ngữ mới có thể làm điều này tốt hơn thì nó được thực hiện ngay cả với một số chi phí tương thích ngược.


1

Người ta có thể lập luận rằng Microsoft đã thực hiện một thay đổi tương tự với ASP.NET (với tư cách là người kế thừa cho ASP cổ điển) hoặc với VB.NET (mặc dù họ đã nhượng bộ rất nhiều vì sau đó hầu hết các lợi ích của việc "khởi động lại" ngôn ngữ đã bị mất).

Dù sao, nếu bất cứ ai nhớ đến cơn ác mộng Di chuyển mã VB6 sang VB.NET ngay cả với sự hỗ trợ của công cụ di chuyển, họ sẽ đồng ý ngay rằng các công cụ di chuyển ngôn ngữ không hoạt động tốt cho các cập nhật ngôn ngữ chính.

Có thể có thể di chuyển nền tảng về phía trước, nhưng, bạn vẫn nên cung cấp hỗ trợ cho các API "không dùng nữa" thông qua ít nhất một vài sửa đổi.


1

Rất nhiều "lỗ hổng" mà mọi người hét lên trong các ngôn ngữ lập trình phổ biến không phải, đó là những thứ đồ chơi yêu thích của người la hét ngày nay mà ngôn ngữ đó thiếu, vì vậy ngôn ngữ đó bị thiếu sót một cách cơ bản vì nó thiếu ngôn ngữ đó.
Sự cường điệu tiếp theo xuất hiện, ngôn ngữ đột nhiên bị lỗi vì nó không tuân theo sự cường điệu đó.

Việc thiếu các bao đóng trong Java là một ví dụ cổ điển. Đó hoàn toàn không phải là một lỗ hổng trong ngôn ngữ và việc thay đổi ngôn ngữ (đáng buồn là trong chương trình nghị sự) để đưa chúng vào IMO về cơ bản làm tê liệt nó hoặc ít nhất làm cho việc đọc và hiểu trở nên khó khăn hơn rất nhiều.

Điều mà quá nhiều người mất đi là mỗi ngôn ngữ đều có điểm mạnh và điểm yếu và việc cố gắng tạo ra thứ gì đó kết hợp các điểm mạnh của mọi thứ trong khi tránh mọi điểm yếu sẽ chỉ tạo ra một con quái vật hoàn toàn không thể sử dụng, không có gì là không thể, không thể bảo vệ, không thể sử dụng hiệu quả.

Thêm vào, như những người khác đã chỉ ra, khả năng tương thích ngược là rất quan trọng để giữ chân người dùng hiện tại, nhiều người trong số họ sẽ KHÔNG dành hàng ngàn giờ và hàng triệu đô la / Euro để trang bị thêm hàng triệu tiền mã hóa cho bất cứ điều gì bạn nghĩ là "tốt hơn" so với phiên bản ngôn ngữ mà họ đã sử dụng trong nhiều năm qua và bạn có rất nhiều lý lẽ rất hay để lại một mình đủ tốt và nếu bạn muốn chơi với một số ý tưởng vượt trội mới được cho là "kẻ giết java" tiếp theo, bạn ' d tốt nhất chơi với đồ chơi đó thay vì hét lên rằng "Java iz cống hiến" trừ khi nó "được sửa" thành bản sao của đồ chơi đó.


1

Tôi sẽ đề nghị rằng các phiên bản mới hơn của ngôn ngữ nên cố gắng đảm bảo rằng 99.99999% mã được biên dịch trong cả hai phiên bản cũ và mới của ngôn ngữ sẽ hoạt động giống hệt nhau trừ khi nó được thiết kế không cố ý và hầu hết thời gian khi phiên bản mới từ chối mã được biên dịch theo phiên bản cũ, đó sẽ là do mã đó - tốt nhất là - tinh ranh, và nên được viết theo một cách khác để biên dịch theo cả trình biên dịch cũ và mới.

Ví dụ: nếu tôi đang thiết kế một ngôn ngữ mới tương tự như Java hoặc C #, tôi sẽ cấm chuyển đổi kiểu ngầm định trong một số ngữ cảnh nơi các ngôn ngữ đó cho phép chúng. Như một ví dụ đơn giản trong C #, được đưa ra

int someInt;
double someDouble;

biểu thức someInt.Equals(someDouble)được đảm bảo trả về false, bất kể nội dung của các biến. Nó biên dịch bởi vì doublecó thể được chuyển đổi thành ObjectintEqualsquá tải cho loại đó, vì vậy trình biên dịch thực hiện chuyển đổi và thực hiện cuộc gọi. Tôi đã thiết kế một phiên bản mới của C # và .NET Framework, tôi sẽ cấm nó chuyển đổi quyền anh vì nó không thể làm bất cứ điều gì hữu ích. Có thể có một số chương trình so sánh theo cách vô dụng nhưng vô hại và việc trình biên dịch từ chối mã đó có thể phá vỡ chương trình đó, nhưng sửa hoặc xóa mã vô dụng đó sẽ là một sự cải tiến.

Như một ví dụ ít rõ ràng hơn, giả sử

float f=16777216f;
int i=16777217;

và xem xét biểu thức f==i. Có thể là một số mã không nổi so sánh / số nguyên và làm việc một cách chính xác, nhưng các mã nên được viết lại như một trong hai f==(float)i, (double)f==i;hoặc (double)f==(double)i;[ intđể doublexúc tiến là lossless, vì vậy sau này hai sẽ tương đương]. Một số mã so sánh trực tiếp floatintegercác giá trị có thể luôn luôn xử lý các số đủ nhỏ floatdoubleso sánh sẽ hoạt động giống hệt nhau, nhưng một trình biên dịch thường không thể biết điều đó; mã cần làm rõ loại so sánh nào là cần thiết, thay vì hy vọng các quy tắc của ngôn ngữ sẽ phù hợp với ý định của lập trình viên.


1

Tốt nhất là không bao giờ phá vỡ tính tương thích ngược.

Microsoft đã thay thế ngôn ngữ lập trình VB6 bằng một ngôn ngữ mới hoàn toàn phá vỡ tính tương thích. Vì vậy, ngay cả ngày nay, VB6 16 tuổi vẫn phổ biến hơn phiên bản dotNet (chỉ số Tiobe tháng 8 năm 2014). Và Gartner ước tính có 14 tỷ dòng mã VB6 vẫn đang được sử dụng.

Năm 2014, Microsoft một lần nữa phải tuyên bố họ sẽ không cập nhật hoặc mở VB6 bất chấp yêu cầu từ cộng đồng lập trình Visual Basic. Nhưng họ đã mở rộng hỗ trợ VB6 cho đến 'ít nhất là' năm 2024 và nó hoạt động tốt trên Windows 7 và 8. Đó sẽ là hơn 26 năm hỗ trợ cho cùng một phiên bản VB6.

Tại sao phần mềm làm việc hiện tại phải được viết lại, thậm chí Microsoft không bao giờ "cập nhật" Office để sử dụng dotNet?


điều này dường như không cung cấp bất cứ điều gì đáng kể so với 14 câu trả lời trước
gnat

1

Có một vài vấn đề khác nhau với việc phá vỡ tính tương thích ngược. Một số vấn đề xuất phát từ thực tế là hầu hết các ngôn ngữ lập trình cũng là nền tảng (phiên dịch / thời gian chạy), các vấn đề khác xuất phát từ một giả định về bản chất con người.

A. Mã được viết trong các phiên bản cũ hơn sẽ không nhận được lợi ích của các bản phát hành mới giúp cải thiện hiệu suất, bảo mật hoặc tính năng. Bạn có thể giảm thiểu vấn đề này bằng cách hỗ trợ nhiều phiên bản chính của trình biên dịch / trình thông dịch, nhưng đó là một sự tiêu tốn tài nguyên rất lớn (tức là nó tốn kém hoặc mất nhiều thời gian, và là một nỗi đau ở mông).

B. Mã được viết cho các phiên bản mới hơn có thể không tương thích với mã được viết trong các phiên bản cũ hơn. Bạn có thể giải quyết vấn đề này bằng cách có một trình thông dịch / trình biên dịch có thể xử lý nhiều phiên bản chính của ngôn ngữ, nhưng điều này gây khó khăn hơn cho việc hỗ trợ trình thông dịch / trình biên dịch riêng biệt (cách giải quyết cho A).

C. Những thay đổi lớn, nếu chúng xảy ra quá thường xuyên / nhanh chóng cũng đơn giản làm cho ngôn ngữ khó sử dụng hơn, vì bạn có nhiều thứ để học và không học. Thay đổi ngôn ngữ có thể đẩy mọi người vượt ra ngoài để chuyển sang ngôn ngữ mới hoặc có thể khiến mọi người tiếp tục sử dụng các phiên bản ngôn ngữ lỗi thời và không bao giờ chuyển sang phiên bản mới (như đã xảy ra với python). Sau đó, một lần nữa, những thay đổi cũng có thể thu hút người dùng mới và kích thích những người dùng cũ.

D. Tài liệu mới cần được lưu giữ và duy trì. Đây luôn là một trải nghiệm khá khó hiểu khi tìm kiếm mọi thứ trên google và thấy rằng bạn đang đọc tài liệu cho một phiên bản khác so với hiện tại bạn đang sử dụng.

Nhìn chung, nếu bạn tạo một ngôn ngữ lập trình trong đó các mô-đun bên ngoài không cần quan tâm bạn đang sử dụng phiên bản nào, phá vỡ tính tương thích ngược vì những lý do chính đáng (để sửa các lỗi chính trong ngôn ngữ) gần như là điều nên làm . Có khả năng lý do chính điều này không được thực hiện là do các nhà thiết kế ngôn ngữ lập trình đánh giá quá cao ( để phản bác lại câu trả lời của người khác ) về chi phí phá vỡ tính tương thích, đặc biệt là từ rất sớm. Thực tế là, các vấn đề về khả năng tương thích có thể được giải quyết xung quanh hoặc được cung cấp bởi người dùng ngôn ngữ đó. Và điều này không chỉ giữ cho các ngôn ngữ lập trình; điều này áp dụng cho API, giao diện người dùng - thực sự là bất kỳ giao diện nào trong mọi tình huống.

Facebook làm phiền mọi người khi họ thay đổi giao diện người dùng hoặc API nhà phát triển. Trong quá khứ, nó làm cho nền tảng khó làm việc. Trong một số trường hợp, API chỉ đơn giản là ngừng hoạt động. Nhưng mọi người vẫn tiếp tục sử dụng nó, và bây giờ các API và UI là những bước nhảy vọt tốt hơn so với 5 năm trước. Mọi người sẽ phàn nàn về sự thay đổi dù nó tốt hay xấu đối với họ, nhưng điều đó (phàn nàn) không phải là lý do chính đáng để từ bỏ sự thay đổi đó. Thật không may, các nhà phát triển ngôn ngữ lập trình sử dụng điều này như một lý do để giữ nguyên các vấn đề về ngôn ngữ của họ.

Vì vậy, một số lý do khác khiến các ngôn ngữ không thực hiện các thay đổi đột phá để cải thiện bản thân là:

E. Các nhà phát triển ngôn ngữ nghĩ rằng người dùng của họ sợ thay đổi là lý do chính đáng để trì trệ ngôn ngữ của họ

F. Các nhà phát triển ngôn ngữ thích ngôn ngữ của họ khi họ tạo ra nó, và họ có thể nghĩ rằng nó chỉ tốt với những sai sót của nó.

G. Ngôn ngữ khi chúng lớn lên thường không còn có một nhóm nhỏ các nhà phát triển, và biến thành những con thú được xây dựng bởi nhiều ủy ban hơn. Điều này có nghĩa là các quyết định về những ngôn ngữ này chậm và thường bảo thủ và không sáng tạo.

H. Lý do cuối cùng là một số thay đổi vi phạm đòi hỏi phải đánh giá lại đáng kể các quyết định thiết kế được thực hiện cho trình thông dịch / thời gian chạy. Đôi khi những cải tiến về ngôn ngữ chỉ đơn giản là đòi hỏi quá nhiều công việc để có thể khả thi. Tôi đoán đây là một vấn đề hiếm hơn hầu hết tho.

Thông thường, các nhà thiết kế ngôn ngữ không nhất thiết phải là người thiết kế công cụ và vì vậy họ không nghĩ ra giải pháp tốt cho vấn đề này hoặc họ không thực hiện chúng tốt. Dưới đây là một số giải pháp tôi có thể nghĩ ra để giải quyết vấn đề thay đổi đột phá:

  1. Khấu hao mọi thứ trước khi chúng sẽ được gỡ bỏ.

  2. Cung cấp một công cụ chuyển đổi tốt , tiêu chuẩn. Python cung cấp công cụ 2to3, nhưng nó không được quảng cáo tốt, không đạt tiêu chuẩn với python 3 như tôi nhớ và thậm chí không hoạt động tốt (tôi nhớ phải tự mình trải qua các chương trình được tạo bởi 2to3 để khắc phục sự cố không sửa chữa). Công cụ chuyển đổi này thậm chí có thể tự động chạy nếu trình biên dịch / trình thông dịch của bạn phát hiện phiên bản cũ hơn. Điều gì có thể dễ dàng hơn?


Vấn đề với sự tương tự của Facebook là không có Di sản Facebook nào được sử dụng. Không có lựa chọn. Hoặc bạn sử dụng phiên bản hiện tại của Facebook hoặc bạn hoàn toàn không sử dụng Facebook. Trong khi đó, vẫn còn hàng tấn người sử dụng Python 2bảy năm sau khi phát hành Python 3vì nó vẫn tồn tại - nếu không, họ sẽ càu nhàu, nhưng họ sẽ chuyển đến Python 3.
Kevin

Tôi không nghĩ đó là một vấn đề với sự tương tự, đó thực sự là quan điểm của tôi. Facebook đã chọn con đường "sửa lỗi" và chủ yếu tránh lộ trình "tương thích ngược". Đó là lý do tại sao họ không có phiên bản kế thừa của API. Đó là một ví dụ hoàn hảo về một thái cực.
BT

Phá vỡ tính tương thích ngược trong các ngôn ngữ lập trình sẽ chỉ dẫn đến việc mọi người tiếp tục sử dụng và / hoặc bỏ qua phiên bản cũ. Phiên bản cũ của Facebook không còn tồn tại nữa; Tôi cho rằng bạn có thể tạo một bản sao hỗ trợ API cũ, nhưng không ai sẽ sử dụng nó, bởi vì Facebook là một thương hiệu có lượng người dùng khổng lồ.
Kevin

Facebook có lợi thế là khi cập nhật, các phiên bản trước về cơ bản không còn tồn tại nữa. Ngôn ngữ lập trình không giống như vậy và đó là một sự khác biệt có liên quan - bạn có thể sử dụng phiên bản lỗi thời của ngôn ngữ lập trình, chẳng hạn như Python 2, vì nó vẫn tồn tại.
Kevin

Tôi thấy điểm của bạn. Tôi vẫn nghĩ rằng một đầu của hai thái cực. Nếu các lỗ hổng lớn trở nên rõ ràng trong một phiên bản ngôn ngữ không được hỗ trợ, thì nó có thể nằm dọc theo dòng của phiên bản đó không còn tồn tại, bởi vì không ai muốn sử dụng nó.
BT

0

Tôi không biết đó có phải là vấn đề đối với mã PHP hay không, nhưng trong nhiều ngôn ngữ cũ, mã kế thừa không bao giờ được cập nhật sau nhiều năm hoặc đôi khi, thậm chí hàng thập kỷ, vì nó hoạt động, rất quan trọng đối với doanh nghiệp vận hành nó và quá lớn (nói hàng triệu SLOC), vì vậy sẽ không có ý nghĩa khi viết lại nó. Đó là lý do tại sao java biến khả năng tương thích ngược trở thành một vấn đề gần như tôn giáo, mặc dù biết các vấn đề cũ, đặc biệt là trong các thư viện (ngay cả khi chúng dễ cập nhật hơn). Tôi đoán rất nhiều mã từ nhân Linux cũng không được cập nhật trong nhiều thập kỷ, mặc dù việc áp dụng các tiêu chuẩn như C99 và C11.

Ngay cả trong các ngôn ngữ ít "vướng víu", việc phá vỡ mã chức năng cũ có thể là một vấn đề. Đó là những gì đã xảy ra với Python 2 -> 3. Cả một loạt các thư viện và tập lệnh hệ thống đã ổn định và không được duy trì nữa, không phải vì chúng bị bỏ rơi mà vì chúng ổn định và thực hiện công việc của chúng. Thích nghi với chúng mất một vài năm. Vì vậy, với tư cách là nhà phát triển, bạn không nhất thiết phải chuyển sang python 3 nếu thư viện yêu thích của bạn chưa thực hiện di chuyển, do đó, mã của riêng bạn cũng không hoạt động theo python 3, do đó dẫn đến sự phân mảnh cộng đồng.


-1

Vấn đề nằm trong vấn đề tương thích ngược. Hầu hết các tập lệnh PHP tôi thực thi đang chạy trên máy chủ RedHat cũ hơn. Nếu tôi sử dụng phiên bản mới hơn của ngôn ngữ cho các tập lệnh trong tương lai, thì tôi sẽ phải cập nhật PHP trên máy chủ này - và có nguy cơ bị các tập lệnh cũ hơn bị hỏng / phải mất hàng giờ để viết lại tất cả mã cũ bằng tiêu chuẩn mới. Thêm vào đó, tất cả các nhà phát triển của tôi đã quen với PHP phản ứng theo một cách nhất định (cho dù cách đó có bị 'hỏng' hay không). Nếu nó không còn phản ứng theo cách đó, nó có thể là một trở ngại lớn cho năng suất, vì về cơ bản các nhà phát triển có thể phải tự dạy lại PHP.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.