<tormen>
... I have to admit that I am still a bit lost with all the ocaml typing possibilities... (class, object, first-class module, functor, class-types, ...) I am sure there is an easy way to do what I want to do, but I am not able to put the pieces that lay in front of me together :(
<Algebr`>
I think you might need to add a .. to the tmp_result definition.
<Algebr`>
not entirely sure.
nzyuzin has quit [Ping timeout: 252 seconds]
<tormen>
Algebr`: tried that already :) ... but then I get a : In type < pack : 'a tmp_results; to_str : string; unpack : 'a; .. > as 'b
<tormen>
the variable 'b is unbound
nzyuzin has joined #ocaml
<tormen>
?
<tormen>
;)
<tormen>
I feel so stupid around ocaml typing :( ... usually not the case ... argh ;)
<Algebr`>
well to be fair, the object/row typing hurts many peoples head
<Algebr`>
don't feel stupid
<Algebr`>
introduce another type variable
<tormen>
hmm. not sure how to do that :/
ggole_ has joined #ocaml
ggole has quit [Ping timeout: 250 seconds]
kdas__ has quit [Ping timeout: 260 seconds]
kdas__ has joined #ocaml
kdas__ has quit [Read error: Connection reset by peer]
<Algebr`>
type 'a tmp
<Algebr`>
but now: type ('a, 'b) tmp
soupault has quit [Ping timeout: 244 seconds]
nzyuzin has quit [Ping timeout: 258 seconds]
nzyuzin has joined #ocaml
soupault has joined #ocaml
sdothum has joined #ocaml
silver has joined #ocaml
zpe has joined #ocaml
ontologiae has joined #ocaml
ggole__ has joined #ocaml
<tormen>
Algebr`: Hmm. but I have type 'a tmp_result = <...> ?
<tormen>
So ocaml is now telling me I need a type 'b = 'a tmp ? or do I simply add 'b as you said to type ('a, 'b) tmp_result = <...> ? But ... then what does 'b stand for ? the unknown in form of the ".." ?
ggole_ has quit [Ping timeout: 244 seconds]
<tormen>
Algebr`: Now I get a : A type variable is unbound in this type declaration.
<mrvn>
tormen: you want an universal type tmp_results so you can e.g. put lots of different tmp_results into a list?
Anarchos has joined #ocaml
fraggle_ has quit [Read error: Connection reset by peer]
<tormen>
Hi guys :)) I have to run grab something to eat :(( .... I am also still thinking if my pack / unpack makes sense like this. I'll have a good look at your propositions + think it through again and let you know :)))
copy` has joined #ocaml
antoro_ is now known as antoro
fraggle_ has joined #ocaml
Iwan_ has joined #ocaml
<Iwan_>
Does anybody know if it's possible to expose record types when you include them through a functor?
<orbitz>
Is exposing first class modules in APIs the suggested way to design something? I'm writing an API where, without first class modules, I'd create a record of functions. I'm not sure if I should still do this to make my API a little bit less awkawrd or just put the first class modules in my API.
<mrvn>
orbitz: matter of taste
<Drup>
orbitz: I would say avoid first class modules in your API if you can
<orbitz>
Drup: how come?
<ggole>
Typing becomes more complicated
<Drup>
it's a general design principle. Even if you have complicated type stuff inside your library, you should aim for you library to be usable by people who do not know the complicated type stuff
<orbitz>
Ok
<ggole>
Simply using them becomes more complicated, too
<mrvn>
but with modules you don't have do build the record by hand
<orbitz>
So wrap up a first class module in this record of functions?
<Drup>
(in particular first class modules ocasionally require non trivial type annotations)
<orbitz>
To some degree I'm just making objects again, but I'd like to avoid the object portion of th elanguage if possible.
<Drup>
orbitz: we need the rest of the API too .
<orbitz>
Drup: oh, that's it though..
<orbitz>
Drup: things will implement that
<orbitz>
Drup: and I want to make those things look the same in some cases
alienbot has joined #ocaml
<Drup>
I'm surprised the t is inside the signature
agarwal1975 has joined #ocaml
<orbitz>
How come?
<Drup>
did you actually managed to implement that ? :)
<orbitz>
Drup: not yet :)
<Drup>
Yeah
<orbitz>
Drup: So I have this module type, and I want people to implement it. Then I want to treat all the ones that have the same 'msg type to be groupable together
<orbitz>
so the t needs to be in there
<Drup>
You kinda bump in the absence of HKT with this kind of APIs
<orbitz>
So I'll hide the t inside a closure, in the end.
<orbitz>
Drup: so where I"m stuck is how to write a function that takes a module implementing S and getting back my record
<Drup>
honestly, I would need to see more to help you make a simpler API.
<orbitz>
I sent just base.ml before, the nI added otehr.ml
<Drup>
ah, you want the t out
<orbitz>
Yep
<orbitz>
So waht I need is something that takes a Base.S and gives me an Other.t
<orbitz>
Does that make sense or am I doing something wildly wrong?
<orbitz>
actually, sorry, what I want is something that takes a module M that is a Base.S and an M.t and gives me an Other.t
nzyuzin has quit [Ping timeout: 250 seconds]
mcc has joined #ocaml
<Drup>
yeah, you are going to write that with a parametrized type t
dakk has joined #ocaml
<Drup>
you are not*
<Drup>
(you should just use objects for that ...)
<Drup>
(or records)
shinnya has joined #ocaml
nzyuzin has joined #ocaml
<mrvn>
orbitz: as long as it isn't an 'a Other.t
<orbitz>
mrvn: what do you mean?
<mrvn>
orbitz: I think you are doing something wrong
<orbitz>
ok
<mrvn>
By having 'msg in Other.t you making each Other.t unique. That means your Other.t aren't interchangable.
<Drup>
orbitz: you can't write those kind of things (as I mentionned earlier, HKT issues)
<Drup>
mrvn: that's not the issue.
<orbitz>
WHat I'm after is I want this 'tower of types' Where if you want to implement this and use it as a concerete module, you can do that, but then I also want you to be able to use it more like an object if your usecase needs it
<Drup>
the issue is that the typechecker is not going to let you manipulate a function of type (module M : S -> _ M.t -> ...
<orbitz>
mrvn: yes tha tis ok, I want all Other.t's with the same 'msg to be the same
<mrvn>
orbitz: but that means you can't use the result of t.recv () without having the first class module that was used to create the Other.t.
<mrvn>
orbitz: I assumed your intention was to hide the specific implementation of M that will be used.
<mrvn>
orbitz: can you show some context and not just the hammer you came up with for your problem?
<Drup>
(btw, while you can't write the function, you can totally write the functor that you want :p)
<mrvn>
Drup: I think you can write a function for it if it double wraps the stuff in 2 modules and includes the first class module in it.
<mrvn>
but wether that's the right thing or not depends on the use case for it.
<Drup>
I'm going to repeat myself : "a function of type (module M : S) -> _ M.t -> ... is not expressible in caml"
<Drup>
if that's the signature you are going for, you won't manage it, regardless of the number of wrapping
<Drup>
You can cheat with Obj.magic, but it's not worth it. Just use objects already, they are made for that.
<Drup>
(now, with modular implicits, though .. :p)
<orbitz>
mrvn: the problem would be I want to be able to have a 'msg Other.t list
<mrvn>
orbitz: 'msg Other.t list or _msg Other.t list?
<orbitz>
'msg
<mrvn>
then Other.t must not contain 'msg in it's type.
<orbitz>
Yes, I apologize, I'm trying to explain so much I'm dropping things
<orbitz>
If we drop the 'typ in my exmaple, what I want is a function that takes a M : Base.S, and a 'msg M.t and gives back a 'msg Other.t
<mrvn>
orbitz: if you change your base type to val on_recv : ([ `Reader ], 'msg) t -> ('msg -> unit) -> unit you can hide the 'msg type inside so Other.t isn't dependent on it.
<Drup>
(it's still strictly less convenient than objects, though)
atbagautdinov has quit [Ping timeout: 244 seconds]
<orbitz>
Drup: ok, that addresses what I was running into when I was having my issue, I was stuck with in that you cannot do with type 'a t = 'a b
<orbitz>
or similar
rgrinberg has joined #ocaml
<mrvn>
Drup: isn't the Other in Other.send superfluous?
<Drup>
yeah, the type hint should be sufficient
<orbitz>
That is pretty awkward though.
rgrinberg has quit [Client Quit]
<orbitz>
I'll have to think on it. At least users don't really experience it.
toolslive has quit [Ping timeout: 264 seconds]
rgrinberg has joined #ocaml
<mrvn>
Drup: why the ": msg Other.t"?
<Drup>
mrvn: to annotate the "msg" type, the typechecker is not going to like it otherwise
<mrvn>
Drup: would have thought it infers that from the {send; recv; close }
<Drup>
hum, actually, it infers it now
<mrvn>
same with (x : t)
<Drup>
(but you really need the "with type", you can't remove that one)
<mrvn>
Yeah, the "with type t = t" doesn't work otherwise.
<orbitz>
Does adding type variables in the with type construct for first class modules make the type theory pretty ridiculous?
<mrvn>
orbitz: without with the type would not be exposed
<mrvn>
(if it compiles at all). Two Other.t made from the same M would not be compatible.
<orbitz>
No, I mean that you cannot do with type 'a t = ... with first classmodules as far as I can tell
<mrvn>
huh? sure you can
toolslive has joined #ocaml
<orbitz>
mrvn: for example the following does not succeed for me: module type S = sig type 'a t val foo : 'a t -> unit end;; let f (type v) (module M : S with type 'a t = v) (t : v) = M.foo v;;
<orbitz>
I tried adding an 'a in there, but I'm too ignorant to know where to put it
<Drup>
orbitz: see my remark above, that I repeated twice :)
<def`>
implicits will allow that
silver_ has joined #ocaml
<def`>
but as it is, it is too expressive for OCaml type system
Anarchos has quit [Quit: Vision[0.9.7-H-20140108]: i've been blurred!]
silver has quit [Ping timeout: 252 seconds]
bruce_r has joined #ocaml
<Algebr`>
Who has experience with hackerspaces
<Algebr`>
ie, running them, starting them, maintaing them, funding them
<mrvn>
orbitz: seems like you are right, in the first class module case the with can only be an indent, not 'a t
<mrvn>
s/indent/ident/
ontologiae has quit [Ping timeout: 250 seconds]
<orbitz>
Drup: yes, Is aw it, but there seemed to be some confusion so making sure I was on the same page.
<rgrinberg>
Drup: you can hit merge too :P
* Drup
is overwhelmed by the responsability.
<orbitz>
Drup, mrvn : thanks for your feedback. I'm going to sit and think about what I want to accomplish and see how I want to do it.
slash^ has quit [Remote host closed the connection]
slash^ has joined #ocaml
govg has quit [Quit: leaving]
nicoo has quit [Remote host closed the connection]
nicoo has joined #ocaml
laserpants has joined #ocaml
dakk has quit [Ping timeout: 240 seconds]
bruce_r has quit [Ping timeout: 250 seconds]
atbagautdinov has joined #ocaml
atbagautdinov has left #ocaml [#ocaml]
atbagautdinov has joined #ocaml
Algebr` has quit [Ping timeout: 276 seconds]
yomimono has joined #ocaml
rgrinberg has quit [Ping timeout: 240 seconds]
rgrinberg has joined #ocaml
average has joined #ocaml
average has left #ocaml [#ocaml]
atbagautdinov has quit [Ping timeout: 250 seconds]
atbagautdinov has joined #ocaml
scrooge has joined #ocaml
atbagautdinov has quit [Quit: atbagautdinov]
sh0t has quit [Remote host closed the connection]
yomimono has quit [Ping timeout: 258 seconds]
<scrooge>
Are there any uses of the `let x = ... and y = ... in` construct over `let x = ... in let y = ... in`? Is it good style to use the former where possible?
<scrooge>
Note that I'm aware of the uses for `let rec x = ... and y = ...`, and am just interested if anyone uses the non-recursive version.
<Drup>
scrooge: "let x = y and y = x in .. " :3
<scrooge>
Won't that break without `rec`?
<scrooge>
Heck, won't that break *with* `rec`?
<Drup>
nope
<Drup>
that will break with rec
<Drup>
it basically swap the names
<scrooge>
I tried it (without rec) and got "Unbound value x"
<Drup>
x and y need to be previously defined
<Drup>
(it's pretty much useless ;)
<scrooge>
Oh. Well that doesn't seem like good style.
<scrooge>
So basically it's perfectly idiomatic to say `let x = ... and y = ...` even if `y` doesn't depend on `x` at all.
<Drup>
this kind of thing is very usefull in ppxs, to avoid shadowing names and introducing generated identifiers in the user's code
<Drup>
it's rarelly used outside of that context
<scrooge>
OK. Thanks for the help.
Algebr` has joined #ocaml
<ggole>
You could use it as an idiom to indicate that there is no dependency between the bindings
nicholasf has joined #ocaml
<scrooge>
I was wondering if that was a common thing to do, or if most people just did `let in let in let in` unconditionally.
TheLemonMan has quit [Quit: "It's now safe to turn off your computer."]
<ggole>
The typical approach seems to be to use and only for mutual recursion
<ggole>
So yeah, let in let in unless you absolutely need and.