John Elam - Home | twitter:@elamje | my coding flow playlist: spotify | coding music: List | me now

Welcome!

6/16/20 | Excellent C# async/await tips

Async Antipatterns

5/20/2020 | Start with SELECT *

Start with Data. If there is no description of the system you are trying to grok - look at the data that comes in and out. If you don't have data in the system - think about what data needs to go in and out.

A simple "SELECT * FROM X" can save you and your coworkers lots of time and energy.

I'm getting started on an ETL project that a couple of architects have been designing the past few weeks. We are lacking documentation. The schema in the database is still being fleshed out. However, we have a bit of test data in the DB.

For the piece I am responsible for, I want to understand what kind of database models I'll be working with. Without a description of the schema and what each column represents, I need help to understand. I almost reached out to one of the staff-level engineers to get some insight, when I realized I should probably just look at the underlying mock data to understand the relationships.

This reminded me of my journey from a junior to senior engineer. Juniors need to be told how something works. Seniors can use code, docs, and data for understanding. In the old days, I didn't look at the Data. I was overwhelmed with the number of tables. Their names. And their column names. I never bothered to look inside those tables with a "SELECT *". I could have saved a huge amount of time by sitting down and going through the entire database with "SELECT *".

Although this ETL project isn't using Clojure, I'm constantly being reminded of the superpowers embedded in lisps. We are doing ETL and supporting a DSL written on top of a statically-typed, compiled language. If you want to understand the power of Clojure (any lisp really), work in those two domains using a typed, compiled language (lots of reflection, and lots of waiting for the compiler). I'm also reminded of Rich Hickey's talk on the essence of data.


5/3/2020 | Enterprise Dev to Self Employed, 5 month followup

Wow! My original post (below), got over 1,000 views, opened many new connections, and I got to respond to everybody that wrote me on email (which I encourage you to do as well!).

It's been about 4.5 months, since I wrote that, and I've experienced a couple of months of React contracting and a lot of C# & .NET Blazor work! It's been a success, even though I had to sell my car to make the first couple of months happen.

My results were 2 jobs landed, 1 outbound and 1 inbound. The data: I posted once on the HN freelancer thread in October, and once in November. I reached out to about 5 people I could have helped out, 1 turned into a gig. 1 was a really sketchy person who insisted everything was under NDA and he could only pay me in crypto, so I avoided going further down that path. Lastly, I got 1 inbound gig, that turned into a full time job (which I wasn't aiming for, but couldn't pass up).

Breaking it down further, I got the first gig by reaching out to someone who was seeking an intermediate android developer. We scheduled a call, chatted, happened to have a lot in common and he ended up letting me work on another project instead which wasn't advertised, and ended up being React! The second gig was really more of a take home job interview project that I got paid for. I had to build a pretty basic CRUD app to show that I knew what I was doing. Importantly, the only reason I even got the "interview" was because I had a Twitter. On Twitter, many months before, I had decided I wanted to get really good with .NET Blazor, a new Single Page App paradigm, so I put ".NET Blazor expert" in my Twitter bio as an aspirational public goal. I had no itention of anyone hiring me based on that data point, but it just so happened that my boss was looking for a Blazor person. I was totally forthcoming about my actual level of Blazor skill once we talked and he said he needed me for Blazor.

The biggest takeaway from following and generating leads so far, has been simple: It doesn't happen like you anticipate. Both gigs were totally indirect opportunities, but I can say that it helped that I had a twitter and blog tied directly to my name and hacker news profile.

Now, the actual job - I've been a .NET Blazor "expert" since early January this year, and to be honest, at the pace my team works at, I could easily be in the top percentage of Blazor server developers just because we work rapidly and only make new things! No rewrites means I have cranked out many new features each week since January, which counts for something. However, I still have a long way to go in the .NET ecosystem, and my coworkers literally have 10x the amount of experience in .NET than I do, so they are truly experts on the platform.

Anyways, I was more than happy to take this as a full time job, purely for the fact that my coworkers are experts. It's just icing on the cake that we use cutting edge technology, only work on MVP's, and are about to build a product in our spare time. Oh, and the pay is better than my big-corp job and it's remote. These are the reasons I will intentionally be ignorant of my selection bias and luck, and recommend for others to follow suit and leave big-corp America! There are sweet opportunities out there if you are willing to give up some safety. Some of you might have better luck, and others might take a bit longer to find an opportunity. Of course, you can always try to get consulting going in the evenings while you have your job, so you can minimize the risk.

The sad part of this story is that I have not been able to work with Clojure for $ yet. I'm still holding onto hope, and maybe I can even convince my boss to use it on a product, but until then, I'll just fire up emacs and toy with it here and there.

The last thing I want to say is that I haven't invested much energy into my twitter, which I'm trying to grow. I did take down my aspirational title of ".NET Blazor Expert", but as part of my online journey into opportunity I'm going to be documenting what I've learned, tips, and such on there. I occasionally tweet about investing (stocks/derivatives) and Sweden as well:) If you have questions or want to say hey, feel free to email me at j3elam+hey@gmail.com or dm me at @elamje


4/29/2020 | C# missed the rocket ship

Sparked by my curiousity of why SQL Server only has language extension support for Java. I think it has to do with Data Engineering

C# missed the big data rocket ship. Do orgs use C# for data workloads? Of course. But It could have become the defacto standard for Big Data had it been less restrictive and platform specific in the early days of explosive data growth. I think it was a mistake that is a similar order or magnitude to missing out on smartphones.

There is no doubt that Microsoft had the resources in the early 2000's to create something akin to .NET Core, but for whatever reason, they missed the mark. No cross platform usage meant companies like Google, Twitter, etc. could not use .NET and C# on linux servers and so it struggled to get the same kind of adoption by orgs that operate at that scale. Instead Java and the JVM became king of big data.

1/8/2020 | 1 year on Hacker News

You might be wondering, why it matters that I've been on a link aggregator for 1 year. Well, for most people it probably doesn't. However, for me it has led to an inner revival, contract work, learning Clojure, meeting people, understanding leverage, and an awesome new job. Thanks HN.

The following thank you is a bit unstructured, but I hope this might resonate with with you. If you don't want to read further, just check out my favorite threads on HN!

Awoken geek!

The first thing that HN unlocked for me, was the inner nerd that had died the day I believed that the only way to get wealthy was to do finance, medicine or law. As much as I loved my engineering courses in high school and college, at some point I began to think the only way to be successful was to be engaged in those fields, or be an engineering executive. When I found Hacker News, I was delightfully flooded with a wave of people who were obsessed with learning, entrepreneurship, and generally, thought-provoking stuff. Many threads and comments were incredibly nuanced, and some had occasional software or startup celebrity appearances. The contrast between my friends' interests and the online people I found, was large, so it made the discovery of HN that much better. I had learned what its like to have a large group of people gathered based solely on interests.

You can make money doing that?!

The second thing HN unlocked for me was wonderful short term career prospects. I found people all over the US, and world, working with their technology of choice, making non trivial sums of money doing consulting work. Not to mention the huge corpus of startups and startup employees on HN. To understand why this was news to me, you need some context.

To give you a very quick background, I was an undergrad studying computer engineering , torn if I should pursue a career in software, machine learning, or hardware design. Long story short, I got a job working at a large company working on a large enterprise C# app that was very hard to understand. So, after I got my head around web app principles, I quickly realized I was going to have to spend several years there to understand the app and its domain fully, or even have a senior enough position to guide its architecture. When I took the job, I didn't understand that, web software, or what other career paths were possible in software. I wanted fast career growth and fast skill acquisition. About the time I realized this I began seeing startups and contracting as a viable alternative. This realization manifested in seriously reconsidering my current career trajectory.

Clojure, so little code, so much power!

The third thing HN unlocked for me, was the joy of writing software. Lisp (Clojure specifically) showed me that I didn't need to write a 100 line Java class just to do basic text parsing. This was a wonderful departure from the boring projects I was assigned in college.

I realized there are languages without boilerplate. I realized the incredible amount of open-source languages that exist. I realized that dynamic, terse languages like Clojure are a superpower. The most important thing you can do for your business or project is minimize all of the boilerplate and you should really use a language that gets out of your way, and is a pleasure to use, lest your project get buried in the GitHub graveyard.

Realizing all of PG's hype about Lisp was rightfully placed was a wonderful feeling. Learning Clojure was the most enlightening thing I have ever done for my software career. No classes? Your code can be manipulated as easily as data? Rick Hickey? Each of these were transformative coming from my C++, C#, and Java background. I realized what it was like to enjoy writing code, and importantly, this sparked motivation and creativity for projects that I would have never set out to do.

Leverage is key!

The fourth thing HN unlocked for me, was the assurance that I am in the perfect field. I don't know, maybe I'm buying into some VC backed BS, hype train that promises to have a fun career that has high financial reward, but there are very real examples of software people solving problems(typically on the web), with a little bit of code and marketing, that have very real, large economic impact. Back when I was a hardware design intern in college I didn't see any legitimate way to do this inside of the engineering world. Luckily HN has many examples of how this is false.

Code is one of the easiest, and most powerful forms of leverage that us software people have at our disposal. I didn't understand this when I first started my big corp job, but it quickly became clear that the successful internet companies and startups all did one thing - write code. At some point the Econ 101 of software clicked, and it was obvious that very few industries that have access to a global, low cost distribution network (internet) and have a cheap army of robots willing to do whatever you code. This is what makes it possible to have monopoly like profit margins, without having a monopoly. Once this clicked, I simply couldn't be content with a salary job that has no equity, slow career growth, and very little creative freedom. This lead to job searching in startup land, building my own MVP, and also moving to contract work. Understanding leverage led me to alter my path to better utilize software and capture value, that I just never would have got working as an enterprise developer.

New jobs!

The last thing that HN has unlocked for me thus far is contract work and jobs! I am always looking for opportunities to get better at software, but man is it great to get paid to get better. Remember when I said that I wasn't content at my big corp job - well, it turns out the only reason I had the boldness to leave without anything else lined up is because I read a lot of comments and posts from other HNers that took the plunge. Wow, was it exactly what I needed to do! Earlier I mentioned wanting fast career growth and fast skill acquisition; taking two months to build an MVP in a new language was great for that, as was doing contract work with a new technology. To top it off, I was lucky enough for a top-tier C# consulting shop to reach out with an opportunity that I'll be starting tomorrow. Each of these things were a direct result of being engaged on HN! Thanks Hacker News!

If you want to say hey, email me at j3elam+hey@gmail.com. If you consider yourself a good writer and have any tips, please email j3elam+writing@gmail.com.


1/2/2020 | Monte Πthon - Monte Carlo, Π, and 8 lines of Python

I don't normally talk about math, but I thought this was too magical not to share! If you are like me, you have heard of Monte Carlo simulations and wondered what they are. I don't use them enough to give you a definition, so I will just share an intuitive example of how to use them. I'll start by saying that I am a computer engineer that primarily does web apps, although I'm interested in other spaces. However, being an engineer, developer, or math genius is certainly not required to continue. The aim of this is to show you a simple way to understand and internalize basic monte carlo methods! We are going to calculate π. You can jump to the code, or develop the intuition first.

Essentially, we will randomly drop many points into a square with a known area, count how many points also lie inside a circle, then use the ratio - points in circle to total points - and some other information to calculate π. Let's look at the equations we need to do this.

The border of circle is made with x-y points that satisfy x^2 + y^2 = r^2, where r is the desired radius. The area of a circle is π * r^2. We will arbitrarily pick r = . 5. Given x-y points, we can find points inside of that circle by checking if x^2 + y^2 < (. 5)^2

radius = . 5 with 10 random x-y points.

In the figure above, you can see that there are 6 points in the circle, and 10 points total, so 6 / 10 is the ratio that represents points in circle to points in square. We will multiply the ratio by area(square) to get area(circle), which in this case, is 6 / 10. Recall, this square has an area of 1, so the area(circle) is just equal to the ratio.

Since area(circle) = π * r^2, we can rearrange such that π = area(circle) / r^2. In our case π = area(circle) / (. 5)^2. At this point we have two unknowns, π and the area(circle). To solve for π, we need an estimate for the area(circle); if you recall, we just calculated this! It's 6 / 10.

And boom! Just like that, we have a method to solve for π. In the picture above, π is (6 / 10) / (. 5)^2, which is 4. To get more accurate, lets write code so the computer can do these steps for us. If you run the code below, you will see that the output gets closer and closer to π's true value(3.141592...) as we increase the number of points. You see that we solved for two unknowns by estimating one of them (area of circle) with random data. As the random data got larger, our estimation got more accurate, and the estimation for π came closer to the truth. I think this is quite magical.

Press the green, play button to run for yourself!

Code explained:
  • Line 1: import library to generate random x-y points
  • Line 4: initialize count of points in circle
  • Line 5: generate random points in 1x1 square
  • Line 7 & 8: if point is in circle, add to count
  • Line 9: calculate ratio of points in circle to total points
  • Line 10: π = circle_area divided by radius squared

If you also think this is magical, I highly recommend this short youtube video of a completely unrelated way that π occurs naturally. If you understand why π appears in the Mandelbrot set, please email me at j3elam+pi@gmail.com. If you use monte carlo simulations regularly, I would love to hear how you use them for complex problems. Reach out at the +π email or say hey at j3elam+hey@gmail.com!

Submit this with https://www.towardssoftware.com/blog#blog28


John Elam @elamje

I am a consulting software engineer living in Boulder, CO - primarily working with Clojure, Python, .NET & React. I am mainly interested in helping people make stupid simple software, ideally from scratch or very early on (startups and new projects). I also work with mature small & medium sized, non-tech firms to make custom software.

Not available for clojure, python, react, or data engineering projects at the moment. j3elam+consulting@gmail.com

Previously, I worked at PwC, and pre-previously studied Computer Engineering at the University of Texas. Since leaving corporate work I have been making better software, and had time to create several projects which will be linked here in the future. I also run a pearl business.

I am highly interested in high speed rail, hyperloop, and generally, fast transport. Additionally, snowboarding and hiking are a passion. If you are working on anything cool in any of these spaces, I'd love to help out.

See some of my work.

See what I'm up to now.


12/21/2019 | Migrating from Enterprise C# to Self Employed Clojure & React

Over the past 9 months, I've been somewhat enlightened by a new kind of work that exists for software engineers. I'm going to try to paint a picture of my transition, as well as explain why it could be worth it. You can skip to the pro & con list below, or read the background:-).

I'm currently 3 months into an exploratory hiatus from corporate life, and I've been enjoying it massively. About 18 months ago, I was a fresh grad from UT Austin and extremely enthused to start my career in software engineering. I had just gotten a job at PwC, and was somewhat clueless as to what software development was, or could be, as a career. I quickly learned C#, which was my daily language in an enterprise that heavily used the Microsoft stack, and quickly felt stagnation in challenge and learning. It wasn't that things were easy, but for some reason my first year out of the gate was mostly incredibly boring HTML, CSS, and C# copy/paste style coding due to an incredibly mature application (think in the millions of lines of code) that had some hard to grasp domain knowledge caked in.

Somewhere in that time I organically stumbled upon Paul Graham, then his essays, and eventually, Hacker News. That orange site profoundly changed the way I saw my career trajectory. Likely, I could, like many older developers around me, stay there for 10-20 years and end up making $200,000+ a year in a cheap, major city, or possibly make partner and double or triple that, but life is too short to wait 10-20 years for an abstract possibility, so I began absorbing all content I possibly could from Hacker News.

Three key elements presented themselves to me while browsing - startups, importance of ownership, and fun programming. In startups, I saw the wonderful ability to not deal with typical corporate BS (I loved PwC, but I really don't care to watch 40 hours of accounting ethics videos, annually). In ownership, I saw that really having equity in anything, software related or not, is the only way to build wealth that grows non-linearly with time input (thanks Naval Ravikant). In fun programming I found Clojure. With it I realized I can increase the joy of programming, and decrease boilerplate code by a magnitude simply by using it, rather than Java or C#. (Not to mention the magic of LISP!)

Of course, many people don't get wealthy quickly from startups, or just coding. I realized some things in life just take time. With patience in mind, but impatience with my corporate programming growth, I knew I needed something that would be more challenging and provide greenfield projects with architectural decisions. I didn't sense those things would happen quickly at my job, so I spent most of my nights that year learning Clojure, Rust and making a Python web app. Towards the end of the year I decided that I really needed to jump off of the deep end and spend some time trying to make something from scratch, while figuring out what I could do to earn money.

The biggest fears were that I wouldn't have healthcare and I would have to watch my savings account deplete. Both of those things will likely be true for you if you do this. Ultimately, I decided it was worth it, so I set out without a clear short-term plan to make money. I had vague ideas that I wanted to sell pearl jewelry, consult in software (thanks patio11), and make a SaaS MVP (read more here).

I'm in the middle of all three of those things now, and it's starting to feel normal. I'm working on some contract work I got through Hacker News, making pearl jewelry (eventually want to become an importer), and am basically done with that SaaS MVP. It's certainly more dynamic work, but you might find that it's hard to explain what you do at Thanksgiving and Christmas! I am not sure what the next steps are, but I'm very grateful to PwC for providing a small cushion for this time, and to Hacker News people for catalyzing these realizations.

While I have higher ambitions and put much more thought into this than the above paragraphs portray, I want to list some reasons why this work style may, or may not, suit you.

There is essentially unlimited schedule flexibility meaning your best hours of the day aren't given to your employer with the tradeoff that you must remain disciplined. There is very high earning potential for starting a business, or consulting as a software developer with the tradeoff of not having steady income or any benefits. There is potential to work on fast paced, dynamic projects using tech that's more interesting to you with the tradeoff that you also might not have work to do for long periods of time. There is potential to work 100 hours a week making every penny of it as a contractor with the tradeoff that you no longer are guaranteed at least 40 hours of work. There is potential to work less with the tradeoff that you likely won't earn more. There is the ability to work for 13 hours straight in mental flow without slack and email pings with the tradeoff that you may feel isolated. There is time to meet with friends and family at any point in the day with the tradeoff that your friends and family might not respect your working hours like you wish. You now will get paid for overtime and deadline pushes with the tradeoff that you no longer get paid to take off for holidays and vacation. Your pay can now be scaled as you please without waiting for an annual review with the tradeoff that you might not get work at your new rate. Your pay is limited by the wider contract market rate, or if lucky, by your niche expertise (with no competitive market rates) with the tradeoff that you have to justify the "Self-employed consultant" slot on your resume to all future employers who worry that you are hiding an unemployed period.

While the list above is certainly not exhaustive, these are some of things that crossed my mind when considering if self-employment was a good next step. If you are an ambitious engineer that feels inhibited by the corporate grind, you must determine if you have the power to change your workplace into what you want, or if you need to hit the eject button. If you are interested in more details or just want to chat, say hey at j3elam+hey@gmail.com.

To submit this use https://www.towardssoftware.com/blog#blog27


12/17/2019 | Why functional programming
It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures. - Alan Perlis (SICP Foreword)

There is an eternal debate around Object Oriented software vs Functional software, and there likely will never be a conclusion, however, this is why I choose Functional when possible.

The API problem is defined as this - for every abstraction and service we create with software, all consumers will have to spend time learning the API. If you are familiar with concept of domain-specific language, or DSL, you can start to understand the trouble here. As nice as an API is, it introduces a new pattern to follow. But, most importantly, it introduces a new pattern to learn. I first heard the term DSL when I was learning Clojure and LISP. Both give you a magical ability (Google-"homoiconic") to create new languages extremely rapidly, but when you create a new language, you make a DSL. While powerful, it's something new that outsiders will have to learn when reading or modifying your code.

The modern web developer knows APIs well. Typically, APIs are used to gain massive leverage and scalability, without having to write much code, or maintain a complex service. As anyone who has used powerful APIs knows, its great once its working, but most of your time is spent looking over the documentation (which sucks most of the time). If you are lucky, you might get it on the first try, but more likely, you have to keep searching through docs, blogs, and stack overflow to find the essence of what you are looking for. The trouble and frustration comes when you've assumed this service is going to plug and play and easy to set up, but you've just spent two hours learning a DSL that you don't really care to learn.

We don't want to learn an API specific pattern, shape, or json language, BUT WE OBJECT ORIENTED PROGRAMmers spend years making complex APIs.

Let me explain - objects have an API in OOP, we don't call it an "API", but that's effectively what the object is. We use an object, we get a contract that says you can call get(), set(), toString(), foo(), bar(), etc. Not only do our objects have an API layer to access functions/methods, but they have an API to access data (I cannot deny functional programming has a data API, also but I will explain why it's better). Back to objects.

Let's look at a class in .NET Core: PolicySchemeHandler. The actual class doesn't matter for our purposes, but if you're interested, it does some authentication related stuff. Now, if you haven't already, please open up that link and tell me which method sounds the most useful. You may have gotten sidetracked by the long method names, or the descriptions that don't actually say what the method does, but rather where it inherits from (sweet, more hyperlinks to follow to figure out how to use this class). This is the API that you are going to spend at least a few minutes learning, if a lot more. It takes almost a minute just to read the class declaration (public class PolicySchemeHandler : Microsoft.AspNetCore.Authentication.SignInAuthenticationHandler) That's a mouth full!

What I argue, is that this is one class out of hundreds! that your application might need, each with its own interface full of methods. This should not be. Each class you introduce or create for your project brings with it many, many methods that are specific to THAT class alone. Maybe you made a nice interface that required you to implement the sleep() method for the Human, Dog, and Cat classes. Likely, you just typed very similar methods for each one.

So, how does Functional Programming help? I have been spoiled by Clojure, so my opinion will be somewhat colored by my experience with it. In Clojure, we use maps, seqs, vectors, lists, a few other primitive data structures to do all of what a class previously did for us. Something wonderful about this is that I can make 1 function that will accept all of the aforementioned data structures as a parameter and return the correct answer. No need to implement sleep() 3 times (or 100 times for that nasty app you get paid to work on). You implement it once, and it does the magic. You pass in a map with your own shape to represent a human, dog, or cat, and the function treats them all the same.

Would you rather have 1 sleep function for 100 different animal types, or 100 different animal classes with their own sleep method?

This is not a cherry-picked example, this is the norm. You can gain massive leverage by just treating all data as what it is: data! Instead of treating it like an object that is rigid and forces the burden of implementation detail on YOU.

To submit this use https://www.towardssoftware.com/blog#blog26


12/14/2019 | 2020 goals
  • Proficiency in Clojure
  • Proficiency in C#
  • Intermediate Swedish
  • Beginner Russian
  • Option Pricing
  • To Be Continued

12/8/2019 | The perfect web framework

In essence, a web framework does one thing - transform text based on a request and some state. So where does complexity arise? Aren't all web frameworks accomplishing the same goal? Let's dream up the world's most simple web page, then build a web framework from there.

You might have guessed it; the world's most simple webpage is literally just text. Notice most tutorials and most frameworks make sure the configuration is correct by displaying "hello" on a webpage. That's it. No authentication, no file uploads, no POST requests, just a single GET request to show a string.

Note: the remainder of this post will be in Clojure, but the implementation language is just a detail. The idea is that this framework should be so simple, it can be ported to other languages in a few hours. Regarding Clojure - I had to choose a web server to get started, however, this is also just a detail, and the code shared should be portable across servers.

So, at this point our framework does nothing. Let's think about the simplest abstraction for what our web framework will do (remember - we need to transform text based on the request and maybe some state). We need our structure to be composable (linearly independent units that can be added together), flexible (order independent, interoperable), and efficient (fast, minimize blocking time with async). These units are commonly referred to as middleware.

Let's use a unit of work that is naturally composable - a function. Since functions take arguments, keep simplicity in mind and only accept one argument, a request. Now there is a concrete way to move forward - functions that each have some unit of work that they accomplish via a transformation to the request.

Here we define a function respond-hello with a single parameter "req". This function does not do anything with the request, but simply returns a 200 OK status with a text body of "hello".

Now, what functions should we make? Well, all we have is a request. We need to determine - where the request is going (routing), what type of request (GET, POST), and does the request need to persist some data (form)? Now how can we make structure these functions so they maintain maximum flexibility? Ideally the request will be piped though many functions until it is finally turned into a response and returned to the requester. Some functionality is needed by all requests - such as routing. Other functionality is only needed by certain requests - like authentication. It would be nice to have one central location for common middleware to transform the request, then other, less common middleware defined locally at each route or view.

To be continued...

TODOS:
  • Keep it simple
  • Transformations on request
  • Copy/Paste framework, so no deps and cross language.

12/6/2019 | Building a SaaS

A few months ago, I decided to quit my job at PwC, to make time capsules on the internet a bigger thing. The idea sprouted when I reflected on why I didn't have more pictures with my dad. 10 years after he passed I still don't understand. Now-a-days when people pass away, they lose their digital belongings - unless they're meticulous in their will. Most people are not. So, the Facebook account stays up, the LinkedIn profile is still around, and that Dropbox with 10,000 special photos in it, is just, in limbo. This makes me incredibly sad as I reflect on my dad's life. His digital self is still around, but I can't access it. I can't access those incredible moments that I only care about now. Many people want those photos. But, there is no unified way for this to be accomplished - every online service has their own procedure.

The fragmentation of one's digital life becomes hard for family to tie together after death. So, how do time capsules play a role in this? Well, directly, they don't. But in the short term, there needs to be an attractive feature while people are healthy, so that they can be nudged to make better end of life plans. Time capsules are nothing new, but they have some appeal. In essence, it does the opposite of what Snapchat did. Document & Photo access appear after a period of time, rather than disappear. So, the hope is that people will be attracted with the novelty of setting a time capsule to deliver to a grandchild 50 years in the future, which will serve as an entry point into the service for modern estate planning.

That gave me inspiration to start making Life Box (name will likely change). It's the solution to a problem that is near and dear to me, but also extremely personal to everyone. Death is no fun, wills are no fun, nothing about the deal is fun. So why is there still so much friction to this thing that happens to everyone? That's a problem that I'm willing to tackle, because I just don't know if anyone else will try. Why are funerals expensive? Why is the funeral home trying to upsell me while I'm a wreck? Where does all my data go when I die? Honestly, who knows? As a tech person I don't even know what happens for any online services I use.

Life Box, while in its infancy, doesn't have a lot of capability to help with these questions, but the roadmap is clear, the fruit is hanging so low, I have no doubt there will be a few people who will use something to make this process just a little more bearable. Life Box is enticing people to come for the time capsules, but hoping they stay for the full-service estate planning & digital archival tool.


12/4/2019 | Advent of Code with Clojure

After a several month hiatus from Clojure, I'm finally back into it thanks to Advent of Code. It's reminding me just how much leverage you get by using Clojure.

This solution, while not performant, illustrates just how different the Clojure paradigm is from say Python. What's it doing? looperb takes two numbers than define a 6 digit range. We then loop over all of the numbers in that range, testing for monotonically increasing digits, and two successive digits that are identical. Looperb counts how many numbers qualify with that predicate.


12/3/2019 | The economics of Google

Alternatively, this could be titled "Why Google kills so many products". I do not claim to be an economist or even an insider at Google. As for the numbers referenced here, only keep the magnitude in mind, they are not based on any published data. This was inspired by many scathing comments on Hacker News about the company's practice of killing off products. Here are my thoughts. First, consider a common engineering method.

Software engineers commonly make a prototype, get feedback either from users or metrics, then iterate. In software development this is a wonderful process because releasing to the world is easy and cheap. Development is the main expense.

As a product developer, or company, one seeks to lower costs and raise revenues, otherwise known a widening the profit margin. So, in software, this typically looks like lowering development costs, and acquiring more users of said software. The issue is that a lot of software has a somewhat fixed cost of development, so whether the software is used by 10 or 10,000,000, the development costs are the same. This brings us back to Google.

Simply put, the economics of software do not work in the favor of users of niche software made by a large organization. For Google, scaling to 10's of millions of users isn't the expense. Getting a product off of the ground, adding features, and fixing bugs is. So, here I (Google) am - 300 developers are tied up on a product that only has 50,000 users and isn't growing. However dedicated those users are, I (Google), as a profit maximizing entity, must immediately recognize this as a wasted resource, when we have many more products to launch and try to reach the holy-grail, hockey stick user growth.

Remember, Google doesn't make a ton of money per user of most products, so hitting the jackpot lottery is necessary to widen its margins. With high fixed development costs, and tiny marginal distribution costs, you must absolutely scale to millions of users rapidly or just wallow in low ROI land.

Wait...Aren't many of Google's loved products free? Yes, we have forgotten about the real economics here. Google needs your data. But, any data scientist or analyst would tell you that they don't need just your data, they need as many people's data as possible. Why? Statistic significance - Google needs to monetize millions of users at a time. When a product doesn't reach this scale, the data isn't as valuable since the aggregate can't be treated as significant (to Google anyways). Furthermore, there is the issue of how useful said data is, if it doesn't apply to a large portion of Google users. Somehow that data needs to be turned into advertising value, but if you don't have 100 million users of a data product, you have less of a value proposition for advertisers seeking very specific targets.

Software people appreciate iteration, but in Google's case, a lot of time iteration can mean its time to scrap a product. The key is that Google is a data company, not a message app or xyz company. Their key value proposition is just a ton of data, so if a particular product is free, and is lagging in the data creation department, it has to go. Google is iterating over products to find a data cash cow to monetize indirectly, but most companies are iterating on products to generate money directly.

Most of us aren't used to this. Many SaaS products we use are the bread and butter of the company who makes them. They would never drop their flagship product. Unfortunately, Google's flagship product is data, not any of these products . And so, we are left to greive with result of using products from a data company, rather than using products of a product company.


4/18/2019 | The power of Clojure

Since undergrad, my project structure would look something like:

    --- Number.java ---
  • print {...}
  • + {...}
  • toString {...}
    --- Int.java ---
  • print {...}
  • + {...}
  • toString {...}

Basically, each class would have the same 5 functions, with slightly different implementations to handle the peculiars of said class. The power of Clojure comes from only writing one class that can essentially take any data type and yield the proper result. Going through 4clojure.com, I see this power more and more with the test cases being different input data types, but the output just working. It's great.


4/5/2019 | Learning 2019 (Ordered)
  • Clojure
  • Call Option Pricing
  • Rust/Embedded
  • Elixir
  • WebAssembly
  • Soviet Russia
  • Limited Partnership Structure

4/4/2019 | Push Notifications are extremely effective

If push notifications were made to push users away from notifications, I would say they are very effective. No, most people are fine with the bombardment of banner notifications and constant pings. I am not one of them.

In the last 3 years I have almost completely shut out all social apps, and for the ones I still have,there are no notifications besides the badge count. Effectively, I have all my attention back. It took a really, really long time for me to shun group chats, news, social media, and just about all forms of contact besides call and text. Interestingly, this practice has coincided with my most peaceful teen/adult years and I think there is a real reason for this.


3/21/2019 | Savings/Emergency Fund

A while back I moved my banking from Wells Fargo to Charles Schwab. The biggest reason being the constant fees at Wells, and the not so great investment options. Moving to Schwab was a breath of fresh air, absolutely no fees for banking, and they refund all ATM fees you incur! The brokerage account has much more to offer than Wells Fargo Advisors, so it just was all-around better. One thing I appreciate the most is that Schwab gives me the ability to directly buy T-bills, instead of being forced to use an account with Treasury like I had to do when I was at Wells Fargo. Right now, these typically yield 2 - 2.5% for bills that mature in under 6 months. It's perfect to use that as an emergency fund, as I don't miss out on interest, and bills are maturing and being reinvested on a rolling basis. The most I would need to wait for the bills to mature is a few weeks, rather than the comparable CD's that tie your money up for years at a time like a Private Equity fund, but yield only slightly better than T-bills.

Long story short, I recommend using Schwab, and I also recommend using the brokerage account(which is automatically opened in sync with Schwab checking) to buy T-bills in intervals so you can use it as emergency money. There are no transaction fees to do this, so it's a nice way to at least keep pace with inflation.


3/4/2019 | Clojure is mind blowing...

Since most of friends aren't CS people, they will not understand, but I wish they could. And I understand that saying this makes me a super nerd, but it's too amazing to ignore. Functional programming, e.g. Clojure, is blowing my mind. Coming from a background of heavy Java and Python in college,I learned that OOP is the only way, but now I feel as if my mind has expanded. For my non-tech friends, I wish I could port my pre-clojure technology skills to their brain, then introduce them to clojure so they could experience the awesome thing that is functional programming,but for now, posting it here will have to do :'-(


2/25/2019 | (--> clojure (get-path-to) (println))

Clojure is amazing, especially coming from an OOP background. I feel like I'm doing next level/meta stuff, with ease, and I'm doing it in 10% of the text as a comparable Java or C# program.

How did I get here? news.ycombinator.com --> paulgraham.com --> "Learn LISP now!" --> SICP --> Scheme --> Ask HN for LISP learning peers --> start project in Clojure --> have free time at work --> here.


2/18/2019 | Awesome Videos, Naval, Scott Adams, Kevin Simler

Over the past week, I have absorbed more naval content than I thought possible. From that, I have found Scott Adams and Kevin Simler, both of which will provide me with a lot of food for thought. I can't wait to digest both of their blogs. (link credit: Kevin Simler)


2/14/2019 | Going Long, Antifragile

One of my favorite books, Antifragile, harps on the point of giving yourself asymmetric, non-linear outcomes. How? Well, you want to make sure you are in a position where the best case has nearly limitless gain, and the worst case is a 1x loss. I believe Naval Ravikant said something along these lines - he wants to play games where the best outcome is a 10,000x positive return, and the worst case is a 1x negative return. These concepts are extremely relevant for tech, venture capital, and options trading.

With those things being said, I want to shift my own portfolio, lifestyle, and career to capture these things. I believe by using long call options and tech I can maximize E[X]. Today, I will start on that journey and keep the blog updated with the results on a semi-regular basis, acknowledging that it might take 10+ years to pull away from the crowd.


2/13/2019 | A treat from the Robinhood API

Today I was playing with Robinhood's API(No official API exists), and I found this nice message at api.robinhood.com/marketdata


2/11/2019 | Spotify Economics

Typically, I think Spotify does a great job of introducing me to new music through the Discovery playlist and some others that are similar. I typically find artists that are smaller, that I have never heard of and I appreciate that. However, the other day someone brought Spotify's economics to my attention when they decide what to give you on these type of playlists. To Spotify, I'm sure they want me to enjoy the playlists, but they also want to push users to lower cost music, which would most likely be smaller artists that don't have expensive royalty fees. I've never thought about that, and the possible bias that introduces into the alogorithms that generate these playlists. Originally I could imagine Spotify's machine learning would optimize for song similarity and probability of a user adding it to their collection, but now I think there might be a more important optimization - cost. With all of that being said, the discovery playlists are still great, but some people have complaints about this fact.


2/10/2019 | Convictions

For most of my life I believed in convictions, these truths of the world that exist only in black and white. Sometime around junior year of college, I began to question if they really were black and white or not. Now, I am only convicted that there are very few convictions to have in life.


2/4/2019 | Gigs vs. The Corporation

It seems to me that the gig economy is inevitable at this point. One day we will get work assigned through API's, work flexible hours, and ultimately, do what we want.

Why is this inevitable? Well, three reasons: people want schedule flexibility, people want to work on personally meaningful things, and the current system kind of sucks.

What does a corporation do right now? Well, for most, the corporation just gives you a reason (social and financial) to do something you wouldn't choose to do, at a time(of day and year) you wouldn't choose to do it.

Right now, only (generally) lower-paying, service jobs like Uber and contracting work well under this model. Startups seem to be moving towards this gig style of work, with increasing remote work and vacation flexibility. Only time will tell.


2/3/2019 | Personal Finance Favorites

Here are my favorite apps, websites, and software for finances.

Personal Banking: Charles Schwab -- weird choice right? Well, if you travel internationally with any frequency, or prolonged amount of time, it's hands down the best option as of this writing. The best features are unlimited, free ATM withdrawals at ANY ATM internationally, a decent account interest rate for a large bank, a good mobile app, and NO fees period. The downsides are no physical locations(so you are limited to interbank transfer, or mobile check deposit) and less appealing interest yields than some smaller banks. It's easier than you think to go all internet banking with Schwab, but it's nice to have a secondary bank account elsewhere to be able to deposit cash with the other bank then transfer to Schwab. Back to international banking: It's wonderful to avoid all service fees, overdraft fees, ATM fees, and international charge fees. Furthermore, when you make a transaction internationally, the exchange rate is extremely good, like they basically pass the VISA exchange rate directly to you with no markup. If having a physical presense is important to you, this is the next best option. The mobile deposit works extremely well, and they allow you "Add External Accounts", which lets you see your other banks' account balances, and make free transfers between the two!

Investing/Brokerage: Robinhood and Charles Schwab -- I recommend both because Robinhood is just so clean and simple(and free), and Schwab is so established, with a lot more to offer outside of the stock market. Robinhood is great, just great, if you have fun money, or like to check prices, but if you have a large portfolio, I would argue the app almost makes you instinctively a short term investor with bright red colors to make you sell on a bad day. Additionally, they have some interesting deals set up with High Frequency Trading firms like Citadel and Virtu which makes me think that you are getting pretty bad prices. I can't prove that, but they are the only big player offering free trading and they make more Payment for Order Flow than most brokerages. This probably only means anything if your trades are in the thousands of dollars, otherwise the bad prices probably are still better than dropping $5 or $10 at a traditional brokerage. Charles Schwab is cool because the have a cash sweep to take your uninvested cash and give you a small return(Robinhood takes that return for themselves), and they offer bonds, option strategies, CD's, and money markets, as well as foreign stocks. Schwab has modest trading fees for people with more capital, but if you just have a few thousand dollars, the fees will eat a non-negligible amount of your return.

Savings/Envelope/Retirement: Acorns -- Acorns is an app that is pretty simply, with small fees. the two products I like are Acorns Core, and Acorns Later. The Core account gets funded by one-time transfers, recurring transfers, or by "round ups". "Round ups" simply track your card purchases and round them up to the next dollar, transferring the difference to your Acorns account. This works really well for people who use their card a lot as it gives you a way to do yourself a favor for later by saving and investing more, the more you swipe. The Later account takes one-time transfers and recurring transfers, then allows you to select if you would like a Traditional or Roth IRA to invest them in. An important, distinguishing feature of the Core is that your investment options are streamlined into 5 options based on risk and exposure. You can look at the app to see exactly which percentage goes to which index fund or investment type. It is able to give you a relatively easy way to invest in index funds and still have a choice, but not be paralyzed by the number of funds available. Later, on the other hand has the same 5 categories, but it automatically puts you into the category based on your age. Younger age puts you in the "Aggressive" setting with mostly stocks, and older age puts you in the "Conservative" setting with more bonds.

Budgeting: You Need A Budget, aka YNAB -- Unlike this app's long name, the app is concise and simple to use. I have enjoyed using it for the past few days after months of struggling on Intuit's Mint. The key difference is Mint is free with advertisements, and YNAB is $7 a month. YNAB however has a much simpler UI, and even conceptually is simpler. Instead of just tracking and trying to self-limit expenses, you give every dollar a job(like enveloping). If one category runs out of money, you must pull funds from another category to use going forward. This helps you regulate and never overspend your overall budget, regardless of a sub-category staying in budget. YNAB imports all transactions directly from your bank or allows you to manually add if you would prefer. Ultimately Mint and YNAB differ in pricing, UI, and budget style. If you are squeezing by, then saving $7 a month and trying Mint would be worth it, otherwise, I think YNAB is a better budgeting style/solution.


2/2/2019 | My current reading list

  • Lenin's Tomb
  • Zero to One
  • Structure and Interpretation of Computer Programs
  • Chaos

  • 1/22/2019 | Tunneling webapp to url

    Today, on Hacker News someone showed their new macOS app for tunneling a webapp to a url, and it jumpstarted my desire to do that for my webapp. I am hoping to try either ngrok(not new) or emporter.app to get my webapp online. I have enjoyed how repl.it allows this with minimal friction on their ide and I have wanted to do it for lifebox for some time.


    1/16/2019 | Information Consumption

    The past couple of days, I have spent so much time consuming information, mostly on Medium, Twitter, Farnam Street, and Hacker News. I have just been spending every moment I can taking in information. It makes me wonder if that is a net positive or if I am eating junk (brain) food.

    I am reasonably certain that the quality of Hacker News and Farnam Street is really good and well thought out, but the other two sources I am not as confident about. I am concerned that what I read on Medium is really just opinion pieces put out by the masses and packaged inside of intellectual lingo, but substantially lacking, on average. For example, I really enjoy Nassim Taleb and Naval Ravikant, and, previously, Signal v. Noise, but I find myself on the home page scrolling through random names and catchy titles and I just get the feeling that Medium isn't what I initially thought.

    Initially, I was attracted to the platform due to several bloggers (listed above), but as I created an account and eventually found myself reading other people's content, I wasn't very impressed. It seems that it is most likely a nice UI to dress up a bunch of BS articles, but nonetheless I still go there occasionally.

    What I'm really enjoying, although it is full of noise, is Twitter. I have curated a list of people that I follow and it really does seem to filter a lot of the noise that social media typically has. People still criticize Twitter for being a terrible platform with an unsucessful business model, but there is a ton of good content on there,and something special about the brevity of each tweet.


    1/12/2019 | barkparkdallas.com

    Today I purchased barkparkdallas.com because I'm tired of going to the dog park by my house when it is muddy. I thought I could make a website to have other people post that it is muddy, then save their fellow dog owners some precious time.


    1/11/2019 | Short Book List

  • Rework
  • Antifragile
  • Structure and Interpretation of Computer Programs
  • Poor Charlie's Almanac
  • Thinking Fast and Slow
  • TODO: Art of Programming

  • 1/11/2019 | Pareto

    Today I spent most of my time on this website trying to get the little black bar formatted correctly so it would render and provide a small amount of help for readers when looking at my linear list of blog posts. It basically acts as an indicator for when one post starts and ends, and does nothing else special.

    It reminded me of how much disproportionate effort goes into design and UI, rather than html and content. This reminded me of the pareto principle - essentially 80% of this blog's content took 20% of my time. The other 80% of my time was spent on marginal changes.


    1/11/2019 | Origins

    I can't remember how I found repl.it I think it had something to do with talking to my friends about some things I wanted to get done in 2019 - learning lisp was one of them. I think that led me to a google of best browser IDE's so I didn't have to install Scheme on my PC, and here we are.

    I ended up creating an account and started playing with Scheme. A couple of days later, i.e. today, as I am writing, I saw a link that you could host your own webpage on a repl subdomain and that seemed interesting. The appeal is this is much more simple than finding a bad wordpress service that one would have to pay $20 a year to use, then spend hours trying to get the formating and aesthetic right.

    I can appreciate how simple Paul Graham keeps his personal website, so I figured this could work well for me.
    (side note: his website is currently served over http, so repl blocks the redirect)

    Overall repl seems pretty nice and I can see myself making cool snippets on here in the future, but for now I plan to host a simple blog to complement my twitter activity.