companion_cube changed the topic of #ocaml to: Discussion about the OCaml programming language | http://www.ocaml.org | OCaml 5.2.0 released: https://ocaml.org/releases/5.2.0 | Try OCaml in your browser: https://try.ocamlpro.com | Public channel logs at https://libera.irclog.whitequark.org/ocaml/
romildo has quit [Quit: Leaving]
waleee has quit [Ping timeout: 248 seconds]
tomku has quit [Ping timeout: 248 seconds]
tomku has joined #ocaml
tomku has quit [Ping timeout: 252 seconds]
tomku has joined #ocaml
mbuf has joined #ocaml
bartholin has joined #ocaml
mbuf has quit [Ping timeout: 252 seconds]
toastal has joined #ocaml
mbuf has joined #ocaml
Serpent7776 has joined #ocaml
tomku has quit [Ping timeout: 276 seconds]
tomku has joined #ocaml
toastal has left #ocaml [Disconnected: Hibernating too long]
kuruczgy has quit [Ping timeout: 245 seconds]
kuruczgy has joined #ocaml
Serpent7776 has quit [Ping timeout: 255 seconds]
toastal has joined #ocaml
<discocaml> <gooby_clown> I wish as well, it feels so wasteful having to recompile the exact same kernel, LSP, utop etc for every project
<discocaml> <gooby_clown> I try to use the global switch when possible but it gets messy with dependencies
bibi_ has quit [Quit: Konversation terminated!]
bibi_ has joined #ocaml
Tuplanolla has joined #ocaml
toastal has left #ocaml [Disconnected: Hibernating too long]
toastal has joined #ocaml
Serpent7776 has joined #ocaml
waleee has joined #ocaml
patrick_ is now known as patrick
patrick is now known as Guest2848
Guest2848 has quit [Killed (iridium.libera.chat (Nickname regained by services))]
patrick_ has joined #ocaml
patrick_ is now known as patrick
patrick is now known as Guest4981
Guest4981 has quit [Killed (iridium.libera.chat (Nickname regained by services))]
patrick_ has joined #ocaml
Anarchos has joined #ocaml
toastal has quit [Ping timeout: 248 seconds]
waleee has quit [Ping timeout: 252 seconds]
tomku has quit [Ping timeout: 248 seconds]
tomku has joined #ocaml
tomku has quit [Ping timeout: 248 seconds]
tomku has joined #ocaml
<discocaml> <yawaramin> i sometimes wonder about this. i guess when they were designing opam, they decided to lock down a 'switch' conceptually as a single compiler with a set of packages with a single version of each. i assume they didn't consider alternatives
<companion_cube> Well the compiler isn't relocatable
<companion_cube> And ocamlfind assumes a single version for each package
<companion_cube> (and it assumes it knows the path to ocaml and the stdlib, too, I think โ€” for things like the + includes)
<discocaml> <yawaramin> yeah i mean alternatives that work more like Nix or Esy
<discocaml> <yawaramin> or even forgetting about Esy for a minute, Nix can still allow using a single compiler in a single location with multiple versions of the same package, as long as they are in different projects
<companion_cube> Does nix do the same kind of horrible tricks as esy?
<discocaml> <yawaramin> from what i understand, no. it just uses symlinks to make findlib think there's only a single version per packake per compiler, when in reality there could be several
<discocaml> <ada2k> i still need to learn nix. it looks very interesting but very complex
<discocaml> <ada2k> i get away with just using a rolling release and global installs of everything
<discocaml> <yawaramin> i am trying to get into it. easing myself in with https://devenv.sh/
mbuf has quit [Quit: Leaving]
<Anarchos> According to ocaml manual " if the token is left-associative, then the parser will reduce; if the token is right-associative, then the parser will shift. I". I would have said the inverse behaviour. What do you think ?
<discocaml> <ada2k> microsoft also now has their own dev containers impl, also called devenv... it's all too confusing
<discocaml> <ada2k> i have enough in my head just dealing with docker and containerd
<discocaml> <yawaramin> yeah the name is not great unique. but anyway Nix users in OCaml seem to be uniformly happy with it
<dh`> anarchos: it is correct (under reasonable assumptions about context)
<discocaml> <ada2k> yeah, it looks quite nice
<discocaml> <ada2k> normally i try to just stick to one global switch. right now i have two, one on 5.2 and one on 5.1.1+tsan
<discocaml> <ada2k> almost all duplicate packages
<dh`> anarchos: I generally recommend against using those associativity declarations and stuff like them, because in order to understand what they _really_ do you have to understand exactly how the grammar turns into state tables
<discocaml> <yawaramin> same, i more or less always use a global switch per compiler version
<dh`> which is (a) not reasonable for ordinary users of parsing tools and (b) easy to get wrong even for people who supposedly understand
<discocaml> <yawaramin> to be clear Nix wouldn't save the duplication between 5.2, 5.1.1+tsan, etc.
<Anarchos> dh` ok i got it. I am struggling with grammars cause i am trying to do the tiger compiler from 'modern compiler in ML'
aljazmc has joined #ocaml
<dh`> anarchos: anyway the idea is... suppose your grammar is e ::= e * e | e + e | v
<dh`> that is hopelessly ambiguous because there are multiple parses of things like 3 + 6 * 5
<dh`> as well as 3 + 3 + 3
<dh`> the idea with the associativity and precedence declarations is to tell the parser generator which of those parses you want, instead of writing the grammar to be unambiguous
<Anarchos> dh` yes, reduce first just reduce as 3+3 + 3 hence (3+3)+3 hence left-assoc
<dh`> so e.g. if you have 3 + 3 + 3 and you're looking at the second +, you reduce if you want to be left-associative, but shift if you want to be right-associative
<dh`> that is, [3 + 3] + 3 -> [e] + 3 (then [e + 3] then [e]) vs. [3 + 3] + 3 -> [3 + 3 + 3] then [3 + e] then [e]
<dh`> where [] marks the stuff that's been shifted
<dh`> and if you have [3 + 3] * 3 you reduce if + is more tightly binding than *, and shift if it's not
<dh`> all of which is all very well but is only true in _this specific state_
<dh`> and furthermore the usual implementation of these things attaches the precedence/associativity to the token, not the use of the token
<dh`> so if you have * or + elsewhere in your grammar, which you usually do in real grammars (vs. toy examples)
<dh`> you can get unexpected effects
<dh`> it is in general much better to write out the precedence and associativity
<dh`> even though it can be verbose and tedious sometimes
<Anarchos> dh` i know but it is such a pain to mix if-then-else and arithmetic operators
<dh`> it doesn't have to be
<Anarchos> dh` i am not skilled enough to rewrite a grammar without %left/right annottations
<dh`> sure you are, you've talked enough in here over the last few months that I can't buy that claim :-)
<dh`> the thing that gets annoying is let-bindings where the syntax isn't left/right symmetric
<dh`> that is, you customarily want 3 + let x = y in z + 3 to parse as 3 + (let x = y in (z + 3))
<dh`> writing that out is lengthy (especially if you have a lot of precedence layers)
<dh`> but, it's also a mess with the annotations
<dh`> basically what you do is, if you're starting from e ::= e + e | e * e | v
<dh`> expand e into layers, one for each precedence, so e2 ::= e + e, e1 := e * e, e0 := v
<dh`> then change the e's in the expansions to either the same layer or the next layer down depending on the associativity you want
<dh`> so e2 ::= e2 + e1, e1 := e1 * e0, e0 := v makes both + and * left-associative
<dh`> then the base case of each layer is the next layer down
<dh`> so e2 ::= e1 | e2 + e1, e1 := e0 | e1 * e0, e0 := v
<dh`> and if you had e ::= (e) in the original, that goes at the bottom and is a reference back to the top: e0 ::= v | (e2)
<dh`> the idea is that each layer collects all the subexpressions of that precedence within the subexpressions of the higher layer, which makes the lower layer strictly more tightly binding
<dh`> and at each point you always put in a reference to highest layer that's unambiguous
<dh`> so if you have e3 ::= e2 | e2 ? e* : e3, so your if-expression is right-associative like is typically expected, the thing I wrote as e* can be anything self-contained that can't be followed by :, which for the C grammar is the top level of expressions, not the current level
<dh`> and if your if expression is IF e THEN e ELSE e both the enclosed ones can normally be fully general
<Anarchos> dh` ok. Next trouble is how to choose names instead of e0,e1,e2...
torretto has quit [Ping timeout: 260 seconds]
<dh`> you can use "factor", "term", and other such names
<dh`> but there usually aren't enough of those
<dh`> ifexpr, addexpr, mulexpr, mulexpr, prefixexpr, etc usually work ok
torretto has joined #ocaml
<discocaml> <._null._> Wait why are you recommending against using precedence and associativity ? Associativity "just works", and precedence is also fine for most grammars from what I can tell
<dh`> because it doesn't
<dh`> with all those annotations they're not transformations on the input grammar
<dh`> they're annotations on the underlying state machine
<dh`> so unless you understand exactly how the state machine is derived from the grammar, you can get burned
<dh`> I would be fine with annotations that expanded the grammar as I showed above
<dh`> especially if your tool will show you the expanded grammar if a question arises
<dh`> but that's not how yacc works
<discocaml> <._null._> How could you get burned ? I can't see where it could be unintuitive
<dh`> I can't give you a simple example offhand but I've seen (and debugged) any number of grammars written by stuffing in precedence annotations until yacc stopped complaining and the results seemed to work
<dh`> it doesn't fail on simple examples that are entirely operator grammars
<dh`> because that's the intended context
<dh`> ... or at least, not simple ones
<discocaml> <._null._> My expericence is having written a parser for a Go-like grammar and an OCaml-like grammar, and I don't remember precedence being unintuitive. That was quite some time ago though
<dh`> when you get burned, you get burned by getting unexpected results from cases you didn't anticipate and therefore didn't test
<discocaml> <._null._> You mean, after having solved the conflicts ยต?
<dh`> yes
<dh`> you fix a bunch of conflicts and then you shut up the rest by applying precedence annotations
<dh`> and sometimes the precedence annotations do not resolve the conflict the way you intended, or resolve additional conflicts you didn't expect
<dh`> anyway, my recommendation is always to write it out because it's not generally a large burden and then everything's explicit and it's easier to maintain too
<dh`> for anyone who's building parsing tools, my recommendation is to provide better annotations :-)
<discocaml> <._null._> I went back to the parser that I wrote, and I pretty much only used precedence annotations on the subset of tokens where it made sense. I guess expanding the grammar in case of unexpected conflicts works, but not using precedence in the simple subset is needlessly restrictive
aljazmc has quit [Quit: Leaving]
<dh`> I'm not convinced, for simple cases it's not a burden and for complex cases you can't be sure it's doing what you intended
<dh`> er
<dh`> for simple cases expanding it isn't a burden and for complex cases you can't be sure the annotations are doing what you intended
<dh`> anyway, it's only my recommendation, you're absolutely welcome to disagree :-)
<discocaml> <._null._> Not a burden ? Your grammar is quite more complicated after expansion
<dh`> what, because there are three kinds of expression instead of one?
<discocaml> <._null._> If you only have two levels of precedence, 3 kinds. I'm talking of a real grammar with more levels of precedence
<dh`> all it actually adds is the intermediate layer nonterminals and the default productions from one layer to the next
<dh`> and it's an unambiguous LR(1) grammar, which the one with annotations isn't
<dh`> (remember, the annotations don't do this expansion. the expansion is mechanical enough that it's reasonable to have your tool do it for you, but I've not seen a parser generator that does so)
<discocaml> <._null._> I get that it's boilerplate-level of complex, but it still clutters everything
<dh`> sure
<discocaml> <._null._> Expanding the grammar makes for a bigger state machine for no other reason that potentially better explanations
<dh`> no, it gives you the same state machine
<discocaml> <._null._> Wait it does ?
<dh`> the precedence annotations are applied during the state machine construction
<dh`> at least in traditional yacc
<dh`> if you have done all of it exactly as intended, you get the same state machine out
<dh`> if you get a different state machine, one of the formulations has a bug :-)
<dh`> well.
<discocaml> <._null._> Annotations can't make the state machine larger, the question is if expanding the grammar gives the same state machine
<dh`> it may be equivalent rather than identical, but it won't be _larger_
<dh`> you have the same states and the same transitions...
<dh`> and if you don't, the annotation version is wrong somewhere
<discocaml> <._null._> The reduce mul_expr->add_expr doesn't exist in the single expression version, does it ?
<dh`> hmm
<dh`> I suppose that's a point
<dh`> yes, if your parser generator doesn't optimize such transitions out it'll generate extra intermediate states
<dh`> or rather, intermediate configurations, there's no extra _states_
<dh`> this is still of no significance though
tomku has quit [Ping timeout: 276 seconds]
tomku has joined #ocaml
waleee has joined #ocaml
Anarchos has quit [Quit: Vision[]: i've been blurred!]
tomku has quit [Ping timeout: 276 seconds]
Serpent7776 has quit [Ping timeout: 248 seconds]
bartholin has quit [Quit: Leaving]
<discocaml> <joris0588> hi ! i don't have anything interesting to say, i just was following some past link and end up stumbling on that https://discuss.ocaml.org/t/ann-jsonschema2atd-generate-an-atd-file-from-a-json-schema-openapi-document/14718/4
<discocaml> <joris0588> i end up being the "manager" who asked for this work to be done
<discocaml> <joris0588> > It is a sign of a healthy ecosystem that we had 3 OpenAPI related posts this week
<discocaml> <joris0588> i take it as a sign of i am not interacting with the community enough and didn't come on this discord or forum for like 8 months. so just coming to say hi
<companion_cube> Because the web people are looking into it?
<discocaml> <joris0588> i am not sure i understand what you just said ๐Ÿ™‚
<discocaml> <joris0588> oh i am the web people ? right.
<companion_cube> No, I mean the openAPI interest
<discocaml> <joris0588> oh, i don't know. I guess it is because, openAi is becoming a strong standard useful for a lot of stuffs, due to adoption
<discocaml> <joris0588> the reason we developed this was to populate grafana dashboards. Grafana stores those dashboard as json, and we wanted to have dashboard as code, and they have an openapi schema, so we wrote that
<discocaml> <joris0588> but yes, after that it got immediate traction in the company, because, it ends up a lot of api use open api and in the end it ended up being used by like 3 teams
<discocaml> <joris0588> i guess openapi/jsonschema is THE standard right now in term of data schema.
<discocaml> <joris0588> but i mean, it can be a sign of a healthy ecosystem. It can also be a sign that efforts are waste with independant implementations
<discocaml> <joris0588> which one it is is anyone guess
<companion_cube> It's ocaml, of course there'll be fragmentation
<discocaml> <joris0588> ah ๐Ÿ˜„ you think javascript or python is better ?nah yes of course there will be fragementation
<discocaml> <joris0588> even in a single company that is supposed to be optimised you will have fragementation for sure
<discocaml> <joris0588> but yeah i just came to say hi, long overdue ๐Ÿ™‚
<companion_cube> ๐Ÿ‘‹
<companion_cube> Idk, I wish protobuf had won
<discocaml> <joris0588> i have two opinions about that
<companion_cube> I'll say that I don't think protobuf is great, and it's not the most efficient, but it's still way better than openAPI
<discocaml> <joris0588> ofc, you are a very idealistic person on data format. And protobuf is a wire format with variants and size encoded variable lenght encoding. also it sucks, but it has good properties that are good enough
<discocaml> <joris0588> ahah
<discocaml> <joris0588> yeah
<discocaml> <joris0588> the other opinion is that protobuf actually did win in a way. it is a tie
<companion_cube> Well it's binary, that's a start
<companion_cube> Indeed
<discocaml> <joris0588> protobuf is grpc, k8s... it is just not dominating but prominent
<discocaml> <ada2k> openapi can describe json, can it not
<companion_cube> You probably missed it but I have a custom data format now at work for some specific things ๐Ÿ˜‚
<discocaml> <joris0588> i indeed missed but ofc i will have a look at your most recent crazy idea
<companion_cube> Heh
<discocaml> <joris0588> @ada2k yes. openapi is just an extension of json schema. it is in fact json
<discocaml> <ada2k> having a specification lang be decoupled from transport is imo a good thing, but idk enough about openapi to know if it can handle that
<companion_cube> It's a fun little self describing format, like cbor :)
<companion_cube> (and for protobuf I like it with twirp, which is fairly simple)
<discocaml> <ada2k> protobuf winning wouldve been a nightmare for web apps
<discocaml> <joris0588> @companion_cube i missed the oportunity to think about those things. my current job is really to think about the big picture. Thinking about the big picture means you need to know those details, but yet don't have time to think about it that much
<companion_cube> @ada2k why?
<companion_cube> Heh idk if it's just "details" but anyway
<companion_cube> You CTO yet joris? :p
<discocaml> <joris0588> nah, i am SRE lead. hard enough
<discocaml> <joris0588> maybe harder
<discocaml> <joris0588> to me the issue with protobuf, is that, it is not readable
<discocaml> <joris0588> that is why json wins
<discocaml> <joris0588> as a dev you don't care if it is readable
<discocaml> <ada2k> companion_cube: replace the existing methods for optimised json in the browser with protobuf equivalants, write slow javascript polyfills for said methods, implement a protobuf viewer in devtools, deal with the bugs resulting from adding binary object parsing in c++/rust user-accessible from javascript
<discocaml> <joris0588> but sometimes it matters
<discocaml> <ada2k> (i don't know if inspectability without a definition is even a thing in protobuf - imagine if user <x> trying to see what data is being sent to a malicious data collection/advertising server)
<companion_cube> I mean protobuf is kind of easier to parse than json
<companion_cube> But also my ideal web world is closer than htmx than react
<companion_cube> So I don't have much sympathy for big json APIs on the front-end
<companion_cube> Do note that you can use json as a wire encoding for protobuf
<companion_cube> I use that for debugging
<discocaml> <joris0588> the thing is, and this is really a "you are not google" moment. I agree that, protobuf is just superior
<discocaml> <ada2k> my ideal web world is one in which the browser isn't encouraging applications to send hard to analyse binary formats
<discocaml> <ada2k> companion_cube: ah, i didn't know that
<discocaml> <ada2k> in that case though, what is the advantage over openapi ๐Ÿ˜ญ
<discocaml> <ada2k> that was supposed to be a wink
<discocaml> <joris0588> but in the, "what if you are google moment", what if "this is 22h, SRE team got paged on an production incident, and service X is down. you have logs, and dump of requests, debug it"
<companion_cube> That you can switch to the binary format for better perf? :)
<companion_cube> And you still get a better idl
<companion_cube> Cause openAPI is.... :/ :/
<discocaml> <joris0588> i guess, it depends what your are caring about. peformance, or accessibilty
<companion_cube> Joris: you log the requests' bodies? Damn
<discocaml> <joris0588> it is a tradeoff. And the answer is, you are not google, well yes use protobuf
<discocaml> <joris0588> @CCBot well of course
<companion_cube> But there are tools to decode a protobuf following a schema
<discocaml> <joris0588> yes. that is the next stage
<companion_cube> Wdym "you are not google"? They use protobuf too no ?
<discocaml> <ada2k> yeha, but json needs no schema
<discocaml> <ada2k> you can take a glance at a json file and see what it does
<discocaml> <joris0588> that is when you are both google and not lazy, and you are google so you have tooling. so you use protobuf
<discocaml> <joris0588> but 100% convinced that this is why json is winning
<discocaml> <joris0588> it is just a middle ground
<companion_cube> It's like python and the likes
<discocaml> <ada2k> it's horses for courses. if instant inspection is a priority use json - and every web API should encourage and enforce, as much as it can, instant inspectability because web pages are guests
<discocaml> <joris0588> yep
<companion_cube> Easier the first 2h, worse after, but it still wins
<discocaml> <joris0588> yep
<companion_cube> Such is life I guess
<discocaml> <ada2k> (web api as in one passed down to javascript from the browser)
<discocaml> <joris0588> yep (:D)
<companion_cube> Now I just don't care and I do my own thing
<discocaml> <ada2k> for server-to-server or server-to-carefully written client protobuf (and cap'n'proto) are huge improvements over json
<companion_cube> And my own data format to replace Marshall ๐Ÿค”
<discocaml> <joris0588> yep (:D :D)
<discocaml> <joris0588> sorry @ada2k for this meta conversation
<discocaml> <ada2k> haha i muscled in on the protobuf talk in the first place
ggb_ has joined #ocaml
henrytill_ has joined #ocaml
ursa-major_ has joined #ocaml
<discocaml> <joris0588> but honnestly i agree with your points
ggb has quit [Ping timeout: 258 seconds]
anpad has quit [Quit: ZNC 1.8.2 - https://znc.in]
end has quit [Quit: end]
emp has quit [Ping timeout: 258 seconds]
ursa-major has quit [Read error: Connection reset by peer]
anpad has joined #ocaml
gentauro has quit [Ping timeout: 258 seconds]
ggb_ is now known as ggb
henrytill_ is now known as henrytill
henrytill has quit [Read error: Connection reset by peer]
gentauro has joined #ocaml
noddy has quit [Ping timeout: 258 seconds]
prgbln has quit [Ping timeout: 258 seconds]
micro has quit [Ping timeout: 258 seconds]
noddy has joined #ocaml
emp has joined #ocaml
prgbln has joined #ocaml
micro has joined #ocaml
<discocaml> <ada2k> also taking my half-point about json transports back, i can see why that would be quite useful if you need the same server to, say, support a web ui, a very fast cli and a library used by other internal applications
<discocaml> <joris0588> my opinion, somewhat related, is that, when you build a big system, what you care about first is uniformity$
<discocaml> <joris0588> you care about minimizing difference, and reusing tech
ursa-major_ is now known as ursa-major
<discocaml> <joris0588> and at some scale, the fact that some thing is better matters a lot less than, just having the burden to use and build tooling for one format$
<discocaml> <joris0588> at some point this starts to matter, a lot.
<discocaml> <ada2k> i see there are some tools to interop between openapi and protobuf IDL on github
<discocaml> <ada2k> that seems like a better approach to me since theoretically you can then transport that over anything with an openapi convertor, but i don't know how well that works in practice
<discocaml> <ada2k> i'm sure there are too many little incompatibilies, especially since many of the competing binary transports you might want to use are direct memory chunks like capnproto
<discocaml> <joris0588> look i am probably not the best person to debate data format right now. My take is you are not google. so when you are not google you ask yourself what is the best data wire format.
<discocaml> <joris0588> but then when you are tyou are trying to be google, it is a good question to ask. and you answer will be
end has joined #ocaml
<discocaml> <joris0588> just middle ground
<discocaml> <ada2k> this was the point i got to with go
<discocaml> <joris0588> but then when you are tying are trying to be google, it is a good question to ask. and you answer will be
<discocaml> <ada2k> most of it's design decisions make sense if you are google and are very annoying if you are not
<discocaml> <joris0588> yeah well that is the point google tried to do with go
<discocaml> <joris0588> but my personal opinion is that it is farrrrrrr toooo strong on the part of trying to be google
<discocaml> <joris0588> it just sucks
<discocaml> <joris0588> it is not on the right scale of the balance
<discocaml> <ada2k> i wrote a project in go, loved the currency and then the honeymoon period crashed hugely
<discocaml> <joris0588> yeah the concurrency is good
<discocaml> <joris0588> but now we have ocaml 5
<discocaml> <joris0588> so....
<discocaml> <ada2k> it's a great runtime but the language itself is C fetishism
<discocaml> <joris0588> it pushing we need to use json and simply things to an extreme
<discocaml> <joris0588> yeah
<discocaml> <joris0588> go is like, we don't trust our engineers to not write good code
<discocaml> <joris0588> so we made go
<companion_cube> Go for bencode :p
<companion_cube> Even simpler
<discocaml> <ada2k> go feels even worse - it doesn't trust engineers to read it either
<discocaml> <joris0588> and at some scale it is probably a good thing not trust your engineer to write good code
<discocaml> <joris0588> but if you thing go is the solution, you lost really big
<discocaml> <joris0588> like you need to make your engineers better
<discocaml> <ada2k> which is funny since reading other people's code is a problem i don't encounter much even in "complex" languages like ocaml and rust
<discocaml> <joris0588> not write go
<discocaml> <ada2k> it's an issue i hear more complaints about in java, c++ and c which means go says more about google's previous tooling and engineers
<discocaml> <joris0588> but i really understand now how someone could thing go is a solution
<discocaml> <ada2k> it all just comes together to make a language that missed about 40 years of development
<discocaml> <joris0588> it is
<discocaml> <joris0588> imo so just is ocaml. but better
<discocaml> <joris0588> > which is funny since reading other people's code is a problem i don't encounter much even in "complex" languages like ocaml and rust
<discocaml> <joris0588> this, i can tell you it is a real problem
<companion_cube> The perfect application language still doesn't exist
<companion_cube> It's a bit sad
<discocaml> <joris0588> and i hope you trust me, because i have been a guy who wrote code, good code bad code, smart code
<companion_cube> (I have my own theory of what it'd be like but it's not like I'd write a compiler)
<discocaml> <joris0588> but now i am an SRE lead of of company of like 180 people
<discocaml> <ada2k> maybe it's just the codebases i've been reading. recently a lot of dinosaure's stuff and the ocaml stdlib. which are both better than average code haha
<discocaml> <joris0588> and sometimes, it goes to a really bad situation. and good code is code is code i can understand. in 5 minuties. like now now now now. like NOW
<discocaml> <joris0588> and this is really important
<discocaml> <joris0588> that is why google build go
<discocaml> <joris0588> but again you are not google
<discocaml> <joris0588> also, yes i agree dinosaure ocaml is great
<companion_cube> ahrefs is 180 people? Damn !
<discocaml> <joris0588> yeah damn