├── ARCHIVE ├── esy.md └── reason-mobile.md ├── TODO.md ├── continuation-calculus.md ├── life.md ├── ocaml.md ├── programming.md └── theory.md /ARCHIVE/esy.md: -------------------------------------------------------------------------------- 1 | # esy 2 | 3 | This is archived, as I moved away from the esy ecosystem. 4 | 5 | ## Manifest 6 | 7 | esy supports two manifests, `package.json` like manifests and `package.opam` like manifests, you can even mix them. 8 | 9 | For applications you should use `package.json` or `esy.json`. 10 | 11 | ## Opam dependencies 12 | 13 | You can use opam dependencies by getting the package name on opam, and prefixing it as `@opam/package`, examples are `@opam/dune`, `@opam/reason`, `@opam/ppxlib`. 14 | 15 | ## Variables 16 | 17 | esy exposes a couple useful variables on the manifest as `#{package.variable}`. 18 | 19 | In the esy environment there is some alias to the current variables as `cur__variable`. 20 | 21 | You can always use `self` to talk about your own package as `#{self.install}`. 22 | 23 | ### Important variables 24 | 25 | | variable | on shell | manifest | contains | 26 | | ---------- | ------------------ | ----------------------- | --------------------------------------------- | 27 | | target_dir | `$cur__target_dir` | `#{ocaml.target_dir}` | folder where build files will be generated | 28 | | root | `$cur__root` | `#{self.root}` | root folder of a package | 29 | | install | `$cur__install` | `#{@opam/dune.install}` | folder where files of a package are installed | 30 | 31 | ## Debugging 32 | 33 | ### Version 34 | 35 | On **Windows** before 0.6.11 it was required to run it as admin. 36 | 37 | Update to the latest and **enable developer mode**. 38 | 39 | ### VSCode 40 | 41 | It may be that a locking problem happens which leads to your vscode clashing against an esy instance running. Normally restart language server works. 42 | 43 | ### shell 44 | 45 | Sometimes you're already inside of `esy shell` and trying to run it again, a good way to verify that is to check if some variable like `$cur__install` is present. That means esy shell 46 | 47 | ### Missing variable 48 | 49 | You can only use `#{package.variable}` if the package is a direct dependency, so let's say you want `#{ocaml.install}` but your manifest doesn't include `ocaml` as a dependency it will fail. 50 | 51 | ### Opam dep not working 52 | 53 | If an opam dependency is not working it may be that a patch is missing, you can make one and open a PR at https://github.com/esy-ocaml/esy-opam-override 54 | 55 | ## FAQ 56 | 57 | ### Where are the esy variables? 58 | 59 | You probably forgot to run `esy shell`. 60 | 61 | ### Where is my files? 62 | 63 | Probably at `$cur__target_dir`, sometimes at the root of your project as `_build`. 64 | -------------------------------------------------------------------------------- /ARCHIVE/reason-mobile.md: -------------------------------------------------------------------------------- 1 | # Reason Mobile 2 | 3 | This is archived, as I moved away from the esy ecosystem. 4 | 5 | ## Debugging 6 | 7 | ### Clash between interfaces 8 | 9 | Probably happens because the package OR some of it's dependencies was compiled to the host instead of to the target. 10 | 11 | To fix it you should try to use a **dune-universe** version of the package if available. 12 | 13 | - https://github.com/dune-universe/ 14 | 15 | If that is not available, try porting the package to dune and if possible opening a PR on upstream. 16 | 17 | If not possible or too complex, making a patch for reason-mobile is also okay. 18 | 19 | ### Patch failed 20 | 21 | Quite likely that a dependency was updated and the patch no longer works. Fix the patch locally and open a PR. 22 | 23 | ## FAQ 24 | 25 | ### Why it takes so long to build? 26 | 27 | It's essentially rebuilding the universe for the platform target, so it takes a while, but rebuilds should be quite fast, still slower than building to host. 28 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - [ ] debugging sessions put some error messages as examples 2 | 3 | ## OCaml 4 | 5 | - [ ] ppx 6 | - [ ] implementation details 7 | - [ ] typer 8 | 9 | ## Packages 10 | 11 | - [ ] ppx'es 12 | - [ ] dream 13 | - [ ] postgres 14 | - [ ] dune 15 | 16 | ## Dune 17 | 18 | ## esy 19 | 20 | - [ ] low level commands 21 | - [ ] improve manifest section 22 | - [ ] links 23 | - [ ] pnp 24 | - [ ] debugging JS deps 25 | 26 | ## Reason Mobile 27 | 28 | - [ ] debugging: how to try patches locally 29 | 30 | ## Programming 31 | 32 | - [ ] give a look on this file 33 | - [ ] improve nominal typing session 34 | 35 | ## Life 36 | 37 | - [ ] give a look on this file 38 | 39 | ## Continuation Calculus 40 | 41 | - [ ] verify data terms hypothesis 42 | - [ ] call + jmp example 43 | -------------------------------------------------------------------------------- /continuation-calculus.md: -------------------------------------------------------------------------------- 1 | # Continuation Calculus 2 | 3 | ## References 4 | 5 | - Paper https://arxiv.org/pdf/1309.1257.pdf 6 | - Type system https://arxiv.org/pdf/1409.3313.pdf 7 | - Master thesis https://pure.tue.nl/ws/portalfiles/portal/46941433/760931-1.pdf 8 | - CBV and CBN lambda calculus http://www.cs.ru.nl/~herman/PUBS/CBN_CBV_iteration.pdf 9 | 10 | ## Goal 11 | 12 | Use it as an abstract machine where most operations are simply defined and allows fast compilation, simple optimizations and no implicit allocation. 13 | 14 | The continuation calculus seems to allow that as most of it's terms are essentially variables or applications and don't have an implicit stack when doing evaluation, which leads to no implicit allocation. 15 | 16 | Sadly the continuation calculus has implicit allocations in the form of data terms, that can require the creation of closures, my hypothesis is that this can be fixed by rejecting any data term. 17 | 18 | ## Data terms 19 | 20 | As I would like to reject implicit allocations, having closures being allocated is probablematic, but it seems like all data terms inevitably lead to a term in form of `n.a.b -> a` which means it's a term that don't call a continuation just returns it. 21 | 22 | If that's true by rejecting any term that doesn't call something the calculus is not turing complete anymore but also doesn't have any implicit allocation. 23 | 24 | Those can be solved through extensions, like having explicit closures. 25 | 26 | > TODO: Aren't data terms explicit enough? 27 | 28 | ## Advantages 29 | 30 | ### Optimizations 31 | 32 | Because the only model of computation in the CC is the continuation that ensures that any optimization made in terms of continuations will have effect on all sorts of code. 33 | 34 | And because a lot of imperative style code can be really well modeled in terms of continuations that leads to optimizations here being valid for not only functional code, but also imperative code. 35 | 36 | As an example, direct recursion and loops can be compiled to the exact same assembly, not mattering if you're using mutation on the language level or not. 37 | 38 | ### Termination 39 | 40 | ~~In CC some terminations are really easy to check, essentially if there is no rule cycle then no loop can ever happen, unlike the lambda calculus where you can construct fixed point combinators or even the y-combinator.~~ 41 | 42 | This is not true, you can construct the y-combinator 43 | 44 | ``` 45 | a.x -> x.x 46 | loop -> a.a 47 | ``` 48 | 49 | ## Compiling 50 | 51 | ### Stack Trace 52 | 53 | As we're using always continuations the stack trace is now useless, to recover from that one idea is for functions where the depth is small and defined it's possible to emit call instead of jmp. 54 | 55 | My first idea was to return a ret callback as continuation should be provided, this can also be faster for some functions as the continuation will always be the same global callback and the branch predictor will be happy with it. 56 | 57 | But if the function itself already has bounded stack size maybe it could emit `ret` instead, being the job of the calleer to call the continuation later if needed, this should be even faster as there is no need to use an additional register or load the callback address 58 | 59 | ### Closures 60 | 61 | The full continuation calculus can be compiled easily to closures, those closures can be described as requiring the closure pointer to be always in the same register, and the pointer itself needs to be dereference to access the function pointer, this reduce the need for having helper functions like `caml_apply`. 62 | 63 | In x86_64 this looks particularly nice as it can be done as `jmp [rax]`. 64 | 65 | Because of this encoding a trick possible is that functions that are just global symbols can have a pointer acquired directly from the `GOTPCREL` so that when the pointer it's called it will dereference the global symbol anyway, avoiding an additional address for them. 66 | 67 | ### Lambda Lifting 68 | 69 | Because of the existance of data terms not every term can be lifted, so high order functions need to support calling closures. 70 | 71 | I believe that this can be worked around by making so that only leaf function handle closures, which in the presence of whole program transformation is IO functions and external functions, but external functions can also have explicit signature saying marking if it returns a closure or not. 72 | 73 | ### call + jmp 74 | 75 | I'm not sure if this works, but another interesting approach which may be possible is to do a convention of call + jmp where the first call will always only move registers around and return a pointer to jmp, this allows the encoding of data in a simple style while not requiring closures, the first call will never mess with the stack so the stack can be used. 76 | 77 | ```cc 78 | f.a.b.r -> a.(r.a).(r.b) 79 | ``` 80 | -------------------------------------------------------------------------------- /life.md: -------------------------------------------------------------------------------- 1 | # Life 2 | 3 | > Life sucks and then we all die 4 | 5 | ## Drugs 6 | 7 | ## Love 8 | 9 | ## Death 10 | 11 | If I can one day choose to die, watching the heat death of the universe seems fun. 12 | 13 | ## College 14 | 15 | The opportunity cost of a degree is really high, 3+ years, a lot of money to burn. To this day I still wonder if it is worth it, and if I should try to get one. 16 | 17 | Knowing more people from the academia is something that I desire, it's a big pleasure to me to be able to speak to the authority on a topic and something I want to do more during my life. 18 | 19 | ## Master 20 | 21 | > what makes a master? 22 | 23 | Are masters even real? I feel like a master is just a human being which is on the edge of the knowledge, pushing it forwards. 24 | 25 | Can one became a master "alone" in the age of the internet? Can you truly know that you know the state of the art on something? 26 | 27 | ## Achievements 28 | 29 | > What should a man try to achieve? 30 | 31 | ### Money 32 | 33 | After having enough money for a living, why do I still try to get more and more? When is more enough? Is a billion us dollars enough? 34 | 35 | Probably not, and this truly concerns me, what if I keep running the hedonic treadmill forever? Will the feeling still be the same? Can I say that I'm happy on that? 36 | 37 | > Can I say that I'm happy on that? 38 | 39 | For a long time I've been thinking that the only way to be happy in the longterm is to be outside of the hedonic treadmill altogether. 40 | 41 | The problem is that it seems to me that the way to escape is not just stop running, I believe that stop running or just jumping out of the treadmill will lead to long term insatisfaction. So the only remaining solution is to run faster, faster than I could ever imagine until, at somepoint, it's done, everything is gonne. 42 | 43 | Quite likely this is just a dumb dream, but if I'm right, then it will be a really fun long life with a sad end. 44 | 45 | ### Knowledge 46 | 47 | Should a man always try to pursue knowledge? Or is the ignorance the ultimate blessing? 48 | 49 | I trully don't know, but as a human in this age, I know that I will never be truly happy about my level of knowledge. 50 | 51 | In retrospect I think the wording is not correct, I believe I'm happy with my level of knowledge, but I'm still not pleased enough with it. 52 | 53 | It is possible to be happy with how much you know and still want to learn more. It is about reconizing the small wins. 54 | 55 | ### Social 56 | 57 | What if a man is alone? Or even worse, what if all man are also alone? 58 | 59 | Well, I'm not into having the absolute definition of alone, so I will choose a useful one. 60 | 61 | Can a man be happy alone? Family? Friends? A loved one? Is it reasonable to ignore it? 62 | 63 | Should one try to change this? 64 | 65 | ## Plato's Cave 66 | 67 | > Leaving the cave was a mistake 68 | 69 | Why are humans so interested in an unknown world where everything it's quite likely worse? Should a man trying to find the truth of the world and sacrificing his own well being to achieve this be called crazy? 70 | -------------------------------------------------------------------------------- /ocaml.md: -------------------------------------------------------------------------------- 1 | # OCaml 2 | 3 | ## Memory Model 4 | 5 | To do unsafe things or FFI understanding the memory model is important, the following link is quite useful. 6 | 7 | - https://dev.realworldocaml.org/runtime-memory-layout.html 8 | 9 | ## FFI 10 | 11 | It's REALLY important to understand how the memory model works, if you do understand, the following links are always useful. 12 | 13 | - https://ocaml.org/manual/intfc.html 14 | 15 | ### When to use ctypes? 16 | 17 | I truly don't know. Overall it seels less error prone, so it's probably a good idea to always use it. 18 | 19 | - https://opam.ocaml.org/packages/ctypes 20 | 21 | ## Future - Memory Management 22 | 23 | - https://blog.janestreet.com/building-a-lower-latency-gc/ 24 | 25 | ### refcounting 26 | 27 | > Why? 28 | 29 | The goal is to somehow get OCaml be lower latency, but actually the things that we get more easily is fast finalizers, especially for data that is known to be short lived it can be quite useful. 30 | 31 | But the latency improvement aspect is by hoping that we can prevent compacting the major a lot of times if we can find big holes in the major, created by operations like `List.map`, by putting the minor data inside the major hole. 32 | 33 | This should also allow to have a refcounted only heap, which may be interesting. 34 | 35 | ## offloading GC 36 | 37 | Goal is to offload considerable computing of major heap collections to a different thread. 38 | 39 | ### Memory is mutable 40 | 41 | As memory is mutable, any scanning in parallel with the worker thread can only detect things that were live recently, but never be a proof that something is dead. 42 | 43 | **Solution**: segregate heaps in mutable and immutable, immutable memory can be scanned in parallel safely and as OCaml memory is mostly immutable this should be a considerable help. 44 | 45 | ### mutable -> immutable 46 | 47 | Pointers from the mutable to immutable memory can not be detected in parallel which makes makes so that scanning the immutable memory ensures you that some values are definitely alive but not having a reference doesn't mean the value is necessarily dead. 48 | 49 | **Solution**: registers + reference table = roots, use minor to get registers 50 | 51 | Can also add a tag of externally referenced in the header of a block, and mark it during caml_modify or initialize. 52 | 53 | Both will affect performance of mutable blocks, by making initialization and / or mutation slightly slower. 54 | 55 | This means that initializing fields on 56 | 57 | - major work during minor collection 58 | - segregated heap's(immutable and mutable) 59 | - tagging 60 | 61 | ### modules are mutable 62 | 63 | Can the parallel GC runs during the initialization of the module? Root_initialization 64 | 65 | ### comballoc 66 | 67 | We cannot combine two allocations for mutable and immutable, but ideally we should be able to combine alloc -> alloc(mut) -> alloc 68 | 69 | ### TRMC 70 | 71 | How does this immutability interacts with TRMC? Can we treat TRMC data somehow as immutable? Maybe by first cleaning it? 72 | 73 | ### parallel minor 74 | 75 | To do minor in parallel we need to somehow move the pointers from the minor to major, but while we do that the worker may create references to the old minor in both the immutable and mutable heap, with this the old minor can never be moved as an invalid reference may exists. 76 | 77 | Possible ways to handle this is through mprotect and segfault handling or mmap on a mapped fd. 78 | 79 | Maybe userfaultfd if this leads to smaller overhead. 80 | 81 | ## multiple major heap 82 | 83 | As Caml_state already exists with a bit of work we could lift the major heap to it so that in the same process multiple threads can be running it's own OCaml with independent GCs. 84 | 85 | Also great on Windows, as Unix.fork is really slow there. 86 | 87 | ## frametable on caml_call_gc 88 | 89 | OCaml emit's an additional label for frametable on GC, my hypothesis is that this could be removed so that the label always points one instruction before the jmp, that would lead to slightly better compaction and also one label less. 90 | 91 | ## segfault to trigger minor gc 92 | 93 | The block after young_ptr needs to always be disabled by mprotect so that when an overflow happens it always triggers a segfault. 94 | 95 | Problem PAGESIZE may be 64k in macOS m1. 96 | 97 | ## use xchg %rsp to allocation 98 | 99 | Instead of mov with offset we can then do pushq which is considerably smaller 100 | 101 | ## use smaller register for young_ptr 102 | 103 | %r15 could be used for last OCaml argument, and something like %rdi could be used for young_ptr 104 | 105 | ## use STP for ARM64 106 | 107 | It probably allows to reduce instructions 108 | -------------------------------------------------------------------------------- /programming.md: -------------------------------------------------------------------------------- 1 | # Programming 2 | 3 | ## What is good software? 4 | 5 | ## What do you get by having good code? 6 | 7 | ## Constraints 8 | 9 | ## Correctness 10 | 11 | The property of your program to behave as expected. 12 | 13 | ### Static types 14 | 15 | Overall static types prevents the developer from commiting a large class of errors, by ensuring that no piece of code can ever fail with an error not specified by the functions being called. 16 | 17 | ### Nominal typing 18 | 19 | Nominal typing provides a lot of really useful features, as a type is now identified by it's name instead of it's content. 20 | 21 | Abstract types in OCaml allows you to ensure properties of a system that cannot be broken anywhere else in the codebase, by ensuring that only a limited piece of code can operate on a piece of data. 22 | 23 | An important additional example is private fields combined with final class like in Java, of course Java type system is unsound, which is problematic. 24 | 25 | ### Tests 26 | 27 | While tests cannot proof that a piece of code works it can ensure that it works for a specific case, which is important for you and your users, this on itself is already a good sign of correctness. 28 | 29 | ### Defensive coding 30 | 31 | This is the idea of you should expect that your function can be called with the wrong inputs, normally in dynamic languages that would be ensuring the type of a function, but besides of that you can instrument it to ensure that a number is in a specific range or that a function before it was called. 32 | 33 | A good trick is to add this assertions through a macro or a function call that can be removed by the compiler in production, for something like JS you can think about webpack / babel / typescript. This allows you to go crazy on assertions without affecting performance at all. 34 | 35 | ### Type Level Programming 36 | 37 | This idea is one of writing code to satisfy the type checker, this code will be executed only on checking time, so it is "type time" code. 38 | 39 | Whenever someone refers to be doing programming on the type level, they're probably trying to enforce some properties on the type checker. 40 | 41 | ### Dependent Types 42 | 43 | Types that can depend on values. This allows to be more specific about values and enforce properties on them. This is also one of the most convenient properties to do type level programming. 44 | 45 | In most languages with dependent types, there is no separation between term and type level, making so that you can proof properties about your code. 46 | 47 | ```rust 48 | // aka, if pred is true then x will be an int, otherwise it will be a string 49 | (pred : Bool) => (x : pred | true => Int | false => String) => x 50 | ``` 51 | -------------------------------------------------------------------------------- /theory.md: -------------------------------------------------------------------------------- 1 | # Theory 2 | 3 | I don't have a good description of theory, so here I intend it to mean more or less: Any idea that partially explains something and is more or less verified. 4 | 5 | Such as scientific theories and models that no proof exist but hold enough such that the theory(idea) is still useful. 6 | 7 | It is a stronger version of "hypothesis", theories are hypothesis that were at least thought through. 8 | 9 | ## Thinking 10 | 11 | The main goal of most thinking is to produce theories, not to actually proof them, but to produce hypothesis and casually verify them. 12 | 13 | Theories are reliable enough to guide you through some decision but easy enough to produce on a daily basis, no proof needed. 14 | 15 | ## Intelligence 16 | 17 | I believe that such a thing as "raw intelligence"(g-factor) do exists and I think it is highly correlated with what people actually perceive as being smart. 18 | 19 | What people actually perceives as being smart, is the number of theories an individual have multiplied by how well they use those theories to work on problems. 20 | 21 | As such while there is no evidence that you can enhance your "raw intelligence", you can always expand on your set of theories. 22 | 23 | ## Theory vs Practice 24 | 25 | > "in theory X, but in practice Y" 26 | 27 | This is a common sentence to hear, this is essentially a clash of theories, not practice vs theory, it is a clash of a well tested theory aka the practice vs a not so well tested theory. 28 | 29 | If a theory doesn't match reality, then it is simply a bad theory for the set of "reality" that is being probed, it may still be an useful theory, but it is a bad theory. 30 | --------------------------------------------------------------------------------