Author here: those type annotations are optional in the case of TypeScript and PureScript; I only included the type annotations for clarity
That said, I didn't know about Go's support for inline struct definitions like that!
HN user
Author here: those type annotations are optional in the case of TypeScript and PureScript; I only included the type annotations for clarity
That said, I didn't know about Go's support for inline struct definitions like that!
Author here: not only have I heard of LLMs but I built a domain-specific programming language for prompt engineering: https://github.com/Gabriella439/grace
Author here: it's not even clear that agents can reliably permute their training data (I'm not saying that it's impossible or never happens but that it's not something we can take for granted as a reliable feature of agentic coding).
As I mentioned in one of the footnotes in the post:
People often tell me "you would get better results if you generated code in a more mainstream language rather than Haskell" to which I reply: if the agent has difficulty generating Haskell code then that suggests agents aren't capable of reliably generalizing beyond their training data.
If an agent can't consistently apply concepts learned in one language to generate code in another language, then that calls into question how good they are at reliably permuting the training dataset in the way you just suggested.
The tool now supports local models. In particular, you can pass an alternative base URL for both embeddings and completions so if you can serve a local model over an OpenAI-compatible API (e.g. using LM Studio) then you can point the tool to that.
Author here: yeah, this is a good point and something I think about even outside the context of agentic coding.
I've also tinkered with this idea myself in the context of prompt engineering with my Grace Browser project (https://trygrace.dev/), which converts code to an equivalent dynamic web form live within your browser.
I do think it's useful to remember that code is not the end goal and is itself just another mediated interface to the actual goal: the product your building. However, I think even if you cut code out of the picture the chat interface is still not necessarily the right interface for building a product. A great example of how to build a non-chat interface to product building (predating the AI boom) is Bret Victor's Inventing on Principle talk (https://www.youtube.com/watch?v=PUv66718DII) and there might be ways we can refresh the ideas in that talk for the AI era (although I still don't have any specific thoughts along those lines yet).
Author here: the source code is linked in the post but it can be easy to miss: https://github.com/Gabriella439/facet-navigator
It's very rough, but I plan on cleaning it up soon (the cluster labeler still needs a lot of work) and writing another post about it soon
Author here: my pronouns are she/her
I did not use AI to generate my blog's content nor layout.
Also, the reason my blog is named "Haskell for all" is because I originally created my blog a long time ago to try to make Haskell more accessible to people and counter the elitist tendencies.
you're welcome!
The post mentions this in the footnotes
Oh whoops, I misread. Never mind me, then
Author here: we didn't lay them off. They left of their own accord.
Author here. It is true that one of my goals in writing that post was to discourage people from jumping on the NeoHaskell train, but a larger goal was to educate people on what NeoHaskell actually was because there were a LOT of misconceptions floating around that led to confusion (and that confusion in turn amplified the drama because people were reading things into NeoHaskell that were not actually true).
You're welcome!
That's actually correct versioning in Haskell. The Haskell ecosystem uses a different versioning convention from other ecosystems where the first two components of the version number signal breaking changes. For more details, see: https://pvp.haskell.org/
All of the above to some degree. I can name some specific examples of each of these occurring:
* For an example of "Drop B", at one point the haskell-lsp package was deprecated in favor of the lsp package, so all downstream packages had to drop the haskell-lsp package as a dependency and migrate to the lsp package (I personally had to do this)
* For an example of "Don't let A change", that might happen for some period of time, although not indefinitely. The most obvious example is holding back the compiler version. For example, Stackage was on GHC 8.10 for a while, even after GHC 9.2 was released, due to breakage introduced in GHC 9.0.
* For an example of "Ignored B's declared dependency constraints", this is extremely common, especially when the `base` package is upgraded (since many packages have conservative upper bounds on their `base` dependency which can often be trivially bumped without issues).
* For an example of "Take over development of B" the `aeson` package for JSON support is one example of this. More generally, this happens when abandoned packages get adopted by the Haskell organization.
And Stackage does require contactable maintainers for supported packages. There are some exceptions to this rule, though. For example, sometimes a package gets added where the maintainer is available, but a dependency for that package was not yet on Stackage. I believe you can either add that maintainer to be the contact for that dependency, too, or it can be an orphan package. There are a bunch of people who fill in the maintenance gaps in the ecosystem by fixing these packages that don't have official contacts or active maintainers.
The order in which you combine overlays can sometimes matter. In other words, overlays are monoids, but not commutative monoids. That said, most of the time overlay order does not matter
The point of the post wasn't to explain that Church encoding is a replacement for the visitor pattern. The purpose of the post was to explain that the visitor pattern is essentially the same thing as Church encoding (thus the title of the post), because I noticed a lot of people were not appreciating that connection between the two.
Thank you for the feedback. I was conscientious of that shadowing issue when writing it, but I just wasn't sure what to change on either side to differentiate them.
You're right that there is no benefit in creating another abstraction, but the point of the post is sometimes the language doesn't have support for the original abstraction (e.g. sum types), so in some cases the other abstraction (e.g. visitor pattern or Church encoding) is the only available abstraction.
Author here: it's not changing the problem definition. I can confirm that the original motivation for writing the post was to show the theoretical underpinnings of the visitor pattern, not to encourage people to gratuitously use double dispatch.
Author here: Go does not have support for discriminated unions.
The trick is not limited to functional programming languages but it is limited to languages that support generic programming / polymorphism
Overall language popularity is only one input into how we prioritize programming languages.
The best way I can summarize our prioritization process is that we prioritize in descending over:
* What people are willing to spend their free time to build (I can't order other people to build high-priority bindings and my own free time is already accounted for by improving Haskell bindings that power a lot of shared tooling such as the language server)
* Bindings specific to DevOps use cases (e.g. Go / Python / Ruby / Nix / JSON / YAML), since they are the dominant languages and formats in this space)
* Bindings that can be used to create derived bindings (e.g. Rust, which can then be used to create a binding in any language that can bind to C. In fact, this is how the upcoming Python bindings work. See: https://pypi.org/project/dhall/)
* Bindings that users request (We have a yearly survey where we ask users to inform the direction of the ecosystem. Python was the most requested language in the most recent survey)
* Overall language popularity (as the final tiebreaker)
So I hope this illustrates that there is a lot more that goes into these decisions beyond just which language is the most popular and we're not being obtuse or dilettantes just because we haven't gotten to a specific language, yet.
Not native JavaScript, but the closest thing we have is PureScript (still in progress):
https://github.com/MonoidMusician/dhall-purescript
PureScript corresponds pretty closely to JavaScript in terms of the code it generates, so once we have a PureScript binding it shouldn't be hard to generate lean JavaScript bindings from that. Also, more people requested the PureScript bindings over the JavaScript bindings anyway in our most recent yearly survey:
http://www.haskellforall.com/2020/02/dhall-survey-results-20...
Dhall now has bindings to Rust and Go and Java/Python bindings are currently in progress
We also do take things seriously, including:
* Creating a language server (do any other configuration languages have this?) * Soliciting donations to fund high priority work (https://opencollective.com/dhall) * Working on a book (https://github.com/Gabriel439/dhall-manual) * Maintaining a formal language semantics (https://github.com/dhall-lang/dhall-lang/tree/master/standar...)
If you think we're still missing something please let us know as we are responsive to user feedback
I just added a screenshot to the README
I just added one. Thanks for the suggestion!
Author here: commas are necessary to separate list elements in any language where function application uses whitespace (i.e. Haskell-style function application). If you're not familiar with the syntax, an expression like `f x y z` is a function `f` applied to three arguments (`x`, `y`, and `z`), analogous to `f(x, y, z)` in a more traditional language.
Nix made this mistake of using whitespace to separate list elements AND using whitespace to separate a function from its argument and it is a very common pain point for new users, because they will write something like this:
[ theFunction theFunction'sArgument ]
... thinking it will be parsed as: [ (theFunction theFunction'sArgument) ]
... but it actually gets parsed as a list with two elements, leading to a bizarre type error.The static binaries for the various interpreters and conversion utilities (i.e. `dhall`/`dhall-to-yaml`/`yaml-to-dhall`) are all roughly 10 MB each
The following languages natively bind to Dhall:
* Haskell * Clojure * Ruby
... and the following language bindings are in progress:
* Rust * Go * Python * PureScript
In the absence of a native language binding, you can convert Dhall to YAML or JSON and read that in.
Author here: the syntax is inspired by all three of Haskell/PureScript/Elm
Author here: This is correct. I'm just borrowing a Haskell convention. Also, I like this convention because it leads to vertical alignment of commas.