What Am I Working On?

Muscadine

f#

Muscadine is a modern web app (inspired by Twitter) for capturing the in-the-moment thoughts of a single user about a variety of specific topics.

As I consume various media or work on various projects, I've noticed that I tend to have a lot of tweet-sized ideas about those subjects. But because those thoughts are separated by lengths of time (since I only have a few hours a week to devote to any particular hobby), my Twitter timeline appears aimless and disconnected.

Thus, Muscadine allows me to associate each microblog entry with a specific media item or project. Microblogs for a specific item can be viewed as a whole or the entire feed can be intermixed to show thoughts over time while still associating each one with a particular thing.

Future Directions

I can imagine automatic cross-posting to Twitter or even implementing the Mastodon specification to join that federated microblog system.

I also think that a system for publishing longer essay-level non-micro blogs is inevitable, but I want to actually build up a backlog of essays to publish before starting that work.

The publishing interface is a little rough today. One day, I'd like to polish that if only as a treat for myself (since I'm the only that ever uses it). And, if there's any enthusiasm from others, possibly even rework the data model to be multi-user.

About the Name

In recent years, I've started choosing wine/grape varietals as project code names.

Muscadine grapes are the grapes most common to my region of the United States and are the grapes most often used to produce local wines in this area. It seemed imminently suitable for the code name for my home page since they are, indeed, the grapes of my home.

Additionally, muscadine wine is not the best tasting wine you'll ever find but it has unabashedly local character. I expect my home page to feel much the same.

Muscadine

f#

Muscadine is a modern web app (inspired by Twitter) for capturing the in-the-moment thoughts of a single user about a variety of specific topics.

As I consume various media or work on various projects, I've noticed that I tend to have a lot of tweet-sized ideas about those subjects. But because those thoughts are separated by lengths of time (since I only have a few hours a week to devote to any particular hobby), my Twitter timeline appears aimless and disconnected.

Thus, Muscadine allows me to associate each microblog entry with a specific media item or project. Microblogs for a specific item can be viewed as a whole or the entire feed can be intermixed to show thoughts over time while still associating each one with a particular thing.

Future Directions

I can imagine automatic cross-posting to Twitter or even implementing the Mastodon specification to join that federated microblog system.

I also think that a system for publishing longer essay-level non-micro blogs is inevitable, but I want to actually build up a backlog of essays to publish before starting that work.

The publishing interface is a little rough today. One day, I'd like to polish that if only as a treat for myself (since I'm the only that ever uses it). And, if there's any enthusiasm from others, possibly even rework the data model to be multi-user.

About the Name

In recent years, I've started choosing wine/grape varietals as project code names.

Muscadine grapes are the grapes most common to my region of the United States and are the grapes most often used to produce local wines in this area. It seemed imminently suitable for the code name for my home page since they are, indeed, the grapes of my home.

Additionally, muscadine wine is not the best tasting wine you'll ever find but it has unabashedly local character. I expect my home page to feel much the same.

Activity

I still haven't answered any questions about what I want this site to become.

But I realized that I forgot to add the X-Clacks-Overhead header to all of my responses, so I've fixed that (and added a few other novelty headers) so at least I'm not letting the site just rot.

For the first time since I started this project, I suddenly find that I am not quite sure what I want this website to be.

It was originally going to be an in-the-moment, somewhat curated, snapshot of what I'm doing with my life.

But I'm not sure what that means. The original goal was going to be largely centered around microblog updates (like this one) where I could share thoughts tied to a specific item.

But what if I'm having a bad day and read a trashy space opera in an afternoon but don't have anything to say about it (or any energy to log in and say it)?

Should I add it to the site later just as a "I have read this" tracker? Should I add a star ratings feature so I can rate items? Should I add a "review" section separate from the microblogs?

Specifically for books, should I make this a Goodreads clone? But isn't Goodreads good enough? Maybe not for the non-books.

But I don't always want to put a star rating on something. I certainly don't always want to write a prose review. Would their absence be interpreted as meaningful?

But ultimately, I can't decide if that would be an evolution for this site's theme, purpose and design...or a step backwards.

It opens up some presentational challenges as well. The original site design was very purposeful and that's a fairly major expansion of purpose.

So this will be something to think about in the weeks ahead.

I wanted to link to that big entry down below but to do that, I needed to add permalinks for microblogs.

That exists now. See?

That last "micro"blog was a doozy. Maybe I don't need to add a "real" blog engine after all.

Since this is my site, the character counter is just a suggestion, after all. Hmm.

One issue that I've had since the beginning was "How do I represent the different item types (book, game, project) in a strongly typed way while also reducing the amount of boilerplate I need?"

In C#, I'd just make some interfaces and an object hierarchy and call it a day. And while one can do that in F#, it's against the spirit of what I'm trying to learn.

I went down a few paths (including some pretty gnarly heroic reflection code, immortalized in this "delete all the old code" commit) but nothing ever really felt right. I ultimately just ended up copy-pasting a bunch of the same code into Book.fs, Game.fs, and Project.fs and moved on.

I've slowly been solving this, starting a couple weeks ago when I added some discriminated unions to represent each type (in this commit). That ended up with a lot of similar code in pattern matching blocks, but I felt okay about it because the compiler was going to help me out by noticing missed patterns.

Then, last weekend, I watched a talk from Mads Torgersen on "The functional journey of C#". He made a point that a big difference between OO and functional programming is that OO lets you put new behaviors in one place (encapsulated in the base class, perhaps) while functional programming makes you spread it out all over the place and duplicate things in each function. But the functional approach is more extensible since all the behavior is out in the open.

He said it better. Go watch the talk.

Anyway, I've taken that to heart and done a great big refactor today.

Before, I really wanted to be able to have a list of, like, FormField<'t> to support things like FormField<string> and FormField<DateTimeOffset> and FormField<string option>.

This is fine as far as it goes but:

  1. You can't put those in the same list because they're all different types
  2. You can't pattern match over the generic type so it's hard to do things with them

This wouldn't have been so bad in C#. I'd just have a non-generic FormField interface or something. I don't know. But in F#, it's kind of a drag.

So I embraced what Mads was saying about duplicating behaviors as needed. I now have a new "FormField" concept where each FormField is a discriminated union of everything that a form field could ever be.

I wrapped up a bunch of pattern matched functions to do things with these and it's kind of annoying but really not that bad. The compiler and tooling helps a lot here.

I'm pretty pleased with it.

I know this is far from perfect and not what an F# master would write.

But I think this is a solid improvement and shows how much I'm growing into this new-to-me language and paradigm.

I can only imagine six months from now when all of this seems really gross to me and I have much better ways to accomplish all of it.

I can't wait.

Today's the day.

I've spent the week polishing all the rough edges I could find.

I've got a commit ready to go to change the index route from "Under Construction" to...well...this.

I still want to write up something to put on social media to tell people about it (I am kind of proud of how this has turned out!) and then I can push that commit.

It's time.

Not sure if the first post-launch feature will need to be a no-context microblogging feature (possibly published to twitter) or a real blogging engine. Either way: do I actually have worth saying?

I've created a colophon. The site is feature complete! I'm not happy with the copy at all, though. So I need to spend a few days thinking about the writing. But I'll probably launch next weekend! Exciting stuff.

Added visible tags and individual item pages today. v1 of the site is nearly complete (indeed, I almost thought it was done until I remembered...) except for the colophon.

One more static page and then I'll just need to look at it very hard before making any small tweaks and going live.

I can't believe it's almost finished!

I got the "list" pages working under the "What am I...?" buttons in the sidebar. I am so excited about it. It looks so good.

Things are really coming together over here and I am starting to feel pretty proud of how it's turning out.

I did a very small amount of refactoring cleanup. The code is really disorganized and it's not at all clear to me how to improve it.

More importantly, though: I did decide to add Markdown support. It was very easy thanks to the Markdig project.

The front page now has dynamic microblogs (like this one!) on it.

I'm still debating if I'm going to support markdown in these or not. The time to make that decision one way or another is fast approaching.

The project code is also really starting to get away from me: a lot of that is to be expected since I'm learning F# as I go, but it might be time for a major cleanup refactor soon. I just need to learn more about what that should look like.

I've now got all of the static content on the main "About" page laid out in a responsive fashion. Will start working on the dynamic stuff next time.

It's looking good! I'm almost tempted to disable links to pages that don't exist yet and put this up instead of my "under construction" banner.

Almost.

I started working on the user-facing site today! I've got the main layout built out and it's responsive and everything. One day, you may even see this very message in that layout! Exciting stuff.

I've put some real data into the backend so I'll actually have something to look at when I start styling the frontend. Probably next weekend. We'll see.

Today, I am "feature complete" for the backend: which has allowed me to write this, the inaugural microblog in the production database.

Next up, it's all about presenting the data in a pleasant frontend!