Logs: liberachat/#haskell
| 2026-02-09 20:19:08 | → | merijn joins (~merijn@host-cl.cgnat-g.v4.dfn.nl) |
| 2026-02-09 20:19:53 | <s3np41> | well i just wanted to get good examples, so i guess the hackage should suffice? |
| 2026-02-09 20:20:00 | <s3np41> | Thanks anyways |
| 2026-02-09 20:20:20 | <EvanR> | there do be those there |
| 2026-02-09 20:21:05 | <ncf> | if you want an introduction to monad transformers in general then https://en.wikibooks.org/wiki/Haskell/Monad_transformers |
| 2026-02-09 20:21:40 | <s3np41> | will read thanks |
| 2026-02-09 20:23:02 | × | sord937 quits (~sord937@gateway/tor-sasl/sord937) (Quit: sord937) |
| 2026-02-09 20:24:12 | × | KindFoxo quits (~KindFoxo@user/KindoFoxo) (Read error: Connection reset by peer) |
| 2026-02-09 20:24:21 | <c_wraith> | There is something people call the "ReaderT pattern" which is not just "this is what ReaderT does". It's about designing your program around a kind of dependency injection in the form of actions being passed around implicitly with ReaderT |
| 2026-02-09 20:24:32 | → | KindFoxo joins (~KindFoxo@user/KindoFoxo) |
| 2026-02-09 20:24:37 | × | merijn quits (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 264 seconds) |
| 2026-02-09 20:26:26 | <ncf> | seems like a very silly name |
| 2026-02-09 20:26:47 | <ncf> | can we not java-fy haskell thanks |
| 2026-02-09 20:27:27 | <c_wraith> | Dependency injection is very natural in haskell. It's an overly formal name for "pass parameters", but it's very good to think about doing. |
| 2026-02-09 20:28:34 | <EvanR> | don't forget to inject your dependencies |
| 2026-02-09 20:28:53 | <c_wraith> | the type checker gets upset when you don't pass enough parameters. |
| 2026-02-09 20:29:05 | <ncf> | if you mean dependency injection say dependency injection! |
| 2026-02-09 20:29:13 | <EvanR> | I was going to say, if it boils down to passing the arguments you need, there's very little wiggle room to do anything else in haskell |
| 2026-02-09 20:29:14 | × | humasect quits (~humasect@dyn-192-249-132-90.nexicom.net) (Remote host closed the connection) |
| 2026-02-09 20:29:27 | <ncf> | although maybe continuation-passing would be a better name for this |
| 2026-02-09 20:29:45 | <EvanR> | if your dependencies are continuations |
| 2026-02-09 20:30:11 | <ncf> | sounds like that's what this is, unless i'm misunderstanding what it is people call the "ReaderT pattern" |
| 2026-02-09 20:31:07 | <EvanR> | https://academy.fpblock.com/blog/2017/06/readert-design-pattern/ |
| 2026-02-09 20:31:08 | <c_wraith> | It's not necessarily continuations. You can pass around `log :: Env -> Level -> Message -> M ()' and there's no continuations there. |
| 2026-02-09 20:32:01 | <c_wraith> | They key point is that you've abstracted managing the log system away from the logic that actually sends messages to the log system. |
| 2026-02-09 20:34:29 | <c_wraith> | There are a lot of ways to do this, of course. But a single indirect function call is very low weight, compared to a lot of abstractions you can come up with. |
| 2026-02-09 20:34:58 | → | merijn joins (~merijn@host-cl.cgnat-g.v4.dfn.nl) |
| 2026-02-09 20:37:29 | <ncf> | i guess this is only necessary in a language without parametrised modules.. |
| 2026-02-09 20:39:18 | <c_wraith> | technically Haskell has those, but they're so painful that no one uses them. |
| 2026-02-09 20:39:43 | × | merijn quits (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 240 seconds) |
| 2026-02-09 20:39:54 | <ncf> | does it? |
| 2026-02-09 20:39:59 | <c_wraith> | Also, I guess it's more that *cabal* has them, and will modify the compilation environment to synthesize the equivalent. |
| 2026-02-09 20:40:04 | <dolio> | backpack |
| 2026-02-09 20:40:10 | <ncf> | oh |
| 2026-02-09 20:40:27 | <c_wraith> | I actually use backpack features, but not for parameterized modules. |
| 2026-02-09 20:40:42 | <c_wraith> | Just for compatibility with different library versions renaming modules. |
| 2026-02-09 20:42:13 | <EvanR> | see also reflection (in haskell, for getting similar things accomplished) |
| 2026-02-09 20:43:36 | × | divlamir quits (~divlamir@user/divlamir) (Read error: Connection reset by peer) |
| 2026-02-09 20:43:42 | × | KindFoxo quits (~KindFoxo@user/KindoFoxo) (Ping timeout: 265 seconds) |
| 2026-02-09 20:43:56 | → | divlamir joins (~divlamir@user/divlamir) |
| 2026-02-09 20:44:02 | → | KindFoxo joins (~KindFoxo@user/KindoFoxo) |
| 2026-02-09 20:44:03 | <EvanR> | which I guess has the proper name Implicit Configurations |
| 2026-02-09 20:44:34 | <c_wraith> | functionally, the reflection library is also just "passing parameters", except it smuggles the parameter in a class constraint. |
| 2026-02-09 20:44:53 | <c_wraith> | Which has interesting UX considerations |
| 2026-02-09 20:50:45 | × | peterbecich quits (~Thunderbi@71.84.33.135) (Ping timeout: 245 seconds) |
| 2026-02-09 20:50:47 | <c_wraith> | I did some funny stuff faking dependent instances using a Reifies constraint. It works, but actual dependent types would be a lot easier to use. |
| 2026-02-09 20:50:58 | → | merijn joins (~merijn@host-cl.cgnat-g.v4.dfn.nl) |
| 2026-02-09 20:55:36 | × | merijn quits (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 244 seconds) |
| 2026-02-09 20:56:01 | <jreicher> | I spent probably full months arguing with some friends about exactly what "dependency injection" meant, and more than half of that was trying to figure out what a "dependency" is. |
| 2026-02-09 20:56:09 | <jreicher> | ...a full month... |
| 2026-02-09 20:56:51 | <EvanR> | a couple lines of code is worth N full months of arguing |
| 2026-02-09 20:58:39 | <EvanR> | is jargon darwinistic, i.e. does it persist and expire based on fitness for its purpose, recognized or not xD |
| 2026-02-09 20:59:09 | <geekosaur> | it certainly changes over time |
| 2026-02-09 20:59:20 | <EvanR> | dependency injection sounds verbose and redundant on the face of it, but maybe that's important xD |
| 2026-02-09 21:00:12 | <jreicher> | I've never tried to transplant it to FP. There are certainly people who believe it's very, very important in OO. |
| 2026-02-09 21:01:32 | <EvanR> | it's one of several OOP things which boils down to "pass a parameter" |
| 2026-02-09 21:01:42 | <EvanR> | in FP |
| 2026-02-09 21:02:41 | <geekosaur> | note however that it's controlled not by actual need but by perceived need, and perceptions can be slower to change |
| 2026-02-09 21:03:23 | <geekosaur> | OOP smuggles parameters in objects. Haskell can smuggle them in contexts. ☺ |
| 2026-02-09 21:03:36 | <geekosaur> | or monads |
| 2026-02-09 21:03:54 | × | KindFoxo quits (~KindFoxo@user/KindoFoxo) (Remote host closed the connection) |
| 2026-02-09 21:04:14 | → | pavonia joins (~user@user/siracusa) |
| 2026-02-09 21:04:25 | <jreicher> | Yes the mutability of objects is a key point, because the representation of state and the way it's mutated is exactly the kind of implementation detail that clients don't want to know. So I don't think an FP equivalent (if there is one) would just be passing parameters. |
| 2026-02-09 21:04:30 | → | KindFoxo joins (~KindFoxo@user/KindoFoxo) |
| 2026-02-09 21:05:15 | <EvanR> | is it? |
| 2026-02-09 21:05:30 | <jreicher> | Is it what? |
| 2026-02-09 21:05:35 | <EvanR> | you can get pretty far in OOP without mutability |
| 2026-02-09 21:06:10 | <jreicher> | I would suggest you're not really doing OO in that case. It's an opinion I'm not even sure I believe, but I just don't see OO offering anything special if its state mutation facilities aren't being used. |
| 2026-02-09 21:06:11 | <EvanR> | immutable objects is kind of fashionable these days |
| 2026-02-09 21:06:32 | <EvanR> | that gets into what OOP even is |
| 2026-02-09 21:06:42 | <EvanR> | I don't think mutability is universally critical |
| 2026-02-09 21:06:45 | → | merijn joins (~merijn@host-cl.cgnat-g.v4.dfn.nl) |
| 2026-02-09 21:06:56 | <EvanR> | (in fact it messes up some classic inheritance relationships) |
| 2026-02-09 21:07:08 | <jreicher> | If you're using an OO language and everything really is immutable, I think you're doing FP in an inappropriate language. |
| 2026-02-09 21:07:38 | trickard__ | is now known as trickard |
| 2026-02-09 21:08:20 | <KindFoxo> | What is immutability tho? Is Erlang/Elixir a language with immutable state? |
| 2026-02-09 21:08:55 | <KindFoxo> | actor seem pretty close to objects for me. I guess originally, in Smalltalk's era, they were the same thing |
| 2026-02-09 21:09:22 | → | Square joins (~Square4@user/square) |
| 2026-02-09 21:10:46 | × | Square2 quits (~Square@user/square) (Ping timeout: 265 seconds) |
| 2026-02-09 21:12:01 | × | merijn quits (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 264 seconds) |
| 2026-02-09 21:12:24 | <ski> | "FP" : programming with variant/sum types and pattern-matching |
| 2026-02-09 21:12:40 | <ski> | "OO" : programming with record/product types and message-dispatching |
| 2026-02-09 21:13:02 | <KindFoxo> | Haskell seems to me like a structural programming language, in a sense category theory is a reborn of structuralism in mathematics. In Haskell it allows to extract the structure emerging in relations into some sort of a pattern. |
| 2026-02-09 21:13:30 | <KindFoxo> | For example, Reader is such an extraction of the fact that a functional arrow is a monad |
| 2026-02-09 21:13:57 | <ski> | KindFoxo : you can store data in processes in Erlang, e.g. in its dict, or simply by having it wait for requests to set and access the state (which is immutably passed around in a tail-recursive loop) |
| 2026-02-09 21:15:26 | <KindFoxo> | ski: you've made Lisps not functional... and I guess the language FP does not fit in the definition being obviously a functional programming language |
| 2026-02-09 21:16:13 | <ski> | yea, those two are very restricted, and highly stylized, alternatives, for the purpose of showing a duality |
| 2026-02-09 21:16:23 | <ski> | (that's why i used quotes) |
| 2026-02-09 21:17:22 | <KindFoxo> | also, all the ML-like FP languages have record types, why should it be not an FP thing... I've seen some formalization of classes as coinductive types. In curry or Coq, not sure, sounds interesting to me... As for right now, I don't understand "the idea" behind OOP... |
| 2026-02-09 21:18:10 | <KindFoxo> | oh, I'm sorry... I don't read while writing... |
| 2026-02-09 21:18:39 | <ski> | but they don't have message-dispatching definition syntax (called "copatterns" in Agda. also used, years before that, by e.g. Erik Poll) |
| 2026-02-09 21:20:00 | <ski> | the point is that *one* way to construe "OO" is that the main idea is to structure your program around records with delayed (possibly parameterized) fields. with or without subtyping. with or without implementation inheritance and late binding, open recursion |
| 2026-02-09 21:20:01 | <EvanR> | jreicher, cardelli theory of objects shows two simplistic OOP "calculi" one with mutable, one without. Both are superficially similar to LC. So yeah |
| 2026-02-09 21:20:43 | <EvanR> | see also ocaml for a function language that happens to also support OOP |
| 2026-02-09 21:20:46 | <EvanR> | functional |
| 2026-02-09 21:21:27 | <ski> | and both these two structuring approaches, "FP", and "OO", are important. both are available in Haskell (although message-dispatching syntax, like in Agda, would help encourage it a bit more). VisitorPattern is a way to simulate (via CPA) pattern-matching on variant types, in traditional OO languages |
| 2026-02-09 21:21:52 | <ski> | yea, OCaml has support for immutable OO |
| 2026-02-09 21:22:11 | <ski> | returning a clone of the current object, but with some of the instance fields swapped out |
| 2026-02-09 21:22:33 | → | merijn joins (~merijn@host-cl.cgnat-g.v4.dfn.nl) |
| 2026-02-09 21:23:12 | <ski> | also, you can specify that an argument type, or result type, of a method is of "This" class (like "binary methods" and "clone methods"). this in turn causes not all subclasses to induce subtypes (which OCaml tracks statically) |
All times are in UTC.