HNHacker News
TopNewBestAskShowJobs

gtf21

1,236 karma · joined May 5, 2014

Ex-Cambridge Natural Scientist (specialised in Astrophysics). Co-founder/CTO of Converge (converge.io) - making construction more efficient, safer, and more sustainable with sensors and AI. Develops mostly in haskell, clojure, typescript, python.
submissionscomments
gtf21··on All four major web browsers are about to lose 80% of their funding
I think I share the same opinion: I think this is going to be a very painful break with the previous paradigm, but a much needed one, and that actually this version of the current paradigm is quite bad: browsers only survive when Google pays them money.

Instead this will put all browsers on a much more even playing field, and perhaps it will force governments and citizens to realise that free software takes someone to write it.

gtf21··on Why Haskell?
I don't think it's specifically Haskell's style of functional programming. It's just functional programming.

Any paradigm shift requires re-learning I think. I don't actually think that's particularly hard, nor do I think it means the paradigm isn't a good one, it's just an inevitable consequence of a paradigm shift. Some shifts are easier than others, if the paradigms are closer together, but functional and imperative programming are quite distant in my view.

Nevertheless, I've seen some people find this easy, others find it hard. YMMV I guess.

gtf21··on Why Haskell?
> Some libraries use exceptions for lots of error states that in Go would be a returned error value.

This just seems like bad libraries, I'd agree that this is bad and sort of defeats the point. I haven't actually encountered this with any libraries I've used, and we tend to avoid MonadThrow / Catch except in particular circumstances.

> in this case, I'm worse off than in Golang.

Having (unfortunately) had to write some Golang, I don't think this is true -- I've encountered plenty of code in Golang in which it seems idiomatic to return things like empty strings and empty objects instead of error values which, I think, it's still possible to mishandle.

Perhaps this can be summarised as: you can still write bad Haskell, but I don't think it's particularly idiomatic looking at the libraries I've spent most of my time using, and the machinery you are provided allows you to do much, much better.

gtf21··on Why Haskell?
Oh ok I get what you mean now, I thought you were being a bit more obtuse than that.

So my original intent with that paragraph was very different, but you're right that I was not very precise with some of those statements.

Thanks for taking the time to explain, you've definitely helped expand the way I've thought about this.

gtf21··on Why Haskell?
I think this is being taken as me saying “therefore you can write any programme in Haskell” which, while true, was not the point I was trying to make. Instead I was trying to reduce the possible interpretation that I was suggesting that Haskell can write more programmes than other languages, which I don’t think is true.

> computability and programming just aren’t that related

I … don’t think I understand

gtf21··on Why Haskell?
> It is a shame that the article almost completely ignores the issue of the tooling.

Mostly because while I found of the tooling occasionally difficult, I didn’t find Haskell particularly bad compared to other language ecosystems I’ve played with, with the exception of Rust, for which the compiler errors are really good.

> The syntax summary in the article is really good

Thanks, I wasn’t so sure how to balance that bit.

gtf21··on Why Haskell?
For reference (in case it's helpful), my website (where this essay is hosted) is written in Haskell and is basically a fairly simple webserver.

For the "hello world" webserver, this might be a bit instructive: https://github.com/gfarrell/gtf.io/blob/main/src/GTF/Router....

gtf21··on Why Haskell?
If I may, as the author of "such sloppily constructed prose" (which I think might be a little unfair as a summary of all 6.5k words):

In this syntax note, I was not trying to teach someone to write Haskell programmes, but rather to give them just enough to understand the examples in the essay. I did test it on a couple of friends to see if it gave them enough to read the examples with, but was trying to balance the aim with not making this section a complete explainer (which would have been too long).

Perhaps I got the balance wrong, which is fair enough, but I don't think it's required to define _every single_ term upfront. It's also not crucial to the rest of the essay, so "The article lost me at following sentence" feels a bit churlish.

gtf21··on Why Haskell?
Yeah I also really don't understand the point that's being made here: it looks like a great way to introduce more errors.
gtf21··on Why Haskell?
Nope: I think the laziness aspect is very interesting, but it's not something that makes Haskell (for me) a great programming language. Or, at least, it's not in my list of the top reasons (it is in there somewhere).
gtf21··on Why Haskell?
> I find some code easier to express with procedural/mutable loops than recursion

This is what I was talking about in the section "Unlearning and relearning". While there are _some_ domains (like embedded systems) for which Haskell is a poor fit, a lot of the difficulties people have with it (and with FP in general) is that they have been heavily educated to think in a particular way about computation. That's an accident of history, rather than any fundamental issue with the programming paradigm.

gtf21··on Why Haskell?
> That's why, if you like the Haskell philosophy, why would you restrict yourself to Haskell?

In the essay, I didn't say "Haskell is the only thing you should use", what I said was:

> Many languages have bits of these features, but only a few have all of them, and, of those languages (others include Idris, Agda, and Lean), Haskell is the most mature, and therefore has the largest ecosystem.

On this:

> It's not bleeding edge any more.

"Bleeding edge" is certainly not something I've used as a benefit in this essay, so not really sure where this comes from (unless you're not actually responding to the linked essay itself, but rather to ... something else?).

gtf21··on Why Haskell?
> In this example bar's type signature doesn't tell you anything about what bar 'consumes'

Yes, it does: `bar` in your example is an `Int`, it has no arguments. That is captured precisely in the type signature, so I'm not sure what you're trying to say.

gtf21··on Why Haskell?
> Which part?

This part: "the type information only tells you how you can use doSomething. To know what is doSomething, you actually have to read the code :\" I think we're disagreeing on something quite fundamental here, based on "it doesn't tell you that bar depends on foo, and on foo's type. Also you have to read the body of bar, and also it is bad for code reuse."

(Although I am certainly open to the idea that "[I] failed to demonstrate it".)

A few things come up here:

1. Firstly, this whole example was to show that in languages which rely on this goto paradigm of error handling (like raising exceptions in python) it's impossible to know what result you will get from an expression. The Haskell example is supposed to demonstrate (and I think it _does_ demonstrate it) that with the right types, you can precisely and totally capture the result of an expression of computation.

2. I don't think it's true to say that (if I've understood you correctly) having functions call each other is bad for code re-use. At some point you're always going to call something else, and I don't think it makes sense to totally capture this in the type signature. I just don't see how this could work in any reasonable sense without making every single function call have it's own effect type, which you would list at the top level of any computation.

3. In Haskell, functions are pure, so actually you do know exactly what doSomething consumes, and it doesn't matter what getResult consumes or doesn't because that is totally circumscribed by the result type of doSomething. This might be a problem in impure languages, but I do not think it is a problem in Haskell.

gtf21··on Why Haskell?
Oh! I hope I wasn't bemoaning too much -- that was the lead-in, but it's mostly about what I really like about the language (and had some examples but I also didn't want to write a tutorial).
gtf21··on Why Haskell?
Sorry to hear that. I built it that way because I prefer reading narrower columns of text (maybe because I read a lot of magazines and newspapers, who knows).
gtf21··on Why Haskell?
I write about this at some length in the essay, perhaps you can help me by telling me why the section on "Make fewer mistakes" _doesn't_ satisfy?
gtf21··on Why Haskell?
I'm not sure that's entirely true (I wrote the examples): the point I'm trying to make is that you can precisely describe what `doSomething` consumes and produces (because it's pure) and you don't have to worry about what some nested function might throw or some side-effect it might perform.
gtf21··on Why Haskell?
> - how easy is it to make a web application with a hello world endpoint?

If that's all you want it to do, it's very easy with Wai/Warp.

> - How easy is it to auth a JWT?

We don't use JWTs, but we did look at it and Servant (which is a library for building HTTP APIs) has built in functionality for them.

> - Is there a good ORM that supports migrations?

There are several with quite interesting properties. Some (like persistent) do automatic migrations based on your schema definitions. Others you have to write migration SQL/other DSL.

> - Do I have to remodel half my type system because a product owner told me about this weird business logic edge case we have to deal with?

I think that's going to really depend on how you have structured your domain model, it's not a language question as much as a design question.

> - How do I do logging?

We use a library called Katip for logging, but there are others which are simpler. You can also just print to stdout if you want to.

gtf21··on Why Haskell?
We do use other ecosystems, yes. I haven't really found the tooling for Haskell to be particularly obstructive compared to other languages. I've run into plenty of mysteries in the typescript, python, ObjC/Swift, etc. ecosystems that have been just as irritating (sometimes much more irritating), and generally find that while HLS can be a bit janky, GHC is very good and I spend less time scratching my head looking at a piece of code that should work but does something wild than in other languages.
gtf21··on Why Haskell?
> so that compilers can reason about it

Actually this is the wrong takeaway, I think it's so that programmers can reason about it.

This isn't about type errors, it's about precisely describing a particular computational expression. In the python example, it's very unclear what `do_something` actually _does_.

gtf21··on Why Haskell?
You can have that syntax if you want it via `OverloadedRecordDot`.

I actually really like the syntax as it makes it easy to write DSLs which are actually just Haskell functions.

gtf21··on Why Haskell?
> The library ecosystem is probably the biggest issue.

I'd love to know which things specifically you're thinking about. For what we've been building, the "integration" libraries for postgres, AWS, etc. have been fine for us, likewise HTTP libraries (e.g. Servant) have been great.

I haven't _yet_ encountered a library problem, so am just very curious.

gtf21··on Why Haskell?
> Granted, the tooling is sh*t.

I hear this a lot, but am curious about two things: (a) which bit(s) of the toolchain are you thinking about specifically -- I know HLS can be quite janky but I haven't really been blocked by any tooling problems myself; (b) have you done much Haskell in production recently -- i.e. is this scar tissue from some ago or have you tried the toolchain recently and still found it to be lacking?

gtf21··on Why Haskell?
I think there are more fundamental differences between functional and imperative programming paradigms (or, perhaps, declarative and imperative programming styles?) than between passing by reference and passing by value (after all, variables are just references, filesystems have links, it just doesn't seem that unfamiliar).

I have definitely seen people struggle to wrap their head around declaring expressions representing what they want to compute when they are very used to imperative control flow like mutating some state while iterating through a loop.

> Kind of reminds me of a sect that promises you great things if only you work hard on leaving all your prior life behind.

I think this is sort of saying "hey this one thing looks like this other thing I don't like, therefore it must carry all the same problems". Perhaps we can call it "the duck type fallacy", but I don't think it's true to say that "anything which tries to change paradigm" is equivalent to cults.

gtf21··on Vizdom: Diagrams as Code
Ah ok thanks for clarifying!
gtf21··on Vizdom: Diagrams as Code
"Diagrams as Code" has been around a long time (e.g. DOT), not sure what this is really bringing as an improvement, especially as seems to require an account (at least it does when I click "get started" and, as someone else points out, is closed source.
gtf21··on Show HN: A CLI tool that enables you to remove files easily and safely
Some comments have already covered the subcommands thing, but why are you using the XDG_CONFIG_HOME directory `~/.config/wrm` to store files? This should be for _configuration_ not _state_. You should follow the specification for XDG base directories for this [1] which would suggest you put the trash in `~/.local/share/wrm/trash`

1: https://specifications.freedesktop.org/basedir-spec/basedir-...

gtf21··on Ask HN: What are your founder's resolutions for 2024?
I've continually been dragged back into the operational weeds of the business over the last few years (by which I mean things like running a team day-to-day, working through risk analyses on a project, etc.). This is (a) not something I enjoy; and (b) not the thing I'm best at (although I am quite good at it for short periods). I'd really like to be spending my time on things I get satisfaction from beyond "you're making your company work so that should be satisfying in itself", so this year one of my goals (sooner rather than later) is to actually make myself as operationally redundant as possible so I can have higher leverage and enjoy it at the same time.
gtf21··on I Love Ruby
> I wonder if there is a generally accepted quantifiable definition of programming language expressiveness. Here the author seems to equate it to closeness to natural languages.

I was going to make a similar comment -- it seems there might not be well agreed definitions of "expressiveness" here. I write most of my own projects in Haskell, precisely because I find Haskell to be extremely expressive, but I mean something different to "reads like English" (for which I think AppleScript is the closest example I can think of): to me, the expressiveness of the language is "how accurately can I describe my problem domain to the computer in a way that lets me naturally reason about it in code". I think this is mostly a function of the type system, not the particular syntax (e.g. allowing "?" in a method).

I am really interested in what other people consider "expressiveness" to mean, however.

Page 1 of 11Next →