So. Farewell then Bystander...
And then the justice,
Ski Sunday presenter Ed Leigh is wowed by Sochi two years ahead of the 2014 Winter Olympics
Just back from the Texas Library Association Conference in Houston!
As always, it was great to see fellow authors and illustrators, as well as the librarians who've supported our books through the years. And I always enjoy seeing what's new at the publisher booths.
We had a great time for my panel Tuesday afternoon, "What's New with Texas Middle Grade and YA Authors," organized by Susie Kralovansky, featuring Jessica Lee Anderson moderating, and fellow panelists Paige Britt, Cory Putnam Oakes, P.J. Hoover, Cynthia Levinson, Liz Garton Scanlon, Jennifer Mckissack, and Joy Preble. Conversation was entertaining and enlightening.
Many thanks to everyone who puts in the work to make TLA the best state library conference in the country!
Here are some pics:
Hitting the road |
Rainy Houston from the hotel |
Me, Cynthia Levinson, PJ Hoover |
Carmen Oliver signs |
Jennifer McKissack, Jennifer Ziegler, Joy Preble |
Paige Britt and Donna Janell Bowman |
Me and the world in the lobby of the Hilton |
Signing BORROWED TIME |
Janet Fox and Jennifer Ziegler |
PJ, Jessica, and Joy |
Me and Elaine Scott |
Buffalo Bayou on my early morning run |
Back in Austin! |
One rocket could decide how soon humanity returns to the Moon — and maybe one day sets foot on Mars.
The gas giant is the Solar System's largest planet. Here's why it's also the fastest-spinning planet.
Knowing that you've found signs of life beyond Earth may not be as clear-cut and simple as one might think.
The Planetary Society and Lerner Publishing Group have teamed up to bring young readers an engaging series of books that make space science fun and accessible.
Life thrives on Earth, and we even send evidence of our presence out into the Solar System. Is anyone out there looking for us?
With the Sun at the peak of its activity cycle, we Earthlings get treated to some awesome sights. Plus, some truly awe-inspiring launches happened this week.
How the inclusion of Katie Taylor v Amanda Serrano on the bill legitimises the carnival of Mike Tyson v Jake Paul in Texas
We just made the decision to ship the remaining copies of Feast to us. There are about 800 left, out of the original 2000 copy print run. Which is a lot of copies, but given that we were originally scheduled to launch March 2020, and had to cancel an entire summer’s worth of scheduled bookstore […]
[BULLETIN: Quicklisp now has the latest version of FSet.]
Sycamore, primarily by Neil Dantam, is a functional collections library that is built around the same weight-balanced binary tree data structure (with leaf vectors) that FSet uses. While the README on that page comments briefly on the differences between Sycamore and FSet, I don't feel that it does FSet justice. Here is my analysis.
Dantam claims that his library is 30% to 50% faster than FSet on common operations. While I haven't done comprehensive micro-benchmarking, a couple of quick tests indicates that this claim is plausible. A look through the internals of the implementation confirms that it is clean and tight, and I must commend him. There may be some techniques in here that I could usefully borrow.
Most of the performance difference is necessitated by two design choices that were made differently in the two libraries. One of these Dantam mentions in his comparison: FSet's use of a single, global ordering relation implemented as a CLOS generic function, vs. Sycamore's more standard choice of requiring a comparison function to be supplied when a collection is created. The other one he doesn't mention: the fact that FSet supports a notion of equivalent-but-unequal values, which are values that are incomparable — there's no way, or at least no obvious way, to say which is less than the other, and yet we want to treat them as unequal. The simplest example is the integer 1 and the single-float 1.0, which have equal numerical values (and cl:= returns true on them), but which are nonetheless not eql. (I have a previous blog post that goes into a lot more detail about equality and comparison.) Since Sycamore expects the user-supplied comparison function to return an integer that is negative, zero, or positive to indicate the ordering of its arguments, there's no encoding for the equivalent-but-unequal case, nor is there any of the code that would be required to handle that case.
Both of these decisions were driven by my goal for the FSet project. I didn't just want to provide a functional collections library that could be called occasionally when one had a specific need for such a data structure. My ambition was much grander: to make functional collections into a reasonable default choice for the vast majority of programming situations. I wanted FSet users (including, of course, myself) to be able to use functional collections freely, with very little extra effort or thought. While Lisp by itself reaches a little bit in this direction — lists can certainly be used functionally — lists used as functional collections run into severe time complexity problems as those collections get large. I wanted the FSet collections to be as convenient and well-supported as lists, but without the time complexity issues.
— Or rather, I wanted them to be even more convenient than lists. Before writing FSet, I had spent years working in a little-known proprietary language called Refine, which happened to be implemented on top of Common Lisp, so it was not unusual to switch between the two languages. And I had noticed something. In contrast to CL, with its several different predefined equality predicates and with its functions that take :test arguments to specify which one to use, Refine has a single notiion of equality. The value space is cleanly divided between immutable types, which are compared by value — along with numbers, these include strings, sets, maps, and seqs — and mutable objects, which are always compared by identity. And it worked! I found I did not miss the ability to specify an equality predicate when performing an operation such as "union". It was just never needed. Get equality right at the language level, and the problem goes away.
Although FSet's compare generic function isn't just for equality — it also defines an ordering that is used by the binary trees — I thought it would probably turn out to be the case that a single global ordering, implemented as a generic function and therefore extensible, would be fine the vast majority of the time. I think experience has borne this out. And just as you can mix types in Lisp lists — say, numbers and symbols — without further thought, so you can have any combination of types in an FSet set, effortlessly. (A project I'm currently working on actually takes considerable advantage of this capability.)
As for supporting equivalent-but-unequal values, this desideratum flows directly from the principle of least astonishment. While it might not be too surprising for a set or map implementation to fail distinguish the integer 1 from the float 1.0, it certainly would be very surprising, and almost certainly a source of bugs in a compiler that used it, for it to fail to distinguish two uninterned symbols with the same name. (I saw a macro expansion recently that contained two distinct symbols that both printed as #:NEW. It happens.) A compiler using Sycamore for a map on symbols would have to supply a comparison function that accounted for this; it couldn't just compare the package name and symbol name. (You'd have to do something like keep a weak hash table mapping symbols to integers, assigned in the order in which the comparison function encountered them. It's doable, but FSet protects you from this madness.)
Along with those deep semantic design choices, I've spent a lot of time on developing a wide and featureful API for FSet (an effort that's ongoing). FSet has many features that Sycamore lacks, including:
Let me digress slightly to give an example of how FSet makes programming more elegant and convenient. Joe Marshall just put up a blog post comparing Go(lang) with Common Lisp, which is worth a read on its own; I'm just going to grab a code snippet from there to show a little bit of what programming with FSet is like. Here's Joe's code:
(defun collate (items &key (key #'identity) (test #'eql) (merger (merge-adjoin #'eql)) (default nil))
(let ((table (make-hash-table :test test)))
(dolist (item items table)
(let ((k (funcall key item)))
(setf (gethash k table) (funcall merger (gethash k table default) item))))))
(defun merge-adjoin (test)
(lambda (collection item)
(adjoin item collection :test test)))
And here's what I would write using FSet:
(Well, I would probably move result outside the dolist form to make it clearer what the return value is, but let's go with Joe's stylistic choice here.)
For those who haven't used FSet: the form (map :default (set)) creates a map whose default is the empty set, meaning that lookups on that map will return the empty set if the key is not in the map. This saves the includef form from having to handle that possibility.
My version makes assumptions, it's true, about how you want to collect the items with a given key; it doesn't give you other choices. It could, but what would be the point? It's already using a general set with better time complexity than lists, and saving you from having to write anything like merge-adjoin. The extensible global equivalence relation means you're not going to need to supply a :test either.
I think the FSet-enhanced code is cleaner, more elegant, and therefore clearer than the plain-CL version. Don't you agree? Maybe you wouldn't say it's a huge improvement, okay, but it's a small example; in a larger codebase, I would argue, these small improvements add up.
* * * * *
To summarize: if you just want a library you can call in a few places for specific purposes, Sycamore might work better for you (but think hard if you're writing a comparator for symbols). FSet can certainly be used that way, but it can be much more. If you want to see one way in which Common Lisp can be made into a better language, without giving up anything that we love about it, I urge you to give FSet a try.
FSet has changed the way I write Lisp programs. — an FSet user
(UPDATE: the magnitude of the performance difference between FSet and Sycamore surprised me, and inspired me
to do some profiling of FSet. It turned out that I could get a 20% speedup on
one micro-benchmark simply by adding some inline
declarations. Mea culpa, mea culpa, mea maxima culpa; I should have
done this years ago. With that change, the generic function overhead
appears to be the only significant cause of the remaining ~20%
performance difference. I tried creating a Sycamore set using a thin wrapper around fset:compare, and the resulting performance was very similar to that of FSet with its new inlines.)
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where. I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
*
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW.
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
CONTINUED TOMORROW. (For those who came in late: The first sentence was posted here on October 1 and a new sentence was posted every day thereafter, to make a complete story.)
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where.I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
FINIS
Above: Every Autumn, I write a Halloween story, write it out on leaves (one word per leaf), photograph the leaves, and then leave them where I found them. The story is then serialized, starting on October 1 and concluding on the 31st--All Souls Day.
.
I am always happiest when a story of mine comes into print. Today, I have the joy of introducing you to "Unquiet Graves," a seasonal tale of graveyard misbehavior and betrayal. Oh, and there's nothing supernatural about it at all.
You can read the story here. But if you're like me, you'll just go to Clarkesworld, look over the table of contents, and decide which story you want to read first. Mine by preference, but follow your whim.
And for those who like trivia . . .
I came up with the handheld's app many long years ago and it took forever to come up with a story for it. You'll notice that it is left unnamed in the story. That's because its secret name was "The Graveyard Reader." Which is the title of a well-known story by Theodore Sturgeon. While I was writing the story, I thought of it as "The New Graveyard Reader." But Sturgeon's story and mine go off in totally different directions, and giving mine (or even the app) a title suggesting there was some implicit connection between the two would only cause confusion.
The title I finally came up with was derived from "The Unquiet Grave" by that most prolific of all poets, Anonymous. If you look it up, I suggest you do so after reading my story. It gives away some of the plot.
*
.
This year's Halloween story, written on leaves and serialized daily on my blog, one sentence at a time, is done. Every day in October, I added to it, it reached its last words on Halloween.
Funny thing, though. In conversations with two different friends, I learned that neither of them had realized it was a story. They each thought I was just posting random sentences written on leaves. One of them is an artist, and thinks primarily in visual terms, so I thought at first that was a misunderstanding curious to her. The other, however, is a well-known writer and, what's more important, quite a good one. I have no idea what's going on there.
Long story short, at my behest, my son Sean, put all the photos up on Imgur, subtitled. So, if you didn't realize that they told a story... Or if, somehow, you weren't able to hold all the sentences in your head until the story was complete... Now you can find out what was going on. (The stone angels mark the ends of paragraphs.)
You can find it by clicking on the link here.
*
When the thing you're trying to move is bigger than the car you're trying to move it with, you might run into a few problems!
... and by "problems," I mean "other cars."
Along with the pink helmet and white basket, the bike gang had serious questions about granting him membership.
~NSHA
Alexi Lalas and David Mosse reacted to the second United States Men's National Team roster release of the Mauricio Pochettino era, with Christian Pulisic, Tim Weah, and Weston McKennie headlining the squad.
Canada women's soccer coach Bev Priestman has been fired after an independent review of a drone surveillance scandal at the Paris Olympics
Deion Sanders discusses the impressive growth of Shedeur Sanders from last season to this year, highlighting his development as Colorado’s QB and the strides he’s made on the field.