Hacker News new | ask | show | jobs
by SlimTim10 1191 days ago
I find Haskell is really good for this. Typed holes + ghcid makes for a really fast and helpful feedback loop.
2 comments

Ghci is a really impressive REPL, with very fast reloading and very complete metadata handling. Also, it's easier to handle conversations about pure code.

But most languages have many features aimed at it. The captcha is that it tends to come bundled on the debugger, instead of in a separate tool. That makes many people fail to recognize them.

what is typed holes?
https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/type... <- This does a better job than I could at explaining it. But basically, certain expressions are "holes", incomplete/invalid code but where the type of the hole (a variable or _) can be determined. The compiler can also give suggestions on how to fill a hole.

I learned about them with Idris and Type-Driven Development by Brady, I've never used them in Haskell but haven't really touched it seriously in a decade now.

    ghci> let x :: Int = 1; s :: String = "foo" in x + _

    <interactive>:13:46: error:
 • Found hole: _ :: Int
 • In the second argument of ‘(+)’, namely ‘_’
   In the expression: x + _
   In the expression:
     let
       x :: Int = 1
       s :: String = "foo"
     in x + _
 • Relevant bindings include
     x :: Int (bound at <interactive>:13:5)
     s :: String (bound at <interactive>:13:19)
     it :: Int (bound at <interactive>:13:1)
   Valid hole fits include
     it :: Int (defined at <interactive>:11:1)
     x :: Int (bound at <interactive>:13:5)
     maxBound :: forall a. Bounded a => a
       with maxBound @Int
       (imported from ‘Prelude’ (and originally defined in ‘GHC.Enum’))
     minBound :: forall a. Bounded a => a
       with minBound @Int
       (imported from ‘Prelude’ (and originally defined in ‘GHC.Enum’))
@ParetoOptimal this is helpful in that haskell/ghc throws these error but how do you read the error message and how do you use it or infer next steps from the messages regarding the typed hole?
> @ParetoOptimal this is helpful in that haskell/ghc throws these error but how do you read the error message and how do you use it or infer next steps from the messages regarding the typed hole?

Basically it gives you a good starting point at least for what things make sense there. In some contexts though, it can lead you to the right answer when you didn't really have a clear idea provided you've honed some heuristics.

In the example above I:

1. Look at the type from this piece of the error: `Found hole: _ :: Int`. 2. I look at relevant hole fits, user defined functions in scope, and see if any of those belong from the `Relevant bindings` part of the error. 3. If not, I look to `Valid hole fits include` to find valid functions that may fit.

In step 3 however, there's a bit of pattern recognition because very polymorphic functions that never make any sense can sometimes show up there. `minBound` and `maxBound` fit for instance. Other things show up here that you can usually filter out as well such as `forever` when using holes in monad functions.

The above example was for the case where you have a high degree of confidence that there are no other errors. In general, type driven development hinges upon making one small change at a time and having only one type error at a time in your code.

That isn't as restrictive as it seems however, because you can always replace a problematic expression or function full of said expressions with (undefined :: TypeIWishThisExpressionRepresented).