Signposts in Code

When we write code, we often find ourselves pressured to work faster, sacrificing the quality of the product.

Something We can do as Developers:

Clockmakers leave subtle marks to help guide the next person who has to work on that clock - we developers should do the same, it makes everything better for the next person to work on the code, even when that person is you!

Software Engineering is the field I know best about, and this will probably make little sense to people who are not in it.  Specifically FE people in particular might appreciate this post most, as TS is my language de jour.

Double Bang:

Using `!!` at the front of a line, such as:

`const foo = ((thisThis || thatThing ) && (theOther thing && thatOtheThing))`

If you instead write:

`const foo = !!((thisThis || thatThing ) && (theOther thing && thatOtheThing))`

I IMMEDIATELY know that this is going to be a `boolean` with the value of whatever this check returns.  Without it, I need to read the entire thing, then I see there is nothing else, say turnary, it’s just straight this.

Ternaries:

Don’t use double (or more) turnaries!!  They suck, they are hard to mentally process,  and waaaaay too many times I have found bugs specifically because they are bad.

Single ones are totally fine.  Double or higher, you need to break it up.

Single ones are fine.  Double or higher, you need to break it up. 

Again, it sacrifices having code in-line, and instead makes you move things to a function…That I hope you named after what it does! Something something something 2 hardest problems…

IF and Other Statements:

Well, there is too much here to talk about, so I will address the first ones in my mind.

Curly brackets – always use them, unless you can put everything on one line:

“`

if(foo) return bar;

FINE

if (foo) {

Do something!

}

FINE

If (foo)

Do something

BADDDD!  – people will add stuff and not realize there are no curly braces, so their thing after won’t actually fire.  Putting everything on one line is a Signpost that tells us “there are no braces, this is a stand-alone statement.

Functions:

These can be written several ways!

  1. `const foo = function(x) {return ‘But Why!?}`
  2. `function thingyImDoing(…)`
  3. `const bar = () => {return ‘But Why?’}`

Obviously there are more, but these are the basics.

These all do different things.  There are more, but these are the ones most use, and therefore are the ones we should cover.

Do you know the difference?

#2 Is what is known as a “function expression” – these are special.

When you use #2 for function is always there (see: function scoping)

I use this option specifically when I have a lot of code, I take advantage of “hoisting” and put these at the bottom, because I am satisfied with name “removePersonFromEmail()” to be a Signpost that tells me what is happening here.  It also preservers the this binding – not super important these days, but you should be aware especially if you are using jQuery or similar libraries.

#3 is Arrow Function (IE: “Fat Arrow”) – all the cool kids write them this way these days.  You should think about it first though, can you introduce a Signpost?  Mostly NOT using them IS the signpost.  If I see the `function` keyword I know I need to be aware that there is code at the bottom of the file that I need to look at for a more holistic view.

#1 Signpost that tells me you suck…why are you even doing this?  Can it actually make sense?Generally not. …It is _I think_ an unnamed function expression – actually, I kind of want to know what happens – it is unnamed, so the definition might be hoisted in an unusable way? But since it is a const, it would hit the Temporal Dead Zone…Ok, the reason you would use it is because you want to preserve the this binding but don’t need hoisting? That’s my best guess on what would happen. THAT SIGNPOST SUCKS!

Const and let:

These are obviously Signposts – they tell you if a var will change or not.  If it is a `const` it will always be that value – if it is `let` it could be something totally different….Except blah blah blah.

The above are just a few examples of Signposts we can use.  You should come up with more of your own!  If you have any that you LIKE, PLEASE COMMENT BELOW! Also, as always please tell me where I am wrong – I do not like being wrong – It makes me even more upset if I give other people incorrect information.

Is React’s setState Asynchronous?

For this post I am talking about in React when you use (see: https://react.dev/reference/react/useState):

const [foo, setFoo] = useState(“bar”);

And then you use:

setFoo(“fizz”)  ← This right here

Let me ask you a question:

Is setState Asynchronous?

  1. Yes!
  2. No!

Trick question, the answer is “Well, it’s really complicated, and you should just assume it is.”

However…If you want more information about it, I can give you an answer in several parts…It’s complicated.

I feel like the true answer depends on the exact definition of “asynchronous.” So let’s explore how `setState` actually works.

Going deeper:

setState executes in two parts, the first part executing immediately, the second part executing later, however that second part is immediately added to the event loop…Actually that second part isn’t totally true.  It’s not technically added to the event loop – it tells React that it needs to re-render, the check for that is already on the event loop in React’s internal event loop…So technically, it’s not added to the end of the event loop, basically a flag is set saying “do a re-render” and that re-render happens after the current render finishes, when React gets to that check in its internal event loop.

We need to be clear about two different parts of state in React for this to make sense.  

  1. React maintains an internal state that is (usually – it is exposed in updater functions…for brevity, I’m stoping here) not exposed to you, the developer.  
  2. There is also a component state in the example above, this is  foo.

These two states are sometimes the same, and they are sometimes different.

The first thing it does is execute an update to React’s internal state (#1 above).  That is totally immediate, and I don’t think anyone would argue that it is asynchronous.  

When React’s internal state is updated, React tells itself  “I need to do a re-render.”  This re-render however is deferred till after the current render cycle is completed.

This means that the state inside your component (in the example at the top foo, #2 above) is NOT updated till that re-render.  The state inside your component only ever changes during render.  This is true for anything involving state in your component.  More simply: component state only ever changes during the render cycle.

So, is that second part asynchronous?

Well, you can’t await is, so no, it’s not, end of story…Except you can’t await setTimeout and I think we generally agree that setTimeout is asynchronous…You can however wrap setTimeout in a Promise and you can await that…Turns out, you can also wrap a setState in a promise and await that…But don’t ever do that because it makes React unhappy and throw errors.

Fact: React will always execute setStates in the same order, so the last one will always be the final value.  

Fact: You need to use an updater function if you want to access the current internal React value (#1 above) – meaning, if the current render has updated the state, the only way to see that updated state is in an updater function. 

Fact: You CANNOT access the current internal React value of a DIFFERENT state value (during the current render cycle) in your component, even in an updater function.  Meaning, if you have two state values, and you update one, then you update the second one – with or without an updater function – you will ALWAYS get the un-updated value of the first one.  Why: Because component state (#2 above) only changes on the re-render, and that doesn’t happen till after the current render completes.

By “asynchronous” do we mean “doesn’t execute immediately?”  Do we mean “Is added to the microtask queue?” …Does setTimeout(..., 0) count as asynchronous? A lot of what I read says “does not hold up execution” which well, it doesn’t, except it does after other stuff…

Well, that lead me to reading the ECMAScript spec about setTimeout and I couldn’t discern if setTimeout(..., 0) is added to the event loop, added to the microtask queue, one of the previous but with a slight delay, or something else…I’m actually not sure that the behavior is defined – If someone smarter than me knows the answer to this please let me know.

What I do know is that a setTimeout(...,0) will always execute after the re-render cycle (I know this because it obviously isn’t part of React’s render cycle and always is the final update – in my testing) – meaning, that if you have a setTimeout(...,0) that sets the state, as well as other settings of the same state, the final value will always be the one set inside of the setTimeout(...,0) …Except that I say “always” and I actually don’t actually know if that is true.  It is true in my testing.  If that setTimeout is added to the microtask queue, in between other tasks that set that state, then it is possible that it won’t be the final value…but I don’t know if it is…but generally it is true – at least in my testing…And again, I’m not totally positive that is even defined in the spec…and we are splitting hairs here.

Because I don’t think that is complicated enough, React was kind enough to make running in dev mode as opposed to prod work differently.  Well, kind of.  If you are using an updater function, React will update twice in dev mode, and once in prod.  Why?  Oh god how deep does this hole go? 

Short answer: it should be a pure function. (see: https://en.wikipedia.org/wiki/Pure_function & https://react.dev/learn/keeping-components-pure)

Technically when React tells itself it needs to re-render, it applies the update to that component state var (#2) to it’s queue with the current internal value (#1) of the variable – meaning that changes to that variable inside of an updater function ARE NOT SEEN – as the original value was already applied, when the call was queued.  So if you update the state of the variable inside of an updater function, and then try to update it again later with an updater function, the first update is ignored.  Meaning: that’s a really bad idea.  So, in dev mode React will run it twice, once with the first value, once with the second value, and if they are different, ya done goofed.  The reason it does this in dev mode is to show you that you goofed.

So again, how is “asynchronous” technically defined?  And is it asynchronous?  IDFK.

I say setState is not asynchronous because the execution order is defined, and everything it does is immediately added to the the event loop when it is called – if you know what you are doing, the results are deterministic, you absolutely know what the final result will be.  I say please don’t ever rely on this, because the next person who has to modify the code – including future you – is generally not smart enough to understand the nuances here, and if your code relies on this behavior, they will likely break things.

I also say it is asynchronous because part of it executes out of order, and we can (in theory) use a promise to `await` it.

Additionally – because this behavior is so esoteric, I don’t know that it will not be changed in React, sometime the future.

ALL OF THIS IS WHY I SAY TO JUST TREAT IT AS ASYNCHRONOUS! 

I probably made some technical mistakes above…Though I do think it is basically correct.  What I wrote is based on my reading many things, watching many things, and a butt load of tests I wrote myself….Really, I should have saved those tests so I could post them…If you want me to reproduce and post those test, let me know.

PLEASE LET ME KNOW IF ANYTHING I WROTE ABOVE IS INACCURATE.

Some Thoughts on Copilot and AI for Software Development

I have been using Github Copilot for software development for the past year, and my company is now starting to use the corporate version, and I’m even getting Microsoft’s training.  Using AI for software development is clearly the biggest change to happen to the industry since the internet, and it is important to continually evaluate how useful and effective we find new tools to be.  My results range from as a friend described it “autocomplete for my brain” – to, actively making my job harder, my work slower, and (if not checked) having more bugs.

The benefits of Copilot (I will be using Copilot and general AI for software development rather synonymously, but not totally in this post…I assume you are an adult and can figure it out) are clear to many of us who have used it for any extended period of time.  I do not know if it reads my clipboard, or is just good at guessing, but its ability to know that I want to add a specific variable to a string, or in a log is uncanny. When debugging a problem I have even seen it know when I click on a specific line, exactly what I want to log before I do anything – then when I verify the problem is what I believed it to be, when I then click on a different line, it knows the correct fix.  I have really had some mind-blowing moments.

Another thing AI can be great for is refactoring.  A lot of refactoring isn’t “hard” so much as “long and tedious” where it is easy to miss something here or there and break functionality.  In my experience Copilot does a good job of helping refactor without missing things – something I have always struggled with when using say a VSCode extension for refactoring.  I fully admit my experience using extensions is limited as every time I have tried to use them, I get frustrated and just say “fuck it, I’ll do it myself!”

An additional area where I see a benefit using AI tools is when there is something I don’t quite know how to do.  For instance, when I want to unit test a piece of code, but I am not sure how to build the scaffolding needed for the unit test to function – literally the worst part of writing code – many times Copilot can help at least get me started down the right path.

This however leads us directly into my first major problem with using AI.  When we talk about unit testing, AI really wants to help you do it.  It can be great for quickly generating scaffolding.  The problem arises with what checks the tests actually perform.  When you ask AI to unit test code for you, it usually just tests that the code does what you programmed it to do.  This isn’t just unhelpful, it is actively harmful.  Much of the point of writing tests is to catch problems, if the test simply checks that the code does what you programmed it to do, that is a bad test.  We need tests that catch the mistakes in what we programmed.  Otherwise we have a not just a false sense of security but an actively bad sense of security.

Following that problem is the one I have with AI writing code for me.  When I write code, I write code to do something, and I know what I intended it to do because I wrote it to do that. Many times AI wants to take the wheel and complete the logic for me.  Though this is nice in theory, reading and understanding code you didn’t write takes longer, and is harder than just writing it yourself.  I have had experiences where Copilot has written 3-4 lines, or even an entire block of logic, and the amount of time it takes me to analyze it to verify that it is doing what I want, and doing it correctly, actually takes longer than just writing it myself.  Basically it is like I have to review a PR – the other worst part of development.  And yet, we all look to StackOverflow…And some of us looked to help files and books before the internet existed. Sometimes it can be useful in that it might show me a path I may have forgotten, still many times it is slightly not quite correct, or even if it is, it was harder, and took longer for me to use its code.  If it is incorrect…How many developers are actually taking the time to analyze this code correctly?  Well, how many currently do it in PRs?  YMMV.

I have also found code-reuse to be another issue with AI generated code.  Though I don’t believe that every line has to be as DRY as possible, I do believe that code reuse is important.  Moving functionality that does the same thing to a single location helps prevent bugs because the “same” logic isn’t rewritten multiple times, it also makes updating logic easier because it only exists in one place.  I have found that AI isn’t super helpful for this.  It doesn’t suggest I refactor out code from before because I am doing the same thing here.  It doesn’t suggest I build some kind of factory instead of generating the same objects over and over.  It doesn’t know or care that I’m doing this.

The last area I have found AI to be a large problem is learning new things.  And yet, I do think it can learn these these skills. It can – possibly – be an amazing instructor.

I recently decided to learn some Rust for fun.  After about an hour of work I found I had to completely turn off Copilot.  Having autocomplete try to help me with everything when I know nothing just means I learn nothing.  I keep hitting autocomplete and nothing ever cements in my brain.  What can be helpful is when I get stuck, using the Copilot chat to try to help.  This way it never tries to help me until I ask it to. I can ask for help on how to do something new – help is never bad. Blindly listening is totally unhelpful.

In general I have found AI to be helpful in MY workflow – I have reservations about other developers, most especially junior developers using it.  I worry that people will not fully vet the code that it gives them.  I worry that people will generate tests that make them believe their code is safer than it is.  I worry that people won’t actually LEARN.  That said – did we not have the same concerns with things like StackOverflow?  I think we can all admit SA has become less useful over the last 5 to 10 years.  I rarely even care about results that are more than a year old.  Issue trackers, forums, and conferences are much better sources of information.  Perhaps AI is what is needed to replace legacy tools like SA.  What I do know for sure is that if my 8-year-old self had something like Copilot when I first started coding, I would have loved it, just as I loved the QBasic help files when I was that kid. 

Bookmarklet For Increasing YouTube Speed

I made a new tiny bookmarklet to let you increase the speed of a YouTube video beyond 2x.

As always, just drag this link to the bookmark bar on your browser, then just start a YouTube video, once the video starts, click the bookmark, and enter how many “x” you want the video played at. I usually stick to 2.5 or possibly 3, it all depends on the video – but you do you!

YouTube Speed

The code is pretty simple and easily found online, but just in case that’s what you are looking for:

(function(){document.getElementsByTagName('video')[0].playbackRate = window.prompt('Please enter a new speed:');})();

Facebag – A Chrome Extension to make Facebook less interactive!

Long time no update! Well, I just made myself a little Chrome Extension for Facebook. All it does is delete the comment boxes, status box and like buttons from Facebook, so that I don’t use them. It’s great for me! I am considering adding other things to it as well, but for now this was quick and dirty and did what I wanted!

Chrome Store Link

Github Repo

Netflix Autoplay Chrome Extension – v0.8 – Chromecast Support!

I put out an update the other night, this one adds support for Chromecast.

And it looks like I was just in time for the new season of Orange Is the New Black, so get your binge on!

Web Store: https://chrome.google.com/webstore/detail/netflix-autoplayer-with-s/adegickccmlojbmbmemgjakpoammfmkg?utm_source=chrome-ntp-icon

Github: https://github.com/rtpmatt/Netflix-Autoplay-Chrome-Extension

Netflix Autoplay Chrome Extension – Still More Updates

I have added still more updated to my Chrome extension.

0.6 Updates:
*Added episode counter in addition to timer
*Pausing video stops timer
*Fixed bugs when stopping

0.5 Updates:
*Play/Pause, Next and Stop media buttons on keyboard now work with Netflix.
*ctrl+q now causes the same action as the sleep timer ending (ex: pause movie & sleep).

Chrome store link: https://chrome.google.com/webstore/detail/netflix-autoplayer-with-s/adegickccmlojbmbmemgjakpoammfmkg?utm_source=chrome-ntp-icon

Github link: https://github.com/rtpmatt/Netflix-Autoplay-Chrome-Extension

Netflix Autoplay Chrome Extension with Computer Sleep / Shutdown – Updates

I have added a number of updates to my Netflix autoplay extension. In addition to autoplaying TV episodes and shutting down when done, it now also adds support for the keyboard media keys play/pause, next, and stop to Netflix, and also adds a new keyboard shortcut of ctrl+q which does the same thing that will happen when the timer reaches zero. The extension and Github have both been updated.

Also, a little while ago I added default value options for the popup that can be set in the extension option.

Github: https://github.com/rtpmatt/Netflix-Autoplay-Chrome-Extension

Chrome Store Link: https://chrome.google.com/webstore/detail/netflix-autoplayer-with-s/adegickccmlojbmbmemgjakpoammfmkg?utm_source=chrome-ntp-icon

Netflix Autoplay Chrome Extension – With System Sleep!

Bookmarklets are cool and all that, but what I have really always wanted the autoplay functionality for Netflix to do is emulate the ‘Sleep Timer’ found on most TVs. That is, I want it to play for some amount of them, and when done, shut everything off. I know I am not the only person around who has used the function on the TV for years while going to sleep. I have known that this is not possible using just a bookmarklet, but I never got the energy up to actually figure out how to make one. One of the reasons is that I have always known that calling something external like the Shutdown/Sleep command on the computer would be a huge pain. This new HTML5 video Netflix is using for Chrome though made it just a bit too tempting.

The core functionality works basically the same way as this one, since Chrome extensions just use Javascript. I had to figure out how to do all the fancy stuff that makes it an extension, AND add the stuff to allow it to interact with the system to call the Sleep command.

And here it is: Netflix Autoplayer – Chrome Extension

IMPORTANT:
For the ‘Sleep’ functionality to work, once you have installed the extension, you must download the install.bat file that you will see a link for at the bottom of the dialog for the extension. You must run this (and I believe you might need administrator privileges when you do) it creates a couple files that are needed and adds a registry entry. Really, in general I would say you should not do something like that. You shouldn’t be running random things people on the internet tell you to. If you want the ‘Sleep’ to work though, that’s what you need to do. If you understand how .bat files work, it is actually really small, so you can check out what it is doing.

Once you have done the above you can actually edit one of the files it creates, it is located at:
%LOCALAPPDATA%\Netflix-Autoplay\shutdown.bat

And by default should have the following:

:: Lock
::rundll32.exe User32.dll,LockWorkStation
:: Shutdown
::Shutdown.exe -s -t 00
:: Hibernate
::rundll32.exe PowrProf.dll,SetSuspendState
:: Sleep
rundll32.exe powrprof.dll,SetSuspendState 0,1,0

As you can see, ‘Sleep’ is what it does by default, but I have entries for Hibernate, Shutdown, and Lock all listed, just uncomment the one you want and comment the others back out…Hell if you want you could really put anything you like in that file and make it run anything when the timer gets to zero.

Chrome Web Store Link: https://chrome.google.com/webstore/detail/netflix-autoplayer/adegickccmlojbmbmemgjakpoammfmkg?utm_source=chrome-ntp-icon

Github Link: https://github.com/rtpmatt/Netflix-Autoplay-Chrome-Extension

Hope you enjoy!