<?xml version="1.0" encoding="UTF-8"?>
            <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
            <channel>
                <title>Wyatt's blog</title>
                <description>Wyatt and friends</description>
                <link>https://wyattjmiller.com</link>
                <language>en-us</language>
                <ttl>60</ttl>
                <generator>Kyouma 1.0.0-SE</generator>
                <atom:link href="https://wyattjmiller.com/posts.xml" rel="self" type="application/rss+xml" />
                
            <item>
                <title><![CDATA[My journey with Avalonia and F#]]></title>
                <description><![CDATA[<p>So, I finally did it.</p>
<p>Back when I was in college (or university, whatever floats your boat), I made a Windows application called DeskHubSharp. What this application did was it grabbed user data from GitHub, including repositories from the user, and displayed the data. You were allowed to view detail about the user, view detail about a selected repository, download a branch from the repository, and view the repository's GitHub page. However, this application has been largely unmaintained.</p>
<p>There were some drawbacks to this application. For starters, it only worked on Windows (yes, I know, shocker). This happened because the underlying framework was Windows Presentation Foundation (or better known as WPF). Just running on Windows wasn't enough for me. While I was developing the application, I had to use an application called Parsec to develop and run the program on Windows. Even though I still use Parsec to this day, developing and running the application was kind of tedious. Several issues popped up as well, like the repository sorting functionality was broken. I'd go and sort from least to most stars for all of the repositories, and it would sort correctly, but viewing the detail on a particular repository would pick the repository four indexes behind the repository I'm actually trying to view. This happens with every sorting option in my app.</p>
<p>However, there is only one very important question on everybody's minds: What am I going to call the revived project? Don't worry, I came up with something - I have dubbed it DeskHubSharp <strong>Revised</strong>.</p>
<p>Don't let any kind of developers name or title anything, for your own sanity.</p>
<h2>One true love</h2>
<p>I had stated in the past I would proceed with some next steps. One next step was build the application in <a href="http://avaloniaui.net/">Avalonia</a>, a user interface toolkit that was similar to WPF, but vastly different. While WPF used a Windows-only drawing library to draw windows, buttons, labels, and lists, Avalonia used a drawing library called Skia (SkiaSharp to be exact). This means that Avalonia can not only draw on Windows platforms, Avalonia can draw on macOS and Linux platforms. Additionally, Avalonia can also draw on iOS, Android, and even to the web through WebAssembly. Another next step was trying interoperability with the application. Enter F#.</p>
<h2>Exploration</h2>
<p>Why F#? Well, it's part of the .NET framework, so I don't have to learn a whole different standard library/framework. In my Android class, I had to learn not only the Android libraries, but I also had to learn the Kotlin standard library as well (and a part of Java's standard library as well because some of Android's libraries are tied to it). For example, you call an <code>IEnumerable</code> or an <code>ObservableCollection</code> in F# just like you would in C#, which is really handy, especially when interoperability is concerned. Additionally, another next step was to mess with F#. I have never messed with F# before and I still kind of like C# still (sorry Dave) so I thought it would be nice to give F# a fighting chance (because, you know, I'm a language nut). The last step was to port it over to .NET Core (which then it is now just .NET, not Core or Framework. Just .NET) to help with compatibility.</p>
<h2>Onward to new and modern technology</h2>
<p>Let's start with the easy stuff. Porting to .NET 6 was a piece of cake. A simple copy and paste from the old application to the new application did the trick. Next, came the ripping and tearing of WPF and putting Avalonia in it's place. This quite straightforward to do as well. I created new Avalonia windows and then copy-pasted the content from the WPF windows. I did the same thing when it came to the code-behind. Intellisense in VS Code was smart enough to realize I was missing some Avalonia classes so I added those in. However, that is were the easy stuff ended.</p>
<p>I would be wrong in saying that Avalonia is a drop-in replacement because it's not. I had to do some manual adjustments on my end. For example, to show a window, I couldn't do <code>this.ShowDialog()</code> like you would in WPF. You have to call the parent window inside the <code>ShowDialog</code> call: <code>this.ShowDialog(this)</code> or just call <code>this.Show()</code> instead. Another example is with the ListBoxes. You can't call the property <code>ItemsSource</code> like you would in WPF, you have to call the property <code>Items</code> instead. These changes, among others, are not too bad but it would be nice if everything about Avalonia was the same as WPF.</p>
<h2>Porting to F#</h2>
<p>More ripping and tearing coming your way because it's time for me to talk about F#, and what I experienced with the language and it's tooling. F# has quite the syntax and it's vastly different than C#'s syntax. So, I had to learn it for the models. In C#, the models are classes, but in F#, those classes are types, specified with the <code>type</code> keyword. Let me show you what I mean:</p>
<pre><code class="language-fsharp">type Email() =
    let mutable _toEmail: string = &quot;wjmiller2016@gmail.com&quot;
    let mutable _fromEmail: string = &quot;wjmiller2016@gmail.com&quot;
    let mutable _password: string = &quot;password&quot;

    member this.ToEmail
        with get() = _toEmail
        and set(value: string) = _toEmail &lt;- value
    member this.FromEmail
        with get() = _fromEmail
        and set(value: string) = _fromEmail &lt;- value
    member this.Password
        with get() = _password
</code></pre>
<p>The above example is a model for my feedback functionality inside the application.</p>
<p>The <code>let</code> keywords are variables inside a type, kind of like <code>private</code> fields, which is what these variables serve as, or any kind of variable for that matter. The <code>mutable</code> keywords are for letting the variables change values. By default, F# has immutability, meaning that every variable won't change from underneath you unless explicitly defined with the <code>mutable</code> keyword. This concept is similar to Rust's immutability concept and it's <code>mut</code> keyword. The <code>member</code> keywords are for properties, and they can defined with getters and setters, like what's shown above. Don't worry, though, you don't have to add getters and setters. I had to write custom code for my backing fields. It took a while to find my ground when it came to what a property was, what a field was, and variable was. <a href="https://stackoverflow.com/questions/24840948/when-should-i-use-let-member-val-and-member-this">This</a> was immensely helpful along my journey. Once I knew what was what, it wasn't too hard to figure out what I had to do, as far as storing the GitHub data is concerned.</p>
<h2>Tools for a more civilized age</h2>
<p>Let's talk tooling. F# is great and all but I could not find any serialization tool out on the Internet. I'm not talking about <code>Newtonsoft.Json</code>, that's a great tool, but I'm talking about JSON files and transforming them into objects/types for you. It's similar to this website <a href="https://json2csharp.com/">here</a>. I had to write every source file by hand. Don't try it. I'm so irritated by this that I might have to write a tool to do just that. There's some other tools I would like as well, like a C# to F# converter, but I'd imagine that's quite the ambition to take that on. Since C# and F# are both .NET languages, it shouldn't be that hard, right? Right? All-in-all, I think F# is an alright language. There's still so much I have to learn from it, though. Maybe writing the serialization tool in F# will help.</p>
<h2>Existing cruft</h2>
<p>What about existing bugs that need to be ironed out? Well, since I don't know how the bugs even cropped up over the three week course of my developing craze, I will try my best to get rid of existing bugs in the future, as well as squashing new bugs that come my way.</p>
<hr />
<p>For source code on DeskHubSharp Revised, see <a href="https://scm.wyattjmiller.com/wymiller/DeskHubSharpRevised/">this</a>.</p>]]></description>
                <pubDate>Mon, 23 Jun 2025 19:44:00 +0000</pubDate>
                <link>https://wyattjmiller.com/posts/12</link>
                <guid isPermaLink="true">https://wyattjmiller.com/posts/12</guid>
            </item>
            
            <item>
                <title><![CDATA[Test Blog Post 6]]></title>
                <description><![CDATA[Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris libero lacus, luctus non maximus eget, vestibulum quis nisl. Aenean pharetra auctor enim, eget fermentum urna elementum in. Aliquam feugiat non nunc feugiat egestas. Morbi sed nisi et leo rutrum laoreet at quis turpis. Pellentesque tempor ultricies orci sit amet posuere. Nulla vitae ante in tortor tristique tempor eget vitae mi. Nullam ac sem pretium ex porta tristique et eget diam. Nulla facilisi.]]></description>
                <pubDate>Fri, 27 Sep 2024 02:39:44 +0000</pubDate>
                <link>https://wyattjmiller.com/posts/9</link>
                <guid isPermaLink="true">https://wyattjmiller.com/posts/9</guid>
            </item>
            
            <item>
                <title><![CDATA[Trying out Golang (or Go, whatever you'd like to call it)]]></title>
                <description><![CDATA[<p>Golang (or Go, they are interchangeable and I will use it as such) has blown up over the recent years. For example, some features piqued my interest and when say piqued, I mean it. You probably aren't as hyped about Golang as I am. I suppose it helps when you are such a nerd about back-end and server development as well.</p>
<p>Right! Features (a few maybe?):</p>
<ul>
<li>Concurrent</li>
<li><a href="https://stackshare.io/stackups/c-sharp-vs-go-vs-rust">Super-duper fast</a> when compared to Rust and C#.</li>
<li>Compilation support (super useful for sysadmins using GOOS, I found a <a href="https://www.youtube.com/watch?v=hsgkdMrEJPs">cool video</a> about this, watched it to it's entirity)</li>
<li>Package management (Helpful for devs who use git and use platforms such as GitHub and GitLab)</li>
<li>Interpreter is long gone as Go is compiled (No longer are we in the days of Python and Ruby interpreters)</li>
<li>Static typing, for fans of that (C++, C#, Java, and Rust devs will know what I am talking about)</li>
<li>Managed version control repositories (also useful for devs using git)</li>
<li>Powerful standard library (flex, Golang, flex!)</li>
</ul>
<p>Are you interested yet? I know I am!</p>
<p>What makes a Go program, you might ask?</p>
<pre><code class="language-go">package main

import(
    &quot;fmt&quot;
    &quot;os&quot;
)

var name string = os.Args[1]

func main(){
    fmt.Println(&quot;Hello,&quot;, name)
}
</code></pre>
<p>Link to source <a href="https://wyattjmiller.com/code/main.go">here.</a></p>
<p>I'm back! A lot to take in, isn't there? I'm a beginner too so I will try my best to explain this to my utmost competency.</p>
<p>So the the <code>package main</code> deal up top. You will need that to package that up if you want to share this awesome hello world app with your friends.</p>
<p>The <code>import</code> keyword imports packages to help with Go development. So, in this case, I'm importing the formatting tool, <code>&quot;fmt&quot;</code>, and the operating system tool, <code>&quot;os&quot;</code>, into my awesome hello world app which both packages are in the standard library. With that said, you could import other third party packages, like the ssh package. Since you can't find it <a href="https://golang.org/pkg/">here</a>, I looked for Golang's third party packages for ssh packages and it was pretty obvious that I'd find one. You'd just import:</p>
<pre><code class="language-go">import(
    &quot;golang.org/x/crypto/ssh&quot;
)
</code></pre>
<p>I think that's pretty neat as you have flexible package management built right in to Go.</p>
<p>Next up, variables! Variables are a bit different as you have to declare them with a <code>var</code> and then the name of the variable and then the type of the variable. In my case, I need a variable called <code>name</code> with the <code>string</code> type because I know it's going to be <code>string</code> to begin with. Since Go is statically typed, this kind of breaks the rules (kind of like C# with the <code>var</code> keyword) but Go is super smart and can infer the type for you by using the <code>:=</code> operator. An example might help:&lt;br&gt;</p>
<p><code>name := os.Args[1]</code></p>
<p>Depending on what the argument is when the hello world app runs, it will infer the type for you.</p>
<p>The <code>func</code> keyword creates a function! I named my function <code>main</code> because that's the default function that is ran if nothing is written in that has a different function running in the first place (in fact, I don't how that is written in so don't ask me).</p>
<p>Inside the function, I used the <code>&quot;fmt&quot;</code> package to print a line that says &quot;Hello&quot; then your name you put in at the command line. If you don't insert a name before you run the <code>go run</code> command, you'll get an error that the index is out of range. One downside to Go is it doesn't have exceptions but does the <code>panic</code> facility, which you run into that, it's game over.</p>
<p>Go has flow control too, which is pretty cool but I haven't messed with a whole lot yet.</p>
<p>The <code>go</code> command is really robust too. It has everything to the <code>run</code> command which runs your code in go, not compiled (JIT maybe?). It has the <code>test</code> command, which runs your tests if you are in TDD mode. It even has the <code>build</code> command, which Go compiles your code into binary format. This is were GOOS comes in. As a environment variable, GOOS can target whatever operating system you want to target, which could be very helpful if you are using <code>build</code> in a Makefile.</p>
<p>Check Go out, I think you guys will really enjoy it as I am. Next, I might be playing with some of <a href="https://github.com/zmb3/spotify">this</a>.</p>]]></description>
                <pubDate>Thu, 17 Jul 2025 23:31:00 +0000</pubDate>
                <link>https://wyattjmiller.com/posts/24</link>
                <guid isPermaLink="true">https://wyattjmiller.com/posts/24</guid>
            </item>
            
            </channel>
            </rss>
        