Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 840775
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T05:40:53+00:00 2026-05-15T05:40:53+00:00

Earlier I requested some feedback on my first F# project. Before closing the question

  • 0

Earlier I requested some feedback on my first F# project. Before closing the question because the scope was too large, someone was kind enough to look it over and leave some feedback.

One of the things they mentioned was pointing out that I had a number of regular functions that could be converted to be methods on my datatypes. Dutifully I went through changing things like

let getDecisions hand =
    let (/=/) card1 card2 = matchValue card1 = matchValue card2
    let canSplit() = 
        let isPair() =
            match hand.Cards with
            | card1 :: card2 :: [] when card1 /=/ card2 -> true
            | _ -> false
        not (hasState Splitting hand) && isPair()
    let decisions = [Hit; Stand]
    let split = if canSplit() then [Split] else []
    let doubleDown = if hasState Initial hand then [DoubleDown] else []
    decisions @ split @ doubleDown

to this:

type Hand
// ...stuff...
member hand.GetDecisions =
    let (/=/) (c1 : Card) (c2 : Card) = c1.MatchValue = c2.MatchValue
    let canSplit() = 
        let isPair() =
            match hand.Cards with
            | card1 :: card2 :: [] when card1 /=/ card2 -> true
            | _ -> false
        not (hand.HasState Splitting) && isPair()
    let decisions = [Hit; Stand]
    let split = if canSplit() then [Split] else []
    let doubleDown = if hand.HasState Initial then [DoubleDown] else []
    decisions @ split @ doubleDown

Now, I don’t doubt I’m an idiot, but other than (I’m guessing) making C# interop easier, what did that gain me? Specifically, I found a couple disadvantages, not counting the extra work of conversion (which I won’t count, since I could have done it this way in the first place, I suppose, although that would have made using F# Interactive more of a pain). For one thing, I’m now no longer able to work with function “pipelining” easily. I had to go and change some |> chained |> calls to (some |> chained).Calls etc. Also, it seemed to make my type system dumber–whereas with my original version, my program needed no type annotations, after converting largely to member methods, I got a bunch of errors about lookups being indeterminate at that point, and I had to go and add type annotations (an example of this is in the (/=/) above).

I hope I haven’t come off too dubious, as I appreciate the advice I received, and writing idiomatic code is important to me. I’m just curious why the idiom is the way it is 🙂

Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T05:40:54+00:00Added an answer on May 15, 2026 at 5:40 am

    An advantage of members is Intellisense and other tooling that makes members discoverable. When a user wants to explore an object foo, they can type foo. and get a list of the methods on the type. Members also ‘scale’ easier, in the sense that you don’t end up with dozens of names floating around at the top level; as program size grows, you need more names to only be available when qualified (someObj.Method or SomeNamespace.Type or SomeModule.func, rather than just Method/Type/func ‘floating free’).

    As you’ve seen, there are disadvantages as well; type inference is especially notable (you need to know the type of x a priori to call x.Something); in the case of types and functionality that is used very commonly, it may be useful to provide both members and a module of functions, to have the benefits of both (this is e.g. what happens for common data types in FSharp.Core).

    These are typical trade-offs of “scripting convenience” versus “software engineering scale”. Personally I always lean towards the latter.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I asked a question on here earlier and got some fantastic responses. I've since
This question follows an earlier one . Here is some code that reproduces the
Earlier today a question was asked regarding input validation strategies in web apps .
Earlier this week I ask a question about filtering out duplicate values in sequence
Earlier I asked this question How to correctly unit test my DAL? , one
Earlier I asked a question about why I see so many examples use the
Earlier today I asked a question about environ , and one of the more
Earlier today I asked a question about passing dictionary values to a function. While
Earlier today, I asked a question about the way Python handles certain kinds of
earlier today I asked this question . So since moq creates it's own class

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.