Echoes from 308 logo

Echoes from 308

Subscribe
Archives
May 9, 2021

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!

Don't miss what's next. Subscribe to Echoes from 308:
Powered by Buttondown, the easiest way to start and grow your newsletter.