Sunday, June 30, 2024

How could I know?

For some reason, my family has always expected me to just know everything, without ever telling me anything.

When I was 4 years old, Dad died of cancer.  Nobody told me.  One day he was in his hospital bed in the living room, then he and the special bed were gone.  Then the house was full of strangers, and I had to share my (twin sized) bed with Mom and some strange woman.  I wasn't at the funeral.  I didn't even know there was one.  Then Mom took me on a road trip.  We spent the night in South Carolina at some strange woman's house.  Then we went to Florida, and stayed with Grandma and Grandpa.  We went to the beach, and I got to go to a brand-new Disney World!  Wow, the Haunted Mansion sure was scary, Nemo's submarine was fun, and the Swiss Family Robinson's tree house was amazing!

And when we got home, there was still no Dad.  He just wasn't there any more, and nobody talked about it.  Months later, I finally asked my aunt (I was mostly raised by three of my aunts), "Is my daddy dead?"  She just looked at me like I was stupid, and said, "Of course he is."

Friday, June 28, 2024

What is a monad?

There is a lot of hoopla and obfuscation in the functional programming world about monads.  "A monad is a monoid in the category of endofunctors."  Well, that certainly helps, doesn't it?

So, what actually is a monad?  A monad is a data type, either a struct or a tuple, that combines some base data type with a boolean flag (okay, something, valid, etc.), along with functions/procedures that use this structure.  At a minimum, you need a function to convert the raw data to the data+bool structure ("constructor"), a function that takes data+bool and extracts the raw data ("unit"), and a function that takes data+bool, applies some other monadic function to the raw data, and then returns data+bool ("bind").

So, if you're converting a string into a monadic string, you need the following:
type:  (String, Bool)
constructor: String --> (String, Bool)
unit:  (String, Bool) --> String
bind:  ((String, Bool), Proc(String --> (String, Bool)) --> (String, Bool)

In actual practice, the data structure guard can be either a boolean or an enum.  When an enum is used, the "true" value is usually called something like Okay or Just, and the "false" value is called Nothing.  The data structure then becomes a typed variant (tagged union) with either the base type if Okay/Just, or null if Nothing.  Or, in languages where every variable is a pointer to data, "Nothing" is a null pointer, and "Just" is a valid pointer.  This is equivalent to the (data, bool) tuple where you have the two cases of ("some string value", true) and ("", false).

In Listack, every piece of data is monadic, because it comes with an "invalid" flag, which is false by default.