Why not annotate function parameters?

To make this question answerable, let’s assume that the cost of ambiguity in the mind of a programmer is much more expensive then a few extra keystrokes.

Given that, why would I allow my teammates to get away with not annotating their function parameters? Take the following code as an example of what could be a far more complex piece of code:

let foo x y = x + y

Now, a quick examination of the tooltip will show you that F# has determined you meant for x and y to be ints. If that’s what you intended, then all is well. But I don’t know if that’s what you intended. What if you had created this code to concatenate two strings together? Or what if I think you probably meant to add doubles? Or what if I just don’t want to have to hover the mouse over every single function parameter to determine its type?

Now take this as an example:

let foo x y = "result: " + x + y

F# now assumes you’ve probably intended to concatenate strings, so x and y are defined as strings. However, as the poor schmuck who’s maintaining your code, I might look at this and wonder if perhaps you had intended to add x and y (ints) together and then append the result to a string for UI purposes.

Certainly for such simple examples one could let it go, but why not enforce a policy of explicit type annotation?

let foo (x:string) (y:string) = "result: " + x + y

What harm is there in being unambiguous? Sure, a programmer could choose the wrong types for what they are trying to do, but at least I know they intended it, that it wasn’t just an oversight.

This is a serious question… I am still very new to F# and am blazing the trail for my company. The standards I adopt will likely be the basis for all future F# coding, embedded in the endless copy-pasting that I am sure will permeate the culture for years to come.

So… is there something special about F#’s type inference that makes it a valuable feature to hold onto, annotating only when necessary? Or do expert F#-ers make a habit of annotating their parameters for non-trivial applications?

4

I don’t use F#, but in Haskell it is considered good form to annotate (at least) top-level definitions, and sometimes local definitions, even though the language has pervasive type inference. This is for a few reasons:

  • Reading
    When you want to know how to use a function, it’s incredibly useful to have the type signature available. You can simply read it, rather than trying to infer it yourself or relying on tools to do it for you.

  • Refactoring
    When you want to alter a function, having an explicit signature gives you some assurance that your transformations preserve the intent of the original code. In a type-inferred language, you may find that highly polymorphic code will typecheck but not do what you intended. The type signature is a “barrier” that concretises type information at an interface.

  • Performance
    In Haskell, the inferred type of a function may be overloaded (by way of typeclasses), which may imply a runtime dispatch. For numeric types, the default type is an arbitrary-precision integer. If you don’t need the full generality of these features, then you can improve performance by specialising the function to the specific type you need.

For local definitions, let-bound variables, and formal parameters to lambdas, I find that type signatures usually cost more in code than the value they would add. So in code review, I would suggest you insist on signatures for top-level definitions and merely ask for judicious annotations elsewhere.

5

Jon gave a reasonable answer which I won’t repeat here. I will however show you an option that might satisfy your needs and in the process you will see a different type of answer other than a yes/no.

Lately I have been working with parsing using parser combinators. If you know parsing then you know you typically use a lexer in the first phase and a parser in the second phase. The lexer converts text to tokens and the parser converts tokens into an AST. Now with F# being a functional language and combinators being designed to be combined, parser combinators are designed to make use of the same functions in both the lexer and the parser yet if you set the type for the parser combinator functions you can only use them to lex or to parse and not both.

For example:

/// Parser that requires a specific item.

// a (tok : 'a) : ('a list -> 'a * 'a list)                     // generic
// a (tok : string) : (string list -> string * string list)     // string
// a (tok : token)  : (token list  -> token  * token list)      // token

or

/// Parses iterated left-associated binary operator.


// leftbin (prs : 'a -> 'b * 'c) (sep : 'c -> 'd * 'a) (cons : 'd -> 'b -> 'b -> 'b) (err : string) : ('a -> 'b * 'c)                                                                                    // generic
// leftbin (prs : string list -> string * string list) (sep : string list -> string * string list) (cons : string -> string -> string -> string) (err : string) : (string list -> string * string list)  // string
// leftbin (prs : token list  -> token  * token list)  (sep : token list  -> token  * token list)  (cons : token  -> token  -> token  -> token)  (err : string) : (token list  -> token  * token list)   // token

Since the code is copyright I won’t include it here but it is available at Github. Do not copy it here.

For the functions to work they must be left with the generic parameters, but I include comments that show the inferred types depending upon the functions use. This makes it easy to understand the function for maintenance while leaving the function generic for use.

7

The number of bugs is directly proportional to the number of characters in a program!

This is usually stated as the number of bugs being proportional to lines of code. But having less lines with the same amount of code gives the same amount of bugs.

So while it’s nice to be explicit, any extra parameters you type can lead to bugs.

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật