companion_cube changed the topic of #ocaml to: Discussions about the OCaml programming language | http://www.ocaml.org | OCaml 4.11 release notes: https://caml.inria.fr/pub/distrib/ocaml-4.11/notes/Changes | Try OCaml in your browser: http://try.ocamlpro.com | Public channel logs at http://irclog.whitequark.org/ocaml
Anarchos has quit [Quit: Vision[0.10.3]: i've been blurred!]
zolk3ri has quit [Ping timeout: 240 seconds]
nicoo has quit [Ping timeout: 240 seconds]
cantstanya has quit [Ping timeout: 240 seconds]
tryte has quit [Ping timeout: 240 seconds]
ygrek has quit [Ping timeout: 240 seconds]
mxns has joined #ocaml
andreas303 has quit [Ping timeout: 240 seconds]
mxns has quit [Ping timeout: 258 seconds]
tryte has joined #ocaml
cantstanya has joined #ocaml
nicoo has joined #ocaml
andreas303 has joined #ocaml
Anarchos has joined #ocaml
amiloradovsky has quit [Remote host closed the connection]
Jesin has quit [Quit: Leaving]
Jesin has joined #ocaml
Tuplanolla has quit [Quit: Leaving.]
<Anarchos> what is the best way to do hashconsing in ocaml ?
<d_bot> <psteckler> is there a pure-OCaml version of `re2`, to avoid dependencies on C++ libs?
<d_bot> <Anurag> There is a pure ocaml regex library <https://github.com/ocaml/ocaml-re>.
<d_bot> <Anurag> Janestreet's ocaml-re2 is eventually going to be migrated to `ocaml-re` as well (from re2)
<d_bot> <jktuglu> hey @Anurag , could you provide some insight for me on json parsing in ocaml
<d_bot> <jktuglu> I have an issue with parsing a 2d JS array to a OCaml array
<d_bot> <jktuglu> I have tried with using recursion, but am unable make it work, it would be awesome if you could provide any insight?
<d_bot> <jktuglu> here is a snippet:
<d_bot> <jktuglu> ```let rec loop2 row rowNum colNum =
<d_bot> <jktuglu> match row with
<d_bot> <jktuglu> | [] -> ()
<d_bot> <jktuglu> | piece :: cols ->
<d_bot> <jktuglu> let result = extractPieceDetails piece rowNum colNum in
<d_bot> <jktuglu> printIndex rowNum colNum;
<d_bot> <jktuglu> match result with
<d_bot> <jktuglu> | None -> loop2 cols (rowNum) (colNum + 1 )
<d_bot> <jktuglu> | Some p ->
<d_bot> <jktuglu> eprintf "\n OLD BOARD on COL"; flush stderr;
<d_bot> <jktuglu> eprintf "\n ADDING PIECE: "; flush stderr;
<d_bot> <jktuglu> printPieceType result;
<d_bot> <jktuglu> newBoard.(rowNum).(colNum) <- result;
<d_bot> <jktuglu> loop2 cols (rowNum) (colNum + 1);
<d_bot> <jktuglu> in
<d_bot> <jktuglu> let rec loop1 jsonBoard rowCount =
<d_bot> <jktuglu> eprintf "\n blah"; flush stderr;
<d_bot> <jktuglu> printRow rowCount;
<d_bot> <jktuglu> match jsonBoard with
<d_bot> <jktuglu> | [] -> (newBoard)
<d_bot> <jktuglu> | (`List row) :: rows ->
<d_bot> <jktuglu> eprintf "\n OLD BOARD"; flush stderr; (loop2 row rowCount 0); eprintf "\n NEW BOARD"; flush stderr; boardToJson newBoard; loop1 rows (rowCount + 1);
<d_bot> <jktuglu> | _ -> failwith "Not working"
<d_bot> <jktuglu> in```
<d_bot> <jktuglu> Ideally, this will output an OCaml Array with a type piece
<d_bot> <Anurag> Which json library are you using?
<d_bot> <jktuglu> Yojson
<d_bot> <jktuglu> AFAIK, Yojson doesn't provide support for iterating through and keeping row count for this, so I figured I would do recursion
<d_bot> <jktuglu> but im not sure this is best practice
<d_bot> <Anurag> Something like https://github.com/janestreet/ppx_yojson_conv will help you a lot for such tasks. With the ppx you can do something like:
<d_bot> <Anurag>
<d_bot> <Anurag> ```ocaml
<d_bot> <Anurag> type foo = int array array [@@deriving yojson]
<d_bot> <Anurag> ```
<d_bot> <Anurag> You'll get your encoder/decoder functions auto generated
<d_bot> <Anurag> it'll be a much nicer way to manage your serialization as it'll be easy to adapt if the shape of the data structure changes in the future
<d_bot> <rgrinberg> In any case, it's a little hard to understand what is not working in your example
<d_bot> <jktuglu> okay @rgrinberg , Ideally, I have an Array that has different piece types, the ```piece``` type is a Some | None
<d_bot> <jktuglu> what is failing is the array itself, it looks like from the code that it will just go recursively through the json double list object, but it is writing to the array really weirdly
<d_bot> <jktuglu> the function should return:
<d_bot> <jktuglu> ```[> `List of Yojson.Basic.t list ] list -> piece option array array```
<d_bot> <rgrinberg> Try writing your function using `List.iteri`. That should simplify it a lot.
<d_bot> <jktuglu> Will the List library work for Yojson List types?
<d_bot> <Anurag> Yojson uses the stdlib lists so yes it'll work 🙂
<d_bot> <jktuglu> okay cool
Anarchos has quit [Quit: Vision[0.10.3]: i've been blurred!]
<d_bot> <jktuglu> Are there any example snippets you know for this List.iteri?
<d_bot> <rgrinberg> `List.iteri (fun i x -> Printf.printf "(%d, %s)\n" i x) ["foo"; "bar"; "baz"]`
sagax has quit [Ping timeout: 260 seconds]
<d_bot> <theangryepicbanana> is there a way to have a module and a class be mutually recursive without wrapping the class in a module?
<d_bot> <theangryepicbanana> (I'm fully aware that classes are discouraged, that's not the point)
theblatte has quit [Ping timeout: 264 seconds]
<d_bot> <theangryepicbanana> I'm looking for something like this ```ocaml
<d_bot> <theangryepicbanana> module rec A: ... = struct
<d_bot> <theangryepicbanana> type t = something * b list
<d_bot> <theangryepicbanana> end
<d_bot> <theangryepicbanana>
<d_bot> <theangryepicbanana> and class b (a: A.t) = object
<d_bot> <theangryepicbanana> ...
<d_bot> <theangryepicbanana> end```
<d_bot> <theangryepicbanana> (and due to the fact that oop is discouraged, there isn't much I can find about this elsewhere online)
theblatte has joined #ocaml
<d_bot> <rgrinberg> I don't think so. You can't do this for modules and types either
mxns has joined #ocaml
mxns has quit [Ping timeout: 258 seconds]
<d_bot> <theangryepicbanana> dang, that kinda sucks
decentpe- has joined #ocaml
<d_bot> <theangryepicbanana> I literally refactored my code to use classes because I had too many mutually recursive modules
decentpenguin has quit [Ping timeout: 272 seconds]
decentpe- is now known as decentpenguin
<d_bot> <jktuglu> @rgrinberg , could there be a reason why this same thing is returning the same issue?:
<d_bot> <jktuglu> ```let jsonBoardConversion3 gameState =
<d_bot> <jktuglu> let board = gameState |> member "board" |> to_list in
<d_bot> <jktuglu> let newBoard = (Array.make 8 (Array.make 8 None)) in
<d_bot> <jktuglu> for i = 0 to 7 do
<d_bot> <jktuglu> let row = (List.nth board i) |> to_list in
<d_bot> <jktuglu> for j = 0 to 7 do
<d_bot> <jktuglu> (
<d_bot> <jktuglu> let piece = List.nth row j in
<d_bot> <jktuglu> newBoard.(i).(j) <- extractPieceDetails piece i j
<d_bot> <jktuglu> )
<d_bot> <jktuglu> done
<d_bot> <jktuglu> done; boardToJson newBoard;
<d_bot> <jktuglu> newBoard```
<d_bot> <jktuglu> function jsonBoardConversion3 -> JSON -> piece option array array
<d_bot> <jktuglu> where extractPieceDetails returns -> Some Piece or None
<d_bot> <rgrinberg> What is the issue? Earlier you said it's "writing to the array really weirdly". That doesn't make it clear what the problem is
<d_bot> <jktuglu> So array is supposed to be board full of Some pieces and Nones
<d_bot> <jktuglu> the board is being returned as all Somes
<d_bot> <jktuglu> each piece object have row,col attributes
<d_bot> <jktuglu> and its returning that for all these pieces, the row is 7 and col varies correctly
<d_bot> <jktuglu> does that help?
<d_bot> <jktuglu> I've checked that the extractPieceDetails returns correct values: ie Some/None etc.
<d_bot> <jktuglu> Could it be something to do with how OCaml is evaluating this Some piece type?
mfp has quit [Ping timeout: 265 seconds]
narimiran has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 240 seconds]
aaaaaa has joined #ocaml
sagax has joined #ocaml
<d_bot> <ggole> `Array.make` initialises every element of the array with the same value, which here is the same array. Mutations of that array will appear on every row, which is probably what you are seeing.
<d_bot> <ggole> Use `Array.init 8 (fun _ -> Array.make 8 None)` instead.
<d_bot> <jktuglu> oh.
<d_bot> <jktuglu> I cant thank you enough, @ggole thanks!!!!!
<d_bot> <jktuglu> what is the fun _ mean?
<d_bot> <ggole> This is worth remembering because `Array.make len expr` where `expr` results in a mutable thing is a common mistake
<d_bot> <ggole> It's a function that ignores its argument. `Array.init` will call that function with the index as argument, and there isn't any use for the index.
<d_bot> <jktuglu> okay, thanks so much will remember this now
_whitelogger has joined #ocaml
waleee-cl has quit [Quit: Connection closed for inactivity]
_whitelogger has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 264 seconds]
Serpent7776 has joined #ocaml
tane has joined #ocaml
wonko7 has joined #ocaml
neiluj has joined #ocaml
zebrag has quit [Read error: Connection reset by peer]
zebrag has joined #ocaml
hnOsmium0001 has quit [Quit: Connection closed for inactivity]
olle has joined #ocaml
ggole has joined #ocaml
bartholin has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 240 seconds]
mfp has joined #ocaml
troydm has quit [Ping timeout: 260 seconds]
<d_bot> <Manas (prometheansacrifice)> Can I configure Alcotest to emit logs at a different path ie. generate `.output` files somewhere else?
<d_bot> <craigfe> ```
<d_bot> <craigfe> -o DIR (absent=/home/craigfe/t/alcotest/_build/_tests)
<d_bot> <craigfe> Where to store the log files of the tests.
<d_bot> <craigfe> ```
<d_bot> <craigfe> perhaps; I haven't tested it personally
<d_bot> <Manas (prometheansacrifice)> Thanks
inkbottle has joined #ocaml
zebrag has quit [Ping timeout: 256 seconds]
ansiwen has quit [Ping timeout: 240 seconds]
ansiwen has joined #ocaml
webshinra has quit [Ping timeout: 264 seconds]
webshinra has joined #ocaml
aaaaaa has quit [Quit: leaving]
troydm has joined #ocaml
emias has quit [Quit: WeeChat 2.3]
Haudegen has quit [Quit: Bin weg.]
waleee-cl has joined #ocaml
neiluj has quit [Ping timeout: 264 seconds]
ygrek has joined #ocaml
hannes has joined #ocaml
Tuplanolla has joined #ocaml
ygrek has quit [Remote host closed the connection]
mxns has joined #ocaml
mxns has quit [Ping timeout: 256 seconds]
Haudegen has joined #ocaml
mxns has joined #ocaml
narimiran has quit [Quit: leaving]
emias has joined #ocaml
neiluj has joined #ocaml
neiluj has quit [Changing host]
neiluj has joined #ocaml
bartholin has quit [Quit: Leaving]
inkbottle has quit [Quit: Konversation terminated!]
zebrag has joined #ocaml
Haudegen has quit [Quit: Bin weg.]
olle has quit [Ping timeout: 264 seconds]
<d_bot> <Chiyoku!> I hate ocaml documentation it's not clear D:
<d_bot> <Chiyoku!> The `core` lib docs are strange
<mrvn> Sometimes it should say what it's used for / how it's used or give an example.
TheLemonMan has joined #ocaml
jnavila has joined #ocaml
gareppa has joined #ocaml
gareppa has quit [Remote host closed the connection]
Haudegen has joined #ocaml
hnOsmium0001 has joined #ocaml
mrvn has quit [Ping timeout: 256 seconds]
mrvn has joined #ocaml
narimiran has joined #ocaml
kitties is now known as libbies
libbies is now known as kitties
Haudegen has quit [Quit: Bin weg.]
Haudegen has joined #ocaml
<d_bot> <EduardoRFS> there is any way to create an immutable block in OCaml using the `Obj` module? I want to create an immutable block for unsafe code, but it needs a closure tag
<d_bot> <EduardoRFS> maybe `%makeblock`?
<def> Obj.new_block?
<d_bot> <EduardoRFS> def: new_block creates mutable blocks only, `%makeblock` is the way to create immutable ones, but I've no idea how to use it
<d_bot> <Bluddy> why do you need immutable?
<def> It is mutable only in your local scope, meaning that the compiler won't make aggressive optimization that depends on it.
<def> Otherwise there is no difference between mutable and immutable blocks.
<def> As soon as you leave the local scope, it is impossible to distinguish from an immutable block
<def> (Said differently: an "immutable" block is only a concept of the compiler, not of the runtime)
StephenM has joined #ocaml
<StephenM> Is there a way (or standard convention) for providing convenience functions for module type? Suppose I have a module type for "groups", with
<StephenM> op : t -> t -> t and inv : t -> t, can I concretely define "subtract (a : t) (b : t) = op (a) (inv b)"?
<d_bot> <EduardoRFS> @Bluddy I'm making a really fast path of some interpreter and creating the block isn't needed but I need for OCaml to emit the right code. If it was immutable that would be inlined and there would be no allocation
<d_bot> <EduardoRFS> def: yes I know, I want an immutable block for the compiler to reduce some overhead, if it was an immutable block there would be zero functions access on my code
mxns has quit [Ping timeout: 264 seconds]
<d_bot> <craigfe> StephenM: This is typically done by having a functor extend the signature with functions that are implementable in terms of those in the input.
<d_bot> <craigfe> Probably no standard naming conventions, but e.g. JS Base uses `MakeN` functors to extend `BasicN` module types to expanded `SN` equivalents. (https://github.com/janestreet/base/blob/master/src/applicative_intf.ml#L288-L290)
<StephenM> craigfe: Ah, perfect. Thanks!
<d_bot> <Bluddy> Can you define a dummy immutable record and then allocate one?
<d_bot> <EduardoRFS> hmmm that may be an option, let me check
<d_bot> <EduardoRFS> nope, the tag will be wrong
raver has joined #ocaml
<d_bot> <EduardoRFS> essentially I just wanted to emit a `jmp *%rbx` directly, I can have the same effect by using `Obj.new_block` but then it does 2 C call and destroy my performance, and can't be inlined
<mrvn> how about a mutable dummy closure block and you just copy the function pointzer in and call it?
<d_bot> <Bluddy> or just change the tag on the above with `Obj.set_tag`
ggole has quit [Quit: Leaving]
TheLemonMan has quit [Quit: "It's now safe to turn off your computer."]
mxns has joined #ocaml
amiloradovsky has joined #ocaml
mxns has quit [Client Quit]
mxns has joined #ocaml
<d_bot> <EduardoRFS> mrvn: that's what I'm doing right know
<d_bot> <EduardoRFS>
<d_bot> <EduardoRFS> ```ocaml
<mrvn> bluddy: that wouldn't be immutable
<d_bot> <EduardoRFS> let call_pointer input pointer =
<d_bot> <EduardoRFS> let id = Sys.opaque_identity (fun v -> v) in
<d_bot> <EduardoRFS> let call: int ref = Obj.magic id in
<d_bot> <EduardoRFS> call := pointer;
<d_bot> <EduardoRFS> let call: 'a -> 'b = Obj.magic call in
<d_bot> <EduardoRFS> call input
<d_bot> <EduardoRFS> ```
<d_bot> <EduardoRFS> if you look on godbolt you can see the problem `https://godbolt.org/z/WEbsov`
<d_bot> <EduardoRFS> ```
<d_bot> <EduardoRFS> movq %rbx, (%rdi)
<d_bot> <EduardoRFS> movq (%rdi), %rsi
<d_bot> <EduardoRFS> movq %rdi, %rbx
<d_bot> <EduardoRFS> jmp *%rsi
<d_bot> <EduardoRFS> ```
wonko7 has quit [Ping timeout: 258 seconds]
<d_bot> <EduardoRFS> the first two instructions are just dumb
<d_bot> <EduardoRFS> but they do memory operations, which even today isn't ideal
<mrvn> yeah, they could eb combined. But does it make any difference? That just goes to cache and propably not even leaves the writeback buffer
<d_bot> <EduardoRFS> from hard coding the assembly, I got some improvement, just by doing so, also it's code that will be running on CPUs with not a lot of cache, like a raspberry pi
<d_bot> <EduardoRFS> it doesn't matter that much, but I'm kind of sad looking at this code
mxns has quit [Ping timeout: 260 seconds]
<mrvn> I think you can assume that the currentr stackframe is always in cache
<d_bot> <EduardoRFS> hmmm that's a good point
<mrvn> When it matters is when you call lots of small functions at about the same stack level over and over. so the bit of stack in use will be cached. When you go much up or down on the stack it might drop out of cache but doing that often is rare.
<mrvn> but it makes me cringe too.
<d_bot> <EduardoRFS> yeah I'm just bikeshedding at this point
<mrvn> Why is the value in rbx? Is that the register is comes in on the function call?
<d_bot> <EduardoRFS> yup, rbx is the second argument on the OCaml ABI
<mrvn> and how does the block get into rdi?
mxns has joined #ocaml
<mrvn> the thrid movq seems silly too
<d_bot> <EduardoRFS> it's loaded from a global symbol that is one of the reasons why I wanted a immutable block
<d_bot> <EduardoRFS>
<d_bot> <EduardoRFS> ```
<d_bot> <EduardoRFS> movq camlExample__2@GOTPCREL(%rip), %rdi
<d_bot> <EduardoRFS> ```
<d_bot> <EduardoRFS> that could be optimized by flambda if that was immutable
<d_bot> <EduardoRFS> ```
<d_bot> <EduardoRFS> camlExample__call_pointer_80:
<d_bot> <EduardoRFS> movq camlExample__2@GOTPCREL(%rip), %rdi
<d_bot> <EduardoRFS> movq %rbx, (%rdi)
<d_bot> <EduardoRFS> movq (%rdi), %rsi
<d_bot> <EduardoRFS> movq %rdi, %rbx
<d_bot> <EduardoRFS> jmp *%rsi
<d_bot> <EduardoRFS> ```
<mrvn> movq %rbx, %rsi; movq camlExample__2@GOTPCREL(%rip), %rbx; jmp *%rsi
<mrvn> does ocaml always load GOT values into %rdi or did it choose the register?
amiloradovsky has quit [Remote host closed the connection]
<mrvn> can flambda optimize code so local blocks end up on the stack? (never looked what flambda can all do)
<d_bot> <EduardoRFS> no idea, I think rdi was the next register available
<d_bot> <EduardoRFS> flambda can do inlining of things, mostly, but it can't sometimes, and there is some problems, you cannot mutate a immutable block, that generates invalid code(and I tried)
<d_bot> <EduardoRFS> you get an warning saying that your code may be wrong
tianon has quit [Read error: Connection reset by peer]
<mrvn> maybe. Register allocation should look at where it needs the value though. compilers don't always get it right far more often then I would have guessed.
amiloradovsky has joined #ocaml
<d_bot> <EduardoRFS> what makes me upset is the two lines where he writes to memory and reads from memory, that is dumb
wonko7 has joined #ocaml
<mrvn> have you ever read gcc -O0 output? :)
amiloradovsky has quit [Remote host closed the connection]
amiloradovsky has joined #ocaml
<d_bot> <EduardoRFS> Yeah, but I'm running on -O3
tianon has joined #ocaml
narimiran has quit [Ping timeout: 260 seconds]
amiloradovsky has quit [Remote host closed the connection]
amiloradovsky has joined #ocaml
amiloradovsky has quit [Remote host closed the connection]
amiloradovsky has joined #ocaml
StephenM has quit [Ping timeout: 245 seconds]
mxns has quit [Quit: ZNC 1.8.2 - https://znc.in]
mxns has joined #ocaml
Anarchos has joined #ocaml
jnavila has quit [Quit: Konversation terminated!]
ygrek has joined #ocaml
mxns has quit [Ping timeout: 240 seconds]
bjorkint0sh has quit [Quit: Leaving]
mxns has joined #ocaml
mxns has quit [Ping timeout: 260 seconds]
neiluj has quit [Ping timeout: 258 seconds]
<Anarchos> what happens to ref if it is used in forked() process ?
<Anarchos> is it shared with the parent ?
<zozozo> I don't think so, parent and child have different memory, so the ref would be copied but after forking each process would have its own ref
<companion_cube> Anarchos: only fork at the beginning
<companion_cube> That's the only sane way
<Anarchos> companion_cube it is a server : each time it accepts a connection, it forks a child to do the work
mxns has joined #ocaml
<zozozo> Anarchos: that seems heavy
<companion_cube> Don't do that :p
mxns has quit [Ping timeout: 240 seconds]
<Anarchos> companion_cube i copied the code from the source of ocamldebug
<companion_cube> Ocaml debug has a server?
<Anarchos> zozozo or it was in da-ocaml at server code explanation
tane has quit [Quit: Leaving]
mxns has joined #ocaml
mxns has quit [Quit: ZNC 1.8.2 - https://znc.in]
mxns has joined #ocaml
wagle has quit [Quit: http://quassel-irc.org - Chat comfortably. Anywhere.]
ygrek has quit [Remote host closed the connection]
wagle has joined #ocaml
ygrek has joined #ocaml
<d_bot> <Cyclomatic Complexity> is there a way to mark a couple of types as private outside of the module without having to duplicate all types in the .mli?
<d_bot> <Cyclomatic Complexity> like, the following fails:
<d_bot> <Cyclomatic Complexity> ```ocaml
<d_bot> <Cyclomatic Complexity> let bad_argument msg = raise (Failure ("bad argument: " ^ msg))
<d_bot> <Cyclomatic Complexity>
<d_bot> <Cyclomatic Complexity> type weekday = private Weekday of int (* 1-7 *)
<d_bot> <Cyclomatic Complexity> let weekday : int -> weekday = fun n ->
<d_bot> <Cyclomatic Complexity> if n >= 1 && n <= 7 then Weekday n else bad_argument "weekday"
<d_bot> <Cyclomatic Complexity> ```
<d_bot> <Cyclomatic Complexity> and it's a bit sad to have to either wrap my whole module with an .mli, or to do some `include (struct end : sig end)` where the signature is as big as the module
Tuplanolla has quit [Quit: Leaving.]
<d_bot> <Cyclomatic Complexity> other thing that could help me: are there parametric module signatures in ocaml? not signatures of functor, but signatures themselves parametric
<Anarchos> cyclomatic complexity : module type S (A:SIG) = sig..end
mxns has quit [Ping timeout: 258 seconds]
<d_bot> <Cyclomatic Complexity> thanks
mxns has joined #ocaml
<d_bot> <Cyclomatic Complexity> getting a syntax error on this Anarchos
<Anarchos> Cyclomatic Complexity let me look my code, wait a second
mxns has quit [Ping timeout: 272 seconds]
<Anarchos> module type SETFUNCTOR =
<Anarchos> functor (Elt: ORDERED_TYPE) ->
<Anarchos> sig
<Anarchos> type element = Elt.t (* concrete *)
<Anarchos> type set (* abstract *)
<Anarchos> val empty : set
<Anarchos> val add : element -> set -> set
<Anarchos> val member : element -> set -> bool
<Anarchos> end;;
<Anarchos> cyclomatic complexity is it that you are looking for ?
<d_bot> <Cyclomatic Complexity> no, this is the type of a functor
<d_bot> <Cyclomatic Complexity> not a parametric module type
<d_bot> <Cyclomatic Complexity> but i found a solution to my initial problem
<d_bot> <Cyclomatic Complexity> https://pastebin.com/xuETt9BX
<d_bot> <Cyclomatic Complexity> yeah, i can generate the `Autohide` from a predicate to get good private types now
<d_bot> <Cyclomatic Complexity> wooo
<d_bot> <Cyclomatic Complexity> sad that it's the case that both:
<d_bot> <Cyclomatic Complexity> - regular modules don't have implicit polymorphism
<d_bot> <Cyclomatic Complexity> - first-class modules don't support `:=`
<d_bot> <Cyclomatic Complexity> i can't actually generate `Autohide` from just a predicate
<Anarchos> what could be a parametric module type ?
<d_bot> <Cyclomatic Complexity> a module type that takes a module type as parameter and returns you a new module type
ygrek has quit [Remote host closed the connection]
<d_bot> <Cyclomatic Complexity> you can't pass to `SETFUNCTOR` a module type. You can only pass to the `module SF : SETFUNCTOR` a module of type `ORDERED_TYPE`
<d_bot> <Cyclomatic Complexity> same difference as between functions and parametric types
mxns has joined #ocaml