February 7, 2022
What follows is an explanation of projects in my GitHub repositories.
Sculler is an iOS app for rowers that enables them to race their best 2k possible. It does this by showing them in real time, the optimal boat speed at which they need to be rowing at to achieve their goal. “Optimal” means “the speed that will hit my goal exactly”. This is important because when dealing with a difficult goal, the rower doesn’t want to go too slow, since the goal won’t be met, but also runs the risk of going too fast and burning out.
It is useful to be able to ask the question: “Given where I am in this race, at what pace should I row to neither burn out, nor fall behind?”. At every second of the race, Sculler will show a gauge, which holds the answer to that question.
It also includes an Apple Watch app, which writes a workout to the Health app and will show the rower’s heartrate on the screen as they row.
Sculler is written in Swift and C++, and uses SwiftUI for 100% of the interface (ie. no meaningful use of UIKit).
This was a CocoaPod I wrote not long after iOS 7 came out. The goal was to create an absolutely brain-dead way to utilize the
UIMotionEffect API to make a view appear as if it was floating above the screen or recessed behind it (much like the app icons on the homepage).
I’d wished I could simply specify a property on a view to specify its “elevation” rather than write a lot of code using the
I was able to write a category on UIView to do this. It added an extra
parallaxIntensity property to all UIViews (Naming properties is hard. It wasn’t until later when I saw the word “Elevation” in Google’s material design that I wished I’d named my property the same.). This was also settable via Interface Builder so no coding was necessary.
To make this work, I used associated objects using the Objective-C Runtime API
I worked in Elixir full-time for 18 months and it profoundly changed how I think about writing multithreaded code.
Phoenix Draw is a small collaborative white-boarding app in Elixir that uses WebSockets to communicate all the pen-strokes to the other sites in realtime. Elixir is a natural fit for WebSockets and I was quite impressed at how responsive the resulting app was.
NOTE: there is a small delay as heroku starts the app
For a quick demo, open up two browser windows and start drawing in one. But for a really good time, send the site to a friend. It’s a lot of fun when you both draw together.
This is a Ruby extension that extends the language to provide support for Lisp-style Conditions and Restarts.
After reading the Beyond Exception Handling: Conditions and Restarts chapter of Practical Common Lisp I became very jealous of Common Lisp’s notion of exception handling. Rather than pop the stack up to a catching point, code could provide recovery code for any exception that might occur and that code would be executed at the place in the stack where the exceptional situation was created.
I thought I might be able to provide this facility in a very Ruby-ish way. I largely succeeded in that I could make the recovery code execute in the context of the stack frame where the exception was raised. However, I couldn’t prevent the exception from executing all the
ensure cases when the exception was raised which would be required to have a system like Lisp’s.
All in all, I learned a lot about exception-handling in Ruby, and writing native extensions.
While I was working on building code in Rake, I had need of the ability to call one Rake project as a sub-project of another Rake project. With that in mind, I made a gem that would expose all the tasks in a Rake subproject to the Rake superproject with a simple
subproject command inside the super-project.
I contributed code to the Rake project which added the ability to cap the number of MultiTasks that would execute simultaneously.