Monthly Archives: January 2014

Monads

I was trying to move forward with the new installer for the xll8 library. Again. WiX works, but I’m trying to keep up with new technology. I had high hopes for NuGet for native code, but that project seems to be going nowhere. http://coapp.org/not-found.html#page=/pages/developers.html. So much for trying to help out on that. No e-mail address, just a twitter feed. I started signing up for that. First they made me select 5 people twitter thought I might know that had active twitter feeds. Then 5 more people they thought I might like to follow. Took a pass on Justin Egger, but I was good with Jimmy Fallon, Louis CK, and Seth Meyers. Then they wanted me to cough up my address book. Buh, bye. But that didn’t stop them from sending robo-emails.

Category theory has been an ongoing hobby for me, much to the chagrin of my Operator Theory and Functional Analysis colleagues. They think it is generalized abstract nonsense. Pot, kettle.

Actually knowing what a monad is seems to be a hindrance to understanding how computer scientists use them. “Monads reify composition of functions.” At least that is my Dao De Jing definition – if you know everything there is to know about monads, that should make perfect sense to you.

I like examples, but not the examples I’ve been seeing in most monad expositions. I make a living solving practical problems and never came across anything that looked immediately useful to me.

Here is an example that is almost useful: suppose you have an old-school C library that returns error codes that you have to manually check and functions that return results using pointers. Since int is shorter to type than double, lets assume the functions in the library have signature int (*)(int, int*). Or in modern C++, std::function<int(int,int*)>, a function that returns an int error code, takes an integer argument, and stores the integer result where the pointer tells it to.

I’m thinking GSL. They have a lot of std::function<int(double,double*)> functions. I have been plugging some of this stuff into Excel: xllgsl.

Excel is purely functional language, except for macros used to produce side effects. So is Haskell. Brilliant stuff, but I wish they would stop telling people how easy it is. They make fun of C++ in the same breath they use to claim how well metatemplate programming maps to Haskell. Thank the smart C++ people that put many more man-hours into solving really important issues in modern computing. Like r-value references that obviate the need for meta-template programming and let you return big objects by value without a performance hit.

Off my soap box. Back to monads. They have limited usefulness. They are just a programming pattern that involves wrapping up an object and calling a function on the wrapped up object.

They make standard conventions slightly more convenient. E.g., instead of

int err;
int x, y, z;
x = 0;
err = f1(x, &y);
if (err != 0) {
   // deal with it
}
err = f2(y, &z);
if (err != 0) {
    // deal with it
}

you can wrap up the error code and argument

struct wrap {
    int err;
    int val;
    wrap(int x) : err(0), val(x)
};

and lift a GSL style function:

std::function<wrap(wrap)> lift(std::function<int(int,int*)> f) {
    return [f](wrap x) { 
        wrap y;
        if (x.err)
            y.err = x.err;
        else
            y.err = f(x.val, &y.val);

        return y;
    };
}

Now you can compose functions that return error codes:

    lift F1(f1);
    lift F2(f2);
    auto y = F2(F1(wrap(x));

Those big, bad monads don’t look so tough anymore.

The big boys call wrap unit and write unit: a -> M a. The signature for lift is lift: (a -> b) -> (M a -> M b). The Haskell guys are so smart that they call unit return and use bind: M a -> (a -> M b) -> M b instead of lift (a.k.a., fmap). The language is so easy you have to do something to make it complicated.

Advertisements

Oh my ODBC 38

Apologies to David Bowie. I never liked TVC 15 until I saw him perform it in concert. Saw a reddit post about how Frank Zappa was so pissed off at him for stealing his guitarist that claimed the only thing he said to Bowie was “Fuck you Captain Tom.”
All I can say is that I asked my friend Richie Stotts about it without mentioning the guitarist’s name. He said “Adrien Belew?” Evidently reddit thinks that is a bullshit website. Reddit is the new Onion except they are not as honest about all the lying bringing in their revenue. Some people did stuff and actually know things. Now get off my lawn.

Revisiting the ODBC code I wrote for Excel. https://xllodbc.codeplex.com. And looking at what I checked in today. Jeez, forgot to delete the old stuff I’ve been moving over. Not only does code not write itself, it also does not delete your improved code. At least I had some fun tonight going to the local library for chess night with my friend and her son. Met a very cool guy that makes that happen. From Jamaica. He has an easy style with the kids. Let them make mistakes, and feed them with different things until they see a spark.

I know, ODBC is an ancient API. I needed to get a parameterized stored procedure call into Excel for a project.  There are all sorts of amazing new technologies happening with big data and Power Pivot, etc…, but all I needed was to call a stored procedure with parameters you can type into Excel. Please tell me if I’m missing something, it is getting increasingly difficult to keep up with the latest technology.

This is my third iteration through the code. When you work for big companies you don’t have this luxury. ODBC defines SQLCHAR to be unsigned. This was before the days of Unicode so I’m guessing they were trying to accommodate “funny” characters.  The latest C++2011 standard lets you decorate string literals for this, but there is no provision for unsigned chars. You have to use reinterpret_cast for that. Seems a bit drastic.

The other pisser is that it is written in C and you have to worry about managing the memory to strings. If they could just stick to (pointer, length, length_ptr), with the same types, that would be great.

The other trick is how to hook that up with std::string/std::basic_string<T>. There is a provision in the API to find out the exact string length, but why bother? Pass it a string with enough reserve and resize it. Make length_ptr a class and use a macro to call that and have the destructor do the resizing. Like this: https://xllodbc.codeplex.com/SourceControl/latest#xllodbc.h

My fourth iteration will be better.