Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting some LISP to C#

Tags:

c#

lisp

I'm reading Paul Graham's A Plan for Spam and want to understand it better but my LISP is really rusty. He has a snippet of code that calculates probability as such:

(let ((g (* 2 (or (gethash word good) 0)))
      (b (or (gethash word bad) 0)))
   (unless (< (+ g b) 5)
     (max .01
          (min .99 (float (/ (min 1 (/ b nbad))
                             (+ (min 1 (/ g ngood))   
                                (min 1 (/ b nbad)))))))))

My question is twofold: (1) is there a web resource that will convert LISP to a different language? (my preference would be a C based language) or failing that (2) can someone rewrite that code snippet in C# for me?

like image 532
Guy Avatar asked Dec 03 '22 16:12

Guy


2 Answers

I think it's something like this (warning, possible errors ahead. This snippet is intended as a guide, not a solution):

var g = 2 * (gethash(word, good) | 0);
var b = gethash(word, bad) | 0;

if( (g + b) >= 5)
{
    return Math.Max( 
        0.01, 
        Math.Min(0.99, 
            Math.Min(1, b / nbad) / 
            (Math.Min(1, g / ngood) + Math.Min(1, b / nbad))));
}
like image 65
Gonzalo Quero Avatar answered Dec 18 '22 00:12

Gonzalo Quero


Adding on to Gonzola's answer, don't forget that Lisp provides infinite precision integers and rationals, while C# likes to truncate. You'll need to cast 'nbad' and 'ngood' to float first to get comparable (though not identical) results.

You may also want to put the whole converted program in a checked region. C# doesn't even warn on fixnum overflow -- the first approximation would be to treat overflow as if you're memory constrained (in Lisp, if overflow yeilds too big a number to fit in remaining memory, similar behavior results).

checked {
    var fbad = (double)nbad;
    var fgood = (double)ngood;
    var g = 2 * (gethash(word, good) | 0);
    var b = gethash(word, bad) | 0;


    if( (g + b) >= 5)
    {
        return Math.Max( 
            0.01, 
            Math.Min(0.99, 
                    Math.Min(1, b / fbad) / 
                    (Math.Min(1, g / fgood) + Math.Min(1, b / fbad))));
    }
}
like image 26
2 revs Avatar answered Dec 17 '22 22:12

2 revs