Friday, June 12, 2009

Mac Development

I'm not really doing any Mac development at the moment, though I have considered it. What surprises me about OSX is just that Apple hasn't modernized the development platform very much. They don't, for instance, have a virtual machine like the CLR. Why does Windows have .NET and OSX not have anything?
It seems somewhat stoneage to have the only language for Mac development be the venerable but crusty Objective-C. The standard variety of Objective-C does not have garbage collection, and it has all the unpleasant benefits of unmanaged C. I haven't done much development with Objective-C, so I can't say how often memory leaks arise; I do appreciate their auto-release pools and associated reference counting mechanisms, but I strikes me that in modern times, and for application development, there isn't any good excuse not to have automatic memory management in your application. I know that Objective-C 2.0 or whatever has a garbage collector, but it seems half-ass. And it doesn't work on the iphone apparently; so that screws most the Objective-C market.
I really like the idea of Macruby; the HotCocoa screencasts are very impressive. I'd absolutely love to be able to do Cocoa development without having to resort to Xcode and the interface builder. However, it is not clear how stable or production-ready MacRuby is. Their only at version 0.4 -- not that version numbers mean anything -- but I don't have any confidence that Apple is actually committed to the MacRuby project. I mean... where's their epic plan for future development on the Mac. Is MacRuby it? Is that all they've got? That's good enough I suppose, but it seems like their just diddling around with it: they haven't moved forward from Objective-C ever. No innovation, no development, except within the context of what's already there. I know they replaced Carbon or whatever with Cocoa, but I'm talking about building a real managed runtime like you see with .NET or the JVM. Something that can host multiple languages and provide the kinds of things developers have come to expect from modern platforms: the most important being (and I hate to harp on this, but it's true) -- memory management! There's no greater productivity booster for application development than not having to track down memory leaks all the time. And, like I said, maybe no one complains about that because it's not so much of an issue with Objective-C autorelease pools and strict naming conventions... but I still feel like this is some sort of medievilism on their part. Come on to the future why dontcha?
With respect to garbage collection, MacRuby solves that issue for Mac development. And it presents a nice dynamic (and non-compiled) language to add to the toolset. In the presentation I watched (perhaps I should post the link, but I am lazy), the dude mentioned that MacRuby would be set to become THE scripting language for the Mac platform. That makes sense of course, just because there isn't anything else. All the other scripting languages that run on Mac right now can only interact with Cocoa over a bridge; which sucks a lot. This would be the only instance of a scripting language running natively on the objective c runtime, with all the performance and easy accessiblity that entails.
Anyway... time to go. Bye.

Sunday, May 31, 2009

Windows Development

Until last week, I'd never done any Windows development. That's mostly because I think Microsoft is a little gross; and I don't like Windows. But it's also because I've mostly been doing Java or JVM related development, and so I haven't needed to specifically target anything Windowsy. Last week though, I got an assignment that involved coding a Windows service, and accessing a C API on Windows, so I had to learn.
It hasn't been as terrible as I thought it might be; though some parts have been terrible. One thing I hate is that, if you're going to be doing Windows development, you're almost obligated to use Visual Studio; especially if you're doing anything besides Java development. For me, cause I had to interact with some C, I needed access to the Microsoft compiler, and so I had to use Visual Studio. Plus I was exploring .NET, and I think Visual Studio is like the only .NET IDE. I would just as soon use emacs for everything, but then I'd have to use the command line c compiler, which wasn't written for humans. I don't mean GCC, I mean the microsoft c ompiler -- which was never meant to be used from the command line, and is completely unintuitive and alien (from my perspective, having tried to use it.)
On the plus side, installing Python, Perl, and Ruby (the most important scripting languages I can think of) was painless. They all come with msi installers that make everything a breeze. I imagine compiling them from source, which is easy to do on Linux, would be much more painful on Windows -- but, as they say, when in Rome, do as the Romans do, and therefore: when on Windows, do as Windows does -- meaning: use the fricken msi installer.
Because I cannot live without multiple desktops anymore -- osx and linux having addicted me to them -- I cannot live without an Ubuntu VM on my Windows partition. Since Windows doesn't offer multiple desktops, at least not on Windows XP, I've ended up using my Ubuntu VM for a lot of my development work, and just using Windows to compile and deploy stuff. I hop into the vm to do my work, I hop out to run the tests. Also, what irks me about XP (and I don't know if this will be an issue with Windows 7), is that you cannot create custom keybindings without making esoteric changes to the Registry. The evil and mysterious registry, that strikes terror into the mind of every sane developer, or even every sane IT person. In Ubuntu, or any Linux distro, it's as simple as editing xmodmap, or whatever the equivalent keybindings config file. But in Windows, nooooo. Not that simple. You have to do some black magic and possibly corrupt your whole machine. Vomit.
I think .NET is cool. The only thing I wish is that it wasn't tied to Windows. I know there's Mono, but Mono's implementation is kind-of sketchy. If Microsoft wasn't so self-possessed (and perhaps didn't own so much of the desktop market share) they'd make a proper port to Linux and to OSX, like Sun does for Java; though the Apple guys have taken the OSX Java port into the own hands recently and screwed everything up. Anyway, it'd be nice if I could use .NET, and especially nice if I could use .NET languages, just not on Windows. I'd like to program F# from the comfort of my own Ubuntu, in emacs, with a nice Linux runtime. Unfortunately, the dark gods of Microsoft software imperialism say no.
In conclusion, Windows development hasn't been the awful experience I thought it might be. It's been new and interesting. I've even experimented with the satanic Visual Basic .NET -- though just enough to learn the wretched syntax so I could follow examples. And for the record, I think C# has way too much syntactic sugar for its own good. It makes me lightheaded just looking at it. Finally, ctypes for Python is totally awesome. And that's all I have to say about that.

Wednesday, May 13, 2009

Clojurey

Clojure went 1.0! w00t. And in the meantime, my blog languishes for lack of attention. What kind of blogger am I? to Leave it lying here for so long. Soaking in its own silly juices.But I'm back, for a moment. I must consolidate my web presence; fortify it; make it strong again. But it was never strong to start; yet it will be again! Imagine if James Joyce wrote a blog -- it wouldn't make any sense at all. It shocks me, no... flabergasts me, that one can get anything done in Clojure, cause afterall, it is a "functional" language; and aren't functional languages all universally useless? Don't functional languages just burn up cpu? It must be as the Great Maestro Hickey states: that Clojure is the most friendly face ever put to a functional language. Clojure is easier than Haskell because it doesn't have Monads. There was a guy... Ted Neward (I think) who said that the only way a functional language can ever take off outside academia is if it doesn't have monads. F# doesn't have monads, and look how well it is doing. And neither does Clojure, so it's sure to be a success. Instead of Monads, Clojure has mutable reference types; in that sense, it deviates from being a pure functional language. However, the semantics for mutating said reference types are strictly defined by the language -- it's not anarchy, not like Java. Clojure is much safer. The only way you can get yourself into trouble is my calling out to Java; if only Clojure had an effects system: then I would label all my Java code impure and be done with it. That'd be tricky though, being that Clojure is dynamic and everything. I've written several thousand lines of Clojure in the past few months, and its so dynamic: it could change any minute. In fact, as anyone who has ever worked with me will tell you, it does change every minute. and every half a minute. and not just little bits change. no, the whole thing changes. constant mutation! Most of it I've written over and over again in sundry different ways, since it took me a while to figure out what I was doing. But it's always that way with strange new languages. Some people are lulled into thinking that one programming language is much like another -- but it isn't so. C and Java and C++ and all those other gross static imperative languages may all seem pretty much the same, but beyond their provincial pale is a whole galaxy of strange and unnatural languigy artifice. I recall that Shakespeare line about living in a nutshell and thinking yourself king of infinite space. That's how people get. I'm probably that way. Clojure isn't nearly as hardcore as Haskell; I know, I've tried to write Haskell: and I've failed. You'll fail too! and if you don't fail... well.... then shame on you for being so smart. Remember, it wasn't me, it was Ted Neward who said: No Monads!

Saturday, February 7, 2009

Language Libraries

Libraries are a part of language's expressiveness. A language can be compressible and foldable, but if it doesn't have the right libraries, you'll write more code than you have to. Therefore, when you select a language for a project, emphasize libraries.

I don't think Python is a particularly expressive language. It has crappy broken lambdas, no syntax for arbitrary anonymous functions, no currying, no encapsulation, no overloading, no macros, and no regular expression syntax and lame string interpolation. As a scripting language I think Ruby is a whole lot better, and as an application language I think Scala trumps them both. But I'm using Python right because it has the libraries I need. Library beats language feature.
For large do-it-yourself projects it's the opposite: language beats library, because if you're going to be writing your own libraries, you don't want to pay a large language tax while you're doing it. Steve Yegge has talked about the enormous 1/2 Million line game he wrote, and he wishes he'd chosen a more expressive language than Java -- code size becomes a maintenance hazard; the less code you have the happier you'll be, and that is the foremost reason for picking an expressive language in large projects such as his: to avoid paying the language tax and to avoid producing a monstrously large code-base. Languages that support lots of higher order features like Scala or Ruby let you compress your code and factor out syntactic patterns (like for-each) which are intractable in languages with out higher order functions. In such languages, the control structures that come with the language are all that you're going to get, whereas in Scala or Ruby there's syntax for writing your own 'foreach', or you own 'do_times', or your own 'synchronized' etcetera.
Most of the projects I've worked on have not been more than a few thousand lines, ever; and that is because I've made extensive use of libraries and avoided writing thing myself. On that basis I will choose an anemic language like Python or (god forbid) Java if that's what it takes to get things done. Thankfully, I rarely have to choose Java anymore because there are so many other better languages on the JVM which can seamlessly interop with old Java code; but as in the case of Python, I still have to occasionally make the hard choice between a richer platform, or a richer language. And I choose a richer platform almost all of time: with the one exception of (as I said) large do-it-yourself projects for which you do not want to have to pay the language tax.

Friday, January 9, 2009

Streams

So, to lead into this: Scala, despite being a quasi-functional language, doesn't have much laziness support. There is a lazy keyword, and you can have lazy arguments, but by default everything is eager including 99% of the collection functions. Why is this a problem? Because I've changed my mind and decided that instead of returning the first answer to my question, I want all possible answers; except I don't want to pay the price of computing all possible answers until I actually need them, ergo I want a lazy collection. But in order to get my lazy collection, I have to convert my entire API over to Streams, which is the one token lazy sequence in the entire Scala standard library. And it's a hassle!
Clojure, on the other hand, has almost everything set to lazy. Many was the time that I thought: "Hmmm... this would be so much more convenient if I were using Clojure." For whatever reason, I did not listen to myself.
But it's not too late. Perhaps I will make a hybrid project of Scala and Clojure. I'm not sure how difficult that would be, or even if it is possible at all. Maybe it'll be too ugly. Alternatively I could just convert entirely over to Clojure... but that seems like wasted effort; I don't want to keep reimplementing projects in different languages -- throws away too much work. Lastly I could just bite the bullet and use Scala's damn nasty Stream crap, and live with a duplicated API for streams and not-streams.
Something to ponder.

Wednesday, January 7, 2009

Constraints ReReVisited

My wonderful and glorious, and long_windedly_titled Finite-Domain-Constraint-Satisfaction-Library, now solves Sudoku and sundry other Finite-Domain-Constraint-Satisfaction-Problems. Special thanks to Peter Norvig and the wonderful "AI: A Modern Approach" book. Also special thanks to the Cream constraint library (which was the original inspiration) and the Oz/Mozart language/library.
For those of you who haven't been following the progress of my library, it's written in Scala, and clocks in at just over 2000 loc; thats 1000 of library code plus 1000 lines of testing code -- which was essential because I refactored this thing so many times... if I hadn't had the tests I would have never gotten it working.
The future of the library is bright. There are more things to add and some improvements to make; however, its core parts seem to be feature complete. It uses the AC-3 algorithm to do the constraint propagation, and a simple backtracking search to solve the problems (if constraint propagation by itself doesn't do the trick). It maintains arc-consistency as it searches, and the next-variable-picker-algorithm, the constraint-propogation-algorithm, and the search-algorithm are all swappable. I'll be implementing more algorithms as time goes on, so the user may select the best strategy for solving their particular problem. Right now next-variables are selected using the Most-Restricted-Variable strategy, but for completeness I definitely need to add more options.
Oh, and special thanks to the Eular Project, which got me off on this constraints tangent in the first place.

Tuesday, December 30, 2008

Constraints Revisited

In search problems, you often have a great many potential solutions in your space that never need visiting. Many of these solutions are obviously contradictory, and can be discarded early. By applying constraints and enforcing consistency of constraints on your solution space, you can prune off contradictory solutions before starting your search. Thus, can many problems with exponentially large numbers of potential solutions be reduced to much smaller, much more tractable problems of fewer solutions.
There. I said it.

Update: My constraint library is going well. I think it is approaching actual usefulness. Yesterday I fixed my domains so that they can contain arbitrary disjoint ranges of values; like unions of a bunch of different intervals. Today I'm implementing iterative depth first search, and the corresponding tests, as well as a couple new constraints like allDiff and notEq. Using operator overloading in Scala, constraint problems look like this:

val a = problem.newVar
val b = problem.newVar
a + b := 20
a - b := 10
problem.solve

and then you inspect the resulting values of 'a' and 'b' to find out what the solution is. Right now, since I don't have the search implemented and can only propagate constraints upto arc-consistency, problems like the above don't return a definite answer, just a range. But other problems that aren't so tricky do generate definite answers, and in any case, the current implementation correctly narrows the potential solutions for 'a' to "10 < x < 20" and for 'b' to "0 < x < 10". Since the naive alternative is an infinity of integers, you can undoubtedly see the utility.

Other Interesting Things:
I used TDD to begin the project, and I'm pleasantly surprised. It seems almost the natural way of doing it: stubbing out your project with client code (in test form) gets the ball rolling and the mental wheels turning. If you don't know where to start, pretend you already finished and write some tests to make certain you did a good job. They fail, you fix. No more staring at a blank page.
And unit tests are life! I think I would die if I had to do a project without them. I'm starting to find that the more unit tests I add, the better I feel. It's like a drug. Write the test, fix the bug, refactor rinse repeat. Soon I'll be one of those guys who has to have 100 percent code coverage. Nathan Hungry. Nathan Want Code Coverage.