17
Nov
09

Why Go is Cool

When I first heard about Google’s new language, Go, I got interested and began reading the tutorial here. At first it did not really seem all that interesting. Sure, it was garbage collected and provided some access to lower level stuff, but that is not that different. Then I got near the bottom of the tutorial and it got interesting. The first thing of interest in Go is interfaces. These allow one to easily write generic methods. For example, if i have an interface named Foo that has a method A, and a function that takes Foo as an argument, that function can take any object that implements a function named A with the same prototype. This allows a lot of the functions and objects in the Go standard library to work well together. The other cool part is go routines and channels. A go routine is any function prefixed by the keyword ‘go,’ like:
go myFunction();
This function is then simply by themselves run in the background, no extra work required. Anything that would block the main thread can be dispatched in this way and run independently. One can then use channels to talk between go routines. A channel is kind of like a queue object that data gets pushed into and pulled out of in a FIFO order. One use of channels is to constantly pull new data from a thread running infinitely.

For fun, I created a simple server in Go that uses go routines and channels:

package main

import (
    "fmt";
    "net";
    "log";
    )

// This is a comment
// getConnections will run forever, accepting sockets from a listener.  This normally would block in a main thread
func getConnections(listener *net.TCPListener, ch chan net.Conn) {
    for {
        tmp, _ := listener.Accept();
        ch <- tmp; // Here we push tmp, a connection of type net.Conn, into a channel
    }
}

func main() {
    addr, _ := net.ResolveTCPAddr("localhost:6667");
    listener , _ := net.ListenTCP("tcp", addr);
    conChan := make(chan net.Conn);
    log.Stdout("STARTING SERVER...");
    go getConnections(listener, conChan); // getConnections will run in the background, forever adding connections to conChan

    for {
        buf := make([]byte, 256);
        con := <-conChan; // Here we pull out the the connection that we pushed in earlier in getConnections
        con.Read(buf);
        log.Stdoutf("RECIEVED REQUEST FROM %s:\n", con.RemoteAddr().String());
        fmt.Printf("%s\n", buf);
        con.Close();
    }
}

This server will read as much as 256 bytes of data from a connection, print it along with a log, and discard the connection.

15
Nov
09

LibMeval: Math, Strings, and C

I have run into multiple situation while programming in C where I found I needed to take in a string that would contain a math expression like “2+2″ and evaluate it.  After googling, I could only find C++ libraries, and I finally got fed up with it and wrote a library that will do this automatically.  It is a very simple library and very small (about 15Kb), and does handles addition, subtraction, multiplication, division, and parentheses.

It has one function at the moment that is of use: eval(). Here is its prototype:

int eval(char* str, double *ret);

str is the expression and ret is a pointer to a double where the result will be stored. It returns 1 if there is no syntax error in the expression or 0 if there is.

Here is a quick little sample that I used to test and debug the library:

int main()
{
    char *c = malloc(256);

    while (1)
    {
    double result;
    fgets(c, 256, stdin);
    if (eval(c, &result))
        printf("ANSWER IS: %f\n", result);
    else
        puts("syntax error");
    }

    free(c);

    return 0;
}


I am still working out a kink or two, but it is in working order. You may get the code by running:
darcs get http://patch-tag.com/r/jimi_hendrix/libmeval/pullrepo libmeval

Check out the README for more details.

15
Nov
09

Hello world!

Welcome to my humble ramblings about nothing. These posts will be about the little things I discover (mainly computer related) that may help others out and will fill an empty void in the internet.