kmarekspartz

Expanding our capacity to respond to unforeseen changes

Proposed optional assignment operator in Swift


In Swift, given a variable x of type Optional<T>, how can guarantee it is not nil? You can force the unwrapping, but this may result in a runtime error. What if we could set x to some default value? We can manually, but this can be cumbersome to do often, so let's make an operator! This is a good chance to learn about Swift's optionals, generics, custom operators, and in-out parameters.[^1]

operator infix ~= {}

@assignment func ~=<T>(inout lhs: Optional<T>, rhs: T) {
    if lhs == nil {
        lhs = rhs
    }
}

var x: String? = "nil"
var y: String? = nil

x ~= "Test"
y ~= "Test"

x  // "nil"
y  // "Test" 

I'd prefer ?= but ? is not allowed in custom operators.

[^1]: I apologize for the poor syntax highlighting!

Some thoughts on Swift


Apple surprised the world at this year's WWDC: They have been secretly working on a new programming language, Swift, designed to minimize their reliance on Objective-C.

They called it Objective-C minus the C. Considering that Objective-C augments the semantics of C with the syntax of Smalltalk, this would imply that we would be left with the syntax Smalltalk. I don't think that Swift's syntax is like Smalltalk at all. Instead, one could say that Swift has the semantics of Smalltalk (or Strongtalk) with the syntax of C.

While reading the introduction to Swift, I felt that the closest pre-existing language was Dart. There are quite a few differences, but there seems to be some convergent evolution. Given Lars Bak's work on Strongtalk, this isn't too surprising. Both are a departure from the Java and C++ object-orientation style, incorporating progress from type theory along the way.

I have a few issues with some of their language design decisions (which I plan to discuss in the coming weeks), but overall they made some good decisions (playgrounds!).

Automatically create Beeminder datapoints for posts in RSS/Atom feeds.


I've been manually keeping track of my blogging with Beeminder for the last few months. However, since my blog has a feed, why can't I have Beeminder automatically create datapoints from my feed?

Now I can. I created a script to check my feed every 24 hours and create datapoints for new posts using the Beeminder API, Hammock, feedparser, and Heroku. It is available on Github.

You'll need the following:

To configure and install mindfeed:

    git clone git@github.com:zeckalpha/mindfeed.git
    cd mindfeed
    heroku apps:create <somename>-mindfeed
    heroku config:set BEEMINDER_API_URL="https://www.beeminder.com/api/v1/"
    heroku config:set USERNAME=<your-beeminder-username>
    heroku config:set AUTH_TOKEN=<your-beeminder-authentication-token>
    heroku config:set GOAL=<your-beeminder-goal-name>
    heroku config:set FEED_URL=<your-feed-url>
    git push heroku master
    heroku scale worker=1

In related news, I've also added the graph for my Beeminder blogging goal to my blog index page, though I'm not yet sure how I want to organize the page–adding the list of tags and the Beeminder graph pushed the post list below the fold.

The source for this website is now publicly available.


There remain a few features that I'd like to add to this website, including links between adjacent posts, a list of recent posts in the side bar, automated building of my presentations and CV, and a Gophermap back-end. There's a great community around Hakyll, the static-site generator I use to compile this site, but discussing changes to my site without making the source available is no easy task. To facilitate this discussion, I've open sourced this website so that I can link to relevant portions when asking for assistance.

Announcing WX, a web app for weather stations


I have two Raspberry Pis from one of the first US batches and haven't done anything with them until just recently. I'm working toward a RPi weather station!

Instead of having the weather station be its own web server, since it may go in and out of range of the internet or lose power, I decided to make a web app and deploy it elsewhere. It also will allow the RPi to submit measurements via a Rest API.

Recently, I saw a lightning talk demonstrating the use of Peewee, and I thought it looked pretty neat. I decided to play with Peewee (no pun intended) by implementing a quick version of the Rest API and web app. So far I've gotten the Rest API and an Admin interface together, as Flask-Peewee does this automatically.

Today, I put WX on GitHub.

I'm going to make a branch with SQLAlchemy models so that I can directly compare the two. I'll be giving a talk at the upcoming PyMNtos Web Dev Meetup about their comparative strengths and weaknesses.

Eventually, I plan on using Hammock to implement a client that will run on one of my RPis to collect and submit weather measurements.

Announcing datetime-interval, a Python package.


Python's builtin datetime module provides useful representations of points in time (date and datetime) as well as durations of time (timedelta). However, it does not provide a representation of an interval of time, starting at a specific point and lasting for a duration. A representation such as this would be useful for representing calendar events. To fill this need, I've implemented datetime-interval.

datetime-interval provides two classes: Interval and PeriodicInterval. Interval provides a structure for keeping track of events with start and end times. PeriodicInterval provides a representation for recurring events, with a period and a count of occurrences.

I've not yet tested it or used it too extensively, so caveat operator. There are a few things that I'd like to add in before using it more:

  • Interval should have an isoformat method which returns strings of the form “start/end”.
    • This wouldn't work on PeriodicInterval, as recurring intervals have a different semantics in ISO 8601.
  • Property-based testing with props.
  • Add operators (in, +, –, *, [], etc.).
  • How to account for recurrences such as every Tuesday and Thursday.

On (not) reusing generators in Python

A friend of mine had an issue recently with a generator in Python. Here's the code:

def our_generator(input):
    while input:
        do(something, on, input)
        yield something

print(list(our_generator(input)))

for i in our_generator(input):
    do(something, else, with, i)

See the bug?

There was an issue with the for-loop, so the print statement was added in, but this changed the behavior of the program. Once the generator has expired, it can't be reused, so it never entered the for-loop. Since the generator would be exhausted anyway, we can get the expected behavior without additional cost by doing the following:

output = list(our_generator(input))

print(output)

for i in output:
    do(something, else, with, i)

Pictures from the fox hunt


Thanks to Matthew, N2PSR, here are some more pictures from this weekend's HF in the Park

A fox hunt


Mary, KEØALJ, got her ham radio license this past week. To celebrate, we went to HF in the Park. They had a fox hunt that I mentioned recently.

We assembled the 2 meter portion of our Cushcraft A270-6S for the fox hunt, as it was on the 2 meter band. Parry, KCØTWB, supplied the fox, based on the FoxBox.

Mary, KEØALJ, making her first QSO. (Image by Matthew, N2PSR)

Applying category theory to servers and services


Marius Eriksen's Your Server as a Function proposes a useful model for the development and reasoning of distributed systems with a service-oriented architecture. Most of the discussion regarding this paper seems focused on futures, but I've been thinking a lot about services and filters. The following discussion is not dependent on an understanding of futures.

A service takes a request and returns a response:

type Service :: Request -> Response

Services can be parameterized by other services:[^1]

authorizedWwwService :: Service -> Service -> Service
authorizedWwwService authService wwwService request
    | authService `authorizes` request = wwwService request
    | otherwise = unauthorizedMessage authService

[^1]: Type classes should specify the interface of the parameterized services to improve type safety, but that's beyond the scope of this post.

Filters, as defined in the paper, take a request and a service, and return a response:

type Filter'' :: (Request, Service) -> Response

However, if we curry the arguments, and swap the order of the Request and the Service, we get the following:

type Filter' :: Service -> Request -> Response

Noting that the return type of Filter' is Request -> Response, which is just Service. We can thus simplify:

type Filter :: Service -> Service

Filter is just a higher-order service![^2]

[^2]: Another approach would be to make Service an instance of Functor, which is more-or-less done in the paper using the filter combinators (specifically andThen).

We can parameterize filters, too:

timeoutFilter :: TimeDuration -> Filter
cachingFilter :: Service -> Filter
loggingFilter :: Service -> Filter
statusFilter :: Service -> Filter
authenticationFilter :: Service -> Filter

If we add a Filter2, this would allow for things like load balancers:

type Filter2 :: Service -> Service -> Service

loadbalancerFilter2 :: LoadBalancerSettings -> Filter2

Decomposing redundant work in this manner allows a distributed system to be developed declaratively and safely.

Enter your email to subscribe to updates.