Hello! I was curious if you would happen to have any advice or particular comp sci papers you would point as aspiring compiler developer towards.
I think I'm sort of who you're talking about. I have no formal education and I am excited to have my compiler up to the point I can run a basic web server. I think it's a fairly traditional approach with a lexer, recursive decent parser, static analysis, then codegen. I'm going for a balance between languages like Ruby and Rust to get the best of both worlds.
You'll probably find it funny that I don't know the name for the technique Im using for dynamic dispatch. The idea is that as long as a collection doesn't have mixed types then the compiler statically knows the type even in loops and such. Only for mixed type collections, or maybe trait functions, will the compiler be forced to fall back to runtime dynamic dispatch. I find this cool because experts can write fast static code, but beginners won't be blocked by the compiler complaining about things they shouldn't have to care about yet. But, syntax highlighting or something may hint there are improvements to be made. If there is a name for this, or if it's too small a piece to deserve one, I would be very curious to know!
On Refinement Types, I not sure they are a good idea for general purpose languages and would love to be challenged on this. Succinctly, I think it's a leaky abstraction. To elaborate, having something like a `OneThroughTen` type seems helpful at first, but in reality it's spreading behaviour potentially all over the app as opposed to having a single function with the desired behaviour. If a developer has multiple spots they're generating a number and one spot is missing a check and causes a bug, then hopefully a lesson was learned not to do that and instead have a single spot for that logic. The heavy handed complexity of Refinement Types is not worth it to solve this situation.
If there are any thoughts out there they would be greatly appreciated!
I was tired of feeling slowed down by grepping in large Ruby code, and the artificial boundary gems create requiring a `bundle open` to keep digging. I created my own Ruby LSP to solve these problems: https://github.com/pheen/fuzzy_ruby_server
I think it works well, is stable, and I would still reach for it over Shopify's LSP personally. Feel free to use it! Though as a heads up, I don't work in Ruby much anymore unfortunately so I'm not actively working on it or accepting issues.
The real trick is doing both. Code that reads like a short story while including error handling and edge cases. This is achieved in a practical way by first keeping it as simple as possible only implementing strictly necessary abstractions. When the code reaches a "tipping point" then refactor. Rinse and repeat. If the code is structured reasonably that refactor should be mostly limited to the trouble spot.
I'm curious what you're really trying to say here and why feel the need to compare yourself to your peers in such a way. Do you feel like you wasted those years because your peers are "smarter" than you now?
Exactly that. It's hard to have any sort of control over a lifetime, but I went to university, have worked in software, and some of the friends I compare myself to did the same. I'm still "smart". But I feel like smoking as much as I did has accelerated my age-related cognitive decline.
I don't feel that I wasted the years, but I do think that the thousands of hours spent stoned were a complete waste and have decreased the potential quality of the latter half of my life.
I made a Ruby LSP because of this problem. It's not perfect but incase it's helpful for you. It can parse a large project with all of its gems in a few minutes. That data is indexed in an in-memory db with Tantivy. https://github.com/pheen/fuzzy_ruby_server
This is my workflow as well, it's great. Github is configured so merging a PR into master will automatically produce a squashed commit.
My rule of thumb, always rebase unless you hit a series of merge conflict while rebasing. Then either merge, or squash your branch then re-run the rebase.
We require linear history on our shared mainline branches so the squash workflow works great for us using Github as well. Another benefit is the "show changes since last review" option when reviewing a PR - it's been a while but I'm not sure if this is possible with a rebase-based workflow.
Inotify can drop events when there is a burst of file changes. You can bump up the max number of queued events though. For example, if you're watching a git repo and switch to an old branch that has 1500+ changed files then inotify will likely miss some with a default configuration.
Ideally you have a reliable Change Data Capture (CDC) mechanism like a Binlog Reader. Debezium, for example, can write directly to a queue like Kafka. A Kafka consumer picks up the events and writes to your secondary datastore. Something like that can probably handle all of your events without bucketing them, but if you want to cut down the number of messages written to the queue you can add that logic into the Binlog Reader so it emits a burst every 5 seconds or so. During those 5 seconds it buffers the messages in the processes memory or externally in something like Redis using a key so only the latest message is stored for a given record.
I think I'm sort of who you're talking about. I have no formal education and I am excited to have my compiler up to the point I can run a basic web server. I think it's a fairly traditional approach with a lexer, recursive decent parser, static analysis, then codegen. I'm going for a balance between languages like Ruby and Rust to get the best of both worlds.
You'll probably find it funny that I don't know the name for the technique Im using for dynamic dispatch. The idea is that as long as a collection doesn't have mixed types then the compiler statically knows the type even in loops and such. Only for mixed type collections, or maybe trait functions, will the compiler be forced to fall back to runtime dynamic dispatch. I find this cool because experts can write fast static code, but beginners won't be blocked by the compiler complaining about things they shouldn't have to care about yet. But, syntax highlighting or something may hint there are improvements to be made. If there is a name for this, or if it's too small a piece to deserve one, I would be very curious to know!
On Refinement Types, I not sure they are a good idea for general purpose languages and would love to be challenged on this. Succinctly, I think it's a leaky abstraction. To elaborate, having something like a `OneThroughTen` type seems helpful at first, but in reality it's spreading behaviour potentially all over the app as opposed to having a single function with the desired behaviour. If a developer has multiple spots they're generating a number and one spot is missing a check and causes a bug, then hopefully a lesson was learned not to do that and instead have a single spot for that logic. The heavy handed complexity of Refinement Types is not worth it to solve this situation.
If there are any thoughts out there they would be greatly appreciated!