Hacker News new | past | comments | ask | show | jobs | submit login
Wingman for Haskell (haskellwingman.dev)
181 points by dunefox on Dec 18, 2021 | hide | past | favorite | 45 comments



Fantastic. First time I saw something similar to this was Edwin Brady’s recent demo of Idris 2. It’s quite amazing just how much of a program can be machine-written when the types are strict enough.

I hope holes & case-splitting get into many more languages.


I want my sum types damnit. Nothing like writing a case match over a sum type instead of fighting inheritance.


Yes, once I got to know sum-types with match destructuring in F#, every other programming language that doesn't have them feels inferior. It's just such a practical idiom.


Nadia Polikarpova at UC San Diego is doing some interesting work in this space. Skipping to about 42:40 in the video Nadia discusses an evaluation with a range of skills using Hoogle+ and how the usage trends from concrete examples to mostly type level specification.

https://www.youtube.com/watch?v=ZPyVcnCabIU


The download link leads to a github repository called “haskell-language-server”; how are these projects related?

Edit: it’s addressed in the Wingman’s landing page FAQ.

> Wingman is built on top of HLS, and that's the reason it doesn't require dedicated editor support.

The project’s source code also lives in HLS, as a plugin: https://github.com/haskell/haskell-language-server/tree/mast...


A language server is an API for a program in a language, so that text editors and linter and code generators can all interact with the program without knowing about each other.


If only it could do this…

   f :: YourTestInput -> CorrectAndPerformantAdventOfCodeSolution
   f = _
---

Seriously though, even after writing Haskell primarily for years, I've never done hole-driven development and I'm still not sure what I'm missing. I tried once — granted, that was a long time ago — but I didn't get it. This post[0] suggests I'm not alone in thinking this.

I'm glad Wingman exists and I think branding it nicely like this is the right thing to do, but I think I need to see more concrete examples to really see the magic. Probably something like Gary Bernhardt's Destroy All Software screencast series. It's one thing for someone to tell you that vim is fast, but it's another thing entirely watching the tool come to life in the hands of an expert. I imagine it's a similar thing for Wingman — I still have this mental block where I'm picturing the tool conjuring up an undefined for each hole, which is exactly what the documentation suggests the tool doesn't do. I would love to see someone use Wingman to quickly hammer out an Advent of Code puzzle, or even something more real-world like an Esqueleto query (but is that even possible?)

[0]: https://bitemyapp.com/blog/please-stop-using-typed-holes/


The post talks more about usability issues rather than any theoretical issues.

There are more fundamental objections to typed holes - but Wingman is kind of the answer to those concerns - with typed holes you're filling in types from the expressions, with Wingman you're doing pretty much the opposite - synthesizing programs from the type.

Now there might be usability issues with Wingman as well, but it represents a different direction - more suitable for type-driven development.


A video about Wingman with detailed examples https://www.youtube.com/watch?v=S0HvfXq3454 including custom tactics https://www.youtube.com/watch?v=S0HvfXq3454&t=2139s


Wingman is cool and all, but OmegaStar is really holding things up - still waiting on ISO timestamp support:

https://www.youtube.com/watch?v=y8OnoxKotPQ

https://www.youtube.com/watch?v=DYvhC_RdIwQ

Shout out to the Galactus team!


This comment and the relevancy of the videos make no sense to me. Am I the only one?


It's because a microservice in the video is also called Wingman.


I tried the example and it worked. I am indeed amazed, both at Wingman and how good Haskell and its tooling has become since I last looked at it a couple of years ago.


One promise of Haskell is that, once you've become an advanced or expert user, it is a gigantic force multiplier for individual devs or small, tight teams.

The way the tooling has progressed recently imo is that being proven in real-time.


What are your favorite new developments in tooling? I haven’t used Haskell since 2014.


For all the new tools (HLS, Wingman), it's the core tooling that has improved the most since the then. GHC (+ghci) and cabal are leagues ahead of 2014 now.

Some other cool tooling advancements since then that come to mind are.. Nix integration (both nixpkgs and haskell.nix), ghc heapview, ghcjs, a glut of formatters, ghcid (is this that new?)


Ghcid rocks! Makes it super easy to develop in a terminal with no IDE. Just a text editor here and ghcid there, telling me instantly when I make a mistake.


Why would you want to develop in a terminal with no IDE? The only other people I've seen do this were long-term Haskell developers (I remember seeing someone fixing a bug with sed!)


It makes you write better code with a smaller local conceptual branching factor. You need to be able to keep the number of concepts required to comprehend a piece of code small enough to fit in working memory. This forces you to structure your code well, come up with better abstractions, etc. It's also more zen, faster (in terms of UI responsiveness), less prone to breaking, requires less maintenance and configuration, etc.

IDEs are generally terrible for code quality, (and for my personal happiness,) but they're also viral because if one person working on a codebase is using an IDE, then they're probably going to write code that forces everyone else to also use an IDE - e.g. because understanding the code practically requires jump-to-definition.


> […] e.g. because understanding the code practically requires jump-to-definition.

Wait… so the code you write makes me magically able to know the record field names of your data types without looking at their definition?

Your statement may be true if it’s talking only about the core logic of an application, but when we get to the part that interfaces with the rest of the world, things always get somewhat messy. An IDE is a huge help here.

I mean, sure, you may be able to memorize the arguments that “readCreateProcess” takes (https://www.stackage.org/haddock/lts-18.19/process-1.6.13.2/...), but sometimes it’s really handy to have an IDE help you with this.


> I mean, sure, you may be able to memorize the arguments that “readCreateProcess” takes

How frequently would you use and subsequently forget how to use this function?

If I use a library function like this, I most likely write it exactly once in my codebase. The cognitive overhead of going on hackage one time per project-library is very small.

I agree an IDE makes you marginally faster in this case - just pointing out that this marginal benefit need not be significant.


Knowing record field names without looking at the definition isn't a critical path of coding worth optimizing. Amdahl's Law applies to code editing too.

Hoogle and even a simple "rg -A10 'data TheRecordName'" work perfectly fine. No reason to shave seconds with an entirely different tool.

For readCreateProcess, I just..look at the Haddocks while I program :)


Speaking from years of pro & hobbyist Haskelling:

Good Haskell modules tend to be quite literate and are therefore easy to read as plaintext. Clicking into the source of Hackage is often very fruitful compared to other languages (Go comes to mind.)

Often they aren't meant to be read top-to-bottom of course, but they're a few hundred lines of code that makes sense and backs a very readable export list.

And good Haskell isn't especially bound by writing and managing the code. You spend most of the time thinking and then a small amount of excellent, composable code pops out. Rinse, repeat, compose it all together.


> And good Haskell isn't especially bound by writing and managing the code. You spend most of the time thinking and then a small amount of excellent, composable code pops out. Rinse, repeat, compose it all together.

Haskell is no different than any other language in this regard. Implementing e.g. a standard CRUD app in Haskell using “beam” involves a lot of boilerplate, for which a proper IDE is super useful.


> Haskell is no different than any other language in this regard

It absolutely 100% is. This is half the reason people like to use it.

> Implementing e.g. a standard CRUD app in Haskell using “beam” involves a lot of boilerplate

I haven't used beam, but for me, the appeal of Haskell is that that you can throw out like 90% of the low-semantic-density boilerplate you see elsewhere. Composable abstractions, typeclasses, generics, lenses, etc. - all of these things directly serve to reduce unnecessary semantic sparsity, and incidentally obviate the need for an IDE.


Haskell has a decent web ecosystem at this point. However, if you really want to avoid boilerplate when writing a CRUD app, your best choice is one of the big, boring popular web frameworks (Ruby on Rails, Django, etc.) 90% of boilerplate avoidance has less to do with fancy language features than it does with someone else already having done the work for you. (And dynamic languages like Ruby and Python do allow all kinds of fancy abstractions anyway - just without the security of compile time typing.)


What boilerplate exactly? The deriving & trivial instances you write when you define your table schemas?


Also, I write elisp all the time that automates certain code blocks (in all languages.)


Less distraction.

An IDE gives you hints and you learn to rely on them; it takes 1 second to check something and you end up doing many checks like this.

In a terminal you have to check everything and remember about everything yourself. Maybe it takes 1 minute instead of 1 second. So you only do this when it matters and you make sure you remember the result because you don’t want to waste that 1 minute again.


Thanks I'll take a look!


Perusing GHC changelogs since then will show you a _lot_ of new things in the language, compiler, and repl for sure.


I'll also mention that Codex / Copilot could help write Haskell code where I simply couldn't. Or, at least get me close.

Generation with ML and then filtering with the typechecker/compiler for valid results could be a really powerful pair.


I feel that there is some kind of link to duality in optimization. Like you are trying to bound the intended program from below and from above.


If one is able to write a tool to write your program for you, could it be the case that the language lacks syntactic constructs to be terse enough to be pragmatic?


Where is this comment coming from? That is, how much have you looked at what the tool does/written Haskell in the past?

I think the key thing is that sometimes there are multiple ways to answer something. For example consider this type:

  [Maybe a] -> [a]
It takes a list of optional values and returns non-optional values. The ‘obvious’ semantics in Haskell could be achieved with:

  f [] = []
  f (Nothing:xs) = f xs
  f (Just x:xs) = x:f xs
And there are plenty of other ways to write that function. But you could also write functions like

  g xs = []
  h xs = reverse (f xs)
  j [Just a, Just b] = [b, a, b]
  j _ = []
And all three would satisfy the type above. So the type may be a sufficient input to the tool as the programmer may select the suggestion, but it wouldn’t be sufficient input to the compiler as the compiler could just guess the wrong thing.


When can I get Wingman to fill in trivially simple holes, e.g. where the type of the hole is `TypeA -> TypeB` and there’s only one function in scope with that type?

In this situation, choosing “Fill in hole”, Wingman always just fails with a “ran out of gas”-error.

(Using GHC 8.10.7)


You could try to increase the setting for the search tree or restarting VS Code (at least that solved some issues for me).


Stuff like this make me wonder if we'll have jobs in 15 years.


At its heart stuff like this is no different than the jumps from punchcards you asm to c to python. You still need someone to solidify ideas into processes. The change is that the building blocks themselves become more complex.


If I look how much (dumb) code you have to write for stuff like UIs, I certainly hope such tools will automate that work away.

Sure, it's easy money, but also boring, lol


For whatever automation a new tool gives you, you get new maintenance on that tool, other languages will want a tool that gives those features, systems running older versions will want upgrades in order to support the tool, 20% time will be spent on getting it running immaculately on Emacs, security researchers will find bugs in the tool so everyone has to fix, patch and upgrade, web sites for showing off the tool need designing and hosting, support forums have to be staffed, blogs have to be written, some novel use of the tool requires integration with various other systems, enterprise asks for a powerbi version that can integrate with oracle (it ends up being 5x slower, but does lead to more jobs in maintenance and meetings), more research is produced etc. etc.


Wingman just automates sifting through what the Haskell types enforce - they restrict possibilities so much there aren't that many valid programs most of the time. There's plenty of Haskell programmers all the while tho ;)


I was worried about this for several years.

I then had the realization that if someone manages to genuinely automate programming, humans will wind up still being in the loop to confirm that the generated code is reasonable under the hood, and to be sure we have people who understand what it's doing and why.

If I'm right about that, code review chops will be worthwhile in the long haul.


I think the end game is humans just let self-coding machines work as long as they are generating more cash than the cost of resources they use. Otherwise ... DELETE! Or the machine runs out of the crypto it needs to purchase more computing capacity and halts naturally like Odin intended.

Of course, there is just that existential risk that the machines recognizes the profit distributions we are taking are negatively impacting their margins - and ability to survive. :(

Where all this goes, nobody knows! But it won't be boring.


Is the an out-of-the box way to use it in Kakoune right now?




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: