I Hate VS Code
Now that school is over, I’ve had some time for leisure. This to me, means spending a couple of days learning a new programming language until I inevitably get interested in something else.
Recently, I’ve been writing a bit of F#. It’s always been on my bucket list to be familiar with a language from the ML-family. I’ve tried using Haskell a few times, but somehow it never took hold. I’ve heard some good things about F#, so I decided to try it instead. I have a small command-line project that lets me search GitHub and scrape a few URLS (perfect for tracking down public repos of the CPSC 310 project), so I thought I’d rewrite it from Racket to F#.
Everything was going smoothly, until I wrote the following code:
let nameAndRepo (url: string) =
let e = failwith $"Invalid GitHub URL Provided: {url}"
in
let separateNameRepo (x: string) =
match x.Trim('/').Split("/") |> Array.toList with
| [] -> e
| username :: repo :: _ -> username, repo
| _ -> e
match url.Split(".com/") |> Array.toList with
| [] -> e
| _ :: x :: _ -> separateNameRepo x
| _ -> e
Besides the fact that it’s not very good code (I swear there’s a better way to parse this URL), there’s something horribly wrong here. I ran this code and I kept getting an exception. This was weird, since I was definitely passing in strings that would not execute erroneous paths.
It turns out that I had forgotten that F#, unlike Haskell, was a language with eager evaluation. This meant that the let
binding:
let e = failwith $"Invalid GitHub URL Provided: {url}"
in ...
Was immediately being invoked. I’m not a programming languages expert, so this took me a bit to track down. I was able to refactor the code using what I had learned from my PL classes (turns out you actually do learn stuff in school), and used a thunk to delay its evaluation:
let nameAndRepo (url: string) =
let e = (fun _ -> failwith $"Invalid GitHub URL Provided: {url}")
in
let separateNameRepo (x: string) =
match x.Trim('/').Split("/") |> Array.toList with
| [] -> e()
| username :: repo :: _ -> username, repo
| _ -> e()
match url.Split(".com/") |> Array.toList with
| [] -> e()
| _ :: x :: _ -> separateNameRepo x
| _ -> e()
I know that F# actually has a built-in lazy
construct, but I thought that was a bit of overkill.
Writing F# was great and all, but unfortunately, I was reminded of my distaste for VS Code. It somehow manages to use 200% of my machine’s CPU, and it keeps crashing my F# project. A cursory search on Google leads me to believe that it’s a known issue. That said, I’m generally used to development environments that work without a lot of fuss, e.g. Scala, Node, so I’m a bit disappointed.
I think I’ll continue writing F# and try to fix the issues I’m having with VS Code, but I wouldn’t be surprised if this is the thing that just kills any motivation I have right now. Maybe I’ll go write Rust, or something.
That’s it for this week, I’ll see you later!