Standard ML: Pattern Matching And Datatypes

SML is another functional language, but its syntax is a lot more familiar than Racket’s to the average newbie programmer. Values are assigned using the “=” sign, addition works the way you’d expect it to –

(i + 1)

not

(+ i 1)

– and there is a comforting similarity to English/mathematical phrasing (“let val x = 2 in x + 3 end”). That said, I found the syntax and semantics of Standard ML far harder to pick up than I did Racket’s.

We learned using Emacs and a Read-Eval-Print-Loop. So; I can now fumble my way through a REPL, create and delete files, switch buffers, copy and paste in Emacs with some small amount of speed. I suppose that’s another little life skill which might come in handy at some point.

To look at what I learned from Standard ML, I chose to use datatypes and pattern matching. These stood out most strongly on the course as essential parts of the SML language’s ‘feel’.

As ever, I’m just showing this code because it puts pressure on me to keep improving, not as a demonstration of what you should do. If you’re just getting interested in SML, don’t use my code as an example!

datatype Count = Num of int
		  | Fizz
		  | Buzz
		  | FizzBuzz
		  | NoCount

This is how we start off, defining a datatype “Count”.

We need to define “Count” because we’re going to be returning a list from our FizzBuzz function, and in SML every list element must be the same. We could have tried turning everything into one long string, or a list of lots of short strings, but that would create problems later.

All this means is that something called “Num 1″, “Num 2″, “Fizz”, “Num 4″, “Buzz” … and “Fizzbuzz” are all of the same type of thing, counts, just like the numbers 1 2 3 4 5…15 are all ints.

In theory in Standard ML you could have a “One True Datatype” which encompassed absolutely everything. It’s at that point that it’s really unlikely that SML was ever the language you should have been using in the first place.

fun fizzbuzz (x:int,y:int) =
    let fun fb(x,acc) =
	    if x<=0
	    then acc
	    else
		if x mod 15 = 0
		then fb(x-1,FizzBuzz::acc)
		else
		    if x mod 3 = 0
		    then fb(x-1,Fizz::acc)
		    else
			if x mod 5 = 0
			then fb(x-1,Buzz::acc)
			else fb(x-1,Num (x+y)::acc)
    in fb(x,[])
    end

This is the fizzbuzz-making function.

It takes two ints, an int for length (x) and an int to determine our starting point (y, where “0″ will start us off at “1″), and then creates a sequence from FizzBuzz in accordance with those two ints.

“::” in SML is the same as “cons” in the Lisp family, and “[]” is effectively the same as “null” or “empty”. Confusingly, “null” in SML is a boolean operator equivalent to “null?” in Racket.

The logic of it’s pretty simple. We create a temporary tail-recursive function with an accumulator, and kick it off (without using “y” as an argument — “y” is going to remain constant throughout the process so that’d be pointless).

If we hit one of our targets (multiple of 3, multiple of 5, multiple of 15), we cons a “Count” datatype of the appropriate sort to our accumulator. If we don’t, we simply cons a “Count” datatype of “Num i” to our accumulator list, with i equal to x + y.

Once x has counted down to 0, we return the accumulator list, nicely sorted from lowest to highest:

fizzbuzz(20,4);
val it =
  [Num 5,Num 6,Fizz,Num 8,Buzz,Fizz,Num 11,Num 12,Fizz,Buzz,Num 15,Fizz,...]
  : Count list

Simple.

Now before we translate it back using nested pattern matching, we quickly create some exceptions.

exception NoListEntered
exception ImpossibleListEntered

Well, that was thrilling.

On to the function I wrote:

The arguments this time are a list of Counts “xs”, and a starting point “y” (which should match the starting point of Counts, or you will probably get an error – there are ways of improving this function).

It was at this point that I realised that the function was pretty damn stupid in this form, as we could get the same results with a function which simply, well, counted for the length of a list from a given starting point. Creating a “proper” reverse fizzbuzz would be more complicated than this.

I decided to go ahead with the function in this form for the reason that these posts are not supposed to be solving problems — they’re demonstrations that I understand certain concepts in a language.

In that respect, this function does what I want it to. It type-checks, it returns the correct result, it uses pattern-matching and it uses datatypes. It really doesn’t have to do those things, and it’s possibly the most silly way of solving this “problem”, but it does anyway.

dealwithit.jpeg

fun reverseFizzbuzz (xs:Count list, y:int) =
    let fun fb(xs, acc, lastNum, lastCount) =
	    if null xs
            then
		case lastCount of
		    NoCount => raise NoListEntered
		  | _ => rev acc
	    else
		let val x = hd xs
		in
		    case x of
			Num i    => fb(tl xs, i::acc, i, Num i)
		     | Fizz      =>
		       (case lastCount of
			    Num i => fb(tl xs, (i + 1)::acc, i, Fizz)
			  | Buzz => fb(tl xs, (lastNum + 2)::acc, lastNum, Fizz)
			  | NoCount =>
			    if y mod 3 = 0
			    then fb(tl xs, y::acc, y, Fizz)
			    else raise ImpossibleListEntered
			  | _     => raise ImpossibleListEntered
		       )
		     (*end of Fizz case*)
		     | Buzz      =>
		       (case lastCount of
			    Num i => fb(tl xs, (i + 1)::acc, i, Buzz)
			  | Fizz => fb(tl xs, (lastNum + 2)::acc, lastNum, Buzz)
			  | NoCount =>
			    if y mod 5 = 0
			    then fb(tl xs, y::acc, y, Buzz)
			    else raise ImpossibleListEntered
			  | _     => raise ImpossibleListEntered
		       )
		     (*end of Buzz case*)
		     | FizzBuzz  => 
		       (case lastCount of
			    Num i   => fb(tl xs, (i + 1)::acc, i, Buzz)
			  | NoCount =>
			    if y mod 15 = 0
			    then fb(tl xs, y::acc, y, FizzBuzz)
			    else raise ImpossibleListEntered
			  | _       => raise ImpossibleListEntered
		       )
		(*end of FizzBuzz case*)
		     | _ => raise ImpossibleListEntered
		end
    in fb(xs, [], y, NoCount)
    end

All pattern matching does is check what type we’re dealing with (for instance “What was passed to the function “fb” as the argument “lastCount”?”) and then act on that information. This is why we introduced “NoCount” as a datatype up top, so we can introduce a NONE value without breaking type rules.

Pattern matching would be a great way to deal with the real reverse fizzbuzz function, but I’ll get to that another day.

Welp, there’s SML. I know what pattern-matching is, and can implement it in a (very) silly fashion, and I know how to use datatypes. Also, as long as this post remains up, it’ll push me to do better — seriously, it’s like a dull ache in the back of my mind.

I’m going to find a way of showing something about Ruby next — and then I’ll be done with these for a little while, focussing on building a small frontend-only site for my girlfriend.

Hopefully I won’t come back to SML for some time yet

Tagged , , , , ,

Racket: FizzBuzz, Thunks And Streams

It’s all very well talking about what I’ve learned, but keeping up with it and providing proof is another issue entirely.

So, I’m going to provide variations on what I’ve done with FizzBuzz, a simple programming test to see if you understand the basics of a language – to see if you can be taught the rest from there, really.

The Rules Of FizzBuzz:
1. You start counting.
2. If a number is a multiple of 3, it must be replaced by the word "Fizz".
3. If a number is a multiple of 5, it must be replaced by the word "Buzz".
4. If a number is a multiple of both, it must be replaced by the word "FizzBuzz".

Like I said, simple.

I’m hoping to write up quick but unique implementations in Racket, Ruby, and SML that highlight a little of what I’ve learned from each language.

I’m starting with Racket, a programming language developed from Scheme, which in turn developed from Lisp. All together you’ve got a bit of a mafia movie going.

Racket was by far my favourite language studied on the course, which is probably why I’m starting with it. It’s often seen as a teaching language, but you can definitely do some pretty practical stuff with some easily-available libraries – I’ve been playing around with its JSON abilities during my lunch breaks at work, and it seems very natural (especially as I’ve not done any work with web APIs before).

The basic syntax is:

(define a-symbol a-thing)

This develops pretty quickly and naturally into recursive functions:

(define (multiply-recurse-silly x y)
  (letrec ([f (lambda (y acc)
            (if (<= y 0)
             acc
            (f (- y 1) (+ x acc))))])
    (f y 0)))

This is a silly and impractical use for recursion, using repeated addition to multiply two numbers together. To explain what’s going on here, if you don’t speak Racket:

The main function is defined as “multiply-recurse-silly” and given two arguments “x” and “y”.

We need a recursive function, so we “let” a new symbol, “f” be a new, local function. This function won’t need to change “x”, but it will need to count the number of times it’s added “x” to itself (the multiplication), and we’ll give it an accumulator called “acc” to help it keep track of what “x” is so far.

Once “y” has hit 0 (or below, through some error or inappropriate input), the function returns what the accumulator has saved up.

Otherwise, the function calls itself with the value of “y” – 1 (so “y” is like a countdown timer going towards zero) and “x” added to itself.

Finally, none of this will work unless we call our new “f” function in the first place, so we call it with the last line and then close all the brackets up.

Not too complicated. There’s some things I don’t like about this function looking back on it though:

1.
It’s bad that it isn’t an error for y to be less than 0. This is clearly a function to multiply only positive numbers together, so returning “0″ when we try to multiply by a negative number is a big mistake.

What I should have done is either (a) added a new conditional branch so that if y is less than 0 the multiplication works (and works properly) for negative numbers or (b) added a new conditional branch so that if y is less than 0 we raise an error.

2.
For this function we don’t really need a local recursive function. I wanted practice using local functions because I haven’t been using them while designing my game in Java, but this was completely unnecessary. The entire function could have fit on one line, if I’d simply written it to call itself.

Moving quickly on from that:

(define (fizz-buzz start finish)
  (letrec ([f (lambda (strt acc)
                (cond [(> strt finish) (reverse acc)]
                      [(and (= (modulo strt 3) 0) (= (modulo strt 5) 0)
                       (f (+ strt 1) (cons "FizzBuzz" acc)))]
                      [(= (modulo strt 3) 0) (f (+ strt 1) (cons "Fizz" acc))]
                      [(= (modulo strt 5) 0) (f (+ strt 1) (cons "Buzz" acc))]
                      [(integer? strt) (f (+ strt 1) (cons strt acc))]
                      [#t (f 1 acc)]))])
    (f start null)))

My first FizzBuzz function in Racket. It seems to work OK.

Just a simple recursive function, only this time I am using cond, which in practice works like a switch statement, instead of if. “cons”, not to be confused (ha) with “cond”, simply means that we are adding something to a list. At the very end, we see a “#t” condition – this means that for any value other than “#f”, if the conditions before it haven’t executed, the condition at the end will execute. This is because Racket interprets any value other than false (#f) as true (#t).

This means that if an incorrect value is passed by the user as the start value we assume they just meant “start from the bottom!” and go from there.

Again, this is probably not something I would include in a program meant to be used seriously.

Because of the way we are joining the list together, we need to reverse it at the end to make sure it comes out the right way round for human eyes.

This function is able to count from a start number to a finish number, and gives back a Racket list depending on those numbers, in accordance with the FizzBuzz rules.

So:

(fizz-buzz 1 15)

Gives:

'(1 2 "Fizz" 4 "Buzz" "Fizz" 7 8 "Fizz" "Buzz" 11 "Fizz" 13 14 "FizzBuzz")

All working as expected.

Of course, if we put the inputs in the wrong way round, it gives us:

'()

A null or empty list.

Going with the bodge-job aesthetic I’ve employed so far, I decided I wanted it to be able to handle both ways. Simple but unsatisfying to implement:

(define (fizz-buzz-up-or-down x y)
  (letrec ([f (lambda (countdown goal acc)
                (cond [((< countdown goal) acc]
                      [(and (= (modulo countdown 3) 0) (= (modulo countdown 5) 0)
                       (f (- countdown 1) goal (cons "FizzBuzz" acc)))]
                      [(= (modulo countdown 3) 0) (f (- countdown 1) goal (cons "Fizz" acc))]
                      [(= (modulo countdown 5) 0) (f (- countdown 1) goal (cons "Buzz" acc))]
                      [(integer? countdown) (f (- countdown 1) goal (cons countdown acc))]
                      [#t (raise "Inappropriate input!")]))])
    (if (> x y)
        (f x y null)
        (f y x null))))

Giving us:

(fizz-buzz 15 1)
'(1 2 "Fizz" 4 "Buzz" "Fizz" 7 8 "Fizz" "Buzz" 11 "Fizz" 13 14 "FizzBuzz")

Just to confuse everything, this time I’ve changed the function so that the accumulator doesn’t need to be reversed, and the new way of doing things means that I have to raise an error if there’s an inappropriate input – I can’t just guess what the countdown would start at.

On the other hand, with the new up-or-down-ness this function will raise an error for an inappropriate input before I even get to that stage, rendering the error-raising and checking to see if the number’s an integer entirely moot, but it’s nice to be prepared (maybe).

The last thing I did in this file was create the ability to input custom fizzes and buzzes into the function:

(define (fizz-buzz-plus pairs x y)
  (letrec ([f (lambda (xs countdown goal acc)
                (cond [(< countdown goal) acc]
                      [(letrec ([g (lambda (ys ac)
                                     (cond [(null? ys)
                                            (if (null? ac)
                                                (f pairs (- countdown 1) goal (cons countdown acc))
                                                (f pairs (- countdown 1) goal (cons (reverse ac) acc)))]
                                           [(= (modulo countdown (cdar ys)) 0) (g (cdr ys) (cons (caar ys) ac))]
                                           [#t (g (cdr ys) ac)]))])
                         (g xs null))]))])
    (if (> x y)
        (f pairs x y null)
        (f pairs y x null))))

We’ve got an inner loop and an outer loop here.

(fizz-buzz-plus (list (cons "Snark" 7) (cons "Flunge" 4) (cons "Grontch" 9)) 1 25)

This time we pass in a list of pairs and get back:

'(1 2 3 ("Flunge") 5 6 ("Snark") ("Flunge") ("Grontch") 10
11 ("Flunge") 13 ("Snark") 15 ("Flunge") 17 ("Grontch") 19 ("Flunge")
("Snark") 22 23 ("Flunge") 25)

More-or-less what we expected.

(fizz-buzz-plus (list (cons "Snark" 3) (cons "Flunge" 6) (cons "Grontch" 9)) 1 25)
'(1  2  ("Snark")
  4  5  ("Snark" "Flunge")
  7  8  ("Snark" "Grontch")
  10  11  ("Snark" "Flunge")
  13  14  ("Snark")
  16  17  ("Snark" "Flunge" "Grontch")
  19  20  ("Snark")  22  23  ("Snark" "Flunge") 25)

I can’t remember why I chose to cons them together rather than string-append them. That’s this line:

[(= (modulo countdown (cdar ys)) 0) (g (cdr ys) (cons (caar ys) ac))]

It worked for my purposes. I suppose it makes it easier to parse the list as well, when we’re looking back over it.

Yeah, that was probably my reasoning. Let’s go with that.

Now to what I really learned: thunks and streams.

A “Thunk” is a function without arguments which we create only so that we can delay it ever being called, hopefully forever. Thunks are therefore prone to existentialist angst, but they are very useful in many ways.

I remember what they do by thinking of them as an onomatopoeia for a program slamming up against one (THUNK) or alternatively as a “then-function” – a function to do later. Then-func – Th-unc – Thunk. It’s a stretch but it helped me remember it.

Probably the most useful place for a Thunk (at least, at my current level of programming knowledge) is a Stream. A Stream is a Thunked pair, of which pair the latter part is a call to the Stream usually but not always with a different argument. This enables us to create infinite patterns, which we can read at a later date. Naturally this is very useful, and naturally I will only use it to mess around (for now at least).

Here is a simple stream I wrote while on the course. It shows alternately dan.jpg then dog.jpg, but only when called:

(define dan-then-dog (lambda () (cons "dan.jpg" (lambda () (cons "dog.jpg" dan-then-dog)))))

And here is how we read any given stream for a certain number of steps (starting from step 1):

(define (stream-for-n-steps s n)
   (if (<= n 0)
       null
       (cons (car (s)) (stream-for-n-steps (cdr (s)) (- n 1)))))

So, this is how we adapt our simple FizzBuzz function from earlier (I changed modulo to remainder, but it’s otherwise a very similar idea):

(define fizz-buzz-stream
  (letrec ([f (lambda(x)
                (cons
                 (if (and (= (remainder x 3) 0) (= (remainder x 5) 0))
                     "FizzBuzz"
                     (if (= (remainder x 3) 0)
                         "Fizz"
                         (if (= (remainder x 5) 0)
                             "Buzz"
                             x)))
                 (lambda () (f (+ x 1)))))])
                (lambda () (f 1))))

Finally, as an extension of the fizz-buzz-plus function defined earlier, here is a stream for prime numbers.

(define prime-numbers-stream
  (letrec ([f (lambda(x xs ys)
                (if (< x 3)
                    (cons x
                          (lambda () (f (+ x 1) ys ys)))
                    (if (null? xs)
                        (cons x
                              (lambda () (f (+ x 1) (cons x ys) (cons x ys))))
                        (if (= (remainder x (car xs)) 0)
                            (f (+ x 1) ys ys)
                            (f x (cdr xs) ys)))))])
    (lambda () (f 1 (list 2) (list 2)))))

This is really what FizzBuzz is all about. Once you’ve assigned enough multipliers to miscellaneous noises, you end up with only the prime numbers left. If you played FizzBuzz in Primary school, like me, you might have just realised it was a sneaky way of teaching you to think about the patterns involved in multiplication.

Someone once said that prime numbers are what’s left when all the patterns are taken away. I prefer to think of them as the seeds of their own patterns. Each prime fulfils its own unique function, creating a pattern that tessellates perfectly with every other prime, stretching out into infinity.

My method of reading this infinite stream is a lot less elegant and looks like this:

(define (read-prime-stream x)
  (begin (if (equal? x "quit")
             (display "Prime Number Generator Exited.")
             (display (stream-for-n-steps prime-numbers-stream x)))
         (display "\r")
         (if (equal? x "quit")
             (display "\r")
             (read-prime-stream (read)))))

(display "Type \"quit\" (including quotes) to exit. \r")
(read-prime-stream (read))

I learned a lot by writing all of this, though, and it’s really helped solidify some of the concepts of the course in my mind.

Did I get anything wrong? Was I inaccurate somewhere? Should I have expanded on something? Let me know in the comments.

Tagged , , ,

A First Experience With Open Courses

I’ve finally finished what was, for me, a fairly gruelling ten week slog.

Using Coursera, a platform offering free University-level courses to anyone who’s interested, I tried Introduction To Programming Languages as a first course. I met the requirements (just, sort of, not really), and figured “eh, it’s an introduction. How hard could it be?”

Very hard.

I made the mistake of thinking that this was going to be an introduction to the three programming languages on the course. It was actually an introduction to programming languages in general, and concepts in programming language design. I found even the first homework difficult, and struggled through much of the course. It was frustrating, and ate up almost all my free time for the entire ten weeks the course ran (and although I’ve completed the final exam, I still need to complete some peer assessments).

The lesson from this is that open courses are not an easy option, and it is probably not something that most people will be able to do in their spare time without major sacrifices. The courses can be extremely challenging at an extremely high level. It’s not simple stuff. For me, this difficulty was exactly what rendered the courses such a rewarding experience, and really re-affirmed my assumption that what I was learning was really worthwhile rather than just coding busy-work.

On that note, the lectures were top quality. Concepts were taught in a way that seemed very natural, code provided to explain ideas was very clear and useful, and the entire staff (from University of Washington) were extremely dedicated. My thanks to them. Moreover, the concepts built and fed into each other in a very subtle, unassuming way that made ideas that would have frazzled my brain at the start of the course fairly clear by the end. Professor Dan Grossman regularly interacted with and helped students in the forums, and following on from that, the community was incredible. The interaction between people who’d been programming in C for 16+ years, Haskell evangelists and complete novices (like me) was invariably friendly and invariably helpful. It was a great experience.

Just thinking about how much I learned on this course staggers me a little now. Before the course, I had no idea what thunks, streams, or mixins even were, and (as it turns out) I only had a shaky grasp of interfaces, subclassing, and data structures. It would take me twenty minutes to work out what a simple recursive function did, and twenty more to implement my own. I’m now fairly comfortable with functional programming (more comfortable than I am with OOP, in fact), I can edit SML and Ruby with confidence, and I can write programs in Racket. My understanding of Java and its seemingly arbitrary rules and regulations has improved no end, although the syntax looks a lot uglier and more verbose than it used to (and it always looked quite verbose).

In the end I think I got a grade of around 80 (scores aren’t finalised until peer assessments finish), and I would be upset with anything below 70 given the huge amount of effort I put into this course. That’s another thing about these courses – theoretically, the grade doesn’t matter, but once you’ve invested some time into them it becomes just as important as if you’d paid for the course.

I’d recommend this course to absolutely anyone interested in programming should it come up again, and I personally enjoyed my experience with Coursera immensely. I should probably note that there were a few bugs in the autograder, but that these were always found extremely quickly and dealt with almost instantly.

Thanks, Dan. Thdanks.

Tagged , , , ,

Game Update: ThuggRPG

Working title is ThuggRPG. I’ve finally got a level of sorts up and running. It doesn’t look like much but I have big plans for this.

ThuggRPG

Now it’s just a matter of literally everything.

Went for the Alcest, stayed for the Katatonia.

Tagged , ,

Things I Am Doing

I sometimes go quiet for fairly long stretches. Sorry about that.

If you’re interested, these are the kinds of things I tend to be doing during these long stretches. Or in this case the kind of thing I am doing right now.

Learning HTML & CSS (& Javascript)

Thanks to Codecademy, this is so easy it’s ridiculous. It eases you into the learning process as gently as a scared newborn piglet attempting to suckle from a hedgehog.

Learning Java

This is harder. The ultimate aim of this is to…

Design And Complete A Vast Non-Linear 2D RPG/Strategy Hybrid

Should take a little while.

Edit The Novel I Wrote During NaNoWriMo

Looking to focus on this during this year’s NaNoWriMo.

Getting My Poetry Published In Magazines

I have written some poems I’m happy with, so in a way I feel like I’ve ‘completed poetry’. I feel like I should push myself further here, so I’m going to.

Inventing Puns

Why was the Catholic protestor arrested?

He was being in-a-pope-riot.

Proclaiming That Science Is Badass

It really is, especially at the moment.

Life Stuff

Finding people to take my room, trying to keep up with cool games, working for a living, analysing metal until I take all the fun out of it for myself and others, basically doing enough things that take up enough time that I’ll only rarely be able to update here.

Hopefully when I do it’ll be somewhat entertaining.

…this one doesn’t count.

Some 70s War Comics

I picked these war stories up in a small store that sold a few different kinds of oddities. These booklets were really cheap so I bought a very small handful of them.

I found them fairly interesting, both as comic books and as historical artifacts. Though not, actually, historical artifacts from the wars they portray. These are from the mid-’70s, and as such are more pop-culture-historical than propaganda/history-historical.

The stories are sometimes relatively complex in their morals though — relative, that is to say, to the modern action film, where a half-German dude would almost certainly be the villain, rather than a conflicted hero torn between duty and personal crisis.

Here are some of what I consider to be the most fascinating pages of the books.

If anyone’s not happy with me uploading these here for reasons of copyright, I can take them down again. However, I have uploaded these as a useful resource & for commentary, and will not make any money from them being here, so there is a pretty strong Fair Use case.

If you’d like to use the images, I’d appreciate a link back or a credit! I won’t get too upset if you don’t though.

Sergeant Shouts Orders From D-Day Boat As Shells Land

D-Day Landings.

The D-Day landings. Not sure about the face there. Can faces peel half away from the skull and scream at you? If so, why hasn’t there been an album about that yet?

Two Soldiers Flee A Collapsing Pylon | Marines Stand Together With Weapons

Now who needs more pylons.

This is the inside front cover of Hell’s Gates and the title page.

I like that you could just buy 192 pages of pictures of things exploding back then and no-one would look at you askance. Although I suppose Michael Bay Esq. scratches the same itch today.

English Soldiers Shoot A German Soldier

A shiny penny to anyone who can tell me which one is the hero in this image.

I’m not sure whether I’m bothered by the fact they just shoot the German soldier who had refrained from shooting them or not.

I guess not.

More to the point, why did he give them the chance? Why didn’t he shoot the guy with the trusty service revolver as soon as he reached for it? Why was he not even pointing the gun at them at any point despite clearly seeing them and having time to shout at them to stop?

I think these questions will likely remain unanswered.

The Origin Of The Marines

And now, what some guy thinks the marine-navy rivalry started as.

This comic purports to tell the origin of the rivalry between marines and navy. It’s supposed to explain why Cain, the Unfairly Treated Private Who Ends Up A War Hero of this little escapade, is victimised for being called Cain.

I don’t know why I was expecting it to be something to do with Cain from the Bible, but I was. I also assumed some Rime Of The Ancient Mariner would be thrown in there. I think I attended too many English Literature classes to see things properly.

Man Firing Machine Gun

He actually has a fair bit to lose, or we wouldn’t really care about him as readers. His life is the first thing that springs to mind but that might be being facetious.

This comic has the most sophisticated artwork, certainly in terms of cover art, out of all the comics I picked up.

On the inside, too, there was a marked increase in quality over some of the earlier examples. More detail, more realistic facial expressions, motion and emotion captured better.

Unfortunately…

British Soldiers Talk About Japanese Soldiers

“The yellow flood…” – acceptable in January 1942 in Britain, probably. Acceptable in mid-1970s Britain? Really?

I can’t read the actual story without flinching a bit. I understand that it makes sense in context, but the narrative is still one of Allied good, “Japs”, “yellow swarm” bad, and it’s not particularly edifying.

It only gets worse from there, too, I just couldn’t really bring myself to fill my blog with anti-Japanese tirades from the seventies. It’s not really what I want people to find on my personal blog.

The following is from “CUT OFF!”, yet another little booklet.

British squaddie blows up a tank, shouts "Sock-O!"

Sock-O!

As far as I want to know, this was what the entire war was about.

Plucky squaddies blowing shit up and shouting things like “Sock-O!” and “Bally good show!”.

Good clean fun, and everyone’s back in time for tiffin cake at great-aunt Marjorie’s.

German Machine Gun Crew Shot From Behind

Just a machine gunner, crumping.

This was the only book out of the ones I bought that I genuinely enjoyed for reasons other than (a) interest in retro curios and (b) a mind about as complex as a hammer.

With a xenophobic authority figure and a genuinely suspenseful, tight plot, plus a slightly complicated lead character who you could actually empathise with at times, and who dealt with (gasp) emotional issues, this was the only comic that engaged me, and which I would read again.

The others are fascinating examples of cheap comic book art of the time, and I will keep them as long as possible, but the story in Runaway Glory is actually quite well-written. It reminds me of some of the Golden Age superhero comic books in how tightly, simply, and coherently it is plotted.

Now I have written in depth about heavy metal, games, comic books and my favourite search engine. Ahem. I have cool interests too. That involve people. Death matches count as human interaction, right?

I might have used Bolt Thrower before, but damn if it ain’t appropriate here!

Tagged , , , ,

Megaphores

I have been shown a new site, and it is (depending on the time of day and the number of people on board) awesome.

The site is called “Megaphores“, and revolves around creating amusing, ludicrously over-the-top Seanbaby-style similes and metaphors. It’s incredibly addictive and fun, and has the Adult Swim seal of approval.

I can’t vouch for the site as a whole, because the quality is completely dependent on how many people are playing, and how intelligent those people are.

It’s much more fun to think of your own “megaphores”.

I think it has the potential to be amazing, so if you have a talent for words, please give it a go and see how well other people rate your megaphore.

It’s a megadeth for phore.

Thinking About The Dark Knight Rises [SPOILERS]

So, I went to see The Dark Knight Rises, and it was kinda good. But also kinda bad. There were moments, plot points, and entire settings which stretched credulity in a way that the previous two Nolan movies did not.

I’d recommend watching it, because it’s a good movie with excellent action sequences and memorable, interesting characters.

Now I’m going to talk about specifics, so there will be SPOILERS FROM THIS POINT DOWN…

Above : Intermission.

I think part of the reason these new movies have been so successful is the same reason The Dark Knight Rises was kind of bad in places. Christopher Nolan appears to be intent on ‘rescuing’ the Batman franchise.

It could be argued that the Batman franchise didn’t need rescuing. Sure, if you only read the comics and watched the cartoons, that’s true. Most people, though, haven’t done this. I mean, ever.

What people have done is seen the movies, or else picked up what they’re about through pop-cultural osmosis. So their view of the Batman universe contained until very recently a Catwoman who has mystic powers, cheesy Germanic scientists, tight Lycra, holy bat nipples, a series of seemingly-irrelevant baddies with bizarre powers and lame puns, and Adam West.

It’s this that I think Nolan was trying to save the series from.

So this is why we get a genuinely creepifying Scarecrow throughout the series, this is why we get no dubious science (well, less than we would expect from a series of comic book adaptations) and no ‘super powers’ in the traditional sense.

This article’s about The Dark Knight Rises though, so let’s get on that quickly.

Firstly, Bane is no longer a dumb thug in the employ of more sinister villains, as he was in Batman and Robin. Seriously, click that link, that video is horrible. He’s back to how he is in the comic books, an intelligent and sophisticated enemy as comfortable leading men as he is beating them mushy.

This was a real sore point with comic book fans, and I think Christopher Nolan did an excellent job in resurrecting Bane as a complex and intimidating villain…up to a point. The final twist, where it is revealed that (seriously, if you skipped all the spoiler warnings to this point you have no-one but yourself to blame) it was Tate, not Bane, who escaped from the pit, that he was cruelly treated by Tate’s father, and he cries a single tear, felt wrong in the context of Bane’s character before that.

Perhaps this is the point. Perhaps the idea is that we see Bane for what he is, just another human being rather than an unstoppable malevolent force, before Catwoman simply blasts the shit out of him with a cannon.

Personally, I think that the events are not close enough to drive this idea home. I feel that Bane is rounded enough as a character at this stage as he needs to be, and that trying to flesh him out further backfired badly in terms of the drama of the film.

Secondly, we have the bomb scene.

Batman running all over town trying to get rid of a huge round bomb in the ocean before time runs out? Remind you of anything?

Batman Bomb

Source: Know Your Meme.

That’s right, the scene frequently cited as a paragon of bat-cheese (ew, sorry) has been utterly redeemed, made awesome even, by Christopher Nolan. I find it hard to believe that it’s not a shout-out — just look how similar the descriptions of them are!

However, it also created problems, in my opinion.

Why weren’t the citizens of Gotham living on a bomb completely out of their control more interested in finding out something about the bomb, dealing brutally with the trigger-man in the process? They seemed unbelievably calm and content with their lot, all things considered.

Why doesn’t Bane simply crush the city with his huge and violent band of criminals? I know that this is explained as the military just being able to crush them, but he has just let the most dangerous killers and villains loose on a city. This would cause enough destruction on its own, even without the military & police showing up with gung-ho heavy weapons crews and letting loose on the city — I would consider whatever was left over to be pretty much mission accomplished.

Stealing this one from movieline.com:

Batman’s Superhuman Time Management
Before zooming off in the Bat with nuclear bomb in tow, and shortly after returning to the city after five months in the middle of nowhere prison with about a day to save the world, Batman somehow manages to put all of his legal affairs in order, leaves the pearl necklace for Selina (heh) and detailed instructions to Blake in a duffel bag at his lawyer’s office, sets a gasoline fire on the bridge in the shape of the Bat, saves Gordon in the nick of time, saves Blake in the nick of time, and fixes the Bat-symbol. I don’t know how he does it! Literally.

Best explanation: He’s Batman. Enough said?

Source: Movieline.

The time factor was pretty odd. Time stretched and slowed in this film like nobody’s business. And I blame the bomb for it.

Third, Catwoman.

Oh, Catwoman.

The best movie interpretation of your character so far has been essentially a shallow portrait of what the average person thinks an S&M fetishist looks like.

The worst has…has been…oh god, no. No, they can’t make me go back, they won’t!

Anne Hathaway, by contrast, portrays a hugely talented Catwoman with a suit that is actually functional (those cat ears are awesome!), a fairly well-developed character who saves the day despite her belief that she can’t really change anything. She is also less of a sex object (which has been her role in most other portrayals) than she is a skilled woman who happens to be sexy. Does she exploit her sexuality to take advantage of marks? Partly, when it’s easy, but equally she uses other skills such as fakery, deception, wit and charm.

She even redeemed one of the worst scenes in the Catwoman movie starring Halle Berry, making the line “Cat got your tongue?” sound sharp and sassy rather than…weird and psychopathic. Thank god there was no white russian scene, though, even Nolan and Hathaway couldn’t have saved that.

The scenes when she pretended to be crying in fear and shock were also excellent, both as send-ups of what Hollywood typically has expected of its women and as feats of acting.

The problem is that she’s too much of a well-rounded character. You’d have to be a real stereotype of a very particular sort to flee a city about to be destroyed when your friends (and every citizen in the city) needs your help, and Nolan’s Catwoman does not fit that stereotype. She’s too nice, too rational, and too smart. It’s not believable that she’d leave, so the scene where she comes back and shoots Bane is not really a surprise.

So, that’s my theory there. All the problems in The Dark Knight Rises were created by Nolan taking the worst parts of the Batman franchise, giving them a spin, and making them awesome.

On the one hand, slight problems that niggle if you think about them too hard. On the other hand…

AWESOME.

I think it was worth it.

Incidentally I found this quote on some right-wing individual’s site who appears convinced that one of the most right-wing movies (source: Forbes if you can stomach it) of recent years is leftist propaganda:

“Isn’t it fascinating that the villain, a brutal sadistic giant who talks through a voice box that makes Darth Vader seem positively cheerful by comparison, is named Bane. Gosh, what a coincidence. Sounds the same as Bain Capital that the president’s rival for the top office worked at. Oh, no, it’s spelled differently. Couldn’t possibly be any reference to Romney’s Bain.”

In case anyone was wondering, Bane in the comic books came a LONG time before Bain Capital was associated with Romney’s presidential campaign. Bane in the movie is a figure representing complete anarchy & populism as opposed to more moderate well-intentioned left- or right-wing individuals. Bane as a word meant something that causes ruin or woe in the 1570s.

Of course, the liberal reptile elite in Hollywood mean for us to become left-wing so that our blood will run sweeter and redder when the harvest finally comes, so there’s that too.

Correct me if I’m wrong about anything.

Tagged , , , , ,

Glamour Photography

HLO everyone! and welcome to my blog today it is about my glamour photography which is my job and it pays fine thank you I don’t do it just so to look at dinosaurs I am a professional and not an amateur or a semi-professional my girlfriend pays for this.

T-Rex reclining on a red fabric sofa.

(C) All rights reserve no infringemnet intended please.

This is a T-Rex I used a wide-angle lens and then I put it through a fish-eye filter on Photoshop and used the find edges tool I would recommend using this technique if you like your models to look a bit saucy or you could just put sauce on the photos hahaha no that was a joke but sometimes words do mean the same thing even when they are different.

Did I say I used a wide-angle lens? I think I used a zoom actually but either way it’s the same basic picture.

Therapsid

(C) All rights don’t steal.

I think this is some sort of therapsid I didn’t ask it though but does it matter I ask you when you can look at the beauty of the dinosaurs body I think my art is really all about the recording of the beauty of dinosaur bodies which is much nicer than looking at their arse or tits.

Dinosaurs don’t even have tits I mean I ask you some people.

I think that a good man will want to look at a dinosaur even if it has really small tits(!) because that is why they are generous and good but honestly as I said dinosaurs don’t have any at all which shows how good I am for looking at them (very good) and makes the picture sophisticated.

Triceratops on a red fabric sofa by John Lewis + also its bum

(C) COPY (don’t copy)

I will avoid the obvious joke here because I am more like James Bond with a martinei sort of humour I am very much a ladies man and have a dry wit (no not martina hingis lol I heard she played tennis or something!) a martinei!

Anyway I respect dinosaurs too much to say that this one is horny but it is. I gave it eyelashes in photoshop because who wants to look at a dinosaur that looks like it has shave its eyelids like some kind of MAN I ask you. I used infrared and also some candles on top of each other.

Apatosaurus

(C) Copywrong. Copyveryverywrong.

Yes tall dinosaur I said yes you are sexy. That is all you are good for though lol I said that as well.

She was so moved she looked like she was going to cry but then she didn’t she just charged me two hundred dollars for the picture and said that that was her job and if I had a job I would not be living where I am and paying dinosaurs to take off their clothes for me.

I said yes I would and said ha and she said she took pictures sometimes and she did not think I had got her all in and maybe I should use a wide angel but I said no you are not saucy.

Barmaids are saucy but they will not serve me bcos they say I smell like despair. I do have a job though.

I used an ISO 300 and a camera. She broke my pair of heels that I use so I lashed a satellite dish to her foot with some rope from a ship or something.

sofa

Sofa being a cheeky minx!

Hahaha this is great haha this is me and the sofa having some fun after the shoot she is great but needless to say she is not as talented as the models I hired. I tried to take too many pictures but it turns out cameras are not the same as video cameras even though the names are the same (link back to the saucy conundrum, this is what professional comedians call going all the way clown which is a pun on “all the way round” but I am not that funny even though some people say oh that was a funny thing to say it is not always on purpose

sofa

Oh no, “don’t” take a picture of me, hahaha but I did ha she wants it.

She is much more up for doing naughty pictures than the models I hired! But she looks like a bit of a couch unfortunately.

sofa

(C) COPYRIGHT ON ALL OF THEM

I am looking forwards to my next payacheck from where I work. Then I will pay the models again. Sometimes I think that they are so butiful I would just put them up on Nelsons column lol but then I am a romantic. I bet they would love to be put up there forever and never have to move again lol. I would bring them all the different types of cheese they like.

Dinosaurs don’t eat cheese or really any dairy products except eggs I think and thats a bit risky bcos what if they ate there own eggs? But anyway I would bring them cheese bcos I bought them they have to do whatever I say I mean damn.

People think glamour modelling is sexist but really that is just fascism.

I think that you should be allowed to have any fasces that you want, even if your fasce is pretty. It is only sexist if you can see all the naughty parts right up close.NOT the fasces.

Anyway this has been my guide on how to be a glamour model photographer I hope you enjoyed this is all 100% true and accurate and copyright ME so don’t steal or say I lied bcos I didn’t.

If you liked this post you might also like my most popular post by comment volume, Is Water A Ghost.

Secretly I don’t like glamour photographers.

SHHHHHHH.

Tagged ,

The Epic Battle Of Good And Nice

I’ve been thinking about the issue of niceness a lot recently, for three reasons. Two are books.

1. The Psychopath Test by Jon Ronson.

There are several striking scenes in this book in which the author interviews psychopaths who are unrelentingly nice — psychopaths who have committed atrocities and war crimes.

It seems that being nice is actually easier if you don’t really care about other people at all, because niceness can be achieved according to relatively simple formulae — formulae that are hard to use sincerely if you do care about other people.

2. Mr. Nice , a biography of Howard Marks.

Almost everyone buys that Howard Marks is a great guy.

Why? Because he’s nice.

It’s in his name, or at least in his nickname, how could you argue with that?!

Reading his book, though, I’m not sure why.

He admits to being the cause, directly or indirectly, of death, famine and war. That’s three of the four horsemen and I’m only about halfway through the book. I assume pestilence will pop up at some point.

He has funded incredibly violent terrorists, encouraged farmers to drop much-needed food crops for cash crops (in a variation on a tragedy of the commons scenario), made himself rich and not paid a penny in tax. He doesn’t give a shit about suicides, expressing the barest flicker of regret only about one of two suicides he writes about (this is tinged with a hint of “You stupid arsehole, why did you go and make me look bad?”, so I’m not sure if this flicker of regret counts).

I might be convinced by the rest of the book, but I sincerely doubt it.

3. Nice is reliant on Norms.

This means that those who are abnormal (abnormal for whatever your norms are, I mean) are, by definition, not nice. Niceness makes no allowance for the not-nice.

Two examples cropped up lately.

The first was a smug, overbearing fellow who insisted everybody play along with his stupid Rules Of Fun, and actually got a little violent when a woman present objected to his disregard for her right to make decisions.

The second, more serious one, was when a friend-of-a-friend revealed that they were, despite being a very nice person, intolerant of a particular group. This caused a great deal of very real pain.

As far as I can tell, being nice requires nothing more than adhering to social norms at all times. This can be either good or bad.

By contrast, to achieve any change in a community, norms must be challenged. To achieve a significant change for the better, or to ‘do good’, by the same token, norms must be challenged.

There’s a reason it’s “nice ‘n’ easy”, and not “good ‘n’ easy”.

Takin’ it easy.

Tagged , ,
%d bloggers like this: