<discocaml>
<benslc> I've seen it used in academic circles especially among older professors. I've never heard of it used in industry though.
gzar has quit [Quit: WeeChat 4.2.2]
<discocaml>
<contextfreebeer> it has roughly the same core niche as OCaml if you ignore jst, compilers and theorem provers/proof assistants
<discocaml>
<contextfreebeer> SML has several towering achievments in both those fields and important codebases that are still maintained
<discocaml>
<contextfreebeer> but you won't find it in a typical industrial setting
<discocaml>
<benslc> What do you like to build in OCaml? I use it mostly for parsers and CLIs. I want to get more into server programming but I find the async stuff hard. Right now I use Rust when I make a server.
<discocaml>
<benslc> My biggest OCaml project is a templating language called liquid-ml
<discocaml>
<yawaramin> hopefully the new effect handler-based concurrency libraries will make it easier
<discocaml>
<contextfreebeer> so far the biggest ocaml projects I've done are a toy compiler, a SAT solver and a basic MIPS 1 CPU emulator which might become a psx emulator some day. Rust is cool, I have a few projects written in it and one ongoing project
<discocaml>
<benslc> I want to build a compiler one day but I lack the low level knowledge. So I made this project to learn the lexer, parser portion. I've been learning C so hopefully I can make a compiler one day
<discocaml>
<contextfreebeer> Compilers are pretty high level, you don't have to make your own backend, and even so, the code generator is only a moderately sized part of the backend, so not much low-level knowledge is required really
<discocaml>
<benslc> Yes, Jane Street is doing good work there. They are taking inspiration from Rust.
<discocaml>
<benslc> Do you use LLVM or something like that? If you know the youtuber tsoding he made a NASM compiler and it was really interesting. He even bootstrapped the compiler and made his own web server with syscalls
<discocaml>
<contextfreebeer> the compiler I wrote is a backend totally from scratch although the graph-coloring register allocator is an algorithm lifted straight from a textbook
<discocaml>
<yawaramin> the Rust stuff is not about concurrency
<discocaml>
<contextfreebeer> you can use LLVM or qbe, that's way more practical
<discocaml>
<yawaramin> the Rust-like ownership stuff is not about concurrency (directly anyway)
<discocaml>
<benslc> Thats cool, can I see your compiler?
<discocaml>
<contextfreebeer> the repository is private I'm afraid, a bit too messy to make public though I will probably do that at some point. it's nothing to write home about anyway, just a basic toy compiler I made following this book https://www.cs.princeton.edu/~appel/modern/ml/ lots of these compilers around, though I couldn't find any completed compiler written in OCaml, much to my dismay as I would have really appreciated to have reference code to look at
<discocaml>
<contextfreebeer> that's why I want to make it public so the next person at least has something
<discocaml>
<contextfreebeer> all of the public repos I was able to find (and I really looked) all give up before implementing the backend, understandable cause it's pretty hard
<discocaml>
<contextfreebeer> also I couldn't find any implementation that has a garbage collector, not even in SML (the original language of the book), so I have no help when it comes to implementing that either
<discocaml>
<contextfreebeer> incidentally this is a great book, highly recommended
<discocaml>
<contextfreebeer> I've read a few compiler textbooks and this one I find is the most straightforward, and I like that it's project focused
<discocaml>
<contextfreebeer> a lot of this code I would write differently to be honest
<discocaml>
<benslc> I will read it! Same with my project, learning about the OCaml ecosystem I could cut it down to like 2/3 the size. Hindsight is 20/20...
<discocaml>
<contextfreebeer> for sure
<discocaml>
<functionalprogramming> can you provide some insight as to why debugging register allocation is really difficult? My professor said the same thing today, but he did not really expand upon it. @contextfreebeer
<discocaml>
<contextfreebeer> In my case the most difficult part was that the allocator was working with incorrect liveness information, making sure that the register allocator actually allocates things correctly, obviously super important. That's all well and good if you know to look for that, but if you don't know where the problem is and you are neck deep in assembly in gdb trying to figure out wtf is going on, it's not a good time, in my opinion
<discocaml>
<contextfreebeer> the problem ended up being very subtle, not something you can spot really clearly in the code
<discocaml>
<contextfreebeer> the register allocator itself if you just copy paste the algorithm from a book is not so hard, modulo minor mistakes
<discocaml>
<contextfreebeer> anyway, the reason why it's hard is because a buggy register allocator behaves really erratically and it's very hard to pinpoint the cause
<discocaml>
<contextfreebeer> it just makes no sense, takes a lot of effort to understand what is going on, reading assembly is hard enough already
<discocaml>
<contextfreebeer> so it pays to be careful while implementing it, use as many assertions as possible etc.
<discocaml>
<contextfreebeer> I asserted the register allocator invariants that I took from the textbook so that's why the bug wasn't really in the core algorithm
<discocaml>
<regularspatula> That’s interesting
<discocaml>
<contextfreebeer> my biggest problem ended up being that I was coloring precolored nodes in the interference graph, i.e. some nodes are already colored at the start which are the registers that the register allocator should leave alone like RSP etc., that led to the stack pointer sometimes being used as a gpr which of course is a quick way to segfault city
<discocaml>
<contextfreebeer> and another problem I experienced which took a very long time to track down was how to handle the fancy addressing modes in x86 when it comes to liveness
<discocaml>
<contextfreebeer> partly due to how the book recommends handling the code generation, it's designed for RISC mainly I think, so the dst, src temporaries paradigm breaks down a little when you have addressing modes
<discocaml>
<contextfreebeer> at the very start I naively just assumed that for example `mov [rdi], rax` that rdi wouldn't be considered a destination register, because rdi isn't overwritten
<discocaml>
<contextfreebeer> I forget exactly the details but ignoring that kind of stuff leads to wrong liveness information
<discocaml>
<contextfreebeer> would have code generated that looks like `mov rbx, 0; mov rbx, [rbx]` and stuff that makes no sense
<discocaml>
<contextfreebeer> maddening trying to puzzle that out
<discocaml>
<contextfreebeer> so I found it a little difficult personally
<discocaml>
<functionalprogramming> ahhh
torretto_ has quit [Ping timeout: 260 seconds]
torretto has joined #ocaml
tri has joined #ocaml
tri has quit [Ping timeout: 256 seconds]
tri has joined #ocaml
<dh`>
you want to dump out the pre-allocator IR with lifetime annotations and then with the register allocations on top of it
<dh`>
then pore over that for whether it's wrong
<dh`>
by the time you get to the output code the results will be, as you note, incomprehensible
<discocaml>
<contextfreebeer> I also did that once I suspected the liveness information was wrong, I was focusing entirely on the regalloc and code generator for possible bugs at first. dumping the annotated IR was definitely very helpful. still a lot of information, and even if it's wrong you still need to figure out why
pi3ce has joined #ocaml
<discocaml>
<contextfreebeer> reading those logs was how I discovered that I was double-coloring actually, probably the only way you can really figure that out except spotting it in the code
<discocaml>
<contextfreebeer> anyway, I certainly didn't go about things in the most efficient way or anything like that, the backend has a lot of moving parts and is pretty overwhelming so when things weren't working my first idea was just to read assembly output and hop into gdb when necessary, to try to narrow things down. maybe that's not the best idea but I was still able to identify some issues after a while of exploring, but the remaining issues were so obsc
<discocaml>
<contextfreebeer> dumping the interference graph to DOT was especially helpful
mbuf has joined #ocaml
<dh`>
yeah
<dh`>
probably the single most important thing I've learned writing compilers is that (a) every IR needs a dumper and (b) dumping is not the same as prettyprinting
_whitelogger has joined #ocaml
<companion_cube>
How so?
tri has quit [Remote host closed the connection]
_whitelogger has joined #ocaml
tri has joined #ocaml
tri has quit [Ping timeout: 260 seconds]
Serpent7776 has joined #ocaml
Tuplanolla has joined #ocaml
waleee has joined #ocaml
waleee has quit [Ping timeout: 240 seconds]
olle has joined #ocaml
kaptch has joined #ocaml
kaptch has quit [Client Quit]
bartholin has joined #ocaml
chiselfuse has quit [Remote host closed the connection]
chiselfuse has joined #ocaml
kaptch has joined #ocaml
wingsorc has quit [Ping timeout: 268 seconds]
mima has joined #ocaml
jabuxas has joined #ocaml
sroso has quit [Quit: Leaving :)]
Anarchos has joined #ocaml
jabuxas has quit [Ping timeout: 268 seconds]
tri has joined #ocaml
tri has quit [Ping timeout: 240 seconds]
bartholin has quit [Quit: Leaving]
kaptch has quit [Quit: Lost terminal]
tri has joined #ocaml
ocra8 has quit [Quit: WeeChat 4.2.2]
ocra8 has joined #ocaml
olle has quit [Ping timeout: 268 seconds]
tri has quit [Remote host closed the connection]
ocra8 has quit [Ping timeout: 252 seconds]
ocra8 has joined #ocaml
bartholin has joined #ocaml
ocra8 has quit [Quit: WeeChat 4.2.2]
ocra8 has joined #ocaml
ocra8 has quit [Quit: WeeChat 4.2.2]
gzar has joined #ocaml
gzar has quit [Client Quit]
gzar has joined #ocaml
<discocaml>
<functionalprogramming> ahh good ifra
<discocaml>
<functionalprogramming> idea
waleee has joined #ocaml
anadon has joined #ocaml
<anadon>
Hello all. Newbie here. Looking for the List equivalent of Map.Make.map. I have a list of strings that I made a custom trim function for in order to remove all leading and trailing ":" and I want to apply that over all the values.
<discocaml>
<hockletock> it's called List.map
<anadon>
Can I have looked over that obvious of documentation.. I thought I brought up that page.
<anadon>
Yup. There it is. Thanks!
mbuf has quit [Remote host closed the connection]
ocra8 has joined #ocaml
Anarchos has quit [Ping timeout: 256 seconds]
<discocaml>
<yawaramin> if you have the standard opam-based installation you can also use the module man pages, eg `man List`, then search for `val map`
tri_ has joined #ocaml
tri_ has quit [Ping timeout: 255 seconds]
ocra8 has quit [Quit: WeeChat 4.2.2]
<discocaml>
<Kali> wait, you can do that?
<discocaml>
<Kali> that's so cool i never knew that
<discocaml>
<Kali> it works
<discocaml>
<deepspacejohn> the online manual has a search feature for the stdlib too, FWIW
micro has quit [Ping timeout: 272 seconds]
<discocaml>
<contextfreebeer> mind = blown
ocra8 has joined #ocaml
micro has joined #ocaml
tri has joined #ocaml
tri has quit [Ping timeout: 240 seconds]
jabuxas has joined #ocaml
rwmjones has quit [Ping timeout: 272 seconds]
tri has joined #ocaml
tri has quit [Ping timeout: 255 seconds]
ocra8 has quit [Quit: WeeChat 4.2.2]
jabuxas has quit [Ping timeout: 255 seconds]
ocra8 has joined #ocaml
jabuxas has joined #ocaml
jabuxas has quit [Ping timeout: 268 seconds]
rwmjones has joined #ocaml
ocra8 has quit [Quit: WeeChat 4.2.2]
Serpent7776 has quit [Ping timeout: 256 seconds]
wingsorc has joined #ocaml
bartholin has quit [Quit: Leaving]
ocra8 has joined #ocaml
torretto has quit [Remote host closed the connection]