<discocaml>
<barconstruction> Its not too late to get into futhark
<discocaml>
<contificate> its main developer (Troels) is in the FP server
<discocaml>
<barconstruction> I feel like I read something crazy about using GPU to speed up compilation
<discocaml>
<contificate> yeah, I've actually read a few papers about pattern matching various things to lower to GPU primitives
<discocaml>
<contificate> I was interested in it at a time
<discocaml>
<contificate> back when I thought I'd need to bite the bullet and write C++ for a career
<discocaml>
<contificate> don't think I'd consider that now
<discocaml>
<barconstruction> I just applied for a C++ job
<discocaml>
<contificate> my condolences
<discocaml>
<barconstruction> I think they're looking for a PhD tho
<discocaml>
<barconstruction> It doesn't hurt to apply
<discocaml>
<barconstruction> Contificate you should check it out
<discocaml>
<barconstruction> Roblox is hiring a senior compiler engineer
<discocaml>
<barconstruction> They are offering like $300k
<discocaml>
<barconstruction> Seeking 5-10 years experience in compiler design and proficiency in C++
<discocaml>
<barconstruction> Its the compiler for their in game mini game scripting language luau
<discocaml>
<contificate> adorable
<discocaml>
<barconstruction> Which I assume is a dialect of lua
<discocaml>
<contificate> I find that, with jobs, it's neat if you _have an in_
<discocaml>
<contificate> like take some time out, look at their language, modify it or compile some subset of it
<discocaml>
<barconstruction> I should try that.
<discocaml>
<contificate> as a result, I actually really like take home projects
<discocaml>
<contificate> but other people hate this because they're applying to `n` jobs, where `n` is too much to juggle
<discocaml>
<contificate> but, for my first compiler-related job, I got given a take home task and absolutely sweated it
<discocaml>
<contificate> got the job
<discocaml>
<contificate> didn't like the job, alas, and left ater 3-4 months
<discocaml>
<contificate> didn't like the job, alas, and left after 3-4 months
<discocaml>
<contificate> but that's life
<discocaml>
<barconstruction> Greener pastures
<discocaml>
<contificate> applied, on a whim at 4am for an OCaml job, got it, lasted a year, got laid off
<discocaml>
<contificate> good while it lasts
<discocaml>
<barconstruction> I'm going to have a hard time convincing people to take my playing around with Jupyter notebooks in academia as serious software engineering experience
<discocaml>
<barconstruction> I was unsuccessful in convincing the whole bioinformatics research community to switch from python packages to OCaml
<discocaml>
<contificate> I don't even know what I want any more
<discocaml>
<contificate> would be nice to work on compilers, would be nice to work with OCaml, etc.
<discocaml>
<contificate> not a very workable set
<companion_cube>
Janestreet on the compiler team? :)
<discocaml>
<contificate> I'm sure they've got enough Oxbridge grads thinking the same thing
<discocaml>
<regularspatula> Fighting the good fight
DerTeufel has joined #ocaml
<discocaml>
<regularspatula> Oh I forgot the irc bridge doesn’t do replies. That was to bar construction
<discocaml>
<tornato> can someone explain delimited continuations to me lol
<discocaml>
<tornato> im really lost
<discocaml>
<contificate> I would recommend doing it by way of using shift/reset in Scheme or something
<discocaml>
<contificate> OCaml has delimited continuations but they are limited by comparison and wrapped up in the effects feature
<discocaml>
<tornato> what i understand is you basically put a marker on the stack, you go do the rest of your computation, and then you can basically goto that point on the stack again with all your new heap allocations
<discocaml>
<contificate> that is accurate on a few points
<discocaml>
<contificate> you can imagine you have the two primitives: shift and reset
<discocaml>
<contificate> reset, as you say, marks the stack in some way
<discocaml>
<contificate> so the idea is that when you shift, you will move the frames on the stack (up to the reset marker)
<discocaml>
<contificate> to the heap
<discocaml>
<contificate> (I'm now now longer talking about OCaml's impl, before anyone pitches in)
<discocaml>
<contificate> when you shift, you pass a function which accepts an argument `k`, the continuation
<discocaml>
<contificate> invoking this `k` amounts to basically "replaying" the frames, e.g. you will relink/copy the frames back onto the stack
<discocaml>
<contificate> and jump through the return address of the shift
<discocaml>
<tornato> but when you shift don't you move the stack up to the reset marker back onto the heap? what is the single argument function doing here
<discocaml>
<contificate> no, shift is relocating frames away from the stack
<discocaml>
<contificate> think about it
<discocaml>
<contificate> shifting and not using `k`
<discocaml>
<contificate> would amount to what?
<discocaml>
<contificate> discarding the continuation
<discocaml>
<contificate> so it's basically how exceptions work, more or less
<discocaml>
<contificate> it's only when you invoke `k` that you would relink/copy those frames back
<discocaml>
<tornato> so `k` is the continuation
<discocaml>
<contificate> yes
<discocaml>
<contificate> delimited by the extent of the reset marker
<discocaml>
<contificate> in OCaml, as of version 5, the stack itself is a segmented stack (of growable fibers) - linked together by pointers
<discocaml>
<contificate> then, when you perform an effect, that's roughly equivalent to the shift
<discocaml>
<contificate> except you don't know which marker/handler handles your effect
<discocaml>
<contificate> so the implementation, as I understand it, tries them all until they don't raise a specific exception
Haudegen has joined #ocaml
<discocaml>
<contificate> e.g. if they try to handle the effect and get some exception, compiled in by the compiler, they will search up the handlers and keep trying
<discocaml>
<contificate> a bit like how exceptions work as well, I guess
<discocaml>
<tornato> So what `shift k` is capturing is essentially `(+ 1 n)`
<discocaml>
<contificate> exactly
<discocaml>
<contificate> the arithmetic examples are always poor as, in practice, they don't really preserve anything in the frames
<discocaml>
<contificate> but if you ignore that aspect of them, they're quite useful
<discocaml>
<tornato> yeah its hard for me to see the utility with that toy example lol
<discocaml>
<contificate> if you are familiar with A-Normal Form conversion, that is very useful to do here, if you want to understand how this is implemented
<discocaml>
<contificate> the idea is you can emulate a function `fun n -> 1 + n` in your case by jumping through the return address of the `shift` function with the return value register equal to the argument you supply to `k`
<discocaml>
<contificate> that's how it's done in a few direct implementations
<discocaml>
<tornato> ah
<discocaml>
<tornato> haven't heard of A-Normal Form
<discocaml>
<tornato> will google it later
<discocaml>
<contificate> I didn't understand shift/reset until I read a paper about how to implement them
<discocaml>
<contificate> directly
<discocaml>
<tornato> to be honest i probably don't *really* understand it right now
<discocaml>
<tornato> but I can gaslight my advisor into believing I do
<discocaml>
<contificate> you can play with delimcc which provides shift/reset
<discocaml>
<contificate> but it uses prompts which effectively act as witnesses for the answer type
<discocaml>
<contificate> to tie it all together through types
<discocaml>
<tornato> ah
<discocaml>
<contificate> so your example would be like:
<discocaml>
<contificate> ```ocaml
<discocaml>
<contificate> let p = new_prompt () in
<discocaml>
<contificate> push_prompt p (fun () -> 1 + shift (fun k -> 2 * k 3))
<discocaml>
<contificate> ```
<discocaml>
<contificate> so your example would be like:
<discocaml>
<contificate> ```ocaml
<discocaml>
<contificate> let p = new_prompt () in
<discocaml>
<contificate> push_prompt p (fun () -> 1 + shift p (fun k -> 2 * k 3))
<discocaml>
<contificate> ```
<discocaml>
<contificate> something like that
<discocaml>
<tornato> are prompts like labels
<discocaml>
<contificate> they are a bit like naming the reset markers
<discocaml>
<contificate> so you can refer to them in code
<discocaml>
<contificate> if you read the types, it makes sense why you'd want this
<discocaml>
<tornato> well, this is a function that takes a unit argument (essentially) and returns `1 + shift p (fun k -> 2 * k 3)`... so the return type would be `int` if I'm not mistaken
<discocaml>
<contificate> yeah, it evaluates to `8`
<discocaml>
<tornato> i guess ill have to read the type of new_prompt
<discocaml>
<contificate> `unit -> 'a prompt`
<discocaml>
<tornato> ah!
<discocaml>
<tornato> it generates a prompt for you
<discocaml>
<contificate> the resultant binding would have that `'a` is weak, e.g. `let p = new_prompt () in ..` with nothing else would be weak
<discocaml>
<contificate> this is a useful value restriction
<discocaml>
<tornato> ~~what does `'a` being weak mean`
<discocaml>
<tornato> ~~what does `'a` being weak mean~~
<discocaml>
<contificate> are you familiar with let-generalisation
<discocaml>
<contificate> the most confusing type in the whole shebang is `shift`'s: `val shift : 'a prompt -> (('b -> 'a) -> 'a) -> 'b`
<discocaml>
<tornato> nope
<discocaml>
<contificate> you just note that `('b -> 'a)` is what `k`'s type would be and the fully-applied shift would result in `'b` - so it makes sense, if you recall the idea to jump through the return address of shift to emulate the point of the shift as being a kind of places you can place a parameter and continue (delimited)
<discocaml>
<contificate> let-generalisation is what lets you use parametrically polymorphic functions in different contexts
<discocaml>
<contificate> ```ocaml
<discocaml>
<contificate> let id x = x
<discocaml>
<contificate> ```
<discocaml>
<contificate> you could then rewrite `(id "foo", id 4)` etc.
<discocaml>
<contificate> e.g. each usage site of `id` appears to have been freshened
<discocaml>
<tornato> oh so thats what that is
<discocaml>
<contificate> otherwise the first application would taint the definition site and you'd think it was only `string -> string`
<discocaml>
<contificate> it's a rather naive concept, let-generalisation
<discocaml>
<contificate> because it actually does amount to basically emulating a syntactic duplication of terms
<discocaml>
<contificate> without actually duplicating anything
<discocaml>
<contificate> in the context of the typechecker, that is
<discocaml>
<contificate> this naivety means it's generally unsound in the presence of side effects
<discocaml>
<contificate> so a so-called value restriction limits what bindings can be generalised, based on what is being bound - syntactically, in the case of SML (OCaml has a more relaxed version of the rules)
<discocaml>
<contificate> but anyway, not all that important, just necessary to make sure `p` gets tainted correctly
<discocaml>
<tornato> ah what does taint mean here, I've heard of taint analysis
<discocaml>
<contificate> I'm not using it in the context of taint analysis
<discocaml>
<contificate> I just mean you want a usage site to actually rewrite the binding site, you don't want `p` to be generic over many usage sites
<discocaml>
<tornato> so basically to do that wouldn't you generate a bunch of specific instantiations specialized for those use sites
<discocaml>
<contificate> in other words, it doesn't get generalised, unification will be gaining more information about `p`, not some instance of `p`
<discocaml>
<contificate> yeah exactly
<discocaml>
<contificate> this is a rather well timed question about delimited control, as I happen to be toying with another compiler for shift/reset
<discocaml>
<tornato> unification in FOL logic is where you take some tuple of variables and try to map them to a constant right, effectively deriving a list of substitutions. How does that relate to types
<discocaml>
<contificate> well, types are terms in the typechecker
<discocaml>
<contificate> so types with type variables can be unified with other type terms
<discocaml>
<contificate> imagine you had `fun x -> x + 5`, you'd start by assuming `x` has _some type_, e.g. typecheck `x + 5` in a context extended with a binding `x : 't0` where `'t0` is fresh
<discocaml>
<contificate> it's in the usage of `x` in the context of `x + 5` where you'd go.. alright.. unify `'t0` with `int` and conclude `_ : int -> int`
<discocaml>
<tornato> i see, so in that case we would substitute one instance, but with let generalizations we would find multiple possible substitutions and generate the required functions accordingly
<discocaml>
<contificate> let-generalisation works like this:
<discocaml>
<contificate> ```
<discocaml>
<contificate> let id x = x
<discocaml>
<contificate> ```
<discocaml>
<contificate> it'd infer this type as `'a -> 'a` but then it'd store it as quantified (generalised) in the type environment (e.g. `x : forall a. a-> a`), then each usage site would infer `id` as being instantiated with fresh type variables, in place of the quantified ones
<discocaml>
<contificate> which is a typechecking way of emulating syntactic duplication
<discocaml>
<contificate> as imagine you didn't generalise, then the first applied site of `id` would rewrite `'a` to whatever you used `id` with
<discocaml>
<contificate> but then you could just copy the function definition and make another `id` and use that one somewhere else, lexically distinct from the first one
<discocaml>
<contificate> so generalisation and instantiation are a typechecker way of emulating that
<discocaml>
<contificate> long story short, in a basic impl, `infer env (Var x) = instantiate (lookup env x)`
<discocaml>
<tornato> whats elim doing
<discocaml>
<contificate> I didn't want to add pattern matching to this toy, so it's acting as an eliminator/destructor
<discocaml>
<contificate> `elim` is a primitive that cases on `_ list`s
<discocaml>
<tornato> ah
<discocaml>
<contificate> it actually makes things kind of tedious for me
<discocaml>
<contificate> as it means all recursion is indirect
<discocaml>
<contificate> so I've implemented Tarjan's SCC algo to group "fix" groups together
<discocaml>
<contificate> so mutually-recursive function groups can share a closure
<discocaml>
<contificate> blah blah
<discocaml>
<contificate> "all" recursion => typical list structural recursion tasks*
<discocaml>
<tornato> this reminds me that I should probably take a gander at updating my stratification function in my datalog engine tomorrow
<discocaml>
<contificate> that's for negation, right
<discocaml>
<tornato> im using iterative relaxation rather than SCC + toposort
<discocaml>
<tornato> yeah
<discocaml>
<contificate> never got to negation myself - did a semi-naive bottom-up evaluator with a bunch of hash joins
<discocaml>
<tornato> detect no negative cycles
<discocaml>
<tornato> yadda yadda
<discocaml>
<contificate> got cooked by souffle's performance
<discocaml>
<contificate> gave up
<discocaml>
<contificate> lmao
<discocaml>
<tornato> im struggling with the semi-naive part
<discocaml>
<contificate> is it not just like the monotonic property
<discocaml>
<tornato> i intuitively understand its basically just the stuff from the last fixpoint thing
<discocaml>
<tornato> the new facts
<discocaml>
<contificate> yeah, you can limit what you consider each round
<discocaml>
<tornato> but it gets weird when you have `T(x, z) :- T(x, y), T(y, z)`
<discocaml>
<tornato> or non-linear recursion
<discocaml>
<contificate> what's wrong with that
<discocaml>
<tornato> well looking at souffle's generated output
<discocaml>
<tornato> `\delta T_{new} = (T \bowtie \delta T ) \cup ( \delta T \bowtie T) − T`
<discocaml>
<tornato> the first one is linear recursion
<discocaml>
<tornato> the second one is non-linear
<discocaml>
<tornato> I'm just wondering how I can define the join properly
<discocaml>
<contificate> but I mean the transitive closure rule is basically canonical datalog
<discocaml>
<tornato> yeah but when you do `T(x, z) :- T(x, y), T(y, z)` vs `T(x, z) :- edge(x, y), T(y, z)`
<discocaml>
<tornato> it blows up
<discocaml>
<tornato> cuz now you have to essentially compute multiple joins
<discocaml>
<tornato> basically im just stuck trying to figure out how I can implement it in code lol
<discocaml>
<contificate> is it a problem? it's just fixpoint loop, can do it with literal hash sets and nested loop joins
<discocaml>
<tornato> so would it be basically:
<discocaml>
<tornato>
<discocaml>
<tornato> 1. Find a rule with a fact that was derived in the last iteration.
<discocaml>
<tornato> 2. Compute the join of `delta predicate` with all the other predicates (full-db) for non-linear recursion, update current factset (delta).
<discocaml>
<tornato> 3. Compute the join of `delta predicate'` for each recursive predicate `p`, update current factset (delta).
<discocaml>
<tornato> 4. Update the full factset
<discocaml>
<tornato> so would it be basically:
<discocaml>
<tornato>
<discocaml>
<tornato> 1. Find a rule with a fact that was derived in the last iteration.
<discocaml>
<tornato> 2. Compute the join of `delta predicate` with all the other predicates (full-db) for non-linear recursion, update current factset (delta).
<discocaml>
<tornato> 3. Compute the join of `delta p'` for each recursive predicate `p`, update current factset (delta).
<discocaml>
<tornato> 4. Update the full factset
<discocaml>
<tornato> so would it be basically:
<discocaml>
<tornato>
<discocaml>
<tornato> 1. Find a rule with a fact that was derived in the last iteration.
<discocaml>
<tornato> 2. Compute the join of `delta predicate` with all the other predicates using the full db, update current factset (delta).
<discocaml>
<tornato> 3. Compute the join of `delta p'` for each recursive predicate `p`, update current factset (delta).
<discocaml>
<tornato> 4. Update the full factset
<discocaml>
<tornato> so would it be basically:
<discocaml>
<tornato>
<discocaml>
<tornato> 1. Find a rule with a fact that was derived in the last iteration.
<discocaml>
<tornato> 2. Compute the join of `delta predicate` with all the other predicates using the full db, update current factset (delta).
<discocaml>
<tornato> 3. Compute the join of `delta p` for each recursive predicate `p` with each other predicate, update current factset (delta).
<discocaml>
<tornato> 4. Update the full factset
<discocaml>
<tornato> so would it be basically:
<discocaml>
<tornato>
<discocaml>
<tornato> 1. Find a rule with a fact that was derived in the last iteration.
<discocaml>
<tornato> 2. Compute the join of `delta predicate` with all the other predicates using the full db, update current factset (delta).
<discocaml>
<tornato> 3. Compute the join of `delta p` for each recursive predicate `p` with each other predicate, update current factset (delta).
<discocaml>
<tornato> 4. Update the full factset by unioning delta_db
<discocaml>
<contificate> I can't remember, but it sounds about right
<discocaml>
<tornato> grok agrees but says my wording is garbage
<discocaml>
<tornato> ```
<discocaml>
<tornato> for each predicate P in EDB:
<discocaml>
<tornato> full_P = EDB_P
<discocaml>
<tornato> delta_P = EDB_Ps
<discocaml>
<tornato>
<discocaml>
<tornato> for each predicate P in IDB:
<discocaml>
<tornato> full_P = {}
<discocaml>
<tornato> delta_P = {}
<discocaml>
<tornato>
<discocaml>
<tornato>
<discocaml>
<tornato> while any delta_P is not empty:
<discocaml>
<tornato>
<discocaml>
<tornato> new_delta = {} for each predicate
<discocaml>
<tornato>
<discocaml>
<tornato> for each rule R: head :- body1, body2, ..., bodyN:
<discocaml>
<tornato> for each body predicate bodyI in R:
m5zs7k has quit [Read error: Connection reset by peer]
m5zs7k_ has joined #ocaml
myrkraverk has quit [Ping timeout: 252 seconds]
troydm has joined #ocaml
m5zs7k_ is now known as m5zs7k
<discocaml>
<microwave3607> will we one day have locality in the ocaml compiler like they have in janestreet?
<discocaml>
<microwave3607> that stuff looks cool
bartholin has joined #ocaml
myrkraverk has joined #ocaml
myrkraverk_ has quit [Ping timeout: 265 seconds]
euphores has quit [Quit: Leaving.]
euphores has joined #ocaml
domq has joined #ocaml
Tuplanolla has joined #ocaml
xgqt has quit [Quit: WeeChat 4.2.2]
xgqt has joined #ocaml
euphores has quit [Quit: Leaving.]
euphores has joined #ocaml
myrkraverk_ has joined #ocaml
myrkraverk has quit [Ping timeout: 248 seconds]
Serpent7776 has joined #ocaml
Serpent7776 has quit [Ping timeout: 252 seconds]
Haudegen has joined #ocaml
myrkraverk has joined #ocaml
myrkraverk_ has quit [Ping timeout: 252 seconds]
domq has quit [Ping timeout: 244 seconds]
domq has joined #ocaml
<companion_cube>
Maybe, I think Janestreet is interested in trying to upstream
Serpent7776 has joined #ocaml
domq has quit [Quit: domq]
tremon has joined #ocaml
myrkraverk_ has joined #ocaml
myrkraverk has quit [Ping timeout: 260 seconds]
DerTeufel has quit [Ping timeout: 265 seconds]
no-name has joined #ocaml
DerTeufel has joined #ocaml
myrkraverk has joined #ocaml
myrkraverk_ has quit [Ping timeout: 252 seconds]
myrkraverk has quit [Ping timeout: 272 seconds]
myrkraverk has joined #ocaml
wbooze has quit [Quit: Leaving]
wbooze has joined #ocaml
<discocaml>
<tornato> TFW your friend actually is #5 in the US on hackerrank and you thought he was bullshitting
<discocaml>
<tornato> Guess I need to step up
myrkraverk_ has joined #ocaml
myrkraverk has quit [Ping timeout: 245 seconds]
domq has joined #ocaml
ygrek has joined #ocaml
ygrek has quit [Remote host closed the connection]
wbooze has quit [Read error: Connection reset by peer]
Serpent7776 has quit [Ping timeout: 252 seconds]
halloy9898 has joined #ocaml
<discocaml>
<cod1r> im more looking toward unboxed types like single precision floats
wbooze has joined #ocaml
<discocaml>
<contificate> do you actively implement software
<discocaml>
<contificate> sorry, they*
<discocaml>
<contificate> I know a lot of competitive programmers
<discocaml>
<contificate> and I wouldn't employ them
<companion_cube>
Doesn't encourage robust or readable code
<companion_cube>
But they might still be good programmers anyway
<discocaml>
<contificate> I don't know about that
<discocaml>
<contificate> well, actually, I knew his hackerrank dude who was fun to talk to about random algorithms
<discocaml>
<contificate> but still, sofware engineering is about more than that
<discocaml>
<contificate> my experience of working in industry is 99% of people aren't interested in algorithms
<discocaml>
<contificate> as it's just not what software engineering is about
<discocaml>
<youngkhalid> Software involves more than solving some challenge algorithms (or even being good at DS). You can suck at algorithms and still be a beast. SWE is more about having the right ideas on how to implement things at the right time, searching for the right ressources, doing it in a clean way., choosing the right language, maintaining, good CI/CD pipeline, architecturing it right..etc
<discocaml>
<cod1r> depends on the person i think. ive seen competitive programmers operate differently depending on if they are competing or working
<discocaml>
<contificate> software is about introducing technical debt, not documenting it, and then becoming an irreplaceable principle engineer by way of knowing random lore you instated years prior
<discocaml>
<youngkhalid> Honestly, I've seen DSA teachers writing code from what they learned 20 years ago in Java, and the code sucks
<discocaml>
<contificate> that's a joke, but, as it happens, is also what I actually believe
<discocaml>
<cod1r> that's literally how the seniors at my company operate 🤣
<discocaml>
<cod1r> one guy who started the company just has random lore
<discocaml>
<youngkhalid> smart move
<discocaml>
<youngkhalid> xD
<discocaml>
<contificate> must be nice to be in that position
bartholin has quit [Quit: Leaving]
<discocaml>
<youngkhalid> or you could be that intern that goes through that dark codebase, understand it, fire that mf and become the next senior 😂
<discocaml>
<contificate> meant principal* must have been a Freudian slop that I was thinking about principles
<discocaml>
<youngkhalid> *nobody wants to do that*
<discocaml>
<contificate> slip* it keeps happening
<discocaml>
<youngkhalid> *nobody wants to go through that suffering*
<discocaml>
<contificate> well, that doesn't happen
<discocaml>
<contificate> because nobody internally sponsors efforts to improve things
<discocaml>
<contificate> it's not part of your job when you're applying bandaids to Jira tickets
<discocaml>
<contificate> and principals get very upset when you start speaking negatively about their pile of slop
<discocaml>
<contificate> I can't lie, I've looked at things and actualy thought "I can't believe they were paid to write this.. can't believe mortgages were paid off on the back of this"
<discocaml>
<contificate> I can't lie, I've looked at things and actually thought "I can't believe they were paid to write this.. can't believe mortgages were paid off on the back of this"
<discocaml>
<youngkhalid> you could even clean that codebase as an intern and still doesn't guarantee you to get a job
<discocaml>
<contificate> internships are an Americanism
<discocaml>
<youngkhalid> they'll be like *ok cool ! (we don't care, we just want stuff to work)*
<discocaml>
<contificate> I never did an internship, never felt the desire to
<discocaml>
<youngkhalid> Honestly somehow they teach you a lot more than you think at first (in my experience)
<discocaml>
<youngkhalid> It's more like thank to the environment they put you in than what they actually can teach you
<discocaml>
<youngkhalid> It's more like thanks to the environment they put you in than what they actually can teach you
<discocaml>
<youngkhalid> It's more like thanks to the environment they put you in, than what they actually can teach you
<discocaml>
<youngkhalid> Honestly somehow internships teach you a lot more than you think at first (in my experience)
<discocaml>
<youngkhalid> but people in the job world suck sometimes
myrkraverk has joined #ocaml
<discocaml>
<youngkhalid> they can kill your passion
<discocaml>
<youngkhalid> It's more like thanks to the environment they put you in, than what the people there can actually teach you
<discocaml>
<contificate> life does a good job of that already, I've found
myrkraverk_ has quit [Ping timeout: 244 seconds]
<discocaml>
<youngkhalid> it's also true that the more you know, the more you're (depressed/sad?)
<discocaml>
<youngkhalid> just my observation
<discocaml>
<contificate> I know nothing, I just believe, fully, that we are living through the worst possible timeline
<discocaml>
<youngkhalid> ahah I believe that but I also think it always can get worse buddy
<discocaml>
<youngkhalid> ahah I believe that but I also think it can always get worse buddy