2026/02/25

Newest at the top

2026-02-25 19:09:22 +0100 <__monty__> Backpack was sold to me as bringing ML's functors to Haskell.
2026-02-25 19:09:08 +0100ljdarj(~Thunderbi@user/ljdarj) ljdarj
2026-02-25 19:07:44 +0100wickedjargon(~user@208.98.208.115)
2026-02-25 19:07:18 +0100 <EvanR> what's an example of a sharing constraint
2026-02-25 19:07:15 +0100 <ski> yea
2026-02-25 19:05:20 +0100 <EvanR> so much stuff boils down to the management of scopes
2026-02-25 19:04:59 +0100 <ski> (iirc, you can also add sharing constraints for whole submodules)
2026-02-25 19:04:07 +0100 <ski> yes
2026-02-25 19:03:55 +0100 <EvanR> ah you called it
2026-02-25 19:03:36 +0100 <ski> (imagine there's a whole bunch of different abstract types, and one `t' is in a nested submodule, and perhaps the other one as well, and you'd like to not disturb all this structure, while still ensuring the two `t's are known to be equal)
2026-02-25 19:03:24 +0100 <EvanR> make that forall
2026-02-25 19:03:17 +0100 <EvanR> xD
2026-02-25 19:03:16 +0100 <EvanR> myFunctor :: exists t . Sig1 t -> Sig2 t
2026-02-25 19:02:35 +0100 <ski> with `myFunctor :: (exists t. ..t..) -> (exists t. ..t..)', how would you ensure the two `t's are the same, *apart* from rewriting to `myFunctor :: forall t. (..t.. -> ..t..)' ?
2026-02-25 19:02:20 +0100 <EvanR> unfortunate past tense did backpack have this "functor" feature?
2026-02-25 19:01:23 +0100 <ski> .. i'm not sure how easy it would be do express something like that, with the "module with abstract data type(s), as existentially quantified record" idiom for simulating modules, in e.g. Haskell
2026-02-25 18:59:38 +0100 <ski> standard module system stuff you do in the ML module system
2026-02-25 18:59:14 +0100 <ski> i mean so that you can specify a functor (module function), that takes a module (with a type inside), and returns another module, with a `sharing' constraint saying that the type exported by the resulting module is the same as the type in the parameter module, so that other code can use values of one type where values of the other are expected
2026-02-25 18:57:42 +0100 <EvanR> I know you don't mean that, but that's pretty common
2026-02-25 18:57:27 +0100 <EvanR> you mean inner class?
2026-02-25 18:57:11 +0100 <ski> (.. i'm not too sure how common it is to be able to define (e.g. abstract) data types inside an object, with OOP, though .. which routinely happens, with modules)
2026-02-25 18:56:15 +0100 <EvanR> it fills the same blank... single term dot stuff, which people like to latch their IDE features onto
2026-02-25 18:54:59 +0100 <ski> (e.g. in OCaml, and Alice ML)
2026-02-25 18:54:17 +0100 <ski> (typically module system have static, compile-time, resolvers. sometimes you can pass around modules at run-time, though, blurring the line a bit)
2026-02-25 18:53:00 +0100 <ski> well .. this is module system dot, not quite the same thing ?
2026-02-25 18:52:26 +0100v0id_7(~v0id_7@user/v0id-7:62772) v0id_7
2026-02-25 18:52:25 +0100 <EvanR> the power of the OOP dot
2026-02-25 18:51:53 +0100 <ski> how do you mean, ijouw ?
2026-02-25 18:51:36 +0100 <ski> (oh, and iirc, with breakpoints in GHCi, you can access them, if you break inside such a scope)
2026-02-25 18:51:25 +0100 <haskellbridge> <ijouw> can you do that top level?
2026-02-25 18:50:42 +0100 <ski> EvanR : mm, yep. i recall pondering a type system that would let you access them, from an interactor / debugger
2026-02-25 18:49:41 +0100 <ski> (iow, this is a shorter way to say `let open M in ...')
2026-02-25 18:49:12 +0100euphores(~SASL_euph@user/euphores) (Quit: Leaving.)
2026-02-25 18:49:00 +0100 <ski> __monty__ : reminds me that in OCaml, you can not only do `M.f x (M.g y z)', but you can also say `M.(f x (g y z))', where for `M.(...)', the identifiers exported by `M' are all in scope directly in the expression `...'
2026-02-25 18:48:21 +0100 <EvanR> putting non trivial functions inside a where clause always bites me since then I can't use it in the repl
2026-02-25 18:47:41 +0100 <EvanR> this was a joke about indentation levels rather than submodules
2026-02-25 18:47:15 +0100 <EvanR> ski, I do, but often it's a oneliner, and or doesn't appear indented more than 1
2026-02-25 18:45:54 +0100 <__monty__> I love Agda's approach to scoping, https://agda.readthedocs.io/en/latest/language/module-system.html
2026-02-25 18:45:20 +0100tromp(~textual@2001:1c00:3487:1b00:7955:9591:6018:7ef9)
2026-02-25 18:45:16 +0100 <ski> (.. sometimes i also want to use `if' or `case', at declaration level. `if ... then {f x = ...; g y z = ...} else {f x = ...; g y z = ...}'. having declarations as the body of the branches, conditionally defining in one of several ways (all branches have to define the same identifiers, naturally))
2026-02-25 18:41:42 +0100 <ski> you never define local functions in a `where' or `let' ?
2026-02-25 18:41:22 +0100 <EvanR> I have to admit I'm a never nester
2026-02-25 18:40:01 +0100 <ski> (of course, you could simply hide, not export, `extraDef', from the module in question. but it's often nice to restrict scope more, to make sure it's evident that `extraDef' isn't used elsewhere in the module. and Haskell doesn't allow nested submodules ..)
2026-02-25 18:38:19 +0100fgarcia(~lei@user/fgarcia) fgarcia
2026-02-25 18:38:09 +0100emaczen(~user@user/emaczen) emaczen
2026-02-25 18:38:04 +0100 <ski> (`fun ... and ...' is mutual recursive functions)
2026-02-25 18:37:38 +0100 <ski> in SML, this would be `local fun extraDef ... = ... in fun foo ... = ... and bar ... = ... end'
2026-02-25 18:37:00 +0100 <ski> in Haskell, you often have to resort to `(foo,bar) = (myFoo,MyBar) where myFoo = ...; myBar = ...; extraDef = ...', for this, which is ugly
2026-02-25 18:36:10 +0100 <ski> a somewhat related thing is the `local <decls> in <decls> end' declaration, in SML. it declares the latter declarations (between `in' and `end'), while hiding the former ones, letting them be in scope in the latter ones, but not visible elsewhere
2026-02-25 18:35:05 +0100emaczen(~user@user/emaczen) (Remote host closed the connection)