Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Saturday, 1 June 2013

Proposal for a GUI Toolkit for Go

The Situation

This isn't a unique topic. It's come up in the mailing list before.

Let’s face it, while Go is a general purpose programming language it is ultimately a systems language. It was designed to be concurrent. It was designed to write servers. It was designed to provide a back-end to other services. It does those things pretty well. There is, therefore, an area where Go is lacking and that’s as an application programming language.

This isn't because Go as a language isn't suited it to but that it's standard library doesn't include a crucial component: a UI toolkit. A few people have blamed Google (which makes no sense because Go is not actually a Google project) and the Go developers for this but honestly, it's not their problem. It's not what Go was designed to do nor are the current devs experts in UI design.

Who’s responsible then?

Us.

To be honest, there have been a few attempts already, each with their own merits, but I think all these solutions still fall short of an ideal GUI for Go. So, let me tell you why I think this.


What We Have and Why They Don’t Work

1. GTK+ or another UI Toolkit Wrapper

The easiest, most obvious choice is to create a wrapper for an existing UI Toolkit because of cgo and SWIG. GTK+ fits the bill and mattn has begun this work already. However, there's a problem. For one, GTK+ is C-based. No matter how well the wrapper is designed I don't think it will every feel very Go-like. The toolkit itself is a beast, too. It has thousands of function signatures in it’s API and will take a fairly large concerted effort to completely implement it. More importantly, however, I don’t think this is the right choice and I'll tell you why.

Using GTK+ means that users will need to install it if they don’t have it already. For Linux users, this usually isn't a problem but what about Windows and Mac users? Now we have a problem. I’m a firm believer that you shouldn't force users to install things onto their computer just to run your application unless it's absolutely necessary; and, it makes the installation process more complicated. There is, of course, a solution by including the GTK+ source into the dev tree but we're not talking something like sqlite3 where this can be done easily. GTK+ is massive and I just don't see this as being a feasible solution.

2. GoWut or another HTML Server

I think GoWut is a great idea with what I think is one glaring flaw: it’s a web server. For a single user application, it doesn't feel right. For one, the server doesn't shut down after you’re done using it. Yes, this could be considered a feature because it would reduce load-time of future invocations and you can have user sessions but to me it’s a problem. As an end-user, I don’t want a terminal hanging open with a server running in it. I certainly don’t want all my applications each running it’s own server hogging up my resources, just waiting to be accessed again. I'm sure you could have a 'quit' button to shut down the server but that just doesn't feel right.

3. Go UIK

A native UI Toolkit designed to work like an idiomatic Go library from the start? Sounds awesome! The problem? It’s not done, yet. It’s still in the early design stages but certainly something I’m going to watch for. I think this project has a lot of promise and I look forward to seeing how it turns out. Another issue might that it is going to use a custom widget design rather than a look and feel native to the OS. If, however, it looks pretty enough I’m sure I can overlook that.

4. GoWebkit

Now we’re talking. This to me feels like a more natural solution than a wrapper for another Toolkit. Open a basic application window with webkit embedded in it? Fantastic! This solution comes very close to the mark with one glaring issue: it uses GTK+ as a back-end. The other issue is that it's not a UI. You will have to have some HTML and CSS skills to actually create anything with it and I don't think that provides a very unified solution.


The Solution

Webkit + Native UI Backend + HTML + CSS + (YA/X)ML

Existing technologies mixed together to provide a hybrid result. I think we need a UI Toolkit that uses the OS’s native windowing mechanism (Win API for Windows, Cocoa for Mac, X, GTK+ or Qt for Linux), maybe using John’s WDE library, an embedded webkit renderer, with an API akin to any traditional UI Toolkit complete with event handling. It should allow for customizable CSS elements and, the icing on top, a markup language UI layout design utilizing something like XML. Hrm...it feels like I've just described Android’s UI toolkit...

Of course, this needs some rationale.

1. Native UI Backend - Go is multi-platform. A UI toolkit should be as multi-platform as possible and not require end-users install additional toolkits onto their system. Many application designers will want to control window sizing and else-wise have control over them, like having modal windows. Javascript could provide some of this behavior as well.

2. Webkit - Creating a custom toolkit from scratch, including widgets and all the rest is a colossal undertaking. Qt, GTK+, Win API and Cocoa took an incredible, collective effort to create. Webkit would allow us to circumvent this effort by using a UI that already exists: HTML5 and Javascript. Is this an ideal solution? Maybe not but it’s a reasonable solution that wouldn't require the herculean effort to create a full UI from scratch.

3. HTML + CSS - I think GoWut has a good idea here. Default widgets and creation mechanism so devs don’t have to write HTML and CSS if they aren't skilled in those areas. There is a request in another toolkit's issue tracker requesting ‘nicer’ CSS style to be used by default which I think is a good idea. All a dev would have to do to make their UI unique or make some minor alterations is edit the existing CSS. Or better yet, have an override system in place so that the built-in CSS wouldn't need to be altered. I think adding a custom CSS file shouldn't require injecting an html string with a link element as it does with GoWut but rather a simple API call of SetCSSFile() for a much more elegant and less error prone solution.

4. XML or some other markup language - Android uses this mechanism and so does GTK with GtkBuilder/Glade. I think the reason for this is twofold: a) a UI can be quickly generated by hand without cluttering up the application itself with hordes of API calls for creating widgets; and b) it allows for the use of visual GUI creation tools for building UI’s, akin to Qt’s QtCreater or GTK+’s aforementioned Glade. Like Qt and GTK+, I’m not sure this should be the sole method of building an application UI but rather a complementary one to a standard API. I suggest XML only because I know it's used in existing solutions like Glade/GtkBuilder and Android.

Is this the best solution? Good question!

Conventional languages for writing applications seem to rely on either an existing native toolkit (Tk for TCL, Swing/JavaFX for Java, GTK+ for C or Qt for C++) or a language wrapper for a non-native toolkit. However, most of those tools are either language specific (Swing/JavaFX) or are encumbered by methods for handling situations native to their own languages that don’t play nice with Go (concurrency/threading). There might be ways to overcome these limitations but there you have it.

There are a lot of existing resources for HTML and CSS. I think it would be far easier to find someone proficient in these technologies to help in such an endeavor than it would be to work on some of the other solutions. As a further plus, most of the groundwork has already been done. By combining something like wde for a backend and webkit to render pages then we already have the canvas on which we can paint. By adding in elements of gowut on top, minus the server aspect of it, we essentially have the end product. Add in a dash of CSS to pretty things up, XML for widget creation and layout and we’re done. Sounds easy huh?

Probably isn’t but I think it’s easier than the other solutions with a better end result. It would feel more idiomatic to Go, build on existing technologies, and make for an easy transition for a wide audience (those who are already familiar with HTML, XML and CSS).

I'd love to see some input.

Monday, 13 May 2013

Go: Interfaces and Type Assertion

Hot on the heals of my last post, I feel I have to share a little trick I just discovered about type assertions. While it is documented within the language specs I handn't really seen anyone talk about this in a formal manner until coming across a post in the Go mailing list.

In the pursuit of implementing Scheme-like functional behaviour in Go in order to solve some exercises in SICP I discovered a problem: Scheme is dynamically typed and it's internal data structures (cons, list) allow for mixed types. While this is obviously handy it creates some problems, most important of which is type safety. Thankfully, Go provides an awesome way to handle this: an empty interface.

Go's implementation of interfaces is awesome. It might be a bit foreign to those who come from other languages with interfaces, like Java, where you have to specifically state that an object implements an interface. No so in Go. If you want an object to implement an interface just implement it. Objects can then be used anywhere that accepts that interface. You don't need to explicitly state anything. An object either implements an interface or it doesn't. However, that's not what this post is about. No, this is about type assertions and the empty interface.

An empty interface is just that: Empty. That means that any type matches an interface because the empty interface has no requirements, no functions to implement. You could think of the empty interface as a generic type but I think that's misleading. Interfaces are interfaces and types are types. And this leads us to what I want to talk about. Implementing a list type which accepts multiple types, all at once:

type List []interface{}

We've created a slice type which accepts variables of any type. As I've already stated, the empty interface doesn't have any requirements so every type implements its interface, which is why we can use it like this. What's truly brilliant, is that we can use all the slice operations on this new type just like regular slices like ranging through the slice or creating sub-slices. This absolves us from even creating a constructor. If you want to simply create a list of integers do:

l := List{1, 2, 3, 4}

Fan-freakin-tastic, I say! So we've created a list type that behaves like it's dynamically typed. The icing on the cake is that we don't even need to create a custom String() function for our List type, even with nested Lists!

This is great and all except that Go isn't dynamically typed. So, what happens if we create a list of integers and try to add them up? Well, since an interface{} isn't a type, and we try to use the + operator on it, the compiler will fail with an error. So, how can we get around this? Type assertions. We can assert that an element in the list is of a specific type by using a type assertion:

l[0].(int)

But, there's a problem with that. We don't know what type we might have and we can't guarantee what we've received is what we expect. If we assert that an element in the list is a specific type, and we're wrong, our program will panic and, if not caught, will crash our program. And this, finally, is what I've been wanting to talk about. Thanks to our intrepid Go developers, functions can have multiple return types. In the case of type assertions, we can check to see if the assertion succeeded, which suppresses the panic if we're wrong. So let's write an Accumulate function which performs an operation on our list:

type Operation func(int, int) int

func (l List) Accumulate(f Operation) interface{} {
res := 0
for _, v := range(l) {
if i, ok := v.(int); ok {
res = f(res, i)
continue
}
if lst, ok := v.(List); ok {
res = f(res, lst.Accumulate(f).(int))
}
}
return res
}

Voila! Now, you'll notice that I've cheated a bit where I assert that the value returned by Accumulate is an integer on line 11, after I test whether the current item in the list is another list. Since I know that Accumulate can only ever return an integer I can be safe in that assumption even though Accumulate returns another empty interface. I could have just made Accumulate return an integer and avoided the type assertion completely but the point was to create a function which could accept and return any type. We might want to be able to concatenate strings or operate on floats. However, I cheated a bit in the implementation details for simplicity's sake. Obviously, if you wanted to write an Accumulate function which accepts lists containing many types different types you'd have to do a bit more work to test what type you received back.

Thankfully, there's another way you can test what type a variable is. If you need your function to accept many different types, you can use an assertion switch. In my case, I didn't need to go that far because I knew I was only dealing with integers and lists of lists. However, I'll show you an example of what it might look like:

func (l List) Accumulate2(f Operation) interface{} {
var res interface{} for _, v := range(l) { switch t := v.(type) { case int: if res == nil { res = 0 } res = f(res.(int), t) case List: if i, ok := t.Accumulate2(f).(int); ok { res = f(res.(int), i) } } } return res
}

And that, as they say as that! Strictly speaking, you'd have to do a heck of a lot more work if you were to add more types. For one, what would happen if there were strings mixed with ints? Or even floats and bytes? This function only really works if all the elements are of the same type or if elements are other lists. If, though, you do need to wrestle with mixed types in a single list you might need to rethink the problem you're trying to solve!

Hopefully, this has provided you with another tool to add to your toolbox, as it did for me. For the complete source code, go here.

Saturday, 4 May 2013

Data as Procedures

* Updated: Made the example a little more idiomatic and used a more intuitive type for differentiating between the numerator and denominator. Thanks to the excellent comments/suggestions! *

It has been a long while since my last post. Having a stressful full-time job, two kids under the age of five, and all the other fun and foibles that come along with life has been a natural distraction. Hopefully, I can get back into the swing of things again but I make no promises!

I've begun reading Structure and Interpretation of Computer Programs. It has proved, thus far, to be truly enlightening and I feel the need to talk about my first revelation, of a sorts. Coming from a primarily imperative based background, functional programming is somewhat foreign to me. For example, the concept of data as procedures came as truly mind boggling. Even the book pokes fun at the reader about it! I have only ever known data as container constructs. In C and Go these would be structs and in C++ and Java, classes. However, through the use of closures you can do away with data structures and use procedures instead.

SICP uses the example of representing a rational number. A rational number consists of a numerator and a denominator and we normally write them as a faction (i.e. 3/4). In essence, they're a number pair and you could represent them as a structure quite easily:


type RationalNumber struct {
numerator, denominator int

}


You would then create constructor and selector procedures to operator on the data structure. Nothing new here. However, there is a way to do away with the data structure. First we'll create the constructor. This is the hard part:


type Fraction func(bool) int

func NewFraction(n, d int) Fraction {
return func(z bool) int {
if z == true {
return n
}
return d
}
}


Utilizing a closure, we create a function which returns a function containing our data. To make this a little more idiomatic Go we've made the return function it's own type. If we supply this function with a value of true it returns the numerator and if we supply false it returns the denominator.

The rest becomes trivial. We just create our selectors to accept the closure as a parameter and tell it what we want to return:


func Numerator(f Fraction) int {
return f(true)
}

func Denominator(f Fraction) int {
return f(false)
}


Voila! We've just represented data without using a data structure! Colour me impressed! In a language like Scheme the implementation is a lot cleaner looking. Because Go emphasis type-safety we have to do define a lot of data types making thing look a lot more complicated than they really are.

Full source code for this example can be found here. Click run to see it in action.


If you want a more thorough, professional explanation I highly encourage you to read SICP yourself. If you want a PDF you can find a link on the Wikipedia page.

Saturday, 21 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.

Monday, 28 November 2011

Creating a Treeview in Glade

Preface: This was one of the first articles I wrote for my blog but never published it. I can't say why but I didn't. It's quite old and it's a little embarrassing. I figure I may as well post it though since it might just help another Glade/GTK+ newbie out there!


Disclaimer: This article assumes you have an understanding of how to implement the Model/View/Controller methodology of a GTK+ treeview. It is also intended for GTK+ 2.xx but may still be applicable to GTK+ 3.xx.

It seems like every day I program I am reminded about how much more I have to learn. Some days, like the name of my blog suggests, I feel like I have no idea what I'm doing. Or more appropriately, what I'm doing wrong. Take for example, a few nights several months ago.

I was continuing the process of converting the user interface for Vocab Builder from a C source code implementation to a gtk-builder xml user interface via Glade. Glade makes designing and maintaining a user interface a dream when it's behaving properly. I am using the latest version of Glade (3.8.0 at the time of writing) on Ubuntu 10.10 Maverick Meerkat and I have experienced a few problems. One of them is a real show-stopper. Literally. Somehow the widget tree gets corrupted and isn't displayed properly. Some widgets are just blank lines where the widget should be or are a garbled mess. If that happens, and you click on the place where the widget SHOULD be, Glade crashes. No warnings, just straight back to the desktop. All unsaved work is lost. Good times! The only work-around is to not click on the spot and instead find the widget (if you can) in your UI and click on it, hoping all the while that it's a visible widget because if its a vbox or adjustment widget you might be out of luck. A work around is to restart Glade. Closing the UI file and re-opening it may fix the issue too, I don't know.

Creating more than just the treeview widget seems to be a relatively new feature to Glade which might explain some of its oddities. First of all, how you add columns isn't exactly clear. Unlike other widgets, there's no treeview subcategory in the tools section where you can click on a category and easily add it to the treeview as a child widget. No sirree, you have to right-click on the treeview widget and select Edit. Okay, fine. Not a big deal. An odd design but whatever. How about a cell renderer? There is absolutely no visual clue that tells you how to add one. What you have to do is go into the Hierarchy tab, where you add new columns, and right-click on each column and select Add. Again, it sort of makes sense but with how easy it is to implement other widgets you would think there would be some kind of a clue like a button or tooltip which would indicate how you add a renderer. At least the Hierarchy tab had an Add button that let you know you could add something to it. View and controller done. What about the model?

Well, there's a property for the treeview where you can select the model to attach to it. It pops up a handy window that allows you to either select a tree model you've already created or, if you haven't created one yet, you can click New and Glade will create one for you. By default, Glade gives you a ListStore. This is where my problems began. I didn't clue in that it was a ListStore that was created by default. To be fair, Glade does call the model ListStore1 or something like that. I just never picked up on it. So I edited the model and put in the values I needed to store in the model. Uh-oh, what's this? Another stumbling block? Where's the string type? There MUST be a string type...Nope, can't find one! As it turns out, while a string is TYPE_STRING in GDK in Glade its called a gchararray. Yes, a string is a character array. So...why change what its called? Why not gstring? Oh...maybe that's why? G-string? Naw...must be another reason. Maybe just to piss me off? Either way, off I went and re-ran Vocab Builder to see if my changes were working. Yup, the treeview headers are clickable and the sort indicators look like they work. It does almost everything I want sans a few options I haven't implemented, yet. However, when selecting New in the Editor the ability to sort by columns disappears. What the heck? What's going on? After hours of trying to solve the issue, nothing. Bah! "I'll fix it tomorrow."

Here it is tomorrow the following day and I'm still not sure what's going on with the treeview so I start converting the Builder interface to get my mind off the Editor. Turns out I use a treeview in the preferences window, too. I can't escape these darned treeviews! Well, I decide to take another stab at it. I go through all the steps, forgetting how to do some of them and getting frustrated again, but I muddle through it. In my original code, I simply removed the old model and created a new one whenever I needed to update the treeview because it would always be new data. However, I realized that I could do away with all that if I just cleared the old treeview. Hrm...why isn't it working? It says it's not a TreeStore...I stared blankly at the screen in consternation. Ya, right, it's not. Its a ListStore. Ohhhh....what an idiot I am! I quickly convert my functions to use that of a ListStore and viola! Everything works as intended! Fantastic! Now, what if I want a TreeStore?

Luckily, this fix was relatively easy to figure out. Rather than have Glade create a default model for me I can just create the TreeStore model first and then attach it to the treeview. Easy. Fixed. Wish I'd known that yesterday the day before after spending hours trying to figure it out...

Addendum: If there turns out to be some interest in an actual step-by-step example of the process of creating a treeview in Glade/GTK+ I'd be more than happy to do so.

Sunday, 23 October 2011

Experimenting with Cgo - Part 3: Errno

In this third installment of introducing cgo to novice Go programmers I want to talk about error handling. More specifically, how to handle C functions that utilize errno. At first glance one would think that this is something no harder to implement than anything else. Not so. There are a couple of "gotchas" with errno in particular you need to be aware of and little to no documentation to help you out. In particular, there was absolutely no documentation describing how to extract errno from os.Error.

  1. errno can't be accessed directly in Go. The cgo documentation clearly states why this is the case. In two words, 'thread safety'.
  2. There is a handy way to trap errno as an os.Error in Go but no obvious way to extract the actual error number.
After a lot of trial and error I finally pieced the puzzle together. First, if the C functions you're implementing set a common system error, as a function like fopen() would, then cgo provides a simple and easy way to get a Go-like error. Again, I refer you to the cgo documentation and you don't really need to look any further. If, however, you're using a library that doesn't you'll need to follow these steps, or at least some of them.

1. Map the error codes to sensible strings describing the error. Documentation on the library you're implementing usually does a good job helping here.

var errText = map[int]string {
    C.EINVAL: "Invalid mode specified",
}

2. Create a helper function to handle printing the error.

func error(e os.Error) os.Error {
    s, ok := errText[int(e.(os.Errno))]
    if ok {
        return os.NewError(s)
    }
    return os.NewError(fmt.Sprintf("Unknown error: %d", int(e.(os.Errno))))
}

This was the hard part. The os package provides Errno, which is Go's equivalent to errno. In order to extract Errno from Error you have to use a type assertion. Errno is typed to int64 which won't work with our C.int error codes so we need to then type cast it to an int.

3. Catch the error value returned by the function utilizing errno to describe errors.

    f, err := C.fopen(cpath, cmode)
    if f == nil {
        return nil, error(err)
    }

It's as simple as that. Complete source code follows:

Makefile:
include $(GOROOT)/src/Make.inc

TARG=cgoexample
CGOFILES=cgofopen.go

include $(GOROOT)/src/Make.pkg

cgofopen.go:
package cgoexample

//#include <stdio.h>
//#include <stdlib.h>
//#include <errno.h>
import "C"

import (
    "fmt"
    "os"
    "unsafe"
)

var errText = map[int]string {
    C.EINVAL: "Invalid mode specified",
}

func error(e os.Error) os.Error {
    s, ok := errText[int(e.(os.Errno))]
    if ok {
        return os.NewError(s)
    }
    return os.NewError(fmt.Sprintf("Unknown error: %d", int(e.(os.Errno))))
}

type File C.FILE

func Open(path, mode string) (*File, os.Error) {
    cpath, cmode := C.CString(path), C.CString(mode)
    defer C.free(unsafe.Pointer(cpath))
    defer C.free(unsafe.Pointer(cmode))
    
    f, err := C.fopen(cpath, cmode)
    if f == nil {
        return nil, error(err)
    }
    return (*File)(f), nil
}

func (f *File) Close() {
    if f != nil {
        C.fclose((*C.FILE)(f))
    }
}

example/Makefile:
include $(GOROOT)/src/Make.inc

TARG=cgoexample
GOFILES=fopen.go

include $(GOROOT)/src/Make.cmd

example/fopen.go
package main

import (
    "cgoexample"
    "fmt"
)

func main() {
    f, e := cgoexample.Open("foobar", "qq")
    defer f.Close()
    
    if e != nil {
        fmt.Println("Error: ", e)
    }
}

Tuesday, 4 October 2011

Experimenting with Cgo - Part 2

In this second cgo article, I am going to demonstrate how to handle strings. There is already an excellent post by Andrew Gerrand, one of the Go developers at Google, on using strings in cgo. My own post will provide a slightly more complete example.

The first thing to understand is that C has no concept of a string. Unlike in Go, where a string is an actual type, a string in C is just a pointer to an array of characters. Thankfully, the "C" package has two simple functions to convert between the two types. However, there are two problems: One, converting from a Go string to a C string (character array) allocates memory to the string which is NOT garbage collected by Go. This is important! The reason for this is because Go has no way of knowing when the C library you're creating a language binding for will be done with the string. Once your function exists, any local variables will go out of scope and Go's garbage collector will at some point free the allocated memory even though the C library involved may not be finished with the string. Therefore, you have to free the memory when you know the C library is finished with it. Second, you still need a means of storing characters into a buffer and there isn't an immediately obvious way to do that.

This article assumes you've read my previous post and already know how to start a basic cgo project and have a working Go development environment. I am going to provide a very simple wrapper for the following functions from stdio.h: fopen, fclose, fputs, fgets and frewind.

Important: Absolutely no attempt was made to provide error handling in this code in order to provide absolute clarity for the code itself. While I believe proper examples should always contain error handling, handling errno and NULL return values is not easily handled in Go.

1. Include any C headers and import any libraries you will need:


// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

Note that, when converting to a C string, you will need to free the allocated memory. Free() from stdlib.h is required to do this. You will also need to the "unsafe" library to handle C pointers.


2. In order to make stdio feel like Go, type the FILE structure:

type File C.FILE

While embedding the FILE type in a struct would allow us to create much clearer code because we could remove all the casting to/from the C and Go types Go does not allow C types to be embedded into Go structs. So, we must do things the hard way.

3. Implement the fopen() function:


func Open(path, mode string) *File {
    cpath, cmode := C.CString(path), C.CString(mode)
    defer C.free(unsafe.Pointer(cpath))
    defer C.free(unsafe.Pointer(cmode))
    
    return (*File)(C.fopen(cpath, cmode))
}

Notice first that, like the original C code, we accept strings as arguments to indicate the path and mode. The CString() function from the "C" package allocates enough memory for the Go string and then converts it to a C string. You must make sure you free the memory after using it, and the defer statement is the ideal way to accomplish this. Not only does it guarantee to free up the memory it does so after we return the value from fopen(). free() take a void pointer as an argument, so variables passed to the function must be cast to an unsafe.Pointer().


4. Implement the fgets() function:


func (f *File) Get(n int) string {
    cbuf := make([]C.char, n)
    return C.GoString(C.fgets(&cbuf[0], C.int(n), (*C.FILE)(f)))
}

I found this to be tricky to figure out until I thought about it. You need to provide a pointer to a C character array but Go provides no obvious ways to do so. Use Go's make() function to build an array of characters. You could also use a static array size but the dynamic version provides a lot more flexibility and is no more complex to implement. Use C.GoString() to convert the C string to a Go string.

5. Implement the rest of the functions. See below for the complete code.

6. Compile and install your library.

7. Compile and run a test program to complete your proof of concept.


The complete code follows:

godev/src/gostdio/gostdio.h:

package gostdio

// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

type File C.FILE

func Open(path, mode string) *File {
    cpath, cmode := C.CString(path), C.CString(mode)
    defer C.free(unsafe.Pointer(cpath))
    defer C.free(unsafe.Pointer(cmode))
    
    return (*File)(C.fopen(cpath, cmode))
}

func (f *File) Close () {
    C.fclose((*C.FILE)(f))
    return
}

func (f *File) Get(n int) string {
    cbuf := make([]C.char, n)
    return C.GoString(C.fgets(&cbuf[0], C.int(n), (*C.FILE)(f)))
}

func (f *File) Put(str string) {
    cstr := C.CString(str)
    defer C.free(unsafe.Pointer(cstr))
    
    C.fputs(cstr, (*C.FILE)(f))
    return
}

func (f *File) Rewind() {
    C.rewind((*C.FILE)(f))
}


godev/src/cgoexample/cgoexample.go:

package main

import "gostdio"
import "fmt"

func main() {
    f := gostdio.Open("test.txt", "w+")    
    defer f.Close()
    
    f.Put("Some example text\n")
    f.Rewind()
    
    fmt.Println(f.Get(13))
}



Monday, 26 September 2011

Experimenting with Cgo - Part 1

** Modified: Updated to comply with Go 1.1 release. **

This is the first in a planned series of posts on cgo. Cgo is a program in the Go language tool suite that allows programmers to wrap C language libraries for use in Go. I have found it to be an incredibly useful tool and I am sure will help provide Go with the ability to grow it's third-party, non-standard library more quickly.

I am currently designing some software for personal business use which would utilize the ncurses library as an interface. There is already a curses wrapper library available for Go but I wasn't entirely satisfied by the completeness of the library. For one, the mouse isn't implemented at all, along with a myriad of other functions. Nor are the form, menu or panel libraries. So I decided that this would the perfect time to learn cgo.

To create a wrapper library for a C library you need to take the following steps:

1. Setup your build environment. I recommend using a sub-directory in your home directory. On Linux you would use:


$ cd ~
$ mkdir -p godev/src/mylibwrapper


Of course, you can change the 'godev' to whatever you want and 'mylibwrapper' to the name of the library you're creating a wrapper for but 'src' must be a sub-directory of your development hierarchy.

You will also need to set your $GOPATH to this new directory. On Linux you might use:


$ export GOPATH="$GOPATH:/home/username/godev"


Take care not to add a slash at the end of the directory name as the go tools won't like it.

2.  Within your wrapper library you need to include the C library header(s) you need to use followed by the C import directive:



// #include <math.h>
import "C"



It is essential that 'import "C"' is on its own, directly after the commented C code in order for cgo to work properly. Or, at all for that matter. You can write your own C code prior to the import call and use either of Go's comment styles. 


3. If you need to pass any compile flags or link to the C library, like the C math library, you would use cgo's LDFLAGS and CFLAGS:



// #cgo LDFLAGS: -lm



4. To access any of the C functions from your Go code, you use the C namespace. Same goes for C types. As a matter of fact, no Go types are available in C and vice versa. Therefore, everything you need to pass to or from a C function must be cast to or from a C or Go type. Unfortunately, strings aren't so easy. In order to convert a Go string to a C string, you need to use the CString function. For a good example and explanation, see Andrew Gerrards blog post on the subject.



func Pow(b, e float64) float64 {
    return float64(C.pow(C.double(b), C.double(e)))
}



5. Run 'go build' to compile your code. This step is not strictly necessary as installing automatically builds the library for you and will not install it if the build stage fails.

6. In order to test your new wrapper, you'll need to run 'go install' and then import your library into some Go source.

That's it, start to finish. To view a complete example:


godev/src/mylibwrapper/mylibwrapper.go:

package mylibwrapper

// #cgo LDFLAGS: -lm
// #include <math.h>
import "C"

func Pow(b, e float64) float64 {
    return float64(C.pow(C.double(b), C.double(e)))
}


godev/src/cgoexample/example.go:

package main

import (
    "mylibwrapper"
    "fmt"
)

func main() {
    b, e := 5.0, 2.0
    f := mylibwrapper.Pow(b, e)
    fmt.Println(b, "raised to the power of", e, "is", f)
}


Wednesday, 24 August 2011

Compiling C Programs in Linux

A lot of beginner programmers, especially those new to the Linux world, have a lot of issues compiling programs. This isn't exclusive to C, of course, so hopefully you can take something away from this post and apply it other languages, too.

There are two primary stages to "compiling" a program. The first stage is the compilation stage. There are several intermediary steps but the end result is that your code, in this case C, is translated into a machine readable language. The second stage is called "linking". This is when each part of your program and any external libraries are linked together to create an actual executable binary file you run or a library file.

Disclaimer - This post may be hazardous to your health (not really). It is a non-exhaustive and non-authoritative introduction to compiling and linking programs on the command line in Linux. I can't emphasize enough that you should reference the documentation provided by the compiler you're using and that said documentation will always trump anything contained herein. Side effects may include: nausea, dry mouth, hair loss, severe depression and momentary blindness. If any of these side effects occur, discontinue use immediately and contact your physician.


Stage 1 - Compilation:


The Compiler:

First off, you have your choice of compiler. We are going to concern ourselves with the GNU C Compiler (gcc); currently, the most widely used C compiler for Linux. LLVM has been gaining ground but we won't be discussing it here though it stands to reason much of what you learn would still be applicable. The GNU C Compiler, usually simply referred to as GCC, is actually a collection of tools for compiling programming languages. Each tool has a unique name which reflects the language it is designed for. For example, compilers exist for the following languages in addition to C: C++ (g++), Java (gcj) and Fortran (gfortran). Only some, though possibly all, may be installed on your system by default.

Important: Do NOT use g++ to compile C language sources. There's a reason why they are separate compilers.

In the case of C, make sure you have a GCC installed on your system. Open a terminal and type:


gcc --version

If you get an error of some kind, chances are you don't have GCC installed and will need to do so before you can go any further.

Hint: For those of you running a Linux system like Arch, Debian, Fedora or Ubuntu you can install any of the tools discussed within this document quite easily. For example, Debian based systems usually have a 'build-essential' target via apt-get for installing commonly used tools for building programs from source. You can simply issue the command 'apt-get install build-essential' without the quotesCheck your specific distribution's instructions for installing these tools from their respective repositories.

Everything in this how-to should be run in a terminal. Make sure you change to the directory where your source files are contained and execute the supplied commands within than directory. There are many, many compiler flags to know but the following should be considered a minimum:

gcc -Wall -pedantic -std=c99 my_file.c -o my_program

...replacing "my_file.c" and "my_program" with the proper names of your file(s) and desired program name.

Compiling a source file with the above flags will produce a final binary, skipping the separate linking stage. However, as your programs get more complex it becomes advantageous to build intermediary objects first then link them together later.


Compiler Flags:

These flags are passed to the compiler to tell it what you want. There are some very important ones to know:

-std=c99 - This flag sets the specific standard for gcc to comply with. At the time of writing gcc defaults to a standard called gnu89, which is the c89 standard with GNU extensions. If you plan on writing a program which may be compiled on a system which does not use gcc as it's C compiler (LLVM, MS Visual Studio, Borland C, etc) then it is probably in your best interest to force the use the most current C standard and disable the GNU extensions. gcc is not 100% c99 compliant but the non-compliant features are rarely used. If you require any of the features of c99 which have not yet been implemented in gcc then you'll have to use another compiler anyway.

-o - Specify an output name for the object or binary. In the most basic case, you use it to specify the name of the program you are producing. If you don't use this flag, gcc will default to using the name of the source file and create a .o file for an intermediary object (myfile.c becomes myfile.o) or, in the case of creating a binary, it will default to a.out for the binary file.

Compiler Warnings:

Warnings should always be turned on. Here are some very important/common ones to know:

-Wall - all warnings; this is misleading because it doesn't actually turn on ALL warnings but just the most commonly desired ones.

-Wextra - turns on extra, more strict warnings.

-ansi - specifies that you want to adhere strictly to the C standard. It turns off all GNU extensions to the C language making it fully ANSI compliant. This is important for portability between compilers. This is automatically turned on when you specify the standards c89 or  c99 with the -std flag. However, as stated earlier, gcc defaults to gnu89 (c89 with GNU extensions) and the -ansi flag will explicitly disable these extensions. -std=gnu89 -ansi is equivilent to -std=c89.

-pedantic - makes ANSI warnings fatal, meaning that they'll be reported as errors instead or warnings and halt compilation. It is usually a good idea to always enable this flag when you give -ansi or -std=c89/99.

Extra Compiler Flags:

-c - compile object code but do not link. This produces a file with the .o extension. Object files, those ending with .o, are later linked together to create a final binary or library.

-I <directory> - This flag allows you to specify an additional location for the compiler to find your header (.h) files by replacing <directory> with the location of the headers being searched for. This is useful if you store your header files in a directory other than the one your regular source (.c) files are located. You can chain as many of these flags together to add as many directories as you need. If you don't know why you would need to use this then it's safe to just leave it out.


Stage 2 - Linking:


The Linker:

As noted earlier, building a program is a two step process. The second step, after compiling, is linking. In most, if not all, large projects sources are usually compiled first into object files. On their own, they do nothing and are essentially useless. In order to work, they need to be linked together to create a single binary file, an actual program, then made executable. This is where the linker, named 'ld', comes in. The linker has its own set of flags which may either be passed to gcc or to ld itself. It is probably easier, and in your best interest, to issue the flags to gcc for simplicity's sake.

Linker Flags:

-l<library> - where library is the name of the external library you need to link into your program, sans (minus) the 'lib' prefix. In other words, if you with to link the math library, libmath into your program, you drop the 'lib' part and use: -lmath. Actually, the linker can find libraries with a basic regex so you can link -lm for the math library.

Extra Linker Flags:

-static - Used to force libraries linked to your program statically. This means that the library itself is incorporated (bolted on) into your program. This increases the size of your program but does away with some of the issues associated with dynamic linking. A discussion on dynamic vs. static linking is WAY beyond the scope of this article.

-dynamic - Force libraries to be dynamically linked to your program. This means that the library is linked to your program but not actually loaded until the program is run.

-L <directory> - Specify a path to find extra/custom libraries by replacing <directory> with the location of the libraries being searched for. This can be used to link external libraries not in installed in the normal paths searched by the linker. It is also used to specify directories within your project if you are linking to internal libraries.


The Next Steps:

For compiling very small programs it is usually easiest just to run gcc from the command line. As programs get larger, though, it usually becomes necessary to remove some of the complexity. The next step would be to create a custom Makefile to build your program. You may then simply issue a single command, make, and the rest of the work is done for you. I mentioned earlier that it becomes simpler to compile sources into objects first then link them later. That is because as a project gets larger the longer it takes to compile and link. By utilizing a Makefile only files which have been modified are recompiled and then re-linking thereby speeding up the build process when changes are being made. This is especially helpful when debugging.

The next step would probably to use a full build system like the GNU autotools. Autotools is a general term for a suite of programs: aclocal, autoconf, autoheader, automake, autopoint and libtool. GNU autotools provides a method of making your code more portable and easier to distribute. They can even roll a tarball for you and compress it. By utilizing tools like GNU gettext and GNOME's intltool you can integrate translations into your project, too. The autotools are the backbone of other distribution methods, as well, like creating an .rpm or .deb in Linux and knowing how to use them tends to be an essential skill. There is plenty of help on the Internet on using GNU's autotools. Just do a web search and you'll find plenty of help.

If you're having trouble, read: How to Get Help

Saturday, 6 August 2011

An Introduction of Sorts, Part 3

The next step of our journey takes us through the second to last leg of my introduction.

So, in my escapades with C, I have learned the following:

1) C is not the best language for every task. Naively, I thought that if I started with C not only would I be able to write any kind of program (which you can) a person can conceive of but that it would act as the basis for learning any future languages (which it doesn't) should I so desire.

2) There are many cool languages to learn, too many in fact. In working through Beginning Linux Programming I came across Tcl/Tk, Perl and shell scripting (Bash specifically). Through other sources I came across Java, Python, LISP and Go. And from there things explode. There are literally hundreds of languages out there!

3) Learning a language doesn't teach you to program, at least, not well. As it turns out, knowing a language doesn't help you much. Algorithms and structure go a lot further in teaching programming. Understanding how to implement a linked list, the best method to store persistent data or the most efficient method of manipulating data is far more essential than knowing where to place a semi-colon or bracket.

4) A compiled language is not the end-all be-all. The JVM, for example, is very cool and Java has all kinds of implementations. You don't need to write Java to use the JVM. Clojure or Jython are examples of languages which are compiled to Java bytecode for execution on the JVM and can take advantage of everything it can provide.

5) Interpreted languages like Perl, Tcl or Python are not slow. First thing to remember, is that over the years things improve and a lot of information on the Internet is old. Really old. A post from 2002 ranting on how slow Python is, is no longer relevant. A heck of a lot has changed in 9 years. With the way technology changes these days, a matter of months can make all the difference. It also has to do with writing idiomatic code and implementing good/quick algorithms which complement the language. While yes, in certain instances, a C implementation of a specific task is faster than the equivalent in Python. However, compare parsing lines of text with C or C++ to Perl. Write an application with a GUI in C and compare that with Tcl/Tk, Java or Python. It's all about matching the tool with the job. You don't bring a hammer to tighten a screw.

6) There is no one way to do something. Quicksort or Bubble Sort are not the only ways to sort data. Not only that but often language implementations may be faster than anything you come up with on your own. You need to know the strengths and weaknesses of the language you're working in to get the most out of it.

7) Dynamic Linking is not necessarily superior to Static Linking. It is also not to be confused with Dynamic Loading. Google's Go language taught me that.

8) Skills aren't necessarily transferable. Knowing how to manipulate pointers, manage memory and use pre-processor directives doesn't usually apply outside the C world. Many languages don't have pointers (or are at least not the headache they are in C), use garbage collection and have no need of  pre-processor directives. That doesn't mean that C, or any other language (read: all), with non-transferable skills don't have something to teach. It just means that everything you learn won't be transferable to another language.

9) There is a trade-off between writing a fast program and writing a program quickly. No one wants a slow and sluggish application. On the other hand, a couple seconds overall is likely not even noticeable in most situations. Now, compare that with how quickly a program can be written in Python or Go to C or C++. There's no comparison.

10) Design is where you should spend 90% of your time. I can't stress this enough. An excellent programmer following poor design will create a mediocre application. A poor programmer implementing an excellent design will create a good program. If you can combine the two, a good design with a good programmer, and you'll make an awesome application.

11) Benchmarks mean little to nothing. Look no further than this example. Any language can be optimized in such a way but I can't think of a better example.

It's funny that, reading back, I haven't even scratched the surface of what there is to learn but this certainly is a foundation for describing how much I know.

In the end, not much.