About a decade ago, I wrote a blog post about how people forget the humanity of others when they hate them. I find hate really interesting - it's not an emotion I'm particular prone to, but the world seems full of it, so it interests me. And it's usually very harmful, so I'm interested in ways to mitigate and eliminate it.
Since writing that post, I have pondered how we start to hate somebody in the first place, and I've noticed a pattern that seems to underlie a lot of hate. I've not seen it called out explicitly before, which is really interesting.
Read more »
So, my van is a former "welfare van"; originally the sort of thing that would pull up next to some roadworks, offering a space for the crew to shelter from the rain and have their lunch. The back has four seats (with belts, so people can travel in them, making it a seven-seater overall), a table and a bunch of storage compartments. But it also has a 200Ah deep-cycle battery pack and a bunch of auxiliary electrical accessories.
Read more »
Continuing my previous series of blog posts about interesting things I've worked on in my career (an analytical database engine and a transactional database engine), I thought it'd be interesting to talk about something I worked on that's less groundbreaking technology, but interesting in other ways.
Read more »
So, I work from home, which means I spend a lot of time in my workshop.
It's a long, thin, building. The door opens into the metalworking area; moving along the building, we get to the electronics bench, then to my desk. As I've previously mentioned, I want to redesign the place a bit, but I'll still be spending a lot of time in here. I have insulated the roof successfully, but the second front in my war against chilliness is my rocket mass heater.
Read more »
So, if you look at a recent Scheme standard such as R7RS, you'll see that the body of a lambda expression is defined as <definition>* <expression>* <tail expression>; zero or more internal definitions, zero or more expressions evaluated purely for their side-effects and the results discarded, and a tail expression whose evaluation result is the "return value" of the resulting procedure.
I used to find myself using the internal definitions as a kind of let*, writing procedures like so:
(lambda (foo)
(define a ...some expression involving foo...)
(define b ...some expression involving a and/or foo...)
...some final expression involving all three...)
But the nested defines looked wrong to me, and if I was to follow the specification exactly, I couldn't intersperse side-effecting expressions such as logging or assertions amongst them. And handling exceptional cases with if involved having to create nested blocks with begin.
For many cases, and-let* was my salvation; it works like let*, creating a series of definitions that are inside the lexical scope of all previous definitions, but also aborting the chain if any definition expression returns #f. It also lets you have expressions in the chain that are just there as guard conditions; if they return #f then the chain is aborted there and #f returned, but otherwise the result isn't bound to anything. I would sometimes embed debug logging and asserts as side-effects within expressions that returned #t to avoid aborting the chain, but that was ugly:
(and-let* ((a ...some expression...)
(_1 (begin (printf "DEBUG\n") #t))
(_2 (begin (assert (odd? a)) #t)))
...)
And sometimes #f values are meaningful to me and shouldn't abort the whole thing. So I often end up writing code like this:
(let* ((a ...)
(b ...))
(printf "DEBUG\n")
(assert ...)
(if ...
(let* ((c ...)
(d ...))
...)
...))
And the indentation slowly creeps across the page...
However, I think I have a much neater solution!
Read more »