Tuesday, 24 July 2012

Experimenting with Cgo - Part 4: C Macros

One of the most frustrating parts of working on Goncurses is the fact that ncurses increasingly uses more and more macros. C macros cause a lot of problems for cgo, which isn't all that surprising, because C macros can cause a lot of problems period.

In order to circumvent C macros you have to provide proper C function wrappers around them. Depending on the library you are trying to port, this could be quick and simple or it could be long and tedious. I will demonstrate a very simple example.

1. You will need to create three files: a go wrapper, a C header and a C source file. The two C files must share the same name.

2. Identify the macro you need to create a wrapper for. For the purpose of this example we will be using a macro called MY_MACRO. In your header file, write a function prototype for the wrapper.

int my_macro_wrapper(const int x);

3. In the C source file, write a definition for the function prototyped in your header which calls the macro you are wrapping.

int my_macro_wrapper(const int x)
{
return MY_MACRO(x);
}

4. In your .go file you will need to include your wrapper header and then wrap the C file in a go function.

// #include "macro_wrapper.h"
import "C"
...
C.my_macro_wrapper(2)

That's all there is to it!

In the complete, trivial example below you'll notice I used the macro to call another function. You might think it a good idea to circumvent the macro altogether and simply call my_function() directly in Go. While this would probably work, and certainly would in this example, it defeats the purpose for why the author of the C library used a macro in the first place. There are several reasons why this could be a bad idea and I recommend using the C API as the author intended.

Complete sources follow:

***
macro_wrapper.h:
***

int my_function(const int x);


#define MY_MACRO(x) my_function(x)


int my_macro_wrapper(const int x);


***
macro_wrapper.c
***

#include "macro_wrapper.h"


int my_function(const int x) 
{
return x;
}


int my_macro_wrapper(const int x) 
{
return MY_MACRO(x);
}


***
library_wrapper.c
***

package main


// #include "macro_wrapper.h"
import "C"


import "fmt"


func main() {
// Uncomment the following line to produce error
// fmt.Println(C.MY_MACRO(2))
fmt.Println(C.my_macro_wrapper(2))
}


Sunday, 10 June 2012

Like Python, like Go

Long ago I vowed I would learn Python. Yet, despite a little dabbling in the past I've never actually dove right into it. Well, now I have and I must say I love it. You might think that I'll be talking about specific features and compare them both but I'm not going to. There's enough of that sort of thing already. Instead, this probably will read like a love letter.

Python's similarity to Go borders on the uncanny. I consider it flattering to Python that that this is the case. Both are fantastic to work with. Slices, great built-in abstract data types, well documented standard libraries and a forced coding style are all reasons I like these two languages. They are so similar that I've even forgotten which language I've been programming in and start using braces in Python and colons in control structures in Go. Thankfully, I don't have to choose between the two languages because I don't think I could. Go is best suited to server programs and system daemons. Python is fantastic for user level applications. Of course, there is a great deal of overlap and cross pollination between the two but that's how I define it.

If you are new to programming I would happily recommend learning either language but, due to the youth of Go, I would probably give the nudge to Python. There is a tremendous amount of introductory material, a plethora of third-party libraries, and a ridiculous amount of other online resources for Python. These will likely come with time for Go, and they are, but its far too young to have the support you would get with Python. After learning Python, however, transitioning to Go will be a breeze. Like Python, it is a terse, well formatted, and powerful language.

Outside of each of their respective third-party libraries, Python is almost a write once, run anywhere language just as Go is almost a write once, compile anywhere language. That is one thing about C that drives me crazy. I hate always having to use tons of boiler plate to conditionally do things depending on the operating system or compiler I'm using to build my application. Its wonderful to know that something I commit to one of my projects will work without modification on any architecture and operating system supported by the language.

That's not to say these languages are perfect. There are things I don't like about both. I prefer the static typing of Go. I prefer how I can run Python scripts directly from the shell without needing to install a third party utility. I prefer compile time error checking in Go. I prefer how I can use the Python shell to interactively run programs and use the interpreter as a calculator. I prefer Go's get program for installing libraries from source. I like how minor changes to the source code, simple things like changes in the doc strings, don't require having to be recompile the work to take advantage of them (via godoc).

Anyway, this is a long winded way of saying that I really like Python and I am glad I've added it to my tool-kit as I intend to continue using it for a long time to come! Hopefully, it won't be so long between posts again. I am going to be learning Scheme and following the SICP soon. I am very happy to see the 1980's lectures up on MIT's OCW site and look forward to watching them!


Friday, 20 January 2012

Build Google Go on Windows

** Important Note: The Go team now provides a Windows port of Go. This is the recommended way of installing Go on that platform but I will leave this here as an exercise to whomever would prefer to install Go this way. **

I've seen countless posts requesting a Windows port of Go. For quite some time there hasn't been one available but, thankfully, there is an experimental port available. However, as it turns out, you can also compile it yourself without waiting for someone else to do it for you. This gives you the advantage of always having an up-to-date version of Go by having immediate access to the latest release without having to wait for a build, or even using the weekly release. In order to do this, we'll need MinGW.

So, without further adieu, here is a step by step installation procedure to start using Go on Windows.

1) Install Msys and MinGW. You will need a POSIX compliant shell in order to build Go. I'm sure Cygwin would also be capable of building Go but I prefer Msys. For anyone new to Msys, or unfamiliar with using the CLI, I would recommend using the GUI installer. As per the golang documentation, you'll need to make sure you install the following tools: gcc,  glibc or some other C standard library, Bison, Make and Awk. All of these tools are available via the apt-like mingw-get tool. If you forget to download one of these tools during installation, don't worry. The mingw-get tool is accessible from within Msys.

2) Install Mercurial. Here you have two choices. One, you can try and build Mercurial from source on MinGW or you can do the sensible thing and download the Windows version. I highly recommend doing the latter. You can also get TortoiseHg if you require a GUI but if your only intention is to use it to download Go then I wouldn't bother. It's much simpler just using the CLI.

3) Open the Msys terminal. Assuming all is right with the world you will be in your home directory. You should now be able to use the following command, as taken from the Golang installation guide:

$ hg clone -u release https://go.googlecode.com/hg/ go

4) Change to the go/src directory and run all.bash.

$ cd go/src
$ ./all.bash

5) If all goes well, Go is now installed and ready to go! That's it! I recommend creating a .bashrc file and add the recommended environmental variables. Something simple like:

$ cat > ~/.bashrc << EOF
# .bashrc
export GOROOT="$HOME/go"
export PATH="$PATH:$GOROOT/bin"
EOF
$ . ~/.bashrc

Msys does not come with any kind of editor installed (not even ed). Vim is available through the repositories via mingw-get or you can just use your normal text editor for Windows to edit the file. There are plenty of other things you might wish put into your .bashrc, too, but that is beyond the scope of this article. If you installed Msys into the default installation directory, you would save it in "C:\MinGW\msys\1.0\<username>\.bashrc" where <username> is replaced with your name. Obviously.

I should mention that on my first attempt on building Go, the build script hung while trying to compile gprof. Sadly, I didn't have the presence of mind at the time to record on which file it got stuck on, so there's not much I can do to see if this is a Go or MinGW/Msys bug. Irregardless, I had to force-quit Msys by closing the window because no other method would unlock the process. Re-running the all.bash script a second time completed successfully and finally reported that, "ALL TESTS PASSED!" Now THAT is what I wanted to hear! Or, in this case, see.

You should now be able to use the Go tools from the 'cmd' shell but in order for the shell to find it you will need to manually adjust your %PATH% environmental variable in Windows, too. A simple way to do this on Windows 7 is to open the start menu, right-click on 'Computer' and select properties. Then, click the 'Advanced Settings' link on the left to open the advanced settings window. A button near the bottom of the window will allow you to alter your PATH variable. A simple search can show you how to do it on other versions of windows or via an alternate method.

And that, as they say is that. A native Windows build of Go. Provided you adjust some environmental variables, as noted in the 'Getting Started' documentation for Go, you are free to relocate the go tree to another location like "C:\Program Files (x86)". You may also want to build the 'hello world' application as an extra sanity test. You can install a Go IDE or add Go syntax highlighting to your favourite editor.

Sunday, 8 January 2012

A Path to Python

I've always liked the saying, "The only truly stupid person is the one who has nothing left to learn." I have no idea who said it, or if I even have the quote right, but it's always stuck with me. So, I am always trying to learn new programming techniques and new languages.

Call it a fault of mine but I always learn the best when I'm enjoying what I'm learning. I know I don't stand alone in that. So, I've discovered that when I'm going to learn a new language I need to know more about it first; and, to really know a language you have to see it in action. Feature's really don't mean a lot unless the language "speaks" to you. So, I always browse the source code of some applications written in the language. I always take a look at a minimal "hello, world" application, too.

Python has been recommended to me in the past on several occasions but I've never really paid it much interest. My first hang up was the need for the Python interpreter. I didn't like the idea that a user of my product would have to install the Python VM just to use my application. I prefer an all-in-one package and bundling Python with the installer would increase an installer's size dramatically. Of course, there are other solutions but at the time that's how I saw it. I was also worried that Python was very slow. Maybe, at the beginning, it was slow but in relation to what? Will the speed difference even matter or be noticeable? And is that still the case? For application level programming it would probably be a complete non-issue but, again, I couldn't see that at the time.

Go also challenged my programming dogmas. For example, take dynamic linking. I had grown to believe that dynamically linking libraries (not to be confused with dynamic loading) was the only way to go. I just couldn't wrap my head around why anyone would ever use static linking (make sure to follow the links at the bottom of the page) and chalked it up as the old, antiquated way of doing things. How wrong was I? Both methods of linking have advantages and disadvantages and I can certainly appreciate why Go does much of it's linking statically.

Go does struggle with a couple issues and one of the big ones is shared with C. Because most third-party libraries utilized by Go are linked to C libraries portability becomes an issue. I've been looking for a "write-once, run-anywhere" solution ever since writing my first non-trivial application. There is only one platform that immediately jumps out at me to fit that bill: Java.

Initially, I thought Java might be a great language. It's C-like, the JVM is installed on most platforms, and has a huge collection of libraries built right in! Unfortunately, despite it's many strengths, I didn't enjoy programming in the language. My feelings about Oracle aside, I felt that it is very, very verbose. Take even a simple "Hello World!" program for example:


class HelloWorld {
  static public void main( String args[] ) {
    System.out.println( "Hello World!" );
  }
}


Now, compare that to Go:


package main
import "fmt"
func main() {
  fmt.Printf("Hello World\n")
}


And, finally, Python:


print "Hello World"


As I began to work with the language I started to feel like it was more of a patched together, band-aid solution, mess. Don't get me wrong, Java is a decent language but it just doesn't work for me. C is painful enough to program in, Java seems to be worse. Thankfully, other avenues to the JVM platform exist.

I considered Clojure, Jython, Groovy and Scala. I want to learn to learn a LISP-ish language at some point so I thought Clojure may work. After looking at some source code and documentation for the other languages, the only one which spoke to me was Jython. Python + the JVM? How can you go wrong?

Documentation for Jython is somewhat lacking if you don't already know Python. Good thing there's an easy solution to that. The Jython documentation is good for learning how it differs from Python and how to utilize the JVM, and Java, from within Jython but not much on learning the language itself. So? Learn Python.

My first observation has been that it is remarkably similar to Go. Go has clearly been heavily influenced by Python and I feel right at home with it. It does differ from Go in several distinct ways but it's turning out to be a completely fantastic language and I can see why so many programmers are using it. It's expressive, concise and an altogether eloquent language.

Time is important to me. I have precious little of it. So getting bogged down with nonsense is something I do my best to avoid. Python, like Go, does away with a lot of the nonsense and let's you get down to producing functional projects. I can see myself working with it a lot in future projects and I look forward to that time. I think, too, it will help me bridge the mental gap with being able to work in a LISP-like language.

After learning the basics of Python I then started to work with Jython. The amount of time it took for the Jython interpreter to load took me aback. I had gotten used to how quickly the Python interpreter loaded. I then discovered that Jython is based on Python 2.5. Not only is it two CPython releases old (as of this writing CPython 2.7 is the current stable 2.x branch) but Python 3 has also been released. While this hasn't proved to be particularly handy-capping thus far I am worried about the future of Jython as it falls further and further behind it's parent project. I am also concerned about it's speed. Is the slowness of it's interpreter indicative of the language itself? I suppose time will tell, literally.