There is some hope for humanity after all I suppose.
Even when I want code written in a different language (e.g., C/C++), I often still start by making a prototype in F#. This helps me nail down the logic without having to worry about things like allocation or layouts. Perhaps I could ask an AI to do this second step for me, and then use the F# implementation as an oracle. Anyway.
Eventually I am sure someone at Microsoft noticed and rang the RLHF alarm, so GPT improved substantially. It seems pretty usable for F#. I am sure some unprincipled F#er is crushing it with agents these days. But I didn't think "oh boy they solved the plagiarism problem, let's go generate some slop!" I thought "oh great, now it's no longer going to be blatantly obvious when ChatGPT plagiarizes." I really don't want to roll a d100, or even a d1000, to completely compromise a core value of mine in in exchange for a productivity benefit. I'll just be slow and jobless, thanks. This is serious: I am getting into solar installations and junk hauling.
[1] The "students don't want to think" problem is much older than LLMs. In 2007 I took a senior-level PDEs class, and almost everyone copied my homework because I was actually motivated to study PDEs, and too psychologically weak to resist those mean lazy math majors. Then it happened again in math grad school! Actually unbelievable. Why are you even in the program?
Emulators are cool as hell though, and GBA ones are a nice one to tackle yourself
For example, I usually like using the `Map` data structure, and that's a pretty neat immutable structure and is usually fine for most stuff, but when performance becomes critical, it's easy enough to break into a boring imperative loop with a regular hash map. If I keep everything contained into one function, I usually can avoid feeling super dirty about it.
There are basically two points to programming with immutable-first data. One, eliminate certain classes of data race concurrency bugs. Two, less mutable state in a given context makes it easier to reason about.
So, if you're inside a function scope and you aren't launching any concurrent operations from inside that function, you don't have to worry about benefit #1. If you're inside a function (and you're not reaching out for global mutable state), then the context you need to keep in your working memory is likely fairly small, so a few local mutable variables doesn't significantly harm "understandability" of the implementation (in most cases). So, you really don't have to worry about #2, either. Make your functions black boxes with solid "APIs" (type signatures), and let the inside do whatever it needs to make it work the best.
Just because premature optimization is the root of all evil, it doesn't mean we need to jump right to premature pessimization...
One thing I do want to try out is publishing it with native AOT. I had a lot of luck with that on one of my other F# projects, I got like a 75% speedup out of it. I understand the JIT is supposed to outperform native AOT in the long term but I haven't seen it reach that speed.
Some low hanging fruit to reduce allocations: the discriminated unions in Instructions.fs could be [<Struct>], reusing field names to reuse internal fields.
Also, minor nitpick but I'm confused about some of the registers. They are already of type byte, the setters with `a &&& 0xFFuy` don't add anything over `member val A = 0uy with get, set`. I'm guessing this changed over time.
// Registers can't be a record type because the values need to be truncated to 8 bits when writing, so setters are needed
// This is for the web renderer as Fable transpiles uint8 to Number (more than 8 bits) in JS and doesn't apply any truncation
// Known non-standard behaviour in Fable (https://fable.io/docs/javascript/compatibility.html#numeric-types)
So, I think, it's just conservatively cleaning the data due to Fable's widening via js Number on the web target.That's terrible on Fable's part, the least they could do is truncate. I wasn't aware Fable's translation is so naive.
https://gbatemp.net/threads/no-gmb-2-5-dos-full-version.6039...
I've got fond memories of using this to get a preview of Pokemon Gold before it was released in NA!
MetalNES, transistor level NES emulation https://github.com/iaddis/metalnes
While searching I also found a new one, VisualNES https://kaiokendev.github.io/nes/about
There is also one for GB https://github.com/aappleby/MetroBoy
MetalNES, transistor level NES emulation https://github.com/iaddis/metalnes
While searching I also found a new one, VisualNES https://kaiokendev.github.io/nes/about
There is also one for GB https://github.com/aappleby/MetroBoy
Don't you see that if you would use F# instead, creating projects with C# and F#, that you would get what is being added to C# but actually working and ergonomically? Interop is great!
The larger issue is the C# community loves OOP so you often have to wrap these libraries into something more “FP” if that’s how you want to work.
Overall it’s far better than having nothing (looking at Haskell, OCaml as much as I enjoy them!)
C# interoperability loosens guarantees (particularly immutability) that F# code normally relies on. There are surprising limits that come up in generics because of how they map to C#.
I mean, ideally, we'd run different color test patterns through, in different lighting conditions, to build a really detailed model, right?
I've been going through a lot of very old stuff recently and a lot of it is well preserved in a way but given enough years everything changes.
I don't think any original Gameboys have been made in twenty years or more.
On the other hand, and this says nothing about you or your work, I realize I can put to bed my desire to learn and use F# after seeing what it looks like in a real project. The purely functional stuff is beautiful but once you drop in to more imperative/mutable code I find it really ugly to look at. I suppose unfortunately I suspect that in most real projects you will have to. Not sure if it just means I should choose a different functional language to jump in to, or if I should just work on applying functional concepts to the language(s) I already work with (fairly easy since C# is my primary language and has ever-increasing support for the functional paradigm).
Speak for yourself