adrien changed the topic of #ocaml to: Discussions about the OCaml programming language | http://www.ocaml.org | OCaml 4.09 release notes: https://caml.inria.fr/pub/distrib/ocaml-4.09/notes/Changes | Try OCaml in your browser: http://try.ocamlpro.com | Public channel logs at http://irclog.whitequark.org/ocaml
Hrundi_V_Bakshi has quit [Ping timeout: 258 seconds]
Haudegen has quit [Ping timeout: 272 seconds]
olle has quit [Ping timeout: 265 seconds]
olle has joined #ocaml
vicfred has quit [Quit: Leaving]
Jesin has quit [Quit: Leaving]
Jesin has joined #ocaml
_whitelogger has joined #ocaml
mfp has quit [Ping timeout: 240 seconds]
dborisog has joined #ocaml
pierpa has quit [Remote host closed the connection]
<rak> Thanks! Also, is there a recommended place to put extra signatures that don't correspond to a particular module file?
<rak> (I'm coming from SML, and am finding this reliance on filenames mildly confusing.)
nullcone has joined #ocaml
wagle has quit [Remote host closed the connection]
Jesin has quit [Ping timeout: 260 seconds]
haesbaert has quit [Ping timeout: 260 seconds]
wagle has joined #ocaml
haesbaert has joined #ocaml
vicfred has joined #ocaml
<rak> Also, does ocaml have the distinction between opaque and transparent signature ascriptions? I can't seem to find anything on it.
jao has quit [Ping timeout: 246 seconds]
_whitelogger has joined #ocaml
waleee-cl has quit [Quit: Connection closed for inactivity]
aav1o2 has joined #ocaml
aav1o2 has quit [Ping timeout: 265 seconds]
Jesin has joined #ocaml
nullcone has quit [Quit: Connection closed for inactivity]
narimiran has joined #ocaml
mbuf has joined #ocaml
amiloradovsky has quit [Ping timeout: 260 seconds]
narimiran has quit [Ping timeout: 258 seconds]
_whitelogger has joined #ocaml
sagax has quit [Ping timeout: 260 seconds]
sagax has joined #ocaml
malc_ has joined #ocaml
_whitelogger has joined #ocaml
_whitelogger has joined #ocaml
jnavila has joined #ocaml
mfp has joined #ocaml
averell has joined #ocaml
sagax has quit [Remote host closed the connection]
Haudegen has joined #ocaml
ggole has joined #ocaml
<olle> Big_int is which package?
<olle> bignum?
<olle> yikes, so many downgrades needed for bigint
<Drup> just use zarith
<olle> says*
<Drup> that's num, yes, it's distributed with the compiler
<olle> ah!
<olle> thanks
tinga has quit [Ping timeout: 264 seconds]
tinga has joined #ocaml
<olle> this is now my reaction to any questions on #ocaml: https://imgur.com/tM7lVhR
<olle> is there an idiomatic way to type the type of a function?
<olle> let my_fun : int -> int
<olle> or
<olle> let my_fun (i : int) : int = ...
<olle> seems like you can't do all types in the second way?
<zozozo> you should be abel to, using the (type a) type annotation : let foo (type a) (a t) : int = ...
<olle> zozozo: oh
<olle> didn't know
<olle> hm
<zozozo> oops, meant to write: let foo (type a) (x : a t) : int = ...
<olle> yeah
<olle> I have this line from lwt-websocket lib (8 years old but works):
<olle> Lwt_unix.bind sock_listen addr_inet;
<olle> should return unit, but returns `unit Lwt.t`
<olle> looks like the program still works.
malc_ has left #ocaml ["ERC (IRC client for Emacs 27.0.50)"]
<olle> hm
<olle> wrapped inside Lwt_main.run instead
<olle> there's a syntax extension to replace >>= fun () ->, right?
<olle> let%lwt ?
<olle> yep
<Fardale> let%lwt a = exp in replace exp >>= fun a ->
<olle> cool
Anarchos has joined #ocaml
<olle> hm
<olle> let%lwt _ = Lwt_unix.bind sock_listen addr_inet in
<olle> gives
<olle> Fatal error: exception Unix.Unix_error(Unix.EINVAL, "bind", "")
<olle> with lwt_ppx
<olle> "Invalid argument"
<olle> this works tho: Lwt_unix.bind sock_listen addr_inet;
<olle> bah
Haudegen has quit [Quit: Bin weg.]
<olle> and `let*` doesn't work at all
<olle> Fardale: any ideas?
cantstanya has quit [Ping timeout: 240 seconds]
cantstanya has joined #ocaml
* olle out jogging
<HyperMonkey> olle: have you tried stracing the process to see what the arguments to bind end up being?
Haudegen has joined #ocaml
<Fardale> olle: the bind fail, I don't think it has any thing to do with the let%lwt
zolk3ri has joined #ocaml
Anukriti has joined #ocaml
<Anarchos> olle maybe address is already in use ?
Anukriti has quit [Remote host closed the connection]
Anukriti has joined #ocaml
<olle> Anarchos: hm!
<olle> no, it works when I remove let%lwt
<Anarchos> ok
<olle> but I see now the new syntax is let*, not let%lwt
<Anarchos> i never understood those letXXX syntax
<olle> 11:55 < Fardale> let%lwt a = exp in replace exp >>= fun a ->
<olle> ^
<olle> it's just some light sugar
<olle> maybe my ocaml version is too old
<olle> let* gives syntax error
<Fardale> olle: try to replace "let%lwt _ = Lwt_unix.bind sock_listen addr_inet in" by "Lwt_unix.bind sock_listen addr_inet >>= fun () ->"
Anarchos has quit [Quit: Vision[0.10.3]: i've been blurred!]
<olle> 12:44 < olle> this works tho: Lwt_unix.bind sock_listen addr_inet;
<olle> Fardale: ^
<olle> works with just `ignore` too
<Fardale> You should not ignore a Lwt.t value
<olle> Fardale: hm, breaks with >>= fun()
<olle> but works with ignore
<olle> wtf
Anukriti has quit [Remote host closed the connection]
<olle> nope
<olle> breaks with ignore
<Fardale> Ignore the behavoir with ignore
<olle> aaah
<Fardale> you should either use the let%lwt or >>= fun () ->
<olle> yeah
<Fardale> with ignore, their is no guarantee that you code will be run or not
<olle> ok, had wrong order of operations
<olle> works now
<olle> :|
ziman has joined #ocaml
<ziman> hello! i've got a file x.ml with content `let _ = print_string Z.version`, and I try to compile it using `ocamlopt -o x -I +zarith x.ml` but I get `Error: Unbound module Z`
<ziman> i'm sure i'm just doing something dumb but i thought that's what the instructions in https://github.com/ocaml/Zarith#installation are saying
<ziman> what's the correct way to invoke ocamlopt/ocamlc here?
<olle> ziman: -linkpkg maybe
<olle> ziman: also, `ocamlfind opt ...` instead of ocamlopt
<ziman> i also tried `ocamlfind opt -o x -package zarith x.ml` but that throws the same error
<ziman> aha!
<ziman> ocamlopt alone does not accept -linkpkg
<olle> hm ok
<ziman> but ocamlfind + -linkpkg does the trick
<ziman> thank you!
<olle> great
<olle> :)
zolk3ri has quit [Remote host closed the connection]
narimiran has joined #ocaml
<olle> Anyone knows what this means?
<olle> "One can generate an expression to serialise/deserialise value of an arbitrary type with the following syntax: "
<olle> let (_ : t -> string) = [%to_json: t]
wingsorc has joined #ocaml
<olle> How could one use that?
Haudegen has quit [Ping timeout: 272 seconds]
<HyperMonkey> there's some examples on github.com/ocsigen/js_of_ocaml/issues/918
<HyperMonkey> haven't tried it but it looks like the syntax is `[%json: expr]`
<HyperMonkey> or rather %json_of
<olle> hm hm
<HyperMonkey> it's probably the js_of_ocaml equivalent of marshal, I doubt it gives you properly named fields and such but I could be wrong
<olle> sure
<olle> how do I make a PR to the ocsigen manual? ><
Haudegen has joined #ocaml
smazga has joined #ocaml
waleee-cl has joined #ocaml
<flux1> which one is better, yojson or ezjsonml?
<flux1> yaml is directly compatible with ezjsonml but on the other hand ppx_deriving_yojson exists 🤔
smazga has quit [Ping timeout: 265 seconds]
<flux1> apparently ocaml decoders could be used to convert between the two 🙄
smazga has joined #ocaml
jao has joined #ocaml
<flux1> (it seems easy enough just convert with 7 lines of patter matching)
smazga has quit [Ping timeout: 256 seconds]
dborisog has quit [Ping timeout: 246 seconds]
<flux1> interesting error from Yaml: "error calling parser: could not find expected ':' character 0 position 0 returned: 0" - does it expect the file to begin with a :?
<olle> no idea
<flux1> well, turns out there was an error in the file, it read `db_name = $1` instead of `db_name: $1`; not the most helpful error message
Haudegen has quit [Ping timeout: 246 seconds]
<olle> flux1: no
<olle> flux1: report it as a bug, maybe
<flux1> actually did!
sagax has joined #ocaml
Haudegen has joined #ocaml
bartholin has quit [Quit: Leaving]
bartholin has joined #ocaml
narimiran has quit [Ping timeout: 256 seconds]
bartholin has quit [Quit: Leaving]
amiloradovsky has joined #ocaml
bartholin has joined #ocaml
<olle> good :)
Anarchos has joined #ocaml
smazga has joined #ocaml
smazga has quit [Ping timeout: 272 seconds]
<flux1> how do I get to see what ppx has produced? hunting a bug :/
<flux1> I noticed dune builds me `config.pp.ml` but its contents seems binary
<flux1> is there some way to read that file?
<flux1> apparently it's "OCaml abstract syntax tree implementation file (Version 027)"
Haudegen has quit [Read error: Connection reset by peer]
<olle> sounds like something you shoulnd't have to do
<thizanne> flux1: add -dsource to the compiler options
<flux1> thizanne: thanks!
<flux1> olle: well, in a bug-free world..
<flux1> ..though I just found the issue by dumping an intermediate state :)
Haudegen has joined #ocaml
<flux1> so who here agrees that yaml is "human friendly"? is it a captcha of modern age?
mbuf has quit [Quit: Leaving]
raver has quit [Ping timeout: 260 seconds]
schlaftier2 has joined #ocaml
schlaftier has quit [Read error: Connection reset by peer]
schlaftier2 is now known as schlaftier
asthasr has joined #ocaml
<asthasr> Afternoon folks. I'm trying to learn Ocaml after some Haskell experience, but I'm having a bit of syntactic trouble. How does one specify an explicit type signature for a Set in a function signature?
<asthasr> I tried "string Set.t", (module String) string Set.t", "Set.t of ((module String) * string)", "Set.t of string", along with the variants thereof without .t
<asthasr> And if there's somewhere better I should be asking these questions, let me know -- or somewhere that has good docs on this sort of thing, I'd appreciate it :)
<HyperMonkey> I don't know about set but the syntax for add would be `let add (a : int) (b : int) : int = ...` hth
<asthasr> Yes, a simple type like 'int' is pretty obvious. But I want to have a function that accepts a set, and a list of another record type, and checks to see if one of the fields of the latter is contained in the former
<Fardale> asthasr: Set is a functor, you don't have a "'a Set.t"
<Fardale> Set.Make is the function
<Fardale> so it will be something like "module StringSet = Set.Make(String)" then you will have StringSet.t
<Fardale> Set.Make is the functor*
<asthasr> I see.
<asthasr> is there any way to refer to the automatically derived types I get with ppx_hash?
<zozozo> asthasr: small note; I suppose you're used to typeclasses in Haskelle, hence the question about taking an 'a set as argument ? If so you can more or less do something similar in ocaml, by creating a function which takes as first argument a first class module which will be e.g. the module resulting from the Set.Make functor
<zozozo> but for every call to the function thus defined, you'd have to manually give the required module (whereas typeclasses would fill it automatically iirc)
<zozozo> concerning ppx_hash, it doesn't seem that the generated code really defines any type (it mainly defines hash functions, using pre-existing type (including the type definition to which it is attached to))
<asthasr> hmm. Maybe I'm asking the wrong question. Maybe a better question would be: what would be the idiomatic, OCaml'y way to do this sort of thing? The idea of a "Set of some type T" that I check for membership seems so basic coming from my background that the above seems cumbersome
<zozozo> there are a few different ways (depending on the context and scale of things I'd say): sometime juste a polymorphic function is enough (iy you only use 1 or 2 functions that operate on sets, your function can take those as arguments)
<zozozo> that works for small things
<zozozo> for bigger uses, you can always put the whole module (or relavant part of the code), inside a functor that take as argument the Set module
<zozozo> assuming that the code will really be used with different sets
<zozozo> with the "put code ina functor" approach, you can either have your functor take as argument a set implementation, or the set elements implementation and then instantiate Set.make inside your functor (sometimes it makes more sens, if the set does not appear in the interface of the functor result)
Anarchos has quit [Quit: Vision[0.10.3]: i've been blurred!]
<zozozo> but again, it might depend on the actual context: what's the exact goal of the function ? and how does it fit into the project (is the project a lib ? a binary ? etc..)
<asthasr> the project will eventually be a portion of a service... so thus a "binary," I guess, in spirit. The general idea is that there will be a number of events being processed in near-real-time, some of which are processed by one function and some of which are processed by another, depending on certain identifiers within the event data
<zozozo> so in that case, I guess you'll have a dedicated type for identifiers, and probably for sets of identifiers, which will occur in those events ?
<asthasr> so, you might see an event come through that has tags "a", "c", "x"; and the next has "c", "d", "y", and so on, and a functions might be applied if "c" is in there, or "y" and "a", or what have you.
<asthasr> Yep.
<zozozo> ok, so in that case you don"t really need your function to be polymorphic over the sets ?
<zozozo> since you'll have a fixed implementation of sets, I guess in your project
<asthasr> no. I just need it to check a given set of "tags" and decide if the current function is "interested" in that event
<zozozo> so, I'd say in a typical ocaml project, you'd have a module Id (or Identifier) in your project, that descreibes the identifiers (with an identifier being of type Id.t), and either another module IdSet, or more likely a sub-module Id.Set to represent sets of ids, and then your function can just call (Id.Set.mem <some_id>) to know whether it is interested
<asthasr> Hmm. So how would you construct distinct "instances" of these submodules?
<asthasr> e.g. if I had a database that contained a few thousand configurations of tags...
<zozozo> why would you need different instances ?
<zozozo> does the type used to represent these tags change ?
<asthasr> No, not the type, but the contents. e.g. if one "processor" gets events with type "d" and one "processor" gets events with type "e", all controlled by database state, I will essentially need to load them all up at bootstrap time
<zozozo> ok, so you have a (I guess finite) number of different kinds of events, each with its own ocaml type (let's say event_X with X in {d, e, ...}), but I guess all of these events have an associated set of tags (question here: is the set of tags purely determined by the event type of can two events of the same type have different tags ?)
<asthasr> my design originally had a "processor" as a record type with 'is_interested : event -> bool', with the idea that it can be parameterized with a function with that type... then, I was envisioning a 'simple_tag_match : Set<tag> -> event -> bool' that could be curried and used as that 'is_interested' function on a processor value
<zozozo> I see
<zozozo> but here the type for tag is always the same, right ?
amiloradovsky1 has joined #ocaml
<asthasr> all events are basically the same type. it's input from an external system. it comes in as something like "event {timestamp, list_of_tags, number_of_tags, irrelevant_datapoints...}"
amiloradovsky has quit [Remote host closed the connection]
amiloradovsky1 is now known as amiloradovsky
amiloradovsky has quit [Remote host closed the connection]
<asthasr> yep, tags are always of the same basic type and can be parsed identically
<zozozo> ok, so you can also have a single implementation of sets of tags (typically Set.Make(Tag), assuming tags of type Tag.t)
amiloradovsky has joined #ocaml
<asthasr> (the reason I want to parameterize the matching function is that we also will have things like 'tag_count_match : int -> event -> bool', that kind of thing)
<zozozo> so in that case, i'd say the typical way to do it would be to have a module Tag in your project, that defines how tags are implemented (i.e. defining the type t for tags, a the hash, comparison, equality, print functions, etc..)
<zozozo> and that module would include a submodule Tag.Set which would typically be the result of Set.Make
* asthasr nods.
<asthasr> Thanks for your help :)
<asthasr> I have to say, it's interesting, being familiar with Haskell, how different OCaml feels in some ways. I kind of expected it to be more similar.
<zozozo> asthasr: so you'd have something like this https://gist.github.com/Gbury/9eae3a590d2e73ce6a77f595cf293a49
<zozozo> with a very simpified exmaple using strings for tags, and where event simply have a name and a set of tags
* asthasr nods.
<asthasr> Thanks!
<asthasr> Would you say it's very common to use interface files like this?
<zozozo> yes, I'd say the gist would represent the typical way to structure a project (at least that's what I do in pretty much all my projects, as wella s what is done in the compiler)
<zozozo> interface files are designed to, well describe the interface (it helps in amintaining abstraction, and hiding some implementation details as well as unsafe functions that should only be used internally in a module)
<zozozo> and interface files are the main way to document modules
<zozozo> (technically tou can write the documentation directly in the .ml file, but I don't know of recent projects that do this)
* asthasr nods.
<asthasr> it's a bit odd feeling because almost all haskell does direct inline annotations
<zozozo> actually I like having the opportunity do have an interface that is the publi facing description of the module (with doc comments), and the implementation, which can contain relative to implementationd etails
<zozozo> it provides a nive separation
<zozozo> *nice
<zozozo> too many typos, I should sleep, XD
ggole has quit [Quit: Leaving]
<zozozo> note: in the prototyping phase of your project you can omit the interface files (the compiler will infer them for you), but it's highly recommended to have them as soon reasonable because it helps quite a lot
<zozozo> also, interface files helps with separate compilation
jnavila has quit [Quit: Konversation terminated!]
<asthasr> What do you mean by "separate compilation"?
<zozozo> so, consider files a.ml, a.mli, b.ml and b.mli , where module B (i.e. file b.ml), uses values from A
<zozozo> with the mli files, as long as a.mli does not change, changing a.ml will requires you to re-compile it, but b.ml will not need to be recompiled
<zozozo> tecnically B only depends on the interfaace of A and not its implementation
<zozozo> whereas if there is no .mli file, the interface and implementation are basically the same, and any change to a.ml will cause all fiules depending on it to be recompiled
<asthasr> Cool. I never thought about that benefit.
<asthasr> Thanks for all your help. :) I'll take a stab at it and let you know how it goes.
<zozozo> asthasr: no pb, have fun, ^^
raver has joined #ocaml
smazga has joined #ocaml
smazga has quit [Ping timeout: 258 seconds]
<HyperMonkey> I'm considering writing a ppx rewriter. is the ppx rewriter limited to manipulating extension points or can it just do arbitrary rearrangements of the program?
<d_bot> <Et7f3> All nodes of the AST.
nullcone has joined #ocaml
kvda has joined #ocaml
malc_ has joined #ocaml
<HyperMonkey> nice
ArthurStrong has joined #ocaml
malc_ has quit [Remote host closed the connection]
kvda has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
kvda has joined #ocaml