Hacker News new | ask | show | jobs
by philh 2049 days ago
> If it seems confusing, it's because it is. That's the point I'm trying to make. I have seen — several times across a number of projects — people writing code with a philosophical ideal along the lines of "well, this page should only know about the state (a subset of the model) that it is responsible for, so I won't give it the whole model. Also it will only send the messages related to just this page. Oh, requirements changed. No problem, I'll just add another part of the global state as an argument. Oh, requirements changed again, and I need to send a global message. Hmm… I'll just… etc"

But... none of that, as far as I can tell, gives you a signature that looks like this? Even making the kind of changes where you think "okay, this is an ugly hack, if I'd known about this in advance I'd never have written it this way, but I don't have time to go back and do it properly so..."

If you've genuinely seen signatures that look like this, then my sense is that the people who wrote those functions have different problems than the one you describe.

Maybe I'm pulling on something that turns out not to matter here. Like, if you've experienced the problem you describe, and you just came up with an example silly type signature that turns out not to really work as an example, then fair enough, that's not a big deal. But if this post was inspired by seeing type signatures looking like that, and trying to explain those type signatures, and trying to come up with advice that will prevent them, then I would guess the advice is mistargeted. Or maybe I'm missing something and the process you describe really does lead to a signature like that, by people who are generally more-or-less competent; I don't say that it couldn't happen, only that I don't see how it could.

(I disagree with the sentiment "If it seems confusing, it's because it is." If people who lack a certain mental model repeatedly make the same sort of mistake, and generate something that seems confusing to people who have that model, it can be extremely helpful for the people with the model to figure out what's going on so they can try to share the model.)

Did you, perhaps, mean something like

    updatePersonalInformation
       : PersonalInformationMsg
      -> Model
      -> Result (PersonalInformationModel, Cmd PersonalInformationMsg)
                (Model, Cmd Msg)
         
? That would let a person say "this branch gets to update the global model, but all the others can stick with local changes and I just need to wrap their return value in `Err`".

(Which is still silly, just start the function with

    let local : (PersonalInformationModel, Cmd PersonalInformationMsg) -> (Model, Cmd Msg)
        local = ...
and wrap the return values in that. But I can at least see what someone would be doing with a type signature like the `Result` version.)