Text
What I Have Learned
I’ve been writing software almost compulsively since I was 11 years old, when I learned how to use Python to create small, barely playable games for my computer. Since then, I’ve written hundreds of programs, including chess engines, programming languages of my own, custom text editors, and much more. Through my experiences writing and sharing software with the world in competitive environments, I’ve learned a lot about making things, working together with people, and life in general. Here are some of the most important lessons I’ve taken away from my experiences.
Be really good at one thing. Practice your trade. Don’t stop learning. If you take shortcuts, you will never improve. You can only succeed by slaying the dragon.
Be somewhat good at a few things. Learn an instrument. Play chess. Paint. Start a blog. It doesn’t have to be huge, just something. Building up skill sets in new territories will help you learn other skills easier. Additionally, having an obscure, funny, or particularly difficult skill set can be interesting or memorable to others, which can be great for making new friends or networking.
Sometimes failure is the best option. Don’t feel obligated to subject yourself to anything you don’t need to.
If you do fail, then fail with purpose. If it’s impossible to make a deadline, sometimes it’s best to just stop and work on something that can be finished on time.
Perfection is possible, but not the goal. Oftentimes, it’s better to use your effort where it’s best spent than trying to improve something that already works well enough. This is particularly true for projects that intend to attract attention: a product’s presentation and demonstration are much more important than its functionality. Make something look good before you make it work well.
Don’t worry yourself over things you cannot control. Your time is better spent working towards your future than thinking about what could have been.
Always assume beyond the worst, and be pleasantly surprised. If you expect more problems than possible, you can never underestimate a workload.
All problems are the sum of previously solved problems. Don’t get creative: other people are smarter than you, and their solutions are better. Stand on the shoulders of giants.
People have good memories. Only give them positive things to remember you by.
Stay close to smart people, but more importantly, stay close to positive people. People who are excited and passionate tend to have something good to be excited and passionate about. Befriend them, and implement what you learn about their happiness in your own life.
Humans are incredibly good at problem solving. Don’t be a problem, or someone will find a solution to you.
If you lose in a fair match, it is because you gave your competition an opportunity you did not foresee or measure properly. Wins are given away, not taken.
Be skeptical. The truth has nothing to hide from doubt. Only false assumptions can lead to contradictions. Intuition is a distraction: only believe what you can know for certain. Measurements are more accurate than estimates.
Don’t do stupid things. It may not seem obvious, but you will regret buying that 10 pound bag of fruit flavored jelly beans.
Teach others. Not only does it help other people grow, it strengthens your own skills, too. Teaching is the best form of study.
First impressions are everything. If you make mistakes during an interview, or you show up late to your first meeting, your errors will be perceived as character flaws rather than gaffes.
Be credible. Only say what you know is true. Never lie, especially to your friends or those who want to help you. If you are uncertain, it is better not to speak.
Be kind. Kindness disarms angry individuals, and turns acquaintances into friends. Everyone loves someone who’s nice.
Share. After all, what else is that 10 pound bag of fruit flavored jelly beans good for?
Have lots of fun. Not only does it make you happier, it gives you more things to talk about. Have you ever met a skydiver who couldn’t hold a conversation? Interesting people have crazy stories, so get some of your own.
Be grateful for what you have. Although things could be better, they could also be worse.
It’s okay to be sad. Go get some Taco Bell, turn on Netflix, and cry as much as you feel like. Skip school today. Don’t do anything you don’t want to. It can wait until tomorrow. I’m proud of you.
0 notes
Text
The Oak Compiler
I've written an alternative to the C programming language. This is how it works, and what I've learned.
Free
About 6 months ago, I began exploring compilers with extremely limited target backends. I came across the brain programming language and I was immediately inspired. How could a high level programming language possibly use such a tiny backend? It was incredibly interesting to me, so I decided to write my own language, free. It used a super-set of Brain**** with 3 new instructions for dynamic memory management. After a substantial amount of keyboard clacking and lots of confusion, I had accidentally made a working compiler! The end result looked like this:
I couldn't believed it worked; it was incredible. The only problem was that free was absolute garbage. It couldn't be used for anything. At all. There wasn't a type system, memory was basically impossible to manage, there wasn't any kind of IO other than STDIN and STDOUT, there was no error checking system of any kind, etc. I loved my creation, but it wasn't practical.
Oak's Conception
Then, I had an idea. What if I kept the tape memory structure from Brain****, kept the memory management operations from free, and added some operators for managing a stack? The result was Oak's backend assembly language. After a week of experimenting, I created an incredibly reduced instruction set with only 12 operators that could output basic C code. "This is perfect", I thought. I implemented an intermediate representation that implemented functions, structures, a type system, and basic operations that any programming language needs. I even added a foreign function interface, so that users could import C code into their programs! I was incredibly excited.
It was at about this point that the language took* off on Reddit, HackerNews, and GitHub. Only a single day after posting the GitHub link to Reddit, I had over 16,000 unique visitors to the repository. I had never received much attention on Reddit or GitHub, so this was incredibly powerful to me. It fueled me to keep going.
At around this point, the project was still pretty barebones. It had all the basic necessities, but nothing more. There was still a lot to be done. Oak was basically just a glorified, stripped down, and less robust C compiler.
Typechecking is hard
Although I knew typechecking could get complicated, I didn't know it would take up about half of my intermediate representation's codebase. Typechecking isn't about confirming if a program is correct, it's about confirming a program isn't correct. Although that distinction might sound a bit unnecessary, I assure you it is not. Typechecking is difficult because you have to consider every incorrect program possible, and try to eliminate each one. It's almost impossible to get right, and there are probably dozens of logic errors in Oak's type system right now. But, in the end, it works pretty well. It's mostly just the fringe cases that are a bit off.
By far, the hardest part is typechecking the code responsible for automatic memory management. There are so many things that can go wrong, it's unbelievable how easy it is to screw up. One big problem I ran into was determining whether or not a structure needed to use automatic memory management at all. Why use copy constructors and destructors for a type that doesn't have any members with copy constructors or destructors? And how do you confirm that all objects' destructors will be called? After some experimenting, I think I figured out an air tight solution, but honestly I really don't know if there are ways to abuse the automatic memory management system.
2 notes
·
View notes
Text
Combinator Compilers
Over the past few months, I've been really excited about the implementation of functional programming languages. The reason I'm so excited about implementing them is because of this concept of combinators. Combinators are basically primitive lambda functions that are really simple but very powerful. There's something REALLY special about combinators though. Any lambda expression that can be written, no matter how complex, can be rewritten as applications of a single combinator. This means that any lambda calculus program can be compiled to a giant expression of single function calls which are really easy to interpret. You dont even need to write a crazy implementation of beta reduction seen below!
The most powerful part about combinator compilers, in my opinion, is the fact that their intermediate code is so portable. Combinator interpreters are so easy to write in any turing machine or lambda calculus based language. Compilers are a bit more complex, but still simple.
The biggest problem with combinator compilers is that they're slow. There is a way to mitigate this issue, though. The more combinators that the intermediate representation has, the faster the output code!
I'm working on a new language implementing this compiler architecture, I can't wait to see how it goes! I'll keep updating this blog with my progress after my school work eases up.
0 notes
Text
Object Oriented Shell Scripting
I used to dislike PowerShell very very much, but now I’ve become inspired by it. I was completely unaware of its Object Oriented features, and I think it’s a genius idea. Although I still dislike the implementation, PowerShell is a beautiful concept.
In the Bash shell, every program returns an exit code. In PowerShell, however, everything returns a table. This is extremely useful for organizing data, and it can be extremely efficient. Operations like filtering files by their size can become really simple.
Having been inspired, I started work on my own shell. Using the abstract syntax tree of xasm and slightly rewriting the parser, I was able to very quickly write an implementation of my shell, named Dune.
Here’s a demonstration of the very first 0.1.0 version!
As you can see, it’s very basic and ugly right now, but aesthetics are simple to change.
Within a few hours of starting the project, we already have the ability to create tables and index them. We also have the ability to do control flow. While loops are also supported, but this is not shown in the demonstration.
If you want to see my progress on Dune, visit the repository at https://github.com/adam-mcdaniel/dune
0 notes
Text
Oak Ridge National Labs Internship
I recently finished a summer internship at Oak Ridge National Labs, and I loved my time there; working for Dr. Graham Lopez and Dr. David Green on the ASGarD project was such a good experience.
What was it like?
Rad. It was rad.
I got to work on several things, including my very own continuous integration tool that can build hypothetical pull requests for GitHub and GitLab projects. It’s written in Rust, and you can find it at https://crates.io/crates/rusty-ci.
I really enjoyed my stay, and I’m really looking forward to going back soon.
0 notes
Text
About Me

Hello! I’m Adam, a 17 year old high school senior, a programmer, and a guitarist. My favorite language is Rust, and I’m majoring in Electrical Engineering. I love golden retrievers, board games, and elegant solutions to problems.
0 notes
Text
Writing a Zero Dependency Compiler
If you’ve read any of my previous posts, then you’re aware that I’ve been writing a cross platform intermediate representation language. Today, I’ve finished a fully functional version!!
It uses honeycomb, a parser combinator library I wrote from scratch. The AST produced by the parser is then compiled to Rust, the language the compiler is implemented in.
Here’s a sample program that implements a really bad random number generator.
It’s dynamically typed, and supports both object oriented and functional programming!
Here’s another sample programming that demonstrates the lambda calculus.
I’m very happy with the results so far. The above programs compile to extremely fast executables. In addition, the compiler can run anywhere! I’ve written a front end for usage from the command line, but the compiler itself doesn’t require any other crates, including the standard library.
If you want to try it out yourself, visit my repository and follow the installation instructions!
https://github.com/adam-mcdaniel/xasm
2 notes
·
View notes
Text
The #![no_std] Compiler Flag
Within the Rust programming language, there’s a very cool feature that promotes writing extremely portable code. This feature is the `#![no_std]` flag.
It does something very subtle, but very interesting. When present in your code, `rustc` will not link the standard library when compiling your program or library. This means that you will not have access to any functionality that requires communication with the operating system. Your program may not shell out commands, it may not do file operations, it may not print to the console or read user input. That may sound terrible, but it’s incredible useful.
Consider the case where you want a library to be as portable as possible. If you use dependencies that require the standard library, you immediately risk losing support for several operating systems. Think about it, what if the dependency you want to use relies on operating system specific behavior? In addition, what about platforms which don’t have an implementation of the standard library?
Here is where `#![no_std]` comes into play. It absolutely, without fail, guarantees that your code can be used by anyone. In addition, because your library doesn’t carry around any extra bloat, your compile times will greatly improve.
Because of the benefits, I’ve been trying to implement everything I possibly can using `#![no_std]`. To see more, checkout my github profile!
adam-mcdaniel GitHub
0 notes
Text
Writing a Compiler with Honeycomb
After reading about parser combinator libraries, I started to write my own! I eventually got it into a working state, and published it on crates.io under the name `honeycomb`.
You can find it here:
My absolute FAVORITE thing about honeycomb is that it doesn't depend on anything, not even the standard library! Im super proud of that fact :)
To test honeycomb's capabilities, I started work on a simple compiler for an object oriented and functional programming language. Within a three or so hours of work, the compiler was fully implemented! This was a huge surprise to me because working with Lark-Parser in Python would take a full days work.
The you can find the language here:
It's dynamically typed, and is compiled to a custom 10 instruction set virtual machine code implemented in Rust. After compiling my language to Rust, the output Rust code can then be lowered to native executable code!
Although this was just a test, I am VERY interested in writing a compiled scripting language that acts as a cross platform version of Bash. I've drawn a lot of my inspiration from Groovy, which is a language commonly used as a more robust replacement for shell scripts. I think a cross platform scripting language and shell would be a wonderful advancement in programming technology, and I can't wait to investigate this topic further.
0 notes
Text
Parser Combinators
Today I listened to a talk about parser combinators and it was fascinating. I wanted to learn more about them so that I could implement a portable parser for my programming language, but I had no idea that parser combinators were so INCREDIBLY powerful in almost every aspect.
Essentially, they're a bunch of mini parsers that can be mixed, matched, twisted, and turned to produce slightly larger parsers. These slightly larger parsers can also be mixed and matched to produce even larger parsers. This allows you to quickly write very generalized yet simple parsers with minimal effort. Their ability to abstract parsing makes them perfect for writing a parser for a programming language.
Another very powerful feature of parser combinators is how they manipulate their consumed data. They can map their consumed input strings into other types, combining the parsing and lexing steps! All thats left is code generation.
Stay tuned for more updates about implementing my programming language / more cool programming stuff!! :)
0 notes
Text
The `nom` crate
Yesterday, I spent the majority of my time trying to wrap my head around the process of writing a parser using `nom`, a crate on crates.io.
https://crates.io/crates/nom
Using it has been EXTREMELY difficult thus far; not because nom itself is bad, it's very good. I'm just very unfamiliar with ML based parsers.
It took me 3 hours to write a combinator that would consume a strings with escaped characters, and it used several unsafe blocks.
I think, however, that I've struck gold with the `pom` crate. It seems to function identically, but with a structure that's more similar to Python's `lark-parser` module.
This is the first time I've written a parser in a language other than Python. If anyone has any tips, let me know!
0 notes
Text
Continuous Integration
Over the summer, I've been working on a cool project called Rusty-CI that I'm very proud of at the moment.
Essentially, it lets you very easily automate testing for GitHub and GitLab projects.
It's gotten so powerful that now, when a new release is pushed to master, it's able to download the new release, uninstall the old one, install the new one, and hot reload the master daemon responsible for testing using the updated version!
I built it using Rust because it's an EXTREMELY expressive and powerful language. I almost feel like a wizard when I use it because it gives you such a feeling of control. Although it IS a systems programming language, I often find myself using it as an alternative to shell scripts.
If you'd like to learn more about Rusty-CI or any of my other projects, you can find them on my GitHub account!
0 notes
Text

The Rust programming language is beautiful and no one can tell me otherwise :)
19 notes
·
View notes