Sử dụng một hệ thống loại mạnh mẽ của người Viking trong thế giới thực, giả sử, cho các ứng dụng web quy mô lớn?


29

Tôi biết đây là một câu hỏi rất rộng, mơ hồ và có thể là triết học. Ở một mức độ nào đó, từ khóa quan trọng nhất trong câu hỏi - hệ thống loại "mạnh" - chính nó, là không xác định . Vì vậy, hãy để tôi cố gắng giải thích những gì tôi có ý nghĩa.

Tổng thể bối cảnh cho câu hỏi

Chúng tôi đã xây dựng một ứng dụng web quy mô rất lớn trong Ruby on Rails và chúng tôi thường rất vui về ngăn xếp của chúng tôi. Khi chúng tôi muốn, chúng tôi có thể vận chuyển công cụ thực sự nhanh chóng - thứ gì đó hoạt động cho 90% trường hợp "kinh doanh", mà không phải lo lắng quá nhiều về các trường hợp cạnh 10%. Mặt khác, với sự trợ giúp của đánh giá mã & phạm vi kiểm tra, chúng tôi có thể chậm và cân nhắc và đảm bảo rằng chúng tôi bao quát tất cả các cơ sở - một lần nữa, chỉ trong các tình huống có sự giám sát và an toàn chặt chẽ hơn như vậy.

Tuy nhiên, khi nhóm phát triển, tôi bắt đầu thấy khó chịu với việc thiếu "mạng lưới an toàn" được nướng ngay vào ngăn xếp của chúng tôi.

Gần đây chúng tôi đã bắt đầu thực hiện một số phát triển Android gốc trên Java. Và tôi đã được nhắc nhở về sự an toàn được cung cấp bởi một ngôn ngữ được biên dịch / tĩnh / gõ mạnh.

  • Các biến sai chính tả, các kiểu dữ liệu sai, các hàm hàm không chính xác và một loạt các lỗi nhỏ được chính IDE của bạn bắt được. Tất cả chỉ vì IDE có thể nối vào trình biên dịch và xác minh các khía cạnh nhất định của "tính chính xác" của chương trình.
  • Cần thay đổi một chữ ký chức năng? Dễ dàng. Trình biên dịch + IDE có thể giúp bạn phát hiện TẤT CẢ các trang web cuộc gọi.
  • Cần đảm bảo rằng các ngoại lệ nhất định luôn được xử lý? Đã kiểm tra ngoại lệ để giải cứu bạn.

Bây giờ, trong khi các tính năng an toàn này có những ưu điểm của chúng, tôi cũng nhận thức được những nhược điểm của chúng. Hơn nữa, trong thế giới của Java "nồi hơi nặng". Do đó, thay vì Java, tôi đã bắt đầu nhìn vào hàng loạt các ngôn ngữ "gõ mạnh" hiện đại mà mọi người đã bắt đầu làm việc trong những ngày này. Ví dụ: Scala, Rust, Haskell, v.v. Điều tôi quan tâm nhất là sức mạnh của hệ thống loại của họ và kiểm tra thời gian tĩnh / biên dịch.

Bây giờ, câu hỏi

Làm cách nào để sử dụng các hệ thống loại mạnh mẽ này và các tính năng tĩnh / thời gian biên dịch trong các ứng dụng lớn hơn?

Ví dụ, làm thế nào tôi có thể vượt ra khỏi kiểu giới thiệu "hello world" tiêu chuẩn cho các tính năng mạnh mẽ này? Một hệ thống sử dụng hệ thống loại aa phong phú để mô hình hóa một vấn đề trong lĩnh vực kinh doanh? Hệ thống loại có giúp ích hay cản trở khi bạn ở trong khu vực 30.000 LỘC + không? Điều gì xảy ra với mạng lưới an toàn được cung cấp bởi các hệ thống loại này (và kiểm tra thời gian biên dịch) khi hệ thống của bạn tương tác với thế giới bên ngoài được gõ yếu, ví dụ. thông qua API JSON hoặc XML, các kho dữ liệu khác nhau, đầu vào của người dùng, v.v.


12
Đây không phải chủ đề vì không có câu trả lời thực sự. Câu hỏi nhằm kích động thảo luận có ý kiến ("Tôi thích / không thích các loại tĩnh vì ..."), không phải là giải thích thực tế . Lời khuyên của tôi là chọn một trong những phần cụ thể hơn trong câu hỏi của bạn, chẳng hạn như "Điều gì xảy ra với mạng lưới an toàn được cung cấp bởi các hệ thống loại này khi hệ thống của bạn tương tác với thế giới bên ngoài bị đánh máy yếu?" và viết lại câu hỏi để được về điều đó. Bạn sẽ nhận được câu trả lời dứt khoát sẽ hữu ích cho độc giả tương lai theo cách đó.
Benjamin Hodgson

5
Các đề xuất tài nguyên cũng không có chủ đề ở đây (vì những câu trả lời như vậy sẽ nhanh chóng bị lỗi thời và chúng tôi thực sự không có gì tốt hơn Google ở ​​đó). Như Benjamin đã nói, có một số câu hỏi có thể trả lời được chôn trong bài đăng của bạn, nhưng toàn bộ bài đăng ở trạng thái hiện tại về cơ bản là yêu cầu mọi người mô tả trải nghiệm của họ bằng các ngôn ngữ này, phù hợp hơn với Quora hoặc Reddit so với StackExchange trang web. Tôi không đánh giá thấp, bởi vì câu hỏi này được hỏi nhiều, nhưng đó không chỉ là câu hỏi StackExchange.
Ixrec

4
Một hệ thống loại là một công cụ, và giống như bất kỳ công cụ nào khác, hiệu quả của nó chủ yếu không phụ thuộc vào chính công cụ mà phụ thuộc vào người sử dụng. Bạn có thể tận dụng hệ thống loại ngôn ngữ như Haskell để mã hóa các bất biến về logic nghiệp vụ của bạn ở cấp độ loại và kiểm tra các bất biến đó bằng máy (trình biên dịch) tại thời điểm biên dịch, nhưng để làm được điều này, bạn cần hiểu về ngữ nghĩa của hệ thống loại và kiểm tra loại. Câu hỏi đúng không phải là "đây có phải là một công cụ tốt cho công cụ web không", đây là "đây là một số vấn đề cụ thể mà tôi gặp phải; làm thế nào một hệ thống loại mạnh có thể được sử dụng để giải quyết chúng?"
user2407038

5
Hầu hết những điều bạn mô tả không liên quan gì đến hệ thống loại. Chúng hoàn toàn là các tính năng IDE. Ngoại trừ (không có ý định chơi chữ) của các ngoại lệ được kiểm tra, tất cả các tính năng mà bạn đề cập đã có trong IDE của Smalltalk từ lâu trước khi chúng xuất hiện trong IDE cho các ngôn ngữ được nhập tĩnh. Trên thực tế, một trong những IDE Java được sử dụng rộng rãi nhất thực sự bắt đầu như một IDE Smalltalk đã được sửa đổi (IBM VisualAge Smalltalk, đã được sửa đổi để hiểu mã Java nhưng vẫn được viết bằng Smalltalk và được phát hành dưới dạng Java VisualAge, sau đó được chuyển sang Java và được phát hành dưới dạng đào
Jörg W Mittag

4
Phiên bản vi mô Java VisualAge, sau đó được chia thành các thành phần có thể sử dụng lại và được phát hành dưới dạng Nguồn mở dưới tên Eclipse). Hơi mỉa mai trong bối cảnh của câu hỏi này, chính là do tính chất năng động của các hệ thống Smalltalk mà các IDE của Smalltalk rất mạnh mẽ. Tái cấu trúc tự động đã được phát minh và lần đầu tiên được thực hiện trong Smalltalk. Theo logic của bạn, Haskell phải có các IDE tốt nhất vì nó có hệ thống loại tĩnh mạnh nhất, nghiêm ngặt nhất trong tất cả các ngôn ngữ bạn đã đề cập. Nhưng nó không. Bạn cũng đã đề cập đến "hooking vào trình biên dịch". Điều này có từ
Jörg W Mittag

Câu trả lời:


34

Tôi sẽ đưa ra một câu trả lời ngắn do hiện tại tôi không có thời gian, nhưng hiện tại tôi đang làm việc với hai dự án lớn (> 100.000 LỘC ở Haskell) - Flowbox.ioluna-lang.org. Chúng tôi sử dụng Haskell cho tất cả các phần, bao gồm phần phụ trợ, trình biên dịch ngôn ngữ lập trình của chúng tôi và thậm chí cả GUI dựa trên webGL. Tôi phải thừa nhận rằng hệ thống loại mạnh và máy móc giống như "loại phụ thuộc" có thể hướng dẫn bạn và cứu bạn khỏi gánh nặng và rắc rối được biết đến từ các ngôn ngữ khác. Chúng tôi sử dụng các loại rất rộng rãi và mọi thứ có thể được kiểm tra trong thời gian biên dịch, đều được thực hiện. Trên thực tế, trong 3 năm phát triển gần đây, chúng tôi chưa bao giờ gặp phải bất kỳ lỗi thời gian chạy hoặc lỗi tràn ngăn xếp nào (và đây là một điều thực sự đáng kinh ngạc). Các lỗi duy nhất là lỗi logic rõ ràng được thực hiện bởi các lập trình viên. Rất nhiều người nói rằng, nếu một cái gì đó biên dịch trong Haskell, nó chỉ hoạt động và bạn nên chắc chắn rằng nó sẽ không thổi vào mặt bạn một ngày nào đó.

Trả lời phần đầu tiên của câu hỏi: Bạn có thể tìm hiểu về các tính năng hệ thống loại mạnh mẽ này khi đọc một số blog tuyệt vời, như:

Trên thực tế, có rất nhiều blog hay khác ngoài kia (như hành tinh Haskell ). Dù sao, phương pháp tốt nhất để thực sự hiểu các hệ thống loại tiên tiến là phát triển một thư viện nguồn mở hữu ích. Chúng tôi (tại Flowbox & New Byte Order) đang phát hành rất nhiều thư viện (bạn có thể tìm thấy chúng tại Hackage), vì vậy nếu bạn không có ý tưởng gì để phát triển, bạn luôn có thể tham gia vào các dự án của chúng tôi - chỉ cần gửi email cho tôi bất cứ khi nào bạn muốn (thư có sẵn tại luna-lang.org ).


4
"Rất nhiều người nói rằng, nếu một cái gì đó biên dịch trong Haskell, nó chỉ hoạt động và bạn nên chắc chắn rằng nó sẽ không thổi vào mặt bạn một ngày nào đó.": Tôi chỉ sử dụng Haskell cho các dự án nhỏ (mặc dù không tầm thường) , nhưng tôi có thể xác nhận điều này: Một khi trình biên dịch Haskell hài lòng, tôi hiếm khi tìm thấy bất kỳ lỗi nào còn lại.
Giorgio

1
Tôi có lẽ là một trong những anh chàng "Haskell" ghét loại nhất (rất nhiều tôi đã viết phiên bản Haskell của riêng tôi mà không có loại nào ) - nhưng vì nhiều lý do khác nhau mà hầu hết mọi người đều làm. Khi nói đến công nghệ phần mềm, tôi cũng có cảm giác rằng, khi GHC hạnh phúc, chương trình của bạn chỉ hoạt động. Các hệ thống kiểu giống như Haskell là công cụ tối ưu không chỉ để phát hiện những sai lầm của con người trong lập trình, mà còn để giữ các cơ sở mã lớn dưới sự kiểm soát của bạn. (Tôi luôn nhớ lời biện minh của Jacanni đối với áo giáp của Mewtwo bất cứ khi nào tôi phải sửa lỗi loại.)
MaiaVictor

Blog của Gabriel Gonzales là tốt nhất để bắt đầu.
sam boosalis

@ danilo2 Đã gửi email đến địa chỉ contact @ trên trang web của công ty bạn. Yêu cầu bạn trả lời. Cảm ơn!
Saurabh Nanda

@SaurabhNanda: Tôi đã kiểm tra lại hộp thư đến của chúng tôi và tôi không thấy bất kỳ tin nhắn nào từ bạn. Bạn đã gửi nó để liên hệ với <at> luna-lang.org chưa? Vui lòng liên hệ trực tiếp với tôi viết thư cho wojciech <dot> danilo <at> gmail <dot> com và chúng tôi sẽ điều tra nguyên nhân của vấn đề này :)
danilo2

17

Vâng, gõ yếu so với mạnh mẽ được định nghĩa khá mơ hồ. Hơn nữa, vì gần nhất có một cách sử dụng chung là 'gõ mạnh' là để chỉ những thứ gây khó khăn cho việc tạo kiểu, nên không còn gì để mô tả các hệ thống loại mạnh hơn nữa. Nó giống như nói rằng nếu bạn có thể mang dưới 30 lbs thì bạn yếu và tất cả những người có thể nâng nhiều hơn đều thuộc cùng loại 'mạnh' - một sự phân biệt sai lệch.

Vì vậy, tôi thích định nghĩa:

  • Các hệ thống gõ yếu sử dụng các loại để ngăn bạn thực hiện một số việc (như lỗi)
  • Hệ thống gõ mạnh sử dụng các loại để làm việc cho bạn

Tôi có ý gì khi làm những điều cho bạn? Chà, hãy kiểm tra việc viết API chuyển đổi hình ảnh trong khung Servant (trong Haskell, nhưng bạn không thực sự cần biết nó để làm theo, bạn sẽ thấy ...)

{-# LANGUAGE
    TypeOperators,
    DataKinds
    #-}

import Codec.Picture
import Data.Proxy
import Network.Wai.Handler.Warp (run)
import Servant
import Servant.JuicyPixels

main :: IO ()
main = run 8001 conversion

Điều này nói rằng chúng tôi muốn một số mô-đun bao gồm gói Servant và plugin JuicyPixels cho Servant và điểm vào chính của chương trình là chạy chức năng 'chuyển đổi' trên cổng 8001 dưới dạng máy chủ sử dụng phụ trợ Warp. Bỏ qua bit ngôn ngữ.

conversion :: Application
conversion = serve (Proxy :: Proxy ConversionApi) handler

Điều này nói rằng chức năng chuyển đổi là một máy chủ trong đó API phải khớp với loại 'ConversApi' và các yêu cầu được xử lý bởi chức năng handler

type ConversionApi
     = ReqBody '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
    :> Post '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage

Đây là chỉ định ConvesionApiloại. Nó nói rằng chúng ta nên chấp nhận các loại nội dung đến được chỉ định bởi danh sách '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] và xử lý chúng dưới dạng DynamicImage và chúng ta sẽ trả lại một DynamicImage được chuyển đổi thành cùng một phạm vi nội dung các loại. Đừng lo lắng chính xác về những gì:> có nghĩa là, bây giờ hãy nghĩ về nó như là phép màu hạnh phúc.

Vì vậy, theo định nghĩa ưa thích của tôi, một hệ thống gõ yếu hiện có thể đảm bảo những thứ như:

  • Bạn không trả lại loại nội dung gửi đi sai
  • Bạn không phân tích yêu cầu đến là loại nội dung sai
  • Nếu máy chủ của chúng tôi phức tạp hơn, nó sẽ ngăn chúng tôi tạo các URI không đúng định dạng, nhưng chúng tôi thực sự không trả lại bất kỳ trang HTML nào để chứa các liên kết (và loại đảm bảo rằng chúng tôi không thể!)
  • Một hệ thống gõ yếu thực sự đầy tham vọng thậm chí có thể kiểm tra để đảm bảo rằng chúng tôi xử lý triệt để tất cả các loại nội dung đến và đi, cho phép loại này cũng hoạt động như một tài liệu đặc tả thay vì chỉ là một ràng buộc.

Tất cả các mục tiêu cao cả, nhưng thực sự không đủ để đủ điều kiện là một hệ thống được gõ mạnh, đưa ra định nghĩa trên. Và bây giờ chúng ta phải đi đến phần khó khăn của việc thực sự viết mã tuân theo đặc tả này. Trong một hệ thống loại thực sự mạnh mẽ , chúng tôi viết:

handler = return

Và thế là xong. Đó là nó, không có thêm mã để viết . Đây là một máy chủ web hoạt động đầy đủ (modulo bất kỳ lỗi chính tả nào tôi bỏ qua). Kiểu này đã báo cho trình biên dịch mọi thứ cần thiết để tạo máy chủ web của chúng tôi từ các loại và các gói (mô-đun kỹ thuật) mà chúng tôi đã xác định và nhập.

Vì vậy, làm thế nào để bạn học để làm điều này ở quy mô ứng dụng lớn? Chà, nó thực sự không khác nhiều so với việc sử dụng chúng trong các ứng dụng quy mô nhỏ hơn. Các loại tuyệt đối không quan tâm có bao nhiêu mã được viết liên quan đến chúng.

Chạy kiểm tra loại thời gian là điều mà có lẽ bạn sẽ muốn tránh, bởi vì điều đó sẽ mang lại một lượng lợi ích khổng lồ và cho phép các loại làm cho dự án của bạn trở nên phức tạp hơn để làm việc, thay vì các loại đơn giản hóa mọi thứ.

Như vậy, chủ yếu chỉ là vấn đề thực hành mô hình hóa mọi thứ với các loại. Hai cách chính để mô hình hóa mọi thứ (hoặc xây dựng mọi thứ nói chung) là từ dưới lên và từ trên xuống. Từ trên xuống bắt đầu với mức độ hoạt động cao nhất và khi bạn xây dựng mô hình, bạn có các phần mà bạn đang trì hoãn mô hình cho đến sau này. Mô hình hóa từ dưới lên có nghĩa là bạn bắt đầu với các hoạt động cơ bản, giống như bạn bắt đầu với các chức năng cơ bản, sau đó xây dựng các mô hình lớn hơn và lớn hơn cho đến khi bạn đã nắm bắt hoàn toàn hoạt động của dự án. Từ dưới lên cụ thể hơn và có khả năng xây dựng nhanh hơn, nhưng từ trên xuống có thể thông báo tốt hơn cho các mô hình cấp thấp hơn của bạn về cách chúng cần thực sự hoạt động.

Các loại là cách các chương trình liên quan đến toán học, theo nghĩa đen, vì vậy thực sự không có giới hạn nào về mức độ phức tạp của chúng, hoặc điểm mà bạn có thể 'hoàn thành' khi tìm hiểu về chúng. Hầu như tất cả các nguồn lực bên ngoài các khóa học đại học cấp cao hơn đều dành riêng cho cách các loại hoạt động trong một số ngôn ngữ cụ thể, vì vậy bạn cũng cần phải quyết định điều đó.

Theo cách tốt nhất tôi có thể cung cấp, các loại có thể được phân tầng như vậy:

  • Được gõ rất yếu, những thứ như JavaScript trong đó [] + {} được xác định
  • Gõ yếu như Python, nơi bạn không thể làm [] + {}, nhưng điều đó không được kiểm tra cho đến khi bạn thử
  • Được gõ yếu như C hoặc Java, nơi bạn không thể thực hiện [] + {}, nhưng điều đó đã được kiểm tra vào thời gian biên dịch, tuy nhiên bạn không có các tính năng loại nâng cao hơn
  • Điều chỉnh đường viền giữa kiểu gõ yếu và mạnh, chẳng hạn như siêu lập trình mẫu C ++ và mã Haskell đơn giản hơn trong đó các loại chỉ thực thi các thuộc tính.
  • Hoàn toàn nhập vào mạnh mẽ, giống như các chương trình Haskell phức tạp hơn, nơi các loại làm việc, như được hiển thị ở trên
  • Kiểu được gõ rất mạnh, như Agda hoặc Idris, nơi các loại và giá trị tương tác và có thể ràng buộc lẫn nhau. Điều này mạnh như các hệ thống loại có được, và lập trình trong đó cũng giống như viết bằng chứng toán học về những gì chương trình của bạn làm. Lưu ý: mã hóa trong Agda nó không thực sự viết các bằng chứng toán học, các loại là các lý thuyết toán học và các hàm với các loại đó là các ví dụ mang tính xây dựng chứng minh các lý thuyết đó.

Nói chung, càng đi sâu vào danh sách này, bạn càng có nhiều loại có thể giúp bạn, nhưng đến tận cùng, bạn đang leo lên tầng bình lưu và không khí trở nên hơi mỏng - hệ sinh thái trọn gói nhỏ hơn nhiều và bạn ' tôi sẽ phải tự viết thêm nhiều thứ so với việc tìm thấy một thư viện có liên quan. Rào cản gia nhập cũng tăng cao hơn khi bạn đi xuống, vì bạn phải thực sự hiểu hệ thống loại đủ để viết các chương trình quy mô lớn.


Lưu ý rằng bạn không cần phải thêm tiền tố vào danh sách cấp độ với dấu nháy đơn nếu có nhiều hơn phần tử trong danh sách. Dấu nháy đơn chỉ cần thiết cho danh sách cấp độ loại 0 hoặc 1 phần tử vì chúng không rõ ràng (chúng có thể được tham chiếu đến trình tạo loại danh sách thông thường)
Gabriel Gonzalez

1
Tôi biết, nhưng tôi đã bị ấn tượng rằng dấu nháy đơn chỉ là hình thức tốt cho các loại dữ liệu được quảng bá nói chung. EG Proxy :: Proxy Truehoạt động tốt, nhưng tốt hơn là viết nó như Proxy :: Proxy 'True.
Steven Armstrong

1
Có vẻ tốt hơn để không sụp đổ các trục khác nhau theo loại hệ thống có thể được phân loại. Khối lambda của Barendregt đã bao gồm ba, và ngoài ra dọc theo trục mạnh-yếu duy nhất, bạn cũng bao gồm tĩnh so với động, và đa hình so với đa hình ad hoc (sau này là thứ cho phép kỹ thuật đầy tớ tạo ra nhiều công việc ' ').
dùng2141650

1
Quan điểm công bằng, nhưng câu trả lời đã có từ rất lâu rồi, và bạn phải tiếp tục nghiên cứu lý thuyết loại trước khi khối lambda thực sự bắt đầu có ý nghĩa. Hơn nữa, bên ngoài các ngôn ngữ rất riêng (và vì tôi đã bao gồm Haskell và thậm chí Agda, tôi thực sự có nghĩa là các ngôn ngữ khá thích hợp), bạn sẽ không thực sự tìm thấy một ngôn ngữ, ví dụ, các loại phụ thuộc nhưng không có toán tử loại .
Steven Armstrong

Bạn có thể giải thích ngắn gọn '[xs]cú pháp? Đây rõ ràng không phải là một Char, nhưng tôi không thấy cách nào TypeOperatorshoặc DataKindscho phép một cú pháp thay thế. Đây có phải là một số loại chuẩn tinh?
wchargein

10

Tôi mới bắt đầu làm việc với đội ngũ nòng cốt của một nền tảng lớn được viết bằng Scala. Bạn có thể xem các ứng dụng nguồn mở thành công, như Scalatra, Play hoặc Slick để xem cách chúng xử lý một số câu hỏi chi tiết hơn của bạn về tương tác với các định dạng dữ liệu động.

Một trong những lợi thế tuyệt vời mà chúng tôi đã tìm thấy về cách gõ mạnh mẽ của Scala là trong giáo dục người dùng. Nhóm cốt lõi có thể đưa ra quyết định và thực thi các quyết định đó trong hệ thống loại, do đó, khi các nhóm khác ít quen thuộc với các nguyên tắc thiết kế phải tương tác với hệ thống, trình biên dịch sẽ sửa chúng và nhóm cốt lõi không liên tục sửa lỗi trong yêu cầu kéo. Đây là một lợi thế rất lớn trong một hệ thống lớn.

Tất nhiên, không phải tất cả các nguyên tắc thiết kế đều có thể được thi hành trong một hệ thống kiểu, nhưng hệ thống kiểu của bạn càng mạnh thì bạn càng có thể thực thi các nguyên tắc thiết kế trong trình biên dịch.

Chúng tôi cũng có thể làm cho mọi thứ dễ dàng hơn cho người dùng. Thông thường đối với họ, họ chỉ làm việc với các bộ sưu tập thông thường hoặc các lớp tình huống và chúng tôi đang chuyển đổi nó thành JSON hoặc bất cứ thứ gì tự động khi cần để truyền tải mạng.

Gõ mạnh cũng giúp tạo ra sự khác biệt giữa những thứ như đầu vào không được khử trùng và khử trùng, có thể giúp bảo mật.

Gõ mạnh cũng giúp các bài kiểm tra của bạn tập trung hơn vào hành vi thực tế của bạn , thay vì cần một loạt các bài kiểm tra chỉ kiểm tra các loại của bạn. Nó làm cho thử nghiệm dễ chịu hơn nhiều, tập trung hơn, và do đó hiệu quả hơn.

Nhược điểm chính là không quen thuộc với ngôn ngữ và mô hình ngôn ngữ, và điều đó là chính xác với thời gian. Khác rằng, chúng tôi đã tìm thấy nó cũng xứng đáng với nỗ lực.


8

Mặc dù không phải là câu trả lời trực tiếp (vì tôi chưa làm việc trên +30.000 cơ sở mã LỘC trong haskell chưa :( ..), tôi khuyên bạn nên xem https://www.fpcomplete.com/business/resource/case-studies / trong đó có rất nhiều trường hợp nghiên cứu về haskell trong các thiết lập công nghiệp thực tế.

Một bài viết hay khác là IMVU, mô tả trải nghiệm của họ khi đổi thành haskell - http://engineering.imvu.com/2014/03/24/what-its-like-to-use-haskell/ .

Từ kinh nghiệm cá nhân trong các ứng dụng lớn hơn, hệ thống loại rất giúp ích cho bạn, đặc biệt nếu bạn cố gắng mã hóa càng nhiều càng tốt trong các loại. Sức mạnh thực sự là thực sự rõ ràng khi tái cấu trúc mọi thứ - có nghĩa là bảo trì và như vậy trở thành một nhiệm vụ ít đáng lo ngại hơn nhiều.

Tôi sẽ chuyển một vài liên kết đến các tài nguyên mà tôi đề xuất, vì bạn đang hỏi khá nhiều câu hỏi cùng một lúc:

Như một nhận xét kết thúc, liên quan đến việc đối phó với thế giới bên ngoài được thực hiện theo nhiều cách. Có các thư viện để đảm bảo mọi thứ ở cuối của bạn đều an toàn, như Aeson cho JSON, Esqueleto cho SQL và nhiều thư viện khác.


1
tuy nhiên, cảm ơn câu trả lời, các nghiên cứu trường hợp trên fpcomplete.com/business/resource/case-studies không còn nữa.
Saurabh Nanda

Có vẻ như các nghiên cứu trường hợp đã được chuyển sang fpcomplete.com/case-study
Steven Shaw

3

Những gì tôi đã thấy:

Tôi đã làm việc với một vài ứng dụng web Ruby lớn (Rails), một ứng dụng web Haskell lớn và một vài ứng dụng nhỏ hơn. Với kinh nghiệm đó, tôi phải nói rằng cuộc sống làm việc trên các ứng dụng Haskell dễ dàng hơn nhiều so với trong Rails về các khía cạnh như bảo trì và đường cong học tập thấp hơn. Tôi cho rằng những lợi ích này là do cả hệ thống loại và phong cách lập trình chức năng của Haskell. Tuy nhiên, không giống như nhiều người, tôi tin rằng phần "tĩnh" của hệ thống loại chỉ là một sự tiện lợi rất lớn ở chỗ vẫn có lợi ích khi sử dụng các hợp đồng động.

Những gì tôi tin rằng

Có một gói tốt đẹp được gọi là Hợp đồng Ruby, đồng thời cung cấp một số tính năng chính mà tôi cảm thấy giúp các dự án của Haskell đạt được các đặc tính bảo trì tốt hơn. Hợp đồng Ruby thực hiện kiểm tra vào thời gian chạy để tốt nhất khi được kết hợp với hội tụ thử nghiệm cao nhưng nó vẫn cung cấp cùng một tài liệu nội tuyến và biểu hiện ý định và ý nghĩa như sử dụng chú thích loại trong các ngôn ngữ như Haskell.

Trả lời câu hỏi

Để trả lời các câu hỏi được đặt ra ở trên, có nhiều nơi người ta có thể làm quen với Haskell và các ngôn ngữ khác với các hệ thống loại tiên tiến. Tuy nhiên, và thành thật mà nói, trong khi các nguồn thông tin này là tuyệt vời theo cách riêng của họ, tất cả đều có vẻ hơi áp đảo khi so sánh với rất nhiều tài liệu và lời khuyên thực tế được tìm thấy trong Ruby, Python, Java và các ngôn ngữ khác. Trong mọi trường hợp, Real World Haskell đang già đi nhưng vẫn là một tài nguyên tốt.

Lý thuyết danh mục

Nếu bạn chọn Haskell, bạn sẽ gặp một lượng lớn tài liệu thảo luận về lý thuyết Danh mục. Lý thuyết danh mục IMHO là hữu ích nhưng không cần thiết. Với sự phổ biến trong cộng đồng Haskell, thật dễ dàng để kết hợp các ưu và nhược điểm của các loại với cảm xúc về tính thực tiễn của lý thuyết Danh mục. Thật hữu ích khi nhớ chúng là hai điều khác nhau, nghĩa là việc triển khai được hướng dẫn bởi lý thuyết Danh mục có thể được thực hiện bằng các ngôn ngữ được gõ động cũng như tĩnh (modulo các lợi ích mà hệ thống loại cung cấp). Các hệ thống loại tiên tiến nói chung không bị ràng buộc với lý thuyết Danh mục và lý thuyết Danh mục không bị ràng buộc với các hệ thống loại.

Thêm về các loại

Khi bạn tìm hiểu thêm về lập trình với các loại và các kỹ thuật trong đó (diễn ra khá nhanh vì thú vị), bạn sẽ muốn thể hiện nhiều hơn với hệ thống loại. Trong trường hợp đó, tôi sẽ xem xét một số tài nguyên sau đây và cùng tôi tham gia để làm cho các nhà cung cấp công cụ nhận thức được rằng chúng tôi muốn các công cụ chất lượng công nghiệp với các tính năng này chỉ được đóng gói thành thứ gì đó để lộ giao diện dễ sử dụng (như Hợp đồng Ruby):


2

Đầu tiên, tôi cảm thấy như có một sự nhầm lẫn trong các câu trả lời giữa gõ yếu so với gõ mạnh và tĩnh so với gõ động. Liên kết OP được cung cấp rõ ràng làm cho sự khác biệt:

Một hệ thống loại mạnh là một hệ thống loại có tính năng hạn chế thời gian biên dịch hoặc tính năng thời gian chạy mà bạn thấy hấp dẫn.

Một hệ thống loại yếu là một hệ thống loại thiếu tính năng hạn chế hoặc tính năng đó.

Ví dụ, C, C ++ và Java được gõ tĩnh do các biến được nhập vào thời gian biên dịch. Tuy nhiên, C và C ++ có thể được coi là gõ yếu vì ngôn ngữ cho phép bỏ qua các hạn chế sử dụng void *con trỏ và phôi. Thêm về chủ đề này.

Trên sự khác biệt này, gõ mạnh chỉ có thể tốt hơn. Càng thất bại sớm thì càng tốt.

Tuy nhiên, khi viết các chương trình lớn, tôi không nghĩ hệ thống kiểu đóng vai trò quan trọng. Nhân Linux là mười triệu LỘC được viết bằng C và lắp ráp và được coi là một chương trình rất ổn định, cách 200 dòng Java của tôi có thể chứa đầy lỗ hổng bảo mật. Tương tự, mặc dù các "ngôn ngữ kịch bản" được gõ động bị ảnh hưởng xấu khi viết các chương trình lớn, đôi khi có bằng chứng cho thấy nó không được bảo vệ (như Python Django, hơn 70 nghìn LỘC)

Theo tôi, đó là tất cả về tiêu chuẩn chất lượng. Trách nhiệm về khả năng mở rộng của các ứng dụng lớn chỉ nên được giữ bởi các lập trình viên và kiến ​​trúc sư và ý chí của họ để làm cho ứng dụng sạch sẽ, được thử nghiệm, được ghi chép tốt, v.v.


-1

Người ta có thể đọc về cách sử dụng các hệ thống loại mạnh mẽ này và các tính năng thời gian tĩnh / biên dịch trong các ứng dụng lớn hơn?

từ câu trả lời trước https://www.fpcomplete.com/business/resource/case-studies/

Làm thế nào để một người vượt ra khỏi kiểu giới thiệu "hello world" tiêu chuẩn cho các tính năng mạnh mẽ này?

nó thực sự giống như bất kỳ ngôn ngữ nào khác để tăng cường sức mạnh

Làm thế nào người ta có thể sử dụng một hệ thống loại phong phú để mô hình hóa một vấn đề trong lĩnh vực kinh doanh?

Bằng cách sử dụng các kiểu dữ liệu trừu tượng hoặc nói chung là đa hình

Hệ thống loại có giúp ích hay cản trở khi bạn ở trong khu vực 30.000 LỘC + không?

Nó giúp tất cả các cách. hệ thống loại giúp bạn viết mã vì nó cho bạn biết hình dạng của kết quả mà bạn muốn có. Trên thực tế Agda viết mã cho bạn.

Tái bút: đừng phạm sai lầm khi có một hệ thống loại và phải tự viết các loại đó là điều ngu ngốc: máy tính có thể làm điều đó cho bạn.

Điều gì xảy ra với mạng lưới an toàn được cung cấp bởi các hệ thống loại này (và kiểm tra thời gian biên dịch) khi hệ thống của bạn tương tác với thế giới bên ngoài được gõ yếu, ví dụ. thông qua API JSON hoặc XML, các kho dữ liệu khác nhau, đầu vào của người dùng, v.v.

Thật tuyệt vời, vì biết cấu trúc của các giá trị thông qua các loại có nghĩa là máy tính có thể suy ra một cách để viết (de) serializer cho bạn.

Nếu bạn thực sự muốn biết về các loại và trừu tượng hóa, phần giới thiệu tốt nhất là về Hiểu các loại, Trừu tượng dữ liệu và Đa hình

Đó là một bài báo, không phải là một nghiên cứu điển hình với những bức ảnh đẹp, nhưng nó thật tuyệt vời


-2

Là một lập trình viên .net, người làm việc trên các ứng dụng web rất nhiều, tôi thấy cả khía cạnh gõ chữ C # và chưa được gõ.

Tôi không chắc chắn tôi đã xem bất kỳ tài liệu về các câu hỏi bạn hỏi. Với một ngôn ngữ đánh máy, bạn coi tất cả những điều này là đương nhiên. Với một cái chưa được đánh dấu, bạn thấy việc xác định các loại là chi phí không cần thiết.

Cá nhân, tôi không nghĩ rằng bạn có thể phủ nhận rằng một ngôn ngữ được gõ mạnh mang lại những lợi ích mà bạn mô tả với chi phí rất thấp (so với việc viết các bài kiểm tra đơn vị tương đương). Tương tác với các hệ thống gõ yếu thường liên quan đến các loại chung chung, chẳng hạn như Mảng hoặc Từ điển của các đối tượng, chẳng hạn như DataReader hoặc sử dụng chuỗi sáng tạo hoặc lớp động mới. Về cơ bản tất cả đều hoạt động, bạn chỉ nhận được một lỗi thời gian chạy thay vì biên dịch thời gian.

Nếu bạn muốn viết một chương trình rất ngắn, có thể xác định một hàm trong một vài dòng để làm việc với một ứng dụng lớn hơn, thì bạn chỉ cần không có chỗ để khai báo các lớp. Chắc chắn đây là ngôn ngữ chưa được đánh dấu thích hợp như JS chiếm?


Bạn có nghĩa là gõ / tháo hoặc gõ tĩnh / gõ động? JavaScript không được đánh dấu nhưng được gõ động.
Giorgio

2
bạn không phải xác định các loại. bất kỳ ngôn ngữ tử tế nào cũng sẽ suy ra các loại dành cho bạn: haskell, ocaml, sml, F # ...
nicolas

1
khi bạn đang sử dụng để một tất cả mọi thứ ngôn ngữ mạnh mẽ gõ khác đang untyped, khi tôi nói xác định các loại tôi có nghĩa là 'tạo ra các lớp học' chắc chắn rằng bạn có thể sử dụng var hoặc bất cứ điều gì, nhưng nó chỉ là một thủ thuật biên dịch
Ewan
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.