szkl has quit [Quit: Connection closed for inactivity]
bibi__ has quit [Quit: Konversation terminated!]
<discocaml>
<bluddy5> yep. I have yet to find a practical application where ocaml has the edge using modules and functors. I think most OCaml programmers would happily trade functors for typeclasses.
bartholin has joined #ocaml
Serpent7776 has joined #ocaml
Tuplanolla has joined #ocaml
szkl has joined #ocaml
<discocaml>
<lukstafi> I disagree with "most".
foo303 has joined #ocaml
<discocaml>
<limp.biskit> coming from a more OOP background, there are many cases where i don't see modules as any more 'elegant' than objects, just better integrated with ocaml. both excessive functors and java-style inheritance are unpleasant imo
dnh has joined #ocaml
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
dnh has joined #ocaml
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jyc has quit [*.net *.split]
jyc has joined #ocaml
dnh has joined #ocaml
sroso has quit [Quit: Leaving :)]
<discocaml>
<contextfreebeer> It's a bit weird to call functors a niche feature, that's a bit like saying C++ templates are a niche feature. Niche in the sense that user code can often avoid writing them, but only because of libraries that do it for the users. Similarly it's hard to imagine an ocaml project that doesn't *use* functors
<discocaml>
<contextfreebeer> But opt-in "typeclasses" via modular implicits could be nice
<discocaml>
<bluddy5> Every project in OCaml tries to remove functor usage as much as it can. They're just too heavy, and there's been nothing practical demonstrated in OCaml that can't be done in other languages without them.
<discocaml>
<bluddy5> Normally I would avoid using such sweeping words as 'nothing' and 'every', but honestly I can't think of anything.
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<discocaml>
<bluddy5> Not to say that they're not useful, but as an alternative to typeclasses, they just don't match up.
<discocaml>
<Kali> i've only ever seen functors exposed in stdlibs for map/set stuff
<discocaml>
<Kali> i don't think i've seen them used anywhere else
<discocaml>
<Kali> to the user of a library i mean; they might be used internally
<discocaml>
<sim642> I maintain a static program analyzer and it's functors all the way down
<discocaml>
<contextfreebeer> I'm confused, how do you create any ordered container without a functor parameterized over an ordered type? isn't that practical? also it's super nice to be able to define the ordering any way you wish imo
<discocaml>
<contextfreebeer> and it feels like there a ton of libraries that expose functors, not just map/set in the stdlib
<discocaml>
<contextfreebeer> ok, compared to typeclasses, maybe, that's definitely debatable, I can see arguments on both sides
<discocaml>
<contextfreebeer> for example to stick with ordered types, the typeclass solution would allow only one type of ordering for any type in any given context, so it's less flexible, but arguably that flexibility is unneeded most of the time
<discocaml>
<Kali> doesn't haskell have functor-like behavior for typeclasses through its minimal required implementation or something anyway?
<discocaml>
<Kali> in fact those are often better than functors since they can have multiple different implementations for the same result, whereas you would need separate functors for each minimum requirement
<discocaml>
<Kali> "minimal complete definition" if you want the exact term hackage uses
<discocaml>
<Kali> for instance (pun not intended) an instance of a Data.Eq typeclass can be expressed in terms of a `==` function or a `/=` function
<discocaml>
<Kali> but you would need to manually select which functor to use for ocaml
Serpent7776 has quit [Ping timeout: 264 seconds]
<discocaml>
<Kali> i feel like the common argument against typeclasses is that you can't have two instances of the same type but 1. that situation is really not that common 2. just make a newtype if you actually must
<discocaml>
<lukstafi> I use functors in `ppx_minidebug` for configuration, but I migrated to using functions with default arguments to setup the functor application. I use a functor in `ocannl` to convert "no-device" CPU-based backends (currently only gccjit) into a "core=device" multicore backends.
<discocaml>
<lukstafi> I'm assuming your argument against functors does not extend to first-class modules? (I'm using them too for code parametrized wrt. backend.)
n8n has joined #ocaml
<discocaml>
<bluddy5> Yeah first class modules are much better, though they could be made lighter.
<discocaml>
<holmdunc> I was more comfortable using functors in SML, because there's not a big buffet of other language to have to think about whether to use or ignore
<discocaml>
<lukstafi> Functors have their obvious applicability: converting one "computational service" (collection of types and functions that operate on them) into another one, where the conversion requires some wrapping. I wonder why you don't encounter that in your projects. If the conversion does not require wrapping then class inheritance would work.
<discocaml>
<deepspacejohn> I like using first-class modules but they're limited by the fact that their types can't have parameters. (e.g. `sig type 'a t end` isn't possible) it's the most common reason why I don't use them.
<discocaml>
<holmdunc> I was more comfortable using functors in SML, because there's not a big buffet of other language features to have to think about whether to use or ignore
<discocaml>
<lukstafi> There's a complication with first-class modules that sometimes you need to repackage them. And in the functions you often need the a variant of this pattern: `let f (type t) (module M : M_type with type t = t) ...`
<discocaml>
<lukstafi> There's a complication with first-class modules that sometimes you need to repackage them. And in the functions you often need a variant of this pattern: `let f (type t) (module M : M_type with type t = t) ...`
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
infinity0 has quit [Remote host closed the connection]
infinity0 has joined #ocaml
dnh has joined #ocaml
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
dnh has joined #ocaml
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
xd1le has joined #ocaml
<companion_cube>
@contextfreebeer I think C++ templates that are not just the equivalent of generics, are also a niche feature, yes
<companion_cube>
Niche as in, it can be very useful, but somewhat rarely
<companion_cube>
First class modules are also kind of niche :p
Serpent7776 has joined #ocaml
<companion_cube>
They're very useful but only because people don't like using objects. Remove functors and first class modules, use objects more, and you more or less end up with F#
<companion_cube>
Anyway in the broader ecosystem of FP languages it's quite clear that typeclasses are the more popular alternative, no new language is, to my knowledge, adding functors
Serpent7776 has quit [Ping timeout: 256 seconds]
n8n has quit [Quit: WeeChat 4.2.2]
bibi_ has joined #ocaml
nickiminjaj has joined #ocaml
nickiminjaj has quit [Changing host]
nickiminjaj has joined #ocaml
<discocaml>
<limp.biskit> ocaml's object system is definitely less weird than f#
<discocaml>
<limp.biskit> i guess thats the more or less but its definitely a big more or less
<discocaml>
<limp.biskit> f# also sprinkles classes around stdlib and most libraries for c# compat
<discocaml>
<akhilindurti> is there a nested fold in any of the ocaml stdlibs?
<discocaml>
<contextfreebeer> like a fold inside of a fold?
<discocaml>
<akhilindurti> like if i have two lists, and i want to compare each element of list 1 with each element of list 2 before putting it into the resultant list
<discocaml>
<akhilindurti> yeah but i would just have to do something like `nested_fold list1 list2 fun el1 el2 acc -> ...`
<discocaml>
<akhilindurti> so not a fold2, just to be clear
<discocaml>
<akhilindurti> since that's pairwise and not quadratic
<discocaml>
<contextfreebeer> `iter` allows you to get a cartesian product of two iterators, and you can then fold over an iterator of tuples, but I'm not totally sure what you want so maybe that won't work for you
<discocaml>
<akhilindurti> basically i'm trying to union two lists
<discocaml>
<contextfreebeer> oh, like a set union?
<discocaml>
<akhilindurti> yeah, although i'd like to preserve order
<discocaml>
<contextfreebeer> `CCList` from containers allows you to do that directly
<discocaml>
<contextfreebeer> not sure if it preserves the order, I guess it should
<discocaml>
<akhilindurti> oh it seems `base` also has a `Cartesian_product` module
<discocaml>
<akhilindurti> i'll see if that works, since i'm using base rn
<discocaml>
<akhilindurti> thanks!
nickiminjaj|2 has joined #ocaml
nickiminjaj has quit [Ping timeout: 252 seconds]
nickiminjaj has joined #ocaml
nickiminjaj|2 has quit [Ping timeout: 256 seconds]
torretto has quit [Remote host closed the connection]
torretto has joined #ocaml
jabuxas has joined #ocaml
cr1901 has quit [Read error: Connection reset by peer]
<Anarchos>
akhilindurti split/combine ?
cr1901 has joined #ocaml
nickiminjaj has quit [Read error: Connection reset by peer]
waleee has quit [Ping timeout: 252 seconds]
<discocaml>
<akhilindurti> my solution ended up being