Recently I changed how the content on this site was generated, from using the standalone OS X application RapidWeaver , to the server-side publishing platform Movable Type . During that transition I changed the site’s style to the minimalist default offered by MT, which uses its own CSS for column layout and typography.
…I used the superb application CSSEdit to help me massage Movable Type’s style into something that compatible with Blueprint’s own typography and layout.
…I’m aware code examples were being truncated on the right side before, but this should be corrected now.
The task at hand is to write a wrapper script for /usr/bin/ld that drops arguments beginning with -Wl,-rpath, .
… Here ld-wrapper is expected to return its arguments separated by NUL characters so I can feed it to xargs , and from there to /usr/bin/ld . I’m sure there’s an easy, all-in-one way to do this with Haskell, I just haven’t reached that chapter yet.
… I wanted to do this with an “inverse grep” instead of select , but couldn’t find a way to grep for the opposite of a pattern.
It creates a Schroedinger type which has two data constructors: an Opened constructor which takes a Probable object — that is, whose Live or Dead state is known — and an Unopened constructor which takes a random generator, and an object without a particular state, such as a Cat.
… If, however, you bind a function to an Opened box with a Live thing, it will apply the function to what’s in the box — in this case, the Cat itself.
… Here is the meat of this example, it’s reason for being, all contained within this one line: If you bind a function to an Unopened box, it gets bound in turn to an Opened box containing a Cat whose fate has been decided by the dice.
… This is fairly linear: it gets a random generator from the operating system, then creates an Unopened box and returns it, which gets printed. print does its work by calling show on the Schroedinger type, since it was derived from Show earlier.
Having just begun my descent down the rabbit hole, into a Haskell land of hiding grins and late late hatters, I thought I’d try journaling what I discover on the way, so that maybe those who are merely curious could play the part of language voyeur.
… This function starts out the list with 1, followed by 1, then it starts adding two lists together — provided by the same function before it’s even done!
…I kept thinking it was something I had to return as I went along, not passed down to each deeper level — and then returned after I’d added to it.
…If that first character is a colon, return a list with the current accumulator as the head, and recurse to process the rest of the string (and so on).
In a recent entry on differences between Haskell and Lisp, one of the Lisp community’s long-time members, Daniel Weinreb, asked about my stated aversion to JVM-based languages for everyday computing (some times referred to as “scripting”).
… The fact that you distinguish between server-side and client-side applications suggests to me that what you’re really talking about is start-up latency: you’re saying that a very small program written for the JVM nevertheless has a significant fixed overhead that causes perceived latency to the user.
… As a hypothetical question just to clarify your meaning: if there were a JVM implementation that started up instantly, so that the speed of execution of a small program would be the same as the speed of the same code appearing in the middle of a long-running server process, would that answer your objections?
…Also, what you said about the JIT, and alternative VMs, can be supplemented by mentioning all the other JVM facilities that exist, like code coverage, performance and memory analysis, and live introspection; along with the ability to pick JVMs to run on phones, or satisfy real-time computing requirements.
Someone recently asked what my issue was regarding the JVM, since at the moment it prevents me from falling too much in love with Clojure — a language with the double-benefits of functional programming, and Lisp syntax and macros.
…These may not seem like much time in the scheme of things, but psychologically it builds up on me when I have to run a particular script over and over and over again. I’ve already noticed the pain with Groovy.
…Ruby (1.9.1-p0) | 0.0196997523308 |
It makes it trivial to write DSLs, for example, since you all you need to do is model the syntax tree as a series of Lisp data structures, and then evaluate them directly.
…Since it was designed at a time when there was One Processor to Rule them All, it didn’t go to great lengths to consider how its design might effect the needs of parallelism.
…Even if the arguments could have been computed in parallel, there’s no way to know for sure that the evaluation of one argument doesn’t cause a side-effect which might interfere with another argument’s evaluation.
…If then I do something in my function which needs some of those values, Haskell can start computing the ones it needs in parallel, waiting on the completion of the whole set before returning the final result.
Following on my last entry, where I built a better pre-commit hook to ensure every commit in my Git history passed make check with flying colors, I realized something today about my good friend, rebase .
…If I have a set of ten commits, and realize the 3rd commit has an oversight I’d like to smooth out, I can make a new commit to fix the problem and then merge it with that old commit, resulting in a nice, clean set of commits for pushing.
…A rewritten commit is really a new commit , which means it hasn’t been tested, may never have existed as a working tree, and certainly isn’t the same as the previous commit, however similar its diff output may be.
… Thus the only way I could use rebase in confidence would be to run the same pre-commit again on every changed commit during the rebase operation — which is something Git doesn’t do.
Recently a friend turned me onto an interesting article about a problem I had just recently discovered about Git and its pre-commit hook:
> Committing in git with only some changes added to the staging area still results in an “atomic” revision that may never have existed as a working copy and may not work.
This has probably been written countless times before, but I found myself needing it today and it was quick to write. It lets you read characters from a char array in C++ via the istream interface:
… ptrinbuf(char * _ptr, std::size_t _len) : ptr(_ptr), len(_len) {
… ptristream(char * ptr, std::size_t len = 0)
