lpw25 has quit [Quit: ERC Version 5.3 (IRC client for Emacs)]
dapz has joined #ocaml
seliopou has quit [Quit: whaaaat]
tlockney is now known as tlockney_away
divyanshu has joined #ocaml
divyanshu has quit [Client Quit]
HoloIRCUser has joined #ocaml
HoloIRCUser is now known as _obad___
dant3 has quit [Ping timeout: 252 seconds]
jwatzman|work has quit [Quit: jwatzman|work]
dant3 has joined #ocaml
racycle has quit [Quit: ZZZzzz…]
dotfelix has joined #ocaml
thomasga has joined #ocaml
thomasga has quit [Ping timeout: 240 seconds]
malo has quit [Remote host closed the connection]
wmealing has joined #ocaml
<wmealing>
was i dreaming or at one stage did i see ocaml running in a browser without a plugin and no server side.. google isnt helping.. in my head it had some kind of a test suite with graphics and web..
<companion_cube>
or js_of_ocaml in a more general way?
rgrinberg has joined #ocaml
<wmealing>
i dont think its the try.omcalpro.com .. i'm researching the latter now
<wmealing>
i get the feeling it was the js_of_ocaml.
shinnya has joined #ocaml
<tautologico>
try ocaml uses js_of_ocaml
<tautologico>
so does iocaml_js
rgrinberg has quit [Quit: Leaving.]
dapz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
dapz has joined #ocaml
shinnya has quit [Ping timeout: 240 seconds]
dapz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
rgrinberg has joined #ocaml
shinnya has joined #ocaml
manizzle has quit [Ping timeout: 245 seconds]
<rgrinberg>
_obad_: i think with 4.02 there's going to be some ppx wrapper around lex/yacc
<rgrinberg>
the syntax will be the same but you won't need the mll/mly ceremonial stuff
dnm has joined #ocaml
<Drup>
rgrinberg: there is already sedlex as "lex with ppx"
<Drup>
(done by alain frisch, go figure :p)
<rgrinberg>
ah so it works with 4.01 already?
<Drup>
no, it needs expansion points
<Drup>
(iirc)
divyanshu has joined #ocaml
shinnya has quit [Ping timeout: 255 seconds]
<dotfelix>
can someone sell ocaml to me? ie which problems does ocaml solves really well etc.
<wmealing>
i've got a shiny ocaml here, for only $99.99 !
<wmealing>
dotfelix: i'm only new at it.. so i'm messing around with it at the moment
<wmealing>
dotfelix: what is your programming history
<dotfelix>
wmealing: new to function programming, just some C and Go
<wmealing>
i know C and go, so i'll do what i can to answer.. people here can correct me if wrong
<wmealing>
so, you can program in a functional style, an object style or an imperative style..
<wmealing>
so you can kind of.. mix it up as you see fit
<wmealing>
ocaml is nearly as fast as C from my naive experiments, much faster than go
<wmealing>
ocaml has a type system, which means you can use the type systems to ensure you're not doing stupid things, ie wrong pointers being passed in to a function.
<wmealing>
because its compiled (like c and go) it has single file deployment..
<wmealing>
i think its kinda like a static compile
<wmealing>
it has "pattern matching" , not regex like.. but on the native types within the program.. i do quite a lot of erlang.. so I like that feature
<wmealing>
you can, from what ive seen extend (expand ?) the syntax of the language.. to your liking
<dotfelix>
yeah I have some erlang into and like pattern matching too
* wmealing
nods
<dotfelix>
wmealing: what's your take so far on ocaml?
<wmealing>
dotfelix: before i go to explain, hows your erlang.. are you familiar with OTP ?
<wmealing>
(i'm not having a problem, its relative to your answer)
<dotfelix>
wmeanling: not really
<wmealing>
ok
<dotfelix>
but I do understand is like its std libs
<wmealing>
ok.
<wmealing>
so i'm familar with leaning hard on erlangs OTP system. allowing the system to recover from my programming/environmental mistakes. Ocaml seems to make me deal with the mistakes more explicitly.. which makes the software development process
<wmealing>
quite a bit slower
<wmealing>
admittedly, I have been programming in erlang now for about 5 years.. so I'm very familar with how it misbehaves.
waneck has joined #ocaml
<wmealing>
ocaml seems to have less "hard" edges than erlang though. The standard libraries seem slightly better thought out
<wmealing>
and i'll be the first to admit that I don't always know the shortest/sanest ways to do things.. so its likely there are much better ways.
<wmealing>
however, as far as languages go, ocaml seems like a very "nice" language that fits many problems
<dotfelix>
g8t to know
<dotfelix>
what about concurrency from an erlang comparison
<wmealing>
erlang you spin up the processes, then use message passing, which makes things dead easy. From what i can see.. ocaml has a slightly different game plan than erlang
<wmealing>
of course only one thing can run on one cpu at any time
<wmealing>
you can farm out work to different processes, but that acts more like C than erlangs implementation
<wmealing>
actually, i dont think ive looked up actors in ocaml
<wmealing>
i can't say i agree with all of the stackxchange reasoning.. but each to their own
<bernardofpc>
my own point for OCaml is two-fold; first, because of theorem-proving, which is "the niche application domain of ML of excellence"
seliopou has joined #ocaml
<bernardofpc>
second, because it was thanks to OCaml that I wrote a multi-purpose Erathostenes Sieve ; not that it is too hard to do or anything, but just as Dijkstra says, "having the right language allows you to write clearly what you're thinking"
studybot_ has quit [Ping timeout: 240 seconds]
<bernardofpc>
anyway, time to sleep
seliopou has quit [Quit: whaaaaat]
seliopou_ has joined #ocaml
studybo__ has quit [Read error: Connection reset by peer]
dnm has quit []
seliopou_ is now known as seliopou
struktured has quit [Ping timeout: 255 seconds]
Nahra has quit [Remote host closed the connection]
tanguy` has quit [Ping timeout: 240 seconds]
Nahra has joined #ocaml
racycle__ has joined #ocaml
Nahra has quit [Remote host closed the connection]
dapz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
dapz has joined #ocaml
michael_lee has joined #ocaml
ygrek has quit [Ping timeout: 245 seconds]
_obad___ has quit [Ping timeout: 258 seconds]
rgrinberg has quit [Quit: Leaving.]
Nahra has joined #ocaml
wmealing has quit [Excess Flood]
wmealing has joined #ocaml
Nahra has quit [Remote host closed the connection]
Nahra has joined #ocaml
dapz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
dapz has joined #ocaml
struktured has joined #ocaml
axiles has joined #ocaml
manizzle has quit [Ping timeout: 245 seconds]
rgrinberg has joined #ocaml
dnm has joined #ocaml
racycle__ has quit [Quit: ZZZzzz…]
ygrek has joined #ocaml
rgrinberg has quit [Quit: Leaving.]
ygrek has quit [Ping timeout: 252 seconds]
wmealing has left #ocaml []
clan has quit [Quit: clan]
clan has joined #ocaml
ygrek has joined #ocaml
clan has quit [Quit: clan]
<whitequark>
an API design question: I have an Encoder and Decoder module
<whitequark>
Decoder has quite a few errors it can raise, so I've exception Failure of error, and type error = A | B | ...
<whitequark>
Encoder has only one error it can raise. currently I have exception Failure of error in Encoder too, and type error = A
<whitequark>
should I keep it as is for regularity, or remove the cruft and only leave exception Overflow?
dapz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
NoNNaN has quit [Remote host closed the connection]
<Pupnik>
a lot of languages use immutable strings, they treat them just like strings. But I don't know about the specifics of what ocaml is doing.
<companion_cube>
mrvn: btw, do you modify strings this often?
thomasga has quit [Client Quit]
<mrvn>
companion_cube: All the time. Ever Unix.read does.
NoNNaN has joined #ocaml
thomasga has joined #ocaml
<mrvn>
+y
maattdd__ has joined #ocaml
<adrien>
anything that uses buffers
cdidd has quit [Remote host closed the connection]
<whitequark>
Buffer.t doesn't require you to mutate strings though
<adrien>
string buffers*
<whitequark>
right
<companion_cube>
mrvn: right, this kind of t hings should use Bytes.t
<adrien>
for many things in Unix
nikki93 has joined #ocaml
<adrien>
but porting shouldn't be difficult
<companion_cube>
it's always the problem with retrocompatibility
<adrien>
(provided Unix is migrated)
<mrvn>
It should use Bigarray
<mrvn>
and allocate on read
<adrien>
hmm
<companion_cube>
it should use a rope! :D
<adrien>
if the allocation is large it might be fairly costly
<mrvn>
read : fd -> off -> len -> string
<companion_cube>
well that prevents you from using the same buffer several times..
<adrien>
but what about when you get a read shorter than you asked for?
<whitequark>
should be "fd -> off -> len -> bytes".
<mrvn>
companion_cube: so?
<whitequark>
ah, hm, not sure
<mrvn>
adrien: then the string is shorter
<mrvn>
whitequark: should have both.
<whitequark>
mrvn: more like, a version that *returns* string and a version that *accepts* bytes
<adrien>
mrvn: and if you read again?
<adrien>
of course it's possible
ygrek has quit [Ping timeout: 245 seconds]
<mrvn>
whitequark: and a third for bigarray
<adrien>
but it gets more annoying to handle
<whitequark>
mrvn: agreed
<companion_cube>
mrvn: well, that's less efficient
<mrvn>
It might have been better to have a String with phantom types.
<companion_cube>
otoh I don't think you should use low-level primitives very often
<mrvn>
companion_cube: bigarray is way more efficient
<companion_cube>
if you allocate them every time?
<adrien>
mrvn: for mmap? or for storing data?
<whitequark>
mrvn: phantom types will break functors.
<adrien>
and how do you print the data from a bigarray? %s definitely won't work
<mrvn>
companion_cube: read/write works in 16k chunks and copies them each time. With bigarray you just have one syscall and no copying.
nikki93 has quit [Ping timeout: 245 seconds]
<whitequark>
mrvn: e.g. you can't Set.Make(struct t = 'a String end)
<whitequark>
that bit me really badly.
<companion_cube>
mrvn: currently, where is there a copy with read/write?
<companion_cube>
hmm well ok, a String.blit, but no allocation?
<mrvn>
whitequark: yeah. That sucks. You need a second function with 'a t
<adrien>
mrvn: mmap() is more costly for small files and if you don't want to read everything it can be annoying
<mrvn>
companion_cube: in the unix module.
<adrien>
and it doesn't solve the issue of reading from a pipe or socket
<whitequark>
mrvn: no, you *cannot* have a functor parameterized by a type with a parameter
<whitequark>
unless the functor has type 'a t itself
<mrvn>
whitequark: that's what I said.
<companion_cube>
right, sockes
<whitequark>
a second functor, you mean. yes.
<adrien>
plus it really only works when the file doesn't change size and you really want to read the data (i.e. it's not applicable for write() and then you get a non-symmetric interface for the two)
<whitequark>
this really sucks. I wonder why can't ocaml just allow it.
cdidd has joined #ocaml
<whitequark>
I mean, it is obviously safe
<companion_cube>
what, you mean having a Set.t with elements = 'a foo ?
<whitequark>
yes
<whitequark>
er, no
<whitequark>
with elements = bar foo.
<mrvn>
companion_cube: The problem is that read/write releases the runtime lock and a String is heap allocated and can be moved by the GC. So read/write need to do the read with a local buffer, aquire the runtime lock and copy the buffer into the string and repeat till it has enough bytes. And write does the reverse.
<companion_cube>
whitequark: you can, Set.Make(struct t = int list .... end) works
<mrvn>
whitequark: even with elements = 'a foo should be safe
<companion_cube>
mrvn: hmm, it can't use the allocated String? :(
<adrien>
mrvn: my main issue with strings as buffers is the size limit on 32b
<companion_cube>
mrvn: with elements = 'a foo, what's the type of Set.choose?
<mrvn>
companion_cube: what if the GC moves it around while the read syscall writes to it?
<companion_cube>
Set.t -> 'a t ?
<adrien>
but there are really too many things that need strings currently to work
<companion_cube>
mrvn: the syscall cannot trigger a GC, can it?
<kerneis>
funny, the only time it has been snapshot by the way back machine (in 2007), it was a 404 too :-D
<jonludlam>
not tried to download it; it might be big :-)
<jonludlam>
I believe there are plans to rehost the info, but I don't know where
<kerneis>
132K
<jonludlam>
heh
<kerneis>
less than a 1MB when unzipped
<whitequark>
github wiki?
<whitequark>
at least that won't be gone for quite a while
<jonludlam>
yep, or ocaml.org
thomasga has joined #ocaml
olauzon has joined #ocaml
studybot_ has joined #ocaml
Hannibal_Smith has quit [Quit: Sto andando via]
studybo__ has joined #ocaml
sgray10 has joined #ocaml
studybot_ has quit [Ping timeout: 240 seconds]
studybo__ is now known as studybot
<flux>
I kinda wish the new Bytes module had used rw/ro tagging for the type t
<mrvn>
now one needs to duplicate all string functions for mutable and immutable.
avsm has joined #ocaml
dsheets has joined #ocaml
<flux>
I have trouble recalling the term, what was the type 'a foo where 'a is only used for the type?
<mrvn>
flux: phantom
<flux>
in any case, had it been that way there could just be type string = Bytes.ro Bytes.t
<flux>
yes, I was thinking of 'ghost' but it didn't click :)
<mrvn>
Problem then is to make a Set(String)
<flux>
actually type string = .. could depend on if you compile with -safe-string or not
maattdd__ has joined #ocaml
<mrvn>
you need a whole new set of functors with a 'a t
<flux>
well the problem wouldn't be for existing code
<flux>
and new code could just do Set(Bytes)? though I suppose it's bad that the module type doesn't tell if it's ro or rw
<mrvn>
Also there are 3 kinds of strings: mutable, immutable and immutable for the function I call
<flux>
you mean mutable, immutable and constant?
<mrvn>
flux: From what was said String is now immutable. So you have to change all your code to Byte.
<mrvn>
flux: whatever you call it. Point is that strings can become temporarily immutable.
<mrvn>
or mutable in one part of the code and immutable in another.
<flux>
with polymorphic variants and phantom types that stuff is simple
<kerneis>
you completely lost me; are you talking about Core or stdlib?
<mrvn>
Does Byte have the same memory representation for strings? Can one Obj.magic them to/from String?
<mrvn>
kerneis: stdlib
<kerneis>
oh, I wasn't aware of the Byte stuff
<mrvn>
kerneis: ocaml 4.02
<mrvn>
so far I think it is only optional.
<flux>
I imagine it's Obj.magicable, maybe it even comes with functions for going the other way?
<ggole>
How could you soundly convert without copying?
<mrvn>
still misses the 3rd kind. If you get a Obj.magiced Byte passed as argument you can't assume it never changes and use it as key in a Hashtbl for example.
<flux>
you cannot, if you only have constant values. but if you have values -you- cannot modify (immutable), others may still modify them :)
<ggole>
Introducing that kind of problem sounds like a bad idea
<flux>
with a phantom type there could be a function val constant : _ t -> [ `constant | `readable ] t
<mrvn>
You need a "this never changes", a "you are not allowed to changed it" and mutable strings.
<flux>
(and that function would copy)
<flux>
there could also be val unsafe_constant that doesn't copy, but where you can guarantee it's not modified (ie. when you return it from the function)
<ggole>
Why would you have this for Bytes.t but not for arrays and refs?
<flux>
or if yuo want to go very non-ocamlish about it, you could add a runtime check :-)
<ggole>
And hashtables
<mrvn>
ggole: hashtables have to be mutable
<mrvn>
ggole: but for arrays it makes the same sense.
<mrvn>
for refs just use ! when you don't want to change it.
<flux>
ggole, personally I would like to have it for everything.. baby steps maybe?-)
<mrvn>
flux: the string could have a bit so a constant string wouldn't have to be copied.
<mrvn>
And then you could have a 4th kind, a copy-on-write string.
<flux>
and how about threads?
<flux>
mutex lock on all writes?
nikki93 has joined #ocaml
<mrvn>
ocamls stdlib isn't thread safe
<flux>
apparently c++ string implementations have switched away from CoW
<ggole>
A lot of ceremony for little actual benefit if you ask me
<mrvn>
ggole: let bool_to_string = function false -> "False" | true -> "True"
<mrvn>
ggole: with mutable strings that needs to allocate every time
<ggole>
I'm fine with immutable strings.
<ggole>
I'm talking about the access types.
<flux>
well, without access types you get to use unsound casting or duplicate modules?
<mrvn>
ggole: the phantom types would prevent code duplication for String and Byte.
<flux>
or perhaps make 'normal' functions operating on strings/bytes functorized
<flux>
for example, the Pcre module..
<ggole>
If code duplication is a problem, you can solve it without making the interface complicated.
<flux>
so how would you solev it for Pcre?
mort___ has quit [Quit: Leaving.]
<ggole>
In fact, I don't see what code duplication has to do with access types at all
nikki93 has quit [Ping timeout: 240 seconds]
<mrvn>
ggole: you can have val length : 'a String -> int but not val length : [String | Byte] -> int
<ggole>
You can already do module Foo : type t ... end = UnderlyingFoo to restrict operations (such as mutation) in a type safe way
<flux>
well, now you have val split : string -> string list. now you need to have that for bytes as well. but with accses types you (say) can do val split : _ bytes -> const_bytes list
<ggole>
So you can have String and Bytes without any duplication, trivially.
Hannibal_Smith has joined #ocaml
<mrvn>
ggole: No you can't. you need a foo_string and foo_byte function for everything.
<ggole>
For the functions in the relevant modules, then
<flux>
and how about splitting a mutable string with an immutable string? and vice versa?
<flux>
not to mention simple things like concatenating the two
<mrvn>
The number of functions is exponential with the number of string arguments.
<mrvn>
and Printf.printf "%s"
<mrvn>
What's the % code for Byte.t?
<ggole>
I doubt there is one? Why would there be one?
<mrvn>
ggole: how else do you print a mutable string?
<ggole>
Bytes.t isn't a mutable string
<ggole>
It's a byte array
zpe has quit [Remote host closed the connection]
tani has joined #ocaml
<mrvn>
ggole: String is immutable. so how else do you do mutable strings?
zpe has joined #ocaml
<ggole>
You don't.
<ggole>
There's things like Buffer if you need to do updatey things.
<ggole>
Makes perfect sense to me.
<mrvn>
which breaks basically every code
<ggole>
And it's not like there aren't several languages which already do exactly this.
<flux>
for years to come, there will be libraries that will use the String
<ggole>
Yes, backwards compat is the big problem there
<ggole>
But you wouldn't be able to be backwards compat with access types either.
<flux>
well, you could in the sense that the whole ocaml installation would need to be compiled in the same -safe-string -mode?
<mrvn>
ggole: I wouldn't say that. type string could be aliased to `Mutable String.t
nikki93 has joined #ocaml
<ggole>
That would break functor applications like Set.Make (String).
tane has quit [Ping timeout: 255 seconds]
<mrvn>
ggole: ok, then String would be a shallow copy of Byte with String.t = `Mutable Byte.t
zpe has quit [Ping timeout: 255 seconds]
<mrvn>
ggole: you can probably make it so that string and String all still works but maps to the new phantom types.
<mrvn>
Or just have String as is and ConstString.
<ggole>
That'd run you into trouble with string literals.
nikki93 has quit [Ping timeout: 252 seconds]
<mrvn>
ggole: is "foo" const or not?
<ggole>
You might be right that access types could be made to work: seems like an awful hack though.
<ggole>
"foo" should have type string
<mrvn>
let get_temp_name () = let s = "/tmp/blafaseXXXXXX" in tempname s; s
<mrvn>
software assumes string literals are mutable
<_obad_>
I have a module M and a signature S. I want to make sure the module matches the signature but I don't want to hide the module. is there a way besides module Foo_check = M : S?
<mrvn>
_obad_: don't thinks so.
<ggole>
Then that software will break when they compile with the new flag
<mrvn>
ggole: and that is the point. A ton of stuff will break
<mrvn>
Can one even write source so it works with and without the new flag?
<ggole>
If you chose the access type thing, and made strings mutable by default, you wouldn't get the advantages that introducing immutable strings were supposed to deliver
<mrvn>
Is there a Byte module without the flag?
<whitequark>
yes
<whitequark>
but type bytes = string
<mrvn>
whitequark: needs to be that way
<whitequark>
(works with and without) yes, use String.copy for literals
<whitequark>
that literals were mutable is such an awful quirk, it should have never happened
<mrvn>
the question is what happens if you mix modules compiled with the flag with modules compiled without.
<ggole>
There was no way of making them immutable (other than designing OCaml with immutable strings from the start).
<whitequark>
as I understand, the flag is only active intra-module
<mrvn>
whitequark: maybe. C and C++ still struggel with that.
<whitequark>
mrvn: hm?
<whitequark>
"" has type const char* there.
<ggole>
No, that's wrong. Ignore what I said.
<whitequark>
(and writing there would segfault on non-Windows, so it's a non-issue for portable software)
<mrvn>
whitequark: C lets you happily pass a string literal to a function taking char* and then you get a segfault when it tries to modify it.
<whitequark>
no, you will get a warning due to dropping the const modifier
<mrvn>
whitequark: "" has type char* in C but is const.
<mrvn>
whitequark: Only in C++ do you get a warning about depreacted cast from const to non const
avsm has quit [Quit: Leaving.]
<whitequark>
hm, you're right
<mrvn>
whitequark: imho totaly screwed up
<ggole>
Literals have type const char[K] iirc
<ggole>
But of course you can cast to char *
<mrvn>
ggole: nope. no const.
<mrvn>
typeof("") x; gives you a char *
<mrvn>
as I said: totaly screwed up
<ggole>
Ah, it's const char[K] in C++.
angerman has quit [Ping timeout: 252 seconds]
<ggole>
OK, yeah. That's all fucked up.
rgrinberg has quit [Quit: Leaving.]
<whitequark>
C++ isn't backwards-compatible with C, yeah
<mrvn>
In python3 there is b"foo" for byte arrays and "foo" for UTF-8 strings. maybe ocaml could have something similar for string literals to mark them mutable.
<ggole>
Yeah, it changes a bunch of (mostly dumb) things
<ggole>
typedef int; is valid C, but not C++.
<whitequark>
why would anyone write that
<ggole>
Why would a compiler allow it?
<whitequark>
why would a compiler allow C to exist?
<mrvn>
"unsigned;" is allowed in C
<companion_cube>
please don't copy how C handles strings
<ggole>
There's a heap of stupid C declarations that don't mean anything, but which compilers have to accept.
<ggole>
int foo(struct does_not_exist); <- this is a good one
<mrvn>
at least gcc warns about a lot of nonsense.
<ggole>
The struct type there is defined *within the scope of the declaration*.
<ggole>
If you later declare struct does_not_exist, that works but is a different type.
<mrvn>
realy just within the scope? I thought that would just declare the type globally.
<ggole>
No, that would be struct foo; int foo(struct foo);
rgrinberg has joined #ocaml
avsm has joined #ocaml
rgrinberg has quit [Client Quit]
dapz has joined #ocaml
rgrinberg has joined #ocaml
<mrvn>
.[] is for strings, .() for arrays, .{} for Bigarray. What does Byte have?
<mrvn>
.<>?
<adrien>
.\/
<adrien>
so you can do .\o/
<whitequark>
yeah, seems like a hasty decision
<mrvn>
adrien: lol
<whitequark>
ocaml really should have typeclasses...
<whitequark>
.[](){} is annoying and pointless
<Drup>
whitequark: soon™
<ggole>
Beats {String,Array,Bigarray}.get/set. But yeah.
<whitequark>
Drup: yeah, you said this to me a year ago
<whitequark>
:p
<whitequark>
half a year maybe
<avsm>
whitequark: i'm telling you soon now :-) surprise incoming soon...
<Drup>
whitequark: well, it's sooner(™) now :D
<ggole>
How would it work? Some kind of implicit module argument?
<mrvn>
whitequark: with a typeclass the compiler couldn't optimize .[]
<Drup>
mrvn: yeah it could
<mrvn>
Drup: only when it knows the type
<whitequark>
avsm: that's real nice!
<Drup>
avsm: someone spoiled me :3
<_obad_>
quick question... is there a way in vim to see the compiler output without losing the formatting?
<avsm>
Drup: :-)
* whitequark
has been advocating (starting using; using more, depending on how you look at it) ocaml at his company for some time already
<companion_cube>
"soon" in Ocaml means in two years ;)
<companion_cube>
but yes, typeclasses would be awesome
<whitequark>
explaining people why they should sometimes use .[] and sometimes .() after Ruby is... annoying.
<NoNNaN>
and every other feature that starts with "type" eg.: type providers
<companion_cube>
type families
<whitequark>
NoNNaN: you could conceivably do that today, no?
<whitequark>
no support from compiler required
<_obad_>
it's a tradeoff that implies mandatory annotations
<whitequark>
_obad_: what is?
<_obad_>
having to add : int, : int array, : string everywhere to be able to write [] and not .() or .[]
<Drup>
companion_cube: type famillies would break the ML's style inference in lot's of bad way, imho
<companion_cube>
I was joking
<Drup>
ok :D
<whitequark>
_obad_: what?
<ggole>
_obad_: type classes are (an) answer to that
<NoNNaN>
whitequark: unfortunately no, type providers not yet available for ocaml
<mrvn>
would be nice if ocaml had polymonomorphism. Then you could declare .[] for strings, bytes, arrays and bigarrays, get the optimized version if the type is known and the generic slow one if not.
<_obad_>
ggole: so no annotations yet you can use the same operator??
<Drup>
mrvn: yes, well done
<whitequark>
NoNNaN: aren't type providers just types autogenerated by the compiler?
<companion_cube>
that's a matter of typeclass + inlining, isn't it?
<Drup>
you just discovered type classes.
<ggole>
Instead of seeing x.[i] and inferring x : string, you'd get x.[i] implying x : Indexable t => t or something like that
<Drup>
mrvn: what you just described is *exactly* type classes ...
tlockney_away is now known as tlockney
<tautologico>
I think it's not too hard to write generic support for type providers using ppx
<Drup>
what is a "type provider" exactly ?
<mrvn>
Drup: except type classes would not provide mutiple code flavours for a function.
<tautologico>
about the "typeclasses soon", is it the implicits stuff?
<Drup>
mrvn: implementation detail
<ggole>
_obad_: so the one operator always implies the same type, but the type is more complicated, allowing for static dispatch of a kind.
<Drup>
mrvn: you can do it, it's a trade off
<Drup>
tautologico: spoilers :3
<whitequark>
Drup: so it is implicits? :/
<Hannibal_Smith>
<ggole> Literals have type const char[K] iirc <-You are right, this is also reported by the standard
<_obad_>
ggole: I see.... but then doesn't it kinda cause implementation issues, as in you need either to box things, or have a number of implementations that is proportional to the number of typeclass combinations?
maattdd__ has quit [Ping timeout: 252 seconds]
<mrvn>
Drup: one is a type system thing, the other a opimizing compiler thing
<Drup>
whitequark: don't look disapointed, it's going to be awesome :p
<Hannibal_Smith>
narrow string literal has type “array of n const char”, where n is the size of the string as defined below, it and has static storage duration <-
<Drup>
mrvn: since when the too are not correlated ?
<Drup>
the two*
<whitequark>
Drup: I've seen alain's posts on the topic, I'm not really impressed
<mrvn>
Drup: they are. I still want the later
<ggole>
_obad_: implementation is kind of fun, I think, but I believe its manageable
Anarchos has joined #ocaml
<ggole>
The usual implementation (eg, Haskell) is dictionary passing
angerman has joined #ocaml
<whitequark>
aka vtables
<mrvn>
ggole: you can do that with first class modules
<ggole>
Right, but the vtables are per function and not per object.
<whitequark>
well, it's inverted a bit
<whitequark>
NoNNaN: can you summarize in one sentence, why can't ocaml have them now?
<ggole>
mrvn: right, and if you make the module argument implicit using some magic lookup machinery, you have something that is a lot like type classes
<Drup>
whitequark: why ?
<_obad_>
oh god all that sounds pretty complicated, just so you can lose the .[] +.?
<companion_cube>
ggole: you also need some prolog-like search
<companion_cube>
because some typeclasses instances are kinda generic
<ggole>
Well, that's what I tried to suggest with "magic lookup machinery"
<Drup>
_obad_: it's not only for that, type classes have lot's of potential uses
<companion_cube>
ok
<companion_cube>
_obad_: if you complexify the type system to get rid of .{} .[] and such, better do it in a generic and clean way
<tautologico>
like doing lens in OCaml :) (runs...)
<companion_cube>
so the whole language benefits from it
<Drup>
tautologico: /me screams in terror
<companion_cube>
:D
<ggole>
A nice way to do equality and ordering will be very welcome
<companion_cube>
now I know what Drup is afraid of
<companion_cube>
indeed
<gasche>
avsm: I really worry about CPU time burned when doing continuous testing
<ggole>
Not sure how it would interact with the existing stdlib though
<companion_cube>
and hashing, and printing
<gasche>
I'm not sure why this is so surprising
<companion_cube>
gasche: sadly I think that's just a tear in an ocean
<adrien>
hmmmm
<gasche>
that's some of the tears we are responsible for
nikki93 has joined #ocaml
<adrien>
need to go ask AMD for a system with their 16-core server CPUs with a 99W TDP
<_obad_>
companion_cube: I think there might be a simpler hack to get rid of .[] .{} +. with maybe some extra syntax.
<_obad_>
companion_cube: think of the way the formatting types work... it's a hack, but it works.. kinda
<Hannibal_Smith>
adrien, don't that kind of cpu tend to have simpler core?
<companion_cube>
_obad_: the problem is type inference
<tautologico>
I'd like to be able to overload indexing, besides the other benefits of ad hoc polymorphism
<avsm>
gasche: I'm seriously facepalming at priorities here.
<adrien>
gasche: I don't think we should worry; compiler is fairly fast, code is fairly fast
<_obad_>
companion_cube: how does SML do it?
<adrien>
gasche: loading google.com takes much more power
<adrien>
(overall)
<NoNNaN>
whitequark: runtime code (generation), not all your types are known at compile time
<companion_cube>
oh, the overloading thing of SML?
<_obad_>
yeah
<companion_cube>
it's just a default case, I think
<tautologico>
_obad_: special casing
<companion_cube>
like, a+b is int by default
<companion_cube>
it's ugly
<gasche>
adrien: do you have actual numbers on that? I would be interested
<adrien>
Hannibal_Smith: mostly the same as far as I know
<companion_cube>
it doesn't solve equality or comparison
<tautologico>
in an expression a+b can be int/float, but inside a function it defaults to int
<adrien>
gasche: look at the amount of JS there
<_obad_>
hmm
<tautologico>
for equality you have to declare eqtypes
<companion_cube>
or php
<tautologico>
it's not pretty
<_obad_>
*need to get back to work*
<companion_cube>
the proper way really is typeclasses
<Hannibal_Smith>
adrien, same pipeline wide and deep, same branch prediction algorithm, same number of BTB buffer...?
<adrien>
gasche: and put another way, a current machine is going to use at most two small regular lamps
<Hannibal_Smith>
At least in production CPU like Oracle Niagara one
<Hannibal_Smith>
CPU core are really more simpler
<whitequark>
Drup: because it's ad-hoc. just randomly selecting some value from context instead of a proper solution
<adrien>
Hannibal_Smith: mostly, yeah; cache is bigger (but shared among more CPUs); clocks are lower though
<Drup>
whitequark: what is a "proper solution" ?
<Drup>
( whitequark: and what is the "proper" way of doing type classes, according to you ?)
<Hannibal_Smith>
That kind of CPU seems really "narrow" so some kind of computation style
<Drup>
( whitequark: because haskell is doing exactly that ...)
<ggole>
It would be nice to be able to select the (implied) implicit argument manually
<whitequark>
Drup: wait, what? haskell does the same thing?
<Hannibal_Smith>
Where a problem has good parallelism characteristics
* whitequark
is really confusing now
<whitequark>
I thought haskell solved it properly...
<Drup>
what is "properly" ?
<adrien>
well, the CPUs I have in mind are still clocked fairly high but not that high
<whitequark>
defining typeclass as an explicit entity, etc
<adrien>
and they tend to have "boost" (temporary overclock provided there's power and temperature headroom)
<Drup>
whitequark: and in what is it different than having a vtable passing around ?
<whitequark>
Drup: I'm talking about the interface, not implementation
<Hannibal_Smith>
That kind of cpu seems interesting for something like web related servers
<Drup>
whitequark: ok
<Drup>
whitequark: so yes, the interface is different
<Drup>
and, imho, is the bad one
<mfp>
whitequark, Drup: aren't Haskell typeclasses even worse in the sense that they are global (and you can only have 1 instance)? With implicits, at least you have modules + open.
<Hannibal_Smith>
I don't know to how Oracle sells the Niagara
<Drup>
mfp: indeed
<Hannibal_Smith>
*who
<Drup>
also, there is an issue at use point
<tautologico>
only one instance per type
<whitequark>
Drup: mfp: hmmm, that is a good argument.
<tautologico>
so people use newtypes a lot for getting around that
<Drup>
with type classes, you can look at a piece of code and it's possible that you don't know which stuff is going to be used.
<tautologico>
also dependencies issues between libraries like orphan instanves
<Drup>
because it depends on some other file implicitly opened
<whitequark>
Drup: you're probably right after all.
<tautologico>
*instances
<Drup>
type classes are not scoped.
<whitequark>
okay, great
<Drup>
(and this is terrible)
<mfp>
hmm implicits can be passed hmm explicitly, cannot they? So you can know for sure if you care
nikki93 has quit [Ping timeout: 276 seconds]
<companion_cube>
so, implicits would be even better?
<companion_cube>
is that what you imply?
<Drup>
I prefer implicits
<companion_cube>
ok
<tautologico>
in Idris instances are named to work around some of these issues
<gasche>
Coq's type classes are better than Haskell's from a coherence point of view
<Drup>
companion_cube: if you look at the backlog, I have said that since a year ago :D
<companion_cube>
well, we just need to wait and pray for the upcoming implementation to be merged
<companion_cube>
:)
<companion_cube>
Drup: I know, it's still useful to check ;)
<gasche>
the problem with implicits is that no effort is made to enforce coherence
<whitequark>
there seem to be not too many objections to merge of implicits
<whitequark>
gasche: coherence?
<mfp>
companion_cube: they feel adhoc and all, but they are objectively better in some ways
<gasche>
whitequark: the fact that the code is not ambiguous
<tautologico>
because instances don't have names in Haskell, they can't be exported/imported explicitly
<whitequark>
gasche: right, that's one thing that annoys me.
<Drup>
whitequark: the main point, imho, is that implicits are more predictable than type classes
<companion_cube>
which reminds me that I'd really like to banish 'open' :/
<tautologico>
type parameters that take a whole line of code :)
<tautologico>
also I feel that "trait" is a better name, less confusing than "type class"
maattdd__ has joined #ocaml
<mrvn>
And here I was thinking ocaml was about infering types
dapz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
<gasche>
type classes infer uses of instances, but I think not inferring them is also a reasonable choice
zpe has quit [Ping timeout: 245 seconds]
<gasche>
(I mean it infers constraints)
nikki93 has quit [Ping timeout: 255 seconds]
<Drup>
mfp: just read the slides
<gasche>
kerneis: thanks, I just fixed the typo
<Drup>
mfp: I'm screaming ocamlgraph and tyxml at the part asking for examples of use for applicative functors :D
<kerneis>
gasche: you're welcome
maattdd__ has quit [Ping timeout: 246 seconds]
dsheets has quit [Ping timeout: 246 seconds]
dsheets has joined #ocaml
ygrek has joined #ocaml
racycle has joined #ocaml
pminten has joined #ocaml
Arsenik has joined #ocaml
michael_lee has quit [Remote host closed the connection]
<gasche>
I am wondering about patch handling
<gasche>
sometimes I want to merge someone's patch somwehere, but I would like a relatively minor change
<gasche>
my current policy is that, if it takes more time for me to describe the change than do it, I do it directly (generally as an amend to the patch)
<gasche>
would you do differenty?
jwatzman|work has joined #ocaml
<adrien>
depends on if you want to each the patch author for the subsequent patches
<gasche>
I don't understand your sentence
<gasche>
ah, each -> teach
<adrien>
yeah, sorry :)
<adrien>
I'll blame the keyboard and attempt to debug C++
Vaur has joined #ocaml
<_obad_>
seems that ocamldoc ignores (** *) comments on variants... :( ?
<whitequark>
I think you have to use something like (**< comment *)
<_obad_>
type blah = Foo (** Foo *) | Bar (** Bar *) works
<_obad_>
oh
<whitequark>
not sure though, but I've seen it sometimes
zpe has joined #ocaml
nikki93 has joined #ocaml
<Drup>
_obad_: I wouldn't be surprised
<_obad_>
there is no talk of (**< *) in the doc and it doesn't work
<Drup>
never heard of "(**< *)"
<Drup>
_obad_: until recently, this annotation was not working on each method in an object, I wouldn't be surprised if it doesn't work on poly variants
<_obad_>
drup: the changes.txt under ocamldoc/ talks of variants though
<rgrinberg>
not really sure if ocaml-re would be interested in this
<avsm>
rgrinberg: i like the cut of that signature's jib
<smondet>
rgrinberg: any reason for choosing the Emacs syntax?
<whitequark>
type str is a bit odd
<rgrinberg>
smondet: nah it's just what I'm testing with. will have a general constructor function later.
<whitequark>
what's it for?
<_obad_>
rgrindberg: do we really want labels on fold?
<rgrinberg>
_obad_: yes!!!!
<whitequark>
I think ~f on fold is great, ~init not so
<_obad_>
or ~pos
nikki93 has quit [Ping timeout: 240 seconds]
<avsm>
~init and ~f let you choose which to curry
<whitequark>
hmm, good point
<rgrinberg>
_obad_, whitequark: they're also the default labels in XLabels modules
maattdd__ has joined #ocaml
<whitequark>
does *anyone* use XLabels modules?
<Drup>
yes
<rgrinberg>
whitequark: *raises hand*
<whitequark>
oh, cool
<smondet>
whitequark: yes, everywhere
<_obad_>
it's like automatic vs. shift
<whitequark>
I really wish they were included by default
<_obad_>
no
<whitequark>
opened
<Drup>
whitequark: also, it's the defaul in core
<flux>
sadly ~f breaks @@
<whitequark>
oh
<adrien>
I use them from time to time
<adrien>
depends
<_obad_>
it's useful when you have a lot of arguments, or when they have similar or equal types
<adrien>
it's mostly to use ~f:(fun ........) on several lines
<whitequark>
adrien: I use arr |> List.map (fun ...)
<rgrinberg>
whitequark: str is there because it's my dream that the it will work on more than 1 string type
<whitequark>
rgrinberg: like what?
<adrien>
whitequark: would work too :)
<rgrinberg>
etc. substrings, bigstrings, ropes
<flux>
rgrinberg, well, at least provide a basic String instantiation
<flux>
whitequark, Bytes :)
<whitequark>
rgrinberg: I mean, ocaml-re only works on strings
<rgrinberg>
flux: i will, module S with type str = string that's what im working with
<_obad_>
labels are like maple syrup... you want to put a little bit of it on some food, but putting it everywhere is... well I guess I'm hungry now
<avsm>
rgrinberg: if it works on bigarrays, then bye-bye string in cohttp...
<rgrinberg>
whitequark: hopefully not for long
<whitequark>
hmm
tobiasBora has quit [Quit: Konversation terminated!]
<rgrinberg>
flux: the basic string implementation is all it's going to have in the beginning
maattdd__ has quit [Ping timeout: 240 seconds]
<rgrinberg>
i think ocaml-re can easily be implemented on top of ropes by simple wrapping every module with module (S : module type of String) and instantiating with rope
<flux>
rgrinberg, how are you going to make that happen with the functorized interface?
<rgrinberg>
flux: just instantiate the functor, then module Str = Make(String) : S with type str = string?
<rgrinberg>
how i wish i could return lazy lists for some functions
clan_ has quit [Quit: clan_]
<rgrinberg>
now i have to choose whether to return eager lists or these awkward folds :/
<rgrinberg>
and streams suck
<companion_cube>
don't use Stream
<ggole>
Stream is pretty strange
clan_ has joined #ocaml
<rgrinberg>
companion_cube: i would never dare to
<companion_cube>
:)
<companion_cube>
use some better iterator type, or lazy list, or whatever
<Drup>
(* INSERT SELF PROMOTION HERE *)
<Drup>
wink wink companion_cube
<rgrinberg>
Drup, companion_cube: i know, i know ideally i'd have something non destructive
<Drup>
rgrinberg: use Sequence
<Drup>
rgrinberg: I think upstream wouldn't mine, btw
<rgrinberg>
Drup: i would 100% use sequence if opam/ocamlfind didn't make it cumbersome to make optional dependencies
<Drup>
cumbersome ?
<rgrinberg>
i mean oasis, not ocamlfind
<Drup>
oh
<Drup>
huum
<Drup>
it's not that terrible
S11001001 has joined #ocaml
<rgrinberg>
what a complimenet
<Drup>
depends of what you want exactly, "optional dependencies" can mean lot's of think
S11001001 has quit [Changing host]
S11001001 has joined #ocaml
<Drup>
things*
<rgrinberg>
some extra functions that return sequences if sequences is present would be the use case here
jonludlam is now known as jonludlam_afk
<companion_cube>
Drup: I said nothing :DD
<rgrinberg>
also, we need SequenceLabels
<companion_cube>
rgrinberg: sequence is a structural type, you can define it anywhere
<rgrinberg>
*wink*
<Drup>
rgrinberg: since sequence is super small, self contained and pure ocaml, do you really need to have it optionnal ?
shinnya has quit [Ping timeout: 255 seconds]
<companion_cube>
type 'a sequence = ('a -> unit) -> unit
<rgrinberg>
ah, i thought it was abstract
<companion_cube>
also yes, you can just copy/paste the ocaml file directly
nikki93 has joined #ocaml
<companion_cube>
I prefer structural types when possible
<rgrinberg>
i like them too, if only objects didn't suck :/
<Drup>
rgrinberg: I agree with that soo much
<rgrinberg>
perhaps someone will make a patch now that we have github contributors :D
<Drup>
rgrinberg: well, the difficult part is that it's not super clear to make them not suck
<whitequark>
what's so terrible with objects?
<rgrinberg>
whitequark: they're dog slow and you can't pattern match on them
<Drup>
whitequark: slow, no full row polymorphism
<whitequark>
slow, hmmm
<rgrinberg>
ive made some benchmarks not long ago
<_obad_>
drup: what does "no full row polymorphism" mean in English?
<rgrinberg>
at least 2x slower in the best case
<whitequark>
rgrinberg: that's not bad at all
<ggole>
Slower than what? Records?
<rgrinberg>
ggole: yeah
Topher has joined #ocaml
<ggole>
Mmm.
nikki93 has quit [Ping timeout: 245 seconds]
<Drup>
_obad_: you can't have this function : "< foo > -> < x : int ; foo >
<ggole>
I've never used objects yet.
<_obad_>
drup: i.e. a function that extends an object with a method
q66 has joined #ocaml
q66 has quit [Changing host]
q66 has joined #ocaml
rgrinberg has quit [Quit: Leaving.]
<Drup>
_obad_: more generally, function that are abstractions along a "row"
<Drup>
abstracts*
<_obad_>
drup: where does that row terminology come from? are there rows? what are columns?
<Drup>
_obad_: well, as everything, it's a type theory thingy :D
<_obad_>
what's the TL;DR
nikki93 has joined #ocaml
<Drup>
when you have a record type
<Drup>
a row is part of this record
<Drup>
of this record type*
<_obad_>
is every field a row?
<Drup>
not every
<Drup>
some
<mrvn>
records don't have row types, only objects
<Drup>
mrvn: talking in general
<mrvn>
right?
<Drup>
mrvn: in ocaml, it's a bit more complicated
<_obad_>
is it like a part of the lattice of subtypes?
<_obad_>
like all elements that are <= than some element?
<Drup>
no, it's different
<Drup>
you can do this kind of stuff with subtyping or row polymorphism
<Drup>
with objects, it's done with subtyping
<_obad_>
*googles row polymorphism*
q66 has quit [Quit: Leaving]
nikki93 has quit [Ping timeout: 240 seconds]
<ggole>
Row polymorphism is like heated discussion polymorphism, only a bit more heated.
<Drup>
ggole: why is it heated ?
<Drup>
either people don't know it or they like it, in my experience :D
<ggole>
Hmm, this joke might not go over with non-English speakers.
<Drup>
oh
nikki93 has joined #ocaml
<ggole>
"row" being another term for "argument"
<Drup>
oh :D
<_obad_>
ggole: now it starts to make sense
<ggole>
I was going to follow that up with something about "blazing row polymorphism", but never mind. It's dead.
<Drup>
ggole: no no, it's very good, my terrible english is the one to blame :)
<ggole>
Something something my type checker is on fire
<Drup>
_obad_: sorry, multi tasking is bad for pedagogy.
<_obad_>
drup: so what you want is mixins
<_obad_>
slide 13
q66 has joined #ocaml
q66 has quit [Changing host]
q66 has joined #ocaml
<mrvn>
smondet: "Well, subtyping and type inference just don't mix. Doing type inference with row polymorphic records is much easier." Somehow I feel the exact opposite
<Drup>
_obad_: mixins is the syntactic construct for that, yes :)
<smondet>
@mrvn:
<smondet>
I don't know
Topher has left #ocaml []
<smondet>
enough about that
<mrvn>
What he calls Row Polymorphism seems to be to be impossible in ocaml without adding indirection to record labels.
<mrvn>
s/be/me/
<mrvn>
Specifically the "let f x = x with {sum: x.a + x.b}" bit
<mrvn>
That would require runtime type infos to say if the record already has "sum" and where.
<_obad_>
runtime type infos are bad, mmmmkay
<Drup>
mrvn: it's already in objects
tobiasBora has joined #ocaml
<mrvn>
Drup: 1) objects use indirection, 2) you still can't extend objects like that
<Drup>
indeed
<_obad_>
drup: are they? is there a place where the runtime representation of objects is described?
<Drup>
_obad_: don't have link for you to read, sorry
<whitequark>
objects seem to be really obscure.
<whitequark>
in many ways
Thooms has quit [Quit: WeeChat 0.3.8]
<_obad_>
according to translcore.ml objects seem to be represented at least partially as arrays
<adrien>
isn't everything in ocaml an array? :P
<Drup>
_obad_: objects are dictionaries, basically.
<mrvn>
a value
<_obad_>
drup: found it, it's in camlinternalOO.ml
<mrvn>
and a value can be a primitive type or a pointer to a block
zpe has joined #ocaml
<_obad_>
for i = 0 to len - 1 do methods.(i*2+3) <- magic pub_labels.(i) done;
<_obad_>
O.O
<adrien>
open Obj
<adrien>
<3
<Drup>
*magic*
<adrien>
should have been called "dirty"
<ggole>
Object typing is almost as magical :/
<adrien>
Obj.dirty
<ggole>
Obj.wrong
<_obad_>
adrien: it wouldn't go with the camels - arabian night - flying carpet magic theme
<whitequark>
Obj.nope
<_obad_>
Obj.saddam
<mrvn>
I object
<Drup>
to be expected :D
<adrien>
_obad_: hehe :P
<whitequark>
mrvn: you object!
<whitequark>
(as in "you monster!")
<whitequark>
although that remark should've been directed at companion_cube
<ggole>
I wonder if Obj.magic would be used less often it it had a long ugly name
<companion_cube>
hey
<mrvn>
Obj.you_know_you_should_not_do_this
<whitequark>
Obj.kill_a_kitten
<ggole>
Anybody with a degree in lexical psychology here?
zpe has quit [Ping timeout: 252 seconds]
<adrien>
Obj.c_plus_plus
lostcuaz has quit [Ping timeout: 265 seconds]
<whitequark>
Obj.php
<adrien>
short but effective
lostcuaz has joined #ocaml
<_obad_>
one problem is that you can't have a class whose constructor is a thread
<_obad_>
i.e. you can't have: class blah ~filename () = Lwt_io.with_open_file filename (fun blah -> ...)