littlelogs

Keep a social journal of your work progress as you make and learn things.

#elm

April 2017

rhitakorrr
rhitakorrr

Time for a mega, 3 weeks #laterlog. [1/2]

I just finished a dev session on the #MidnightMurderParty editor, so I’ll start there. When I started learning #PureScript earlier this month, it was all confusion, overwhelming UI library choices, and packages that were lacking. Simultaneously learning this language and developing an application in it has been quite the ride.

But it’s been fun. The learning curve was (and still is) much steeper than #Elm’s, but as I learn this language, I’m coming to appreciate how much freedom its complexity gives me. The massive boilerplate which is rampant in Elm code hardly exists here, from what I’ve seen, because most of it gets abstracted away.

I’ve now gotten most of the old editor screens coded (though not fully #functional, ha-ha) and have added some new features, namely Google login and Drive Filepicker, so I no longer have to download a Docs file, open it in a text editor, copy the HTML, and paste it into the editor. I just pick a file in the editor and go.

rhitakorrr
rhitakorrr

Finally got the #JSON encoding and decoding working for the #MidnightMurderParty editor. I’m finding that, while I really enjoy #PureScript as a language, the packages are lacking. I think #Elm has it beat so far in the useful docs and full-featured packages department, even if Elm is a much weaker language.

Tonight I finished adding audio to the MMP promo animation—at least as much as I’m going to be able to do before I have music to work with. Simulating movement through a room by automating the volume and panning of two clock-ticking clips with different amounts of reverb/EQ was fun. One for close to the clock, one for in another room, and a lot of tweaking.

I’m also a little ahead of my Camp #NaNoWriMo goal, which isn’t too impressive since I only committed to 10,000 words this month, but I have been writing nightly. My next goal is to shift my writing to the mornings again. I really like writing in the morning, but I don’t like waking up very much at all.

rhitakorrr
rhitakorrr

I’ve been primarily working on 3 things this week:

  • PureScript Editor. The old #MidnightMurderParty editor (my custom CMS) was written in #Elm 0.16 and is basically unmaintainable since 0.16 is so different from the newer versions. I’ve been looking for an excuse to learn #PureScript for a while, so I’ve been rewriting the entire editor in that. I’m still just trying to get JSON decoding working, though.
  • MMP Promo Animation. The promo animation for MMP is done, and now I need to soundscape this whole thing. I started editing with OpenShot, but that can be summed up in one word: Crash. I’m now using Blender as my video editor. So far, I really like it. While I pair up SFX with the video, @larouxn is working on the music. It’s coming along pretty nicely.
  • Camp NaNo. I set my Camp #NaNoWriMo goal for the month to 10k words. I’m trying to finish one #shortstory, write another, and maybe get some MMP writing in there as well!

February 2017

rhitakorrr
rhitakorrr

As of yesterday, the #Elm game engine started to look like an actual engine instead of a mess of #ECS code mixed with half a game implementation. I plan to use this for later optimizations. It originally started as an extension of #MidnightMurderParty, but I think at this point it’s just become its own project. I should think of a name for it.

Changes I made on the engine tonight:

  • When initializing a game, the user can now issue a Cmd before providing the engine with the game data. This allows for basing the game data on HTTP requests and such, which I intend to use for MMP to retrieve JSON from a database as content is released.
  • With a bit of extra type magic (there’s already plenty going on), I got the engine tracking which system (as in Entity-Component-System) is currently running, along with some extra data about the system. I also added a function that will allow running one system from within another and restore the original context when the nested system finishes.
rhitakorrr
rhitakorrr

I’ve spent the last few days working on an engine for text-based games in #Elm, the goal being to use this engine to code the #MidnightMurderParty interactive segments. Turns out, modeling a game engine in a purely functional, strictly typed language is tricky. Since game objects have different properties and behaviors, modeling them as the same type (so they can be stored in a List or Dict) isn’t really straightforward.

After some research, I decided to go with an Entity-Component-System (ECS) approach, which has been a challenge as the first time I’d heard about such a pattern was on Friday. Since then, I’ve written some terrible code, refactored many times, and only now have something that looks promising enough to move forward with. There’s still a lot to figure out (cross-entity/component messaging, for example), but at least now I have an idea of how this might work.

January 2017

rhitakorrr
rhitakorrr

Let’s see if I can get back to daily (or at least near daily) logging again. Today, I:

  • Closed two #GitHub issues for #MidnightMurderParty. Both were small aesthetic things related to the user resizing the book, but because of some race conditions that could occur between #Elm and #JavaScript (and did occur last time I tried this), I’d been putting the issues off for a while.
  • Got some #writing done on my current #shortstory—about 700 words on the manual typewriter, which I’m enjoying quite a bit so far.

Now, I’ll probably read for a little bit and maybe play some Osu! or Overwatch. Something that starts with an ‘O’ anyway.

December 2016

rhitakorrr
rhitakorrr

Since my last log, I’ve

  • upgraded the #midnightmurderparty front-end to #Elm 0.18
  • finished the first draft of the MMP Episode 1 rewrite
  • finished rereading Stephen King’s It
  • written the first draft of a flash fiction piece
  • started reading another book
  • dropped off my manual typewriter at the shop for repairs (which turned out to be pretty expensive!)

Tonight I’m going to

  • have an MMP dev planning meeting with @larouxn so we can get everything needed for the 1.0 release done by the end of January
  • edit the flash fiction piece I wrote last night

September 2016

rhitakorrr
rhitakorrr

I was right. There was a pretty nasty bug hiding in that #midnightmurderparty refactor, but I fixed it now. Plus, I removed all the dead code paths and cleaned up the #Elm model.

I wrote a short story tonight as well, but it ended up being pretty awful. I think it has some promise, but I’m basically going to have to rewrite it from scratch tomorrow. Oh well, it’s all part of #writing.

rhitakorrr
rhitakorrr

I’m terrified right now. I finally wrote the major part of the #midnightmurderparty enhancement, which involved refactoring huge portions of navigation logic. It was the kind of refactor where you really can’t compile and test until it’s basically done.

When I finally compiled it, the compiler found two mistaken type signatures, and then it worked. But surely it couldn’t be that easy, I thought. There will definitely be errors in the runtime since I didn’t change the #JavaScript to work with it yet.

Except there weren’t. As far as I can tell, everything still works fine immediately after this massive refactor. I know this is #Elm, but this is too smooth even still. There must be a sneaky logic error somewhere, but I haven’t found it yet.

It works, and that’s terrifying.

rhitakorrr
rhitakorrr

Tonight I made more progress on #midnightmurderparty. I’m working on a pretty big enhancement at the moment. In the #reader, there is a lot of collision detection regarding which headings are currently within the viewport of the book. The enhancement, instead of checking all headings against the viewport every page turn, just does so once–when it renders–and stores that data in a map from page number to list of elements.

The idea is to cut the slow DOM querying out of the process and to search through less elements each page turn, but there’s another benefit I just realized yesterday. If I pass this map of page num -> element list to #Elm after the render, the Elm side of the program can perform a lot more logic without having to continuously ask the #JavaScript side to check things for it. This will cut out a ton of complexity!

Aside from that, I spent most of the day with a friend. We went to a diner, made cookies, and watched a Twitch stream of Super Mario RPG.

August 2016

larouxn
larouxn

RSS Part 1: Takeaways from a Trip to Dynamic Mutable Hell and Back w/ @rhitakorrr

  • With Active Record you can use as_json to turn your database records into JSON, wahoo! 😊
  • If you .merge!({key: val}) some of your JSON blobs, the merged ones become Hashes (expectedly)… which I forgot and then had some records with values only accessible via ['key'] and some via [:key].
  • Whilst iterating through an array of objects, if you insert an object into an array you initialized outside the iteration block, you’re actually only inserting a reference to that object. If the inserted object changes later but still during the loop, the one you inserted a while back has now also changed. 😒

I love #Ruby and this may not happen often… but I wish it couldn’t happen in the first place. Shoulda used #Elm. #midnightmurderparty

rhitakorrr
rhitakorrr

Tonight turned out to be more of a cleanup night than a dev night.

Also made a repository to publicly track my #midnightmurderparty writing progress!

rhitakorrr
rhitakorrr

After pushing a little further with the #JavaScript config file for the #midnightmurderparty #frontend, I decided it would be better to store the config as a #yaml file and inject it during the build process. This led to a massive build script upgrade.

  • Config is now a #yaml file parsed in the build step instead of bundled #JavaScript used at runtime. This circumvents issues such as:
    • Needing to dynamically create script tags on the page based on config (which leads to all sorts of script loading order mayhem)
    • Needing to pass static data around in the #Elm model
  • Build system upgrade
    • Now injects values from config file directly into the source
    • Appends unique number to #JavaScript and #CSS sources to force bypassing the cache after a code update
    • Allows specifying --dev in terminal to run in dev mode, prod otherwise
      • Dev and prod mode both have their own values in the config file
      • If running in prod, the build script will remove console logs, debuggers, alerts, etc.
rhitakorrr
rhitakorrr

Finished the shim for Chromium-based browsers and added logic to avoid running it unless specific values were detected as “wrong.” This should prevent the fix from breaking browsers that work properly. Also fixed a recurring issue with Firefox… again.

I updated the generated #Disqus IDs to match the #midnightmurderparty #reader’s ID format, so they now work together. Though, I did have to rewrite the URL parsing logic with regex to account for more varying cases, especially links coming back from #Disqus.

Finally got a solid start on that config file. #Disqus is hooked up properly, and #Mailchimp is most of the way there. Currently, it’s just a JS file that gets bundled, but that’s leading to the need for dynamically included script elements as well as passing extra data around in the #Elm model. I’m considering injecting the config values during the build step instead, but I’ll have to think about it.

Does anyone know if there’s a standard way to do this sort of thing?

larouxn
larouxn

Yesterday evening I made one small change and formulated one small hypothesis regarding deploys for #midnightmurderparty. First off, the small change.

Issue was that on deploy, @rhitakorrr’s #Elm files weren’t being recompiled. Turns on that due to the nature of our deploy system, though other files were being updated, the build process was being run on non-updated base Elm files. Threw a tasty little git pull step into deploys before asset builds. Success! 😁

Secondarily, the deploy hypothesis. Background: our deploys run whilst the server is running and perform a hot restart on our #Ruby Puma workers. Also, our server is a $5/month Ubuntu 16.04 x64 droplet on DigitalOcean with 512MB of RAM. Sometimes when running the deploys they would reach the asset build step and the process would be killed. My current hypothesis is that we are running OOM (out of memory) running the deploy while the server is running. Tomorrow I’m going to profile this RAM issue with some htop and redundant deploys.

rhitakorrr
rhitakorrr

Tonight’s been pretty fun. Went out with some friends and didn’t get home until after midnight. Instead of going to bed like a reasonable person, I decided to implement another feature in the #midnightmurderparty #reader.

Honestly, the base feature was pretty easy to implement – just better repositioning of the user within the #reader when they resize the book and cause a text reflow – but, of course, I decided to get fancy and wanted to show the reader with a blinking paragraph approximately where they were before the text moved around. That added a ton of unexpected complexity which took me an extra two hours to get working in a way I liked.

I’d still like to test my book collision checking more; it seems to be acting a little wonky sometimes. Plus, I found a bug I thought I fixed a long time ago. Gotta look into that again too. Can’t wait to get out of #JavaScript land and back to the #Elm half of my code base. Things are nicer in there.

rhitakorrr
rhitakorrr

Spent a good portion of today working out how I wanted to implement two features for the #midnightmurderparty #reader:

  • Bug reporting. (not yet implemented) Went on a pretty long tangent thinking up all sorts of advanced forms that would be hard to implement in #Elm before deciding to just add a contact email with some additional instructions for reporting a bug.

  • Latest release button. (fully implemented) Was supposed to be a quick way to get from the home page to the latest release, but was near impossible to do in an aesthetically pleasing way. Trashed the button idea and, instead, decided to automatically bring the user to the segment they left off on during their last visit. Newcomers will see the text “Start Reading” on the front of the book. Those returning will see “Resume Reading.”

Side note: Day 2 of replacing dinner with Soylent. Got home from work at 7pm and finished implementing a feature + ate before 10pm. I think I’ll read a book for a bit. This is nice.

April 2016

josh
josh

Wrote up some detailed notes on my previous failed attempt to write #larder in #elm. Next step is to turn it into a proper blog post for the Hello Code blog. I think I might hold off for a while though until we have more developer-focussed features, then publish it as a way of drawing in some curious devs. Hopefully.

January 2016

josh
josh

After sleeping on it I decided to give up on #elm for #larder. I do like it a lot, despite not yet being proficient in it, because it allows me to do some cool stuff in a very functional way (the alternative being icky javascript). However, the community just isn’t there yet (and may never be) and I’m not comfortable supporting it forever in a serious product. I might blog a bit about my experience with it sometime to explain the pros and cons I see.

For now, I made some really quick progress moving all my views back into #Django templates. My new approach will be progressive enhancement with minimal #javascript — just enough to avoid some page reloads and make core parts of the interface snappy.

josh
josh

Made some better progress with #elm on #larder tonight. Got routing sorted out and am now officially manipulating the history when switching folders and viewing the add link form, which I also set up.

It’s been a challenge thinking about how to represent all the state and I worry about the best practices on how deep to go — should I represent the state of each input in my form (empty, filled in, validated, invalid)? Should the form itself have a state (in progress, submitted, invalid, complete)? I’ve no idea and I kind of wish it was already decided for me.

I’m definitely much more comfortable thinking about this from a server-side, OOP point of view, and I really miss being able to write and generate HTML from the server. I do love how snappy it is to click around my app without page refreshes, only reloading the bits that have changes, but on the other hand I would’ve been wayyyyyyy further ahead on this if I just did it all server-side in comfortable old #Django.

I guess it’s worth it? 😕

josh
josh

It’s Australia Day here but we’re celebrating by working a bit (@belle more than me, I’m being lazy). Very un-Australian to not make the most of a day off. Anyway, this afternoon I’ve done some more on #larder, making some things work a bit better on mobile, and then moving onto adding routing into #elm. Unfortunately I’m stuck in a dependency hell where some of the dependencies’ dependencies won’t compile. It seems like maybe the elm package server is down and has broken the download of something. I will persist.

josh
josh

A little more work on #larder over the weekend, but haven’t been sleeping well so content to tinker a bit and give myself permission to not get much done. Today I decided on elm-transit-router to handle single page routing in #elm, and started setting that up, as well as fiddling a bit more with the design.

josh
josh

Some #exist work on setting up new attributes today, things we’ll support even if we don’t yet have services that provide data for them. Commits, number of coffees and alcohol drinks consumed, money spent, some commonly-requested attributes from a bunch of different categories.

Then a little tinkering on #larder, adding some new state to my #elm model so that I can tell when I’m waiting for things to load, and show appropriate loading messages, vs those things missing because the returned list is empty or there was an error.

josh
josh

One thing I think it’s cool to note when looking back at my logs on #elm, #mithril, or even #android, is that regardless of whether you’re new to coding or have been doing it for years — we all struggle. Especially when picking up something new. Everyone misunderstands things, and hits brick walls, and makes mistakes, and writes really terrible code. My logs on #elm could be written by an absolute beginner, or I could run into the same issues as @kateo learning #angular. I think it’s a very equalising experience. So if you’re a beginner, don’t fret! Keep at it! We’re all in the same boat :)

josh
josh

Oh-em-gee. I had a really frustrating afternoon with #elm. I couldn’t for the life of me work out why my task to download links for a folder wasn’t returning anything. Everything compiled, no browser errors of course, but no links either. Turns out I was sweeping the error under the rug with Task.toMaybe and my json decoder had been failing — a mismatch between my model and what I was actually returning from the API. Oops. I found a really hacky way to display that error, which I’m too ashamed to share, but I got it working in the end and I can now display links for a folder. Finally at parity with my #mithril branch! Anyway, I think tomorrow I’ll need to look into this “time-travelling debugger” I’ve heard about.

josh
josh

Tonight I switched #larder’s #elm architecture to use StartApp and effects, instead of the way I was doing things directly with ports and tasks. I got really stumped trying to work out how to trigger a new action from within update but fortunately the StartApp architecture is set up to do exactly that (so long as you wrap them in an Effect, something I still don’t quite get).

Definitely more productive thanks to Atom’s linter-elm-make plugin as suggested by @mbylstra, so handy to have the compiler errors integrated.

josh
josh

This afternoon I had a tinker with #larder but felt a bit unsure about how to move forward with #mithril. The downside of having a very loose, “do it however you like” architecture is that if you don’t have your own idea of how best to do it, there’s not really any best practices or convention to follow. As someone who’s much more comfortable putting logic in the back-end, this left me feeling a bit out of my depth. My vague approach so far felt like a dead end.

Sooo.... tonight I started a new branch and gave #elm a go instead. I do like how it enforces the architecture of models, views, and the updates that change them. However, there’s a pretty steep learning curve once you get past that point, and working with JSON decoders that return other decoders and ports for tasks that return signals… it’s pretty hard.

After many hours I’m one step closer to the process I made in Mithril — I can download and display the list of folders for the sidebar, and change the selected folder. Woo.

mbylstra
mbylstra

Over the christmas break I spent a good chunk of time attempting to design and implement an audio/synth framework in using the #elm programming language. I think functional programming is a perfect fit for an audio/synth engine and FRP is ideal for doing music interfaces. It’s build on top of web audio, but just to have access to the soundcard (it’s not using any AudioNodes for synthesis). All audio generated is generated from scratch - oscillators, etc. I discovered flocking.js recently, which seems really similar in design and goal.

josh
josh

Today I started setting up #larder, our secret new #hellocode project, and created the #django project skeleton, models and database. Next step will be to create the API, and then write the front-end client. I’m going to do something different this time to what I normally do — use a front-end framework and generate a minimum of HTML server-side. Unless I get cold feet. Thinking I’ll use #mithril (as described here) but if I want to add to my learning curve I might be persuaded to give #elm a go.