2009-07-16 35 views
15

Nhiều lần tôi nghe nói rằng F # không phù hợp với các tác vụ cụ thể, chẳng hạn như giao diện người dùng. "Sử dụng đúng công cụ" là một cụm từ phổ biến.F # thiếu cho OO hoặc bắt buộc là gì?

Ngoài các công cụ còn thiếu như trình thiết kế WinForms/WPF/ORM, tôi không chắc chính xác những gì bị thiếu trong F # - thành thật! Tuy nhiên, đặc biệt là với giao diện người dùng, tôi đã nói rằng C# chỉ làm tốt hơn. Vì vậy, sự khác biệt thực sự và thiếu sót trong F # khi sử dụng nó là gì?

Dưới đây là danh sách tôi đã đưa ra:

  • Rất nhiều công cụ hỗ trợ còn thiếu

  • F # là vẫn beta

  • nhà phát triển của bạn không biết F #

    • Tôi không muốn xem xét những điểm đó vì chúng thực sự không thực sự là F #
  • Cần vô hiệu hóa "có thể thay đổi" hoặc cần ref, ref needs! để dereference

  • Mutables gán với < - và ref sử dụng: = (họ đang cả hai nhân vật 1 nhiều hơn chỉ =)

  • val cần DefaultValueAttribute để có được một giá trị mặc định

  • F # doesn' t phát ra giao diện ngầm

  • thành viên protected có thể được khó khăn hơn để đối phó với

  • Không tính tự động

  • thực hiện các thành viên ảo trên lớp trừu tượng đòi hỏi hai định nghĩa

  • Báo giá-to-LINQ-Biểu-Trees sản xuất cây hơi khác so với C#/VB (gây phiền nhiễu cho API mong đợi Expressions của họ trong một định dạng cụ thể)

  • không stackalloc

  • F # không có: nhà điều hành có điều kiện

  • Pointer s có thể được coi là cồng kềnh hơn trong F #

  • đại biểu/sự kiện có thể có thể được coi là cồng kềnh hơn (tôi muốn tranh luận họ dễ dàng hơn, nhưng ít nhất họ khác nhau)

  • Không có chuyển đổi kiểu tự động (như int to float, hoặc implicit casts)

  • Không hỗ trợ cú pháp đặc biệt cho Nullable (C# 's? nhập chú thích và ?? toán tử, cũng như sử dụng toán tử trên nullables.)

  • Không upcasting tự động tới lớp cơ sở chung hoặc đấm bốc (ví dụ: cho x: obj = nếu đúng thì 1 khác "hi" // này sẽ không typecheck)

  • giá trị không thể bị loại bỏ mà không có một cảnh báo ("bỏ qua" để có được xung quanh nó)

  • không có cú pháp C-style :)

với câu hỏi: nào sau đây là một trở ngại cho việc viết mã bắt buộc hay OO ? Tại sao (ví dụ ngắn)? Tôi đã bỏ lỡ cái nào? Cách giải quyết tốt nhất là gì và tại sao họ không đủ?

Xin lưu ý, tôi không nói về cách viết cái gọi là F # thành ngữ, và tôi chắc chắn không nói về lập trình hàm. Tôi quan tâm hơn đến các dòng "Nếu tôi buộc mình viết UI hoặc mã OO bắt buộc trong F #, sử dụng các tính năng bắt buộc và loại lớp F # OO, điều gì gây đau nhất?"

Bonus Nếu bạn không biết F # nhưng sử dụng C# hoặc VB.NET và nghĩ rằng nó là một công cụ tốt hơn cho một số trường hợp, xin cho biết các tính năng ngôn ngữ cụ thể và cú pháp bạn tìm thấy hấp dẫn.

+4

Có vẻ như bạn muốn F # thành C# hoặc VB. Bạn sẽ lãng phí rất nhiều thời gian viết theo một phong cách bắt buộc. – leppie

+1

Xin vui lòng không làm cho tôi sai. Nhiều thứ trong danh sách tôi yêu thích Tôi nghĩ rằng chúng là tích cực. Không, tôi quan tâm đến những khác biệt mà C# và VB.NET chia sẻ để làm cho chúng tốt hơn trong các tác vụ như vậy. Không nói chung "oh nó không phải là _designed_ cho rằng", nhưng khó "thiếu các thành viên được bảo vệ có nghĩa là F # không thể đối phó trên x y và z khuôn khổ". – MichaelGG

+0

Nhà thiết kế không phải là một vấn đề lớn, vì bạn có thể sử dụng dll của người khác. Nói chung chỉ là một vấn đề trong các dự án nhỏ. – Dykam

Trả lời

5

Liên quan đến công cụ OO, danh sách của tôi có thể là

  • Bạn nói một số điều về giao diện và virtuals có thể được phiền toái hoặc trở ngại; thiếu các đạo cụ tự động mà bạn đề cập cũng là một sự xấu hổ
  • Các khuôn khổ OO đôi khi yêu cầu nhiều lớp đệ quy lẫn nhau, mà F # hiện buộc bạn đưa vào một tệp (trong 'loại ... và ... và ...' khối)
  • Nếu bạn cần phải gọi hai nhà xây dựng cơ sở khác nhau trong một lớp học có nguồn gốc, bạn phải sử dụng cú pháp lớp 'rõ ràng' (như đã đề cập here)

Điều đó nói rằng, F # có những điểm mạnh trong bộ phận OO cũng như suy luận kiểu, hàm cục bộ, cú pháp ngắn gọn, ... vì vậy tổng thể tôi có thể gọi nó là sự rửa trong bộ phận 'OO nặng nề'.

(I have done hầu như không có lập trình giao diện người dùng của bất cứ loại nào, vì vậy không đủ điều kiện để cân nhắc trong đó.)

(EDIT: Tôi cũng muốn xen vào đó, ngay cả khi bạn dứt khoát lựa chọn để loại trừ ' công cụ 'từ câu hỏi, tôi nghĩ rằng công cụ có vấn đề một chút, và trong khía cạnh này các ngôn ngữ khác được quản lý VS vượt trội.)

+2

Oh yea, toàn bộ kiểu đệ quy có thể là một nỗi đau. Nhưng ... các bạn đang sửa chữa nó, đúng không? :) – MichaelGG

+0

Tài liệu tham khảo OO của bạn là cách tắt. Bạn có nghĩa là gõ tĩnh? Hay bắt buộc? – leppie

+0

@MichaelGG: Cuối cùng nó sẽ được sửa chữa, nhưng nó không rõ ràng nếu điều này sẽ làm cho bản phát hành đầu tiên VS2010. IMO giới hạn này là điều duy nhất về nguyên tắc sẽ ngăn cản bạn từ tác giả ví dụ: khuôn khổ OO 100.000 dòng trong F #. – Brian

1

Nỗi đau lớn nhất của tôi với ngôn ngữ hàm được gõ tĩnh là không có khả năng có đối số biến trên phương thức cần suy ra. Giống như chức năng bản đồ. Trong F # bạn cần map2 map3, v.v.

Mặt khác, C# cũng thiếu, trừ khi bạn muốn qua phản xạ.

Lấy sơ đồ ví dụ, không được nhập tĩnh. Bạn không có một vấn đề để xác định một chức năng duy nhất có thể xử lý tất cả các trường hợp của map_1 ... map_n. Chắc chắn bạn mất an toàn loại tĩnh, nhưng nó pales so với sự tiện lợi bổ sung của việc viết mã súc tích.

+0

Đối với những người ghét PHP cố gắng không gag nhưng tôi vẫn sử dụng PHP để tạo tập lệnh vì các loại động và các hàm chức năng đi kèm. – gradbot

+0

Hmm Tôi không nghĩ rằng tôi đã chạy quá nhiều lần mà tôi cần phải tóm tắt về số lượng tham số. Nhưng, một lần nữa, F # và C# cả hai cho phép bạn trộn trong động nếu bạn cảm thấy nghiêng để làm như vậy vì một lý do nào đó. Nếu bạn muốn truyền các mảng đối tượng và tự động gọi các đại biểu, sẽ không có vấn đề gì. Tôi chỉ không muốn từ bỏ an toàn loại cho điều đó trong hầu hết các trường hợp. – MichaelGG

6

Lập trình bắt buộc trong F # tốt hơn nhiều so với những người sẽ dẫn bạn tin. F # 's match statement là tuyệt vời.Tại sao các ngôn ngữ khác đã không triển khai nó, tôi không biết. Theo như những thứ như cú pháp (có thể thay đổi, ref, vv) chúng rất dễ làm việc. Bạn nhận được hư hỏng bởi sự thưa thớt của F # và nó dễ dàng để khiếu nại khi cú pháp lớn hơn bình thường. Tuples cũng rất tuyệt. Họ cũng sẽ ở trong C# 4.0. Currying là một phần thưởng khác cho Imperative.

Liên quan đến OO Tôi thấy tôi hiếm khi sử dụng thừa kế trong các dự án F # thuần túy và thay vào đó là ưu tiên thành phần và giao diện. Điều này chủ yếu là do sử dụng primary contructor cho phép bạn sử dụng các tham số của nó như là các thuộc tính riêng tư trong các phương thức của bạn (không chắc chắn nếu tôi đã viết chính xác). Các cấu trúc ngôn ngữ khác như đối sánh mẫu cũng kéo bạn ra khỏi thừa kế. Tôi đã không thực hiện bất kỳ dự án hỗn hợp C#/F # vì vậy tôi không thể bình luận về điều đó.

F # không phải là tất cả hoa hồng.

Vấn đề lớn nhất của tôi với F # và lập trình trò chơi là hiệu suất. Việc thực hiện trong F # thực sự nhanh và tôi thường lấy nguyên mẫu và chạy cho những gì tôi muốn làm cùng ngày tôi nghĩ về nó, tuy nhiên tôi thấy mình viết lại mã vì lý do hiệu suất thường xuyên hơn trong C#.

Một phần của vấn đề là sự thiếu kinh nghiệm của tôi với phong cách lập trình hàm là sử dụng Seq, List, Map và tất cả các phương thức đi kèm của chúng như bản đồ, lặp, gấp, quét. Giải pháp chức năng đầu tiên của tôi hầu như không bao giờ là nhanh nhất trong khi giải pháp thủ tục đầu tiên của tôi hầu như luôn gần với mức tốt nhất có thể. Tôi muốn nói một phần của điều này không phải là tôi. Lập trình chức năng đó không cho phép bản thân nó thực hiện trong một số tình huống.

Tôi sử dụng ít loại dữ liệu chức năng hơn trong F # bây giờ so với khi tôi bắt đầu.

EDIT:

Nhiều tháng đã trôi qua kể từ khi tôi đã đăng này và tôi không còn có vấn đề với hiệu suất. Các giải pháp chức năng đầu tiên của tôi thường đơn giản và gần như tối ưu và cấu trúc dữ liệu không thay đổi rất đơn giản. Vấn đề hiệu suất duy nhất tôi có bây giờ là với CLI và tôi luôn có thể làm C++/cli nếu tôi cần. Tôi sử dụng một số kế thừa bên cạnh giao diện bây giờ nhưng nó chỉ dành cho các đối tượng vô danh.

+1

phức tạp f # trên XNA sẽ luôn luôn là đau đớn hơn cho đến khi JIT thoát khỏi phân tích đáng tin cậy hoặc thêm một GC thế hệ. Phân bổ vốn có trong triển khai hiện tại (và có khả năng cố định) của nhiều khía cạnh hữu ích như FastFunc, Tuples và closures. C# có cùng một vấn đề về đại biểu, đóng cửa (và từ 4.0 Tuple) nhưng nó không đẩy sử dụng của họ khá nhiều. Tránh phân bổ trong vòng trò chơi chặt chẽ là thiết kế quan trọng xem xét cho hiệu suất XNA. – ShuggyCoUk

+0

F # nên nhanh nhất là C# và thường nhanh hơn * rất nhiều *. Nếu bạn phải viết lại F # của bạn trong C# để có được hiệu suất đầy đủ thì bạn đang làm điều gì đó nghiêm trọng sai và cần phải học cách tối ưu hóa mã F #. –

+1

@Jon Harrop, thực sự là tôi. Làm quen với lập trình chức năng phải mất một lúc trước khi bạn bắt đầu tiếp cận các vấn đề khác nhau. – gradbot

10

Tôi không phải là người hâm mộ lớn của câu hỏi này vì nó phàn nàn về F # không hỗ trợ thành ngữ C#. Ví dụ, tôi không nghĩ rằng nó công bằng để chỉ trích F # cho việc sử dụng < - và: = cho phép gán biến vì ngôn ngữ làm cho mọi thứ bất biến theo mặc định.

Bất kể, có một số điều bắt buộc/hướng đối tượng bạn có thể thực hiện trong C# mà bạn không thể thực hiện được trong F #.

  • F # không hỗ trợ các lớp lồng nhau. Trong C# bạn có thể khai báo một lớp trong phần thân của lớp khác như một cơ chế cho các kiểu phạm vi. F # không hỗ trợ điều này.

  • F # không cho phép bạn triển khai cùng một giao diện chung hai lần. Ví dụ: trong C#, bạn có thể triển khai IComparable<int>IComparable<string> cùng loại.

  • Trong F #, bạn phải có lớp kiến ​​trúc. Do suy luận kiểu F #, bạn chỉ có thể sử dụng các lớp đã được khai báo 'trước' hoặc trong cùng một 'khối' khai báo kiểu. Trong C# tuy nhiên bạn có thể có bất kỳ tham chiếu lớp nào khác. (Điều này thực sự thực thi một số thực hành lập trình tốt.)

  • F # không có hỗ trợ 'gốc' cho LINQ, như không có từ khóa. Tuy nhiên, bạn có thể sử dụng LINQ API và biểu thức lambda để đạt được kết quả tương tự.

Những điều mà F # có thể làm điều đó C# không thể:

  • đoàn thể kỳ thị. Điều này làm cho nó tầm thường để tạo ra các cấu trúc dữ liệu giống cây trong F #, trong đó trong C# bạn phải dùng đến một hệ thống phân cấp kiểu phức tạp.

  • Quy trình công việc không đồng bộ. Tính năng này của thư viện F # làm cho lập trình không đồng bộ và song song nhiều hơn nữa bằng cách trừu tượng hóa tất cả các cơn đau liên quan đến APM.

  • Đối sánh mẫu và mẫu hoạt động.

  • Đơn vị đo lường lỗi liên quan đến việc sử dụng sai đơn vị. (Ví dụ, thêm 'chân' thành 'm'.)

  • , vv

Bạn không nên tập trung vào những gì F # 'không thể làm như C#' vì toàn bộ điểm của việc học F # sẽ được trình bày với một cách mới để suy nghĩ về giải quyết vấn đề. Nếu bạn viết mã C# thành ngữ trong F # bạn thực sự không đạt được gì cả.

AFAIK F # không thiếu bất kỳ 'phải có' nào cho .NET/COM interop. Trong F # bạn có thể làm những việc như có tham số out và byref, khai báo các chuỗi ký tự và hỗ trợ việc đưa các thuộc tính vào bất kỳ thứ gì.

+0

Có, tôi e rằng tôi đã không làm cho quan điểm của mình rất rõ ràng. Tôi không phàn nàn về F # hay chỉ trích nó - chỉ ra sự khác biệt. Câu hỏi thực sự của tôi là "tại sao C# phù hợp hơn với giao diện người dùng so với F #", hoặc một cái gì đó cho hiệu ứng đó. Tôi chắc chắn không tin rằng đó là trường hợp C# thường hay là "công cụ phù hợp". Tôi chỉ muốn xem liệu có ai đó có thể lùi lại không. (Tôi cảm thấy bị bệnh khi tôi phải viết trong C#. Ngay cả khi tôi sẽ viết "C#", tôi thích làm điều đó trong F # và có suy luận, kết hợp mẫu, v.v.) – MichaelGG

+1

"Ví dụ, trong C# bạn có thể triển khai IComparable và IComparable trên cùng một loại. " - không có ý nghĩa nhiều! – Casebash

0

Chỉ để lưu bản ghi: F # có phân bổ ngăn xếp - hãy thử đệ quy vô hạn không phải là đệ quy đuôi và bạn sẽ bị tràn ngăn xếp. Nó thực sự không khác nhau để phân bổ stack trong C#, ngoài bạn biết rằng bạn có thể sử dụng đệ quy đuôi một cách an toàn F # (trong C# nó phụ thuộc). Ngoài ra, tôi muốn chỉ ra rằng khi bạn nhận được mã định hướng sự kiện thực sự nặng, F # quy mô tốt hơn C# về mặt cho phép bạn xây dựng một khuôn khổ để làm "hệ thống ống nước" của các sự kiện gửi đến các trình xử lý, v.v. mà không có hệ thống ống nước trở thành phần lớn mã của bạn. Đối với một giao diện người dùng đơn giản, C# hoặc VB có thể phù hợp với nhiều người hơn. Đối với các tình huống phức tạp, F # kéo về phía trước, và cá nhân tôi cần giúp đỡ với những tình huống phức tạp hơn những tình huống đơn giản.

+2

Ồ, và tôi nghĩ hoàn toàn ngược lại về "Chắc chắn bạn đã loại bỏ sự tĩnh lặng kiểu tĩnh, nhưng nó lại so sánh với sự tiện lợi bổ sung của việc viết mã ngắn gọn." Bạn có thể tiết kiệm 10% số lần nhập, nhưng bạn sẽ mất nhiều thời gian hơn để thực hiện gỡ lỗi thời gian chạy. Nếu bạn muốn có một số lượng đối số, chỉ cần sử dụng một danh sách! Bạn có thể thực hiện cùng một loại mono phổ quát mà lược đồ sử dụng trong F # rất dễ dàng trong thực tế - nhưng bạn có thể làm tốt hơn và chọn gõ tĩnh chính xác nơi bạn muốn. – RD1

+0

Tôi có nghĩa là trực tiếp "stackalloc" để có được một con trỏ đến một khối bộ nhớ bạn sở hữu trên ngăn xếp. Trong F # tôi cho rằng bạn sẽ phải tạo một cấu trúc lớn và lấy địa chỉ của nó. Nhưng nói chung nó có vẻ như bạn đang nói rằng C# không có nhiều lợi thế, đó là quan điểm của tôi. – MichaelGG

Các vấn đề liên quan