So, to begin with, day 2 of Prolog is still looking like very much the same logic engine rather than something that feels like a full programming language to me. We kick off with recursive rules for working out the ancestry of members of the Waltons. The recursion gives a nice flow to the whole process of defining such a rule, and it is a concept that I'm very used to from my day-to-day coding. Infact, I'm ashamed to say that when I attended J.P. Boodhoo's Nothin' But .Net course and was tasked with writing an app in our own time that could list the contents of a directory tree without using recursion it took me a looooong time to figure out how to do it, because recursion is such a nice and natural fit.
Next up is a demonstration of lists and tuples. The list is obviously a key data structure in my daily .Net (ahhh, List<T> how I love thee) and tuples get mentioned time to time in the more cutting edge sections of the blog-o-sphere, and I recall the term from my comp sci degree, but they're not something that I've had much use for. This was different to the usual examples in the book as rather than write a small app with some pop-culture theme, it was just bashing values into prolog to see what happens when you tell it (1, B, 3)=(A, 2, C). or [4, 5, 6] = [4, [Head | Tail]].
Then we were back to the more traditional programming of write a file and then use it. In this case it was using recursion to write routines to count the number of elements in a list, sum the elements in a list, and using those 2, work out the average value in a list. This is definitely different to the normal ways of coding, but it does feel a bit convoluted, especially in these post-Linq days where any old enumerable collection of data lets you get a count from an extension method, or even pre-Linq where a typical collection class would have a count that it could tell you easily.
The last lesson of this section takes a look at the Prolog method "append" and then walks through writing it from scratch. This ends up as merely a 2 line function, however it does get a bit mind bending with its use of recursion. My initial reaction is that I understand it, but I don't want to have to write it myself. The thing is, the next part of the chapter will get into more exercises, so I may have to...
And I was right to be suspicious. The first of the exercises was to write a function to reverse the elements in a list which leads to a very similar function. I actually managed to get to the right answer pretty quickly, but as a Prolog amateur I failed to put square brackets around a variable that needed them and the code didn't work. There was nothing obvious pointing to why it failed, so fixing it revolved around trial, error, and headbutting the desk. The first sample here doesn't work, the next one does. Simples.
rev([],[]).
rev([Head|Tail], Revd) :- rev(Tail, Revd2), append(Revd2, Head, Revd).
rev([],[]).
rev([Head|Tail], Revd) :- rev(Tail, Revd2), append(Revd2, [Head], Revd).
The next exercise asked us to find the smallest element in a list. I couldn't think of a way to do this without employing a conditional statement, which doesn't really seem very much like idiomatic prolog from what we've been shown so far, but a quick google lead me to a helpful post on stack overflow with this snippet "( condition -> then_clause ; else_clause )" after which it all fell into place. The last exercise was to sort a list. I stared at this for a while, started thinking of ideas that might work but would quickly get convoluted and huge, and rapidly lost enthusiasm. I decided to have a quick google and saw that other people were finding this one a blocker too, and that solutions they'd eventually come up with, or simply copied from elsewhere on the net were as nasty as I'd expected, either longwinded or mindbending, so I decided to cease my pursuit of that final goal there.
This chapter was a pretty heavy load of info, so again it didn't have the same fun vibe of some of the earlier writing, but it did flow well and didn't ram the americanisms down my throat that the previous chapter did, so it is approaching a return to form. Hurrah.
As an aside, whilst I'm doing this all on my mac lappy with the terminal, I'm getting to play around with Vim. It always takes me typing a word or two into a new document before I remember that the stupid thing has different modes for navigation and text entry. Bah. But once I've been reminded by the distinct lack of text appearing, or the end of a word after a vowel suddenly flitting onto the screen, I do like it :) I've tried using ViEmu in Visual Studio, but found that you need to use the escape key way too much in Studio so it clashed with the Vi functionality. So getting to use it a bit here is fun :)
No comments:
Post a Comment