改善
Kaizen  · Today I Learned by Ville Säävuori

Weeknotes 2022/8 - Github Copilot, Weekend Vue Project, War in Europe

To say this was a crazy week would be the understatement of the century. But, just to keep myself a small corner of normality, I’ll try to keep the war talk out of this blog and these weeknotes.

That said, Слава Україні!

Github Copilot

I’ve been using the new AI code suggestion tool from Github for a while now and in general I like it a lot for TypeSCript / Vue projects. It’s helpful enough that it does at least seem to make my coding faster, and there’s been few situations where I’ve actually said aloud “holy shit” to myself when it has, magically, pulled several lines or fully implemented features almost exactly how I’ve planned them in my mind.

Here’s a good example of code that actually saves quite a bit of time. It was 100% suggested by Copilot and it almost works. Note that it knew how to match variable names with locally instantiated variables that didn’t quite fully match the option names, like props.options.maxValue to knobMaxValue.value (which is a Vue ref and therefore you need to use .value to set it).

if (props.options) {
  imageSize.value = props.options?.imageSize || 40
  tickLength.value = props.options?.tickLength || 18
  tickOffset.value = props.options?.tickOffset || 10
  tickStroke.value = props.options?.tickStroke || 3
  rimStroke.value = props.options?.rimStroke || 11
  valueArchStroke.value = props.options?.valueArchStroke || 11
  bgRadius.value = props.options?.bgRadius || 34
  knobMinValue.value = props.options?.minValue || 0
  knobMaxValue.value = props.options?.maxValue || 100
  wheelModifierFactor.value = props.options?.wheelFactor || 10
  keyModifierFactor.value = props.options?.keyFactor || 10
}

Here’s another example where Copilot suggested this not trivial and fully working function just by typing ‘fun’. Again, it knew how to properly use Vue refs (passing .value instead of the ref itself, for example) and the logic of either incrementing or decrementing the angle is correct.

function wheelListener(event: WheelEvent) {
  if (event.deltaY < 0) {
    if (controlAngle.value < MAX_ANGLE) {
      controlAngle.value += 1
    }
  } else {
    if (controlAngle.value > MIN_ANGLE) {
      controlAngle.value -= 1
    }
  }
  knobValue.value = controlAngleToValue(knobMinValue, knobMaxValue, controlAngle.value)
}

Both of the above suggestions are outliers in the sense that most of the (useful) suggestions I get from Copilot are smaller “end of the line” -type suggestions but they’re still useful in most cases. What I’m personally impressed by is how well the suggestions know the actual context. I haven’t gotten totally irrelevant generic “here’s bubblesort implementation for your sort function”-kind of suggestions at all nor has it ever suggested React code for my Vue projects.

One thing I’ve noticed is that Copilot most often gets things right when the relating code is immediately above what you’re doing. Here’s an example:

window.addEventListener('beforeunload', navGuard)

onBeforeUnmount(() => {
  window.removeEventListener('beforeunload', navGuard)
})

After I wrote the addEventListener, all I did was write ‘on’, and Copilot wrote the full implementation for me, exactly as I would have.

For many situations I do, however, find it pretty annoying when it starts to suggest things I know it will not get right or where I’m in the middle of writing something and the suggestions mess up my view on where my actual cursor actually is.

Overall, I do like the Copilot. It’s quite amazing how well it works at times and I’m sure it can be an order of magnitude better pretty soon when the biggest kinks get ironed out. At that point I would pay a lot of money to keep it on my toolbelt. I’d say Github has a great product here.

Copilot reminds me of an anecdote of my father from the early 80s when he was working as an electrician in a shipyard where they manufactured Nauticat yachts. Traditionally this kind of work was considered highly skilled artisan work and the oldtimers looked down on all kind sof new technology. Connecting electrical wires to wire terminals with a screw driver was a big part of electricians workday, and when my father was the first one to bring an electric screw driver to the workplace, his colleagues laughed at him for being lazy and “not fit enough”. But it didn’t take long for everyone to notice that he was getting 2x to 5x more work done just because the new tools helped him to be much faster than everyone else. New tools can be a big leap forward for productivity but like with everything, you need to learn to use them and also know when not to.

Weekend project: Control Knob Component

Control knob

I’ve always loved the way audio software controls work. They have unique feel and they are both easy to use and highly optimized to expert users at the same time which is very unusual.

A control knob for audio gain, for example, works primarily by dragging it with mouse. There’s no awkward round motion, you just drag up or down (horizontal motion does nothing). If the element has focus, you can use keyboard as well. It’s very fast. But, if you need more control, just hold down shift and the travel becomes 10x slower! In case you need very precise control, you can have it. If you want to reset the dial, you can option-click it and it automatically resets. Lastly, if you doubleclick the knob, a small input opens and you can put the desired value in manually. It’s great UX!

I implemented all but the manual input in a Vue component, and published it as an open source NPM package on GitHub.

This was a super fun weekend project (that took two weekends) where I needed to learn SVG, relearn trigonometry, and figure out some interesting things with testing tools as well. I’m pretty happy of the end result. It’s, obviously, not very polished but perfectly usable and easty to move forward from here.