I'm going into my freshman year, and figured that the best way to prepare for the intro to programming Racket course would be to implement my own garbage-collected, dynamically typed, functional programming language in C ;)
Anyways... here's the repo: https://github.com/liam-ilan/crumb
I started learning C over the summer, so I still have a whole lot to learn... Any feedback would be greatly appreciated! :D
At least that was my experience as a self-thought programmer. The first weeks were super boring for me but also lulled me into being complacent until I suddenly found myself in deep trouble. Just because you understand the practical side does not mean you can will automatically grok the academic side of things.
you should be studying: lisp ocaml haskell, interpreters (SICP), compilers, type systems, transaction processing, effect systems, FRP, concurrency NOT java guis python SQL databases webdev gamedev .. whatever
(Serious question. I’m not being snarky)
For example, I had a second major in theatre, but I had no delusion of working a living in theatre that could compare with the kind of career that a CS degree typically delivers. It was and is a personal passion of mine, and to be able to deepen my understanding of it in an academic setting was valuable and rewarding to me personally.
Studying theatre paid dividends in other ways as well. Managing a production is a beast, and you learn a lot about how to manage people and get things done. Dramaturgy, often called literary analysis, was quoted by my professor (a scholar on the topic) as "what are the parts, and how do they go together?" -- a shorthand that I still use to this day when thinking about a new system.
If it wasn't clear already, I had a very positive experience in my studies at a Liberal Arts school, where the connections between fields, and the value they can offer each other, are a big focus.
Just taking on a second major won't necessarily pay off, but keeping in mind the holistic point of your education may create an outcome where the sum is substantially larger than its parts.
I went into mechanical engineering because I had a great natural understanding of basics physics, materials, design, mechanics, blah blah. Even UC Berkeley engineering basically taught me things I knew or would have easily understood it I had to lookup that specific thing. I learned very little from my mechanic engineering degree.
I ALMOST think people shouldn't go into a major based on their strongest aptitude, but I'm not sure yet.
But definitely 100% add another focus since you'll probably breeze through the main course work.
But I dont think it should be philosophy or art or calligraphy like Jobs would recommend. I wouldn't pick a second major that would be a foolish main major.
Pick something that is a hard skill that is useful to learn and understand.
Maybe electrical engineering. Maybe industrial design. Hell, I think tons of people would be well served with what they learned with a second major in accounting.
The other part, that suggests doing more courses of study is somewhat questionable.
Uni courses are designed partially to help you learn skills. But also for other requirements.
If OP wants to learn more skills, they should go for that. Whether in uni or outside. If OP wants to relax and have fun, that would also be a good use of time in your twenties.
That's the main difference between C and C++ and almost any other language. Not the syntax, neither the perceived "low-levelness", nor manual memory management. In any other language, if you make a mistake, the program behaves badly, but in a predictable way. In C and C++ it may behave reasonably, it may crash in another file altogether few seconds after the erroneous line is executed, it may produce the correct answer. Or it may crash only sometimes. Or it may silently produce an incorrect answer. Different behaviors on different systems, and even on the same system with different compiler flags (e.g. optimization level), of course.
That makes reliable experiments with C and C++ impossible. Even if you have just five lines of code, you almost never know if they're valid C or C++ for sure (separately, whether they do what you want with modern/legacy compilers). It's still fun and everything (congrats on making your own language, that should've been fun!), but you never truly know whether what you wrote is not going to break in a few years (or months) with zero code modifications just because there was another UB lurking around.
See https://evan.nemerson.com/2021/05/04/portability-is-reliabil... if you're curious about more practical implications.
E.g. if you work with a single compiler on a single platform all the time and expect the compiler to "just compile the code", then you're likely to learn all its quirks, avoid them automatically, use proper abstractions/contracts/invariants to guard against incorrect code, etc. Moreover, you likely know how exactly the most popular UB shows itself with your compiler.
If you juggle compilers all the time and work with not-so-high-quality code (legacy or not), especially the one with little tests, I expect UB to pop up a lot. Or even if you just test on one platform and do final runs on another, that happens all the time in competitive programming or home assignment grading, especially with beginners.
@OP: I recommend to submit your posts here when you have new ones, and post the older ones slowly (like one per week) so people don't get annoyed.
You may start with reversing compiled-code, but interpreter is much-much more.. interesting. Especialy if of unknown (simple) language.
Have you tried teaching Crumb to GPT4? I bet it could surprise you with what it can do.
Make sure you foster that curiosity continuously until the day you die, because it'll serve you really well
Obviously you are much more advanced, so my advice would be to keep tinkering with everything u can get your hands on.., and keep spreading to adjacent disciplines (electronics, cad, startupy stuff, and even non tech stuff) until u take over the world haha.
Though I didn't implement his language exactly, a lot of what he talks about carries over anywhere. It especially helped me figure out how to handle the memory management and scoping.
Vincent Jacques' DrawGrammar (https://jacquev6.github.io/DrawGrammar/) was also super helpful. Getting to see the syntax definition visually made writing it so much easier :).
1) When a function is finished, all memory related to the scope of that runtime is freed.
2) When an value is not returned out of a statement, or assigned to a variable, said value is freed.
3) When a function is applied, if an argument has no reference (it is not stored in a variable), it is freed.
4) Additionally, if the function itself has no reference (such as in the case of an immediately invoked function), it is freed.
Hope that clarifies things a bit :D
f = {
x = (list 1 2 3)
y = (list x x)
z = (get x 1)
<- y
}
How does the compiler decides if it must free the memory used by x?Hasn’t hurt me from finding interesting jobs that pay well!
You're a freshman, picked up C over the summer, and have already built an interpreter for a language that you haven't officially been taught yet, and have a blog with a couple dozen posts.
I'll be honest, people with achievements like yours make me feel pretty worthless.