z

Hugo: Best Semiprozine - starting point

The finalists are:

  • Beneath Ceaseless Skies, editor Scott H. Andrews
  • Escape Pod, editors Mur Lafferty and S.B. Divya, assistant editor Benjamin C. Kinney, audio producers Adam Pracht and Summer Brooks, hosts Tina Connolly and Alasdair Stuart
  • Fireside Magazine, editor Julia Rios, managing editor Elsa Sjunneson, copyeditor Chelle Parker, social coordinator Meg Frank, publisher & art director Pablo Defendini, founding editor Brian White
  • FIYAH Magazine of Black Speculative Fiction, executive editor Troy L. Wiggins, editors Eboni Dunbar, Brent Lambert, L.D. Lewis, Danny Lore, Brandon O’Brien and Kaleb Russell
  • Strange Horizons, Vanessa Rose Phin, Catherine Krahe, AJ Odasso, Dan Hartland, Joyce Chng, Dante Luiz and the Strange Horizons staff
  • Uncanny Magazine, editors-in-chief Lynne M. Thomas and Michael Damian Thomas, nonfiction/managing editor Michi Trota, managing editor Chimedum Ohaegbu, podcast producers Erika Ensign and Steven Schapansky

In this category, everything but FIYAH is available free online, supported by subscriptions / Patreons etc. FIYAH puts a list of contents of each issue, and also publishes a Spotify playlist for each quarterly issue. Beneath Ceaseless Skies, Fireside Magazine and Strange Horizons also all publish podcasts of each of their fiction / poetry, and Uncanny Magazine publishes two podcasts per issue which cover some but not all of the content (as far as I can tell). Escape Pod is of course a fiction podcast to start with, but does provides transcripts of its episodes.

I subscribe to Uncanny Magazine & FIYAH, I had a subscription last year to Fireside Magazine, I support Strange Horizons on Patreon and I'm on Beneath Ceaseless Skies's mailiing list to get notifications of new issues, even if I don't always read them. I'll need to have a bit of a think about how I'll rank them.



comments




z

Hugo: Best Fanzine - starting point

The finalists are:

The only one of these I follow is The Rec Center, a weekly email of fan news and fanfic recommendations, which I've subscribed to for about 18 months now. That's also the only finalist where the 2019 output isn't easily viewable (but cunningly I already have the emails in my archive folder).



comments




z

Raw Zucchini Chips: Super Easy Raw Food Recipe


Zucchini chips are an awesome/tasty alternative to convention chips, which have few nutrients and are laden with fat and salt. Not only that, but before I was raw, I always overlooked zucchini as a "buy and make it in bulk" vegetable. But, when zucchini is plentiful, this is the perfect recipe to use them up.

 

Zucchini season is best in mid summer, because it's a warm weather plant. Even so, zucchini can be found at most groceries through most of the year. Look for firm and glossy fruit with no marks or soft spots.


Simply wash the zucchini and then slice thinly. A mandolin would be the best choice of tool, but I did just fine with a chef's knife. If you want your zucchini chips to have lighter edges, then peel then first then slice.



Put the sliced zucchini in a lidded container and add the marinade. Shake well to coat.




Spread out in a single layer on lined dehydrator sheets. Dehydrate at around 145 degrees Fahrenheit for about an hour, then reduce the temperature to 120 and dehydrate for another 12 hours or so. Overnight is a good way to time it. They're done when all the moisture has been removed. They should be pretty crispy and only a little chewy. The full recipe is below.


Raw Zucchini Chips
one large batch ~ $7.10


ingredients
  • 8 cups thinly sliced zucchini rounds ($5.00)
  • 1/2 cup agave ($1.00)
  • 1/4 cup balsamic vinegar ($.40)
  • 1/4 olive oil ($.40)
  • 2 tablespoons dried oregano ($.05)
  • 2 tablespoons dried basil ($.05)
  • 2 tablespoons dried parsley ($.05)
  • 1 tablespoon garlic powder ($.05)
  • 1 tablespoon onion powder ($.05)
  • 1 teaspoon salt (or more to taste)
  • 1 teaspoon black pepper
  • 1 teaspoon crushed red pepper flakes ($.05) 
directions
  • Slice the zucchini, pat dry if needed, and place in a large, lidded container. 
  • In a small bowl, whisk together the remaining ingredients.
  • Pour over the sliced zucchini, cover, and shake (or just stir) until zucchini is evenly coated. 
  • Spread the zucchini on lined dehydrator sheets and dry at 145 degrees for about an hour and then at 120 for about another 12 hours or overnight (dehydrating time can vary), until crispy. 
  • Store leftovers in an airtight container and pop into dehydrator for a few minutes to crisp them up again if necessary. 







z

Leo Zovic: Places, Peeps And Plagues

(in-package #:cl-pestilence)

;;   This is _not_ a simulation. It's just a game. And any resemblance
;; to any world, real or imaginary, is entirely coincidental.

;;   You can copy/paste this post in its entirety into a Common Lisp
;; REPL and play around with it if you like. I'm documenting it where
;; possible, but it's just a small toy to poke at for the moment.

;;   I've been thinking a lot about asymmetric multiplayer games and
;; <gestures wildly to world at large> all this.
;; I'm not actively _trying_ to model it accurately, but it's probably
;; obvious what's been consuming my thoughts lately.

;;   Let's get right into this. I'll explain as I go, and tie a few things
;; together neatly at the end. I hope. Regardless, there will absolutely
;; be a repo sometime fairly soon.

;; A place can be tagged arbitrarily, and can contain occupants.
;; They also collect points.

(defclass place ()
  ((tags :initarg :tags :initform nil :accessor tags)
   (occupants :initarg :occupants :initform nil :accessor occupants)
   (points :initform 0 :accessor points)))

(defun place? (thing)
  (eq (find-class 'place) (class-of thing)))

(defun place (&key tags occupants)
  (make-instance 'place :tags tags :occupants occupants))

(defun gen-place ()
  (let ((tag (pick '(:apartment-building :house :cottage
		     :office-building :factory :store
		     :cafe :lounge :theater))))
    (place :tags (list tag))))

(defmethod details ((place place))
  (format nil "====================~%~a {~{~a~}}~%~{  ~a~^~%~}~%"
	  (first (tags place))
	  (rest (tags place))
	  (mapcar #'details (occupants place))))

(defmethod show ((place place))
  (format nil "~20@a ~5a [~{~a~}]~%"
	  (first (tags place)) (points place)
	  (mapcar #'show (occupants place))))

;; A peep goes places.
;; They have
;;  - their daily routine (a list of places to visit)
;;  - their todo (the part of their routine they still need to do;
;;                they are currently at the first place in this list)
;;  - their health (a number from 0 to 100)
;;  - a list of plagues
;; Finally, they _also_ collect points.

(defclass peep ()
  ((routine :initarg :routine :initform (list) :accessor routine)
   (todo :initarg :todo :initform nil :accessor todo)
   (health :initarg :health :initform 100 :accessor health)
   (plagues :initform nil :accessor plagues)
   (points :initform 0 :accessor points)))

(defun peep? (thing)
  (eq (find-class 'peep) (class-of thing)))

(defun peep (&key places)
  (make-instance 'peep :routine places :todo places))

(defun health->string (health)
  (cond ((>= health 90) "@")
	((>= health 80) "0")
	((>= health 70) "O")
	((>= health 50) "o")
	((>= health 30) ":")
	((>= health 1)  ".")
	(t "☠")))

(defmethod details ((peep peep))
  (format nil "[~a ~3d [~{ ~a~^ ->~}]]"
	  (health->string (health peep)) (health peep)
	  (mapcar
	   (lambda (place) (first (tags place)))
	   (routine peep))))

(defmethod show ((peep peep)) (health->string (health peep)))

;; A world is a list of places, occupied by peeps. The world we start
;; peeps in also determines their routine.

(defun gen-world (&key (num-places 20) (num-peeps 100))
  (let ((places (loop repeat num-places collect (gen-place))))
    (loop repeat num-peeps
       do (let* ((routine (loop repeat 5 collect (pick places)))
		 (peep (peep :places routine)))
	    (push peep (occupants (first routine)))))
    places))

(defmethod details ((world list))
  (format nil "~%~{~a~}~%" (mapcar #'details world)))

(defmethod show ((world list))
  (format nil "~%~{~a~}~%" (mapcar #'show world)))

(defmethod all-peeps ((world list))
  (loop for place in world append (all-peeps place)))

(defmethod all-peeps ((place place))
  (loop for o in (occupants place) if (peep? o) collect o))

;; `tick!`ing a world means moving every peep through their routine once.
;;   We `tick!` each peep, then `tick!` each place until all the peeps are
;; done. Then we reset their routines.
;; You can think of this as a turn in the game.

(defmethod tick! ((world list))
  (let ((peeps (all-peeps world)))
    (loop while peeps
       do (setf peeps
		(loop for p = (pop peeps) while p
		   for res = (tick! p)
		   if res collect res))
       do (mapc #'tick! world)
       do (format t "~a" (show world)))
    (loop for p in (all-peeps world)
       do (setf (todo p) (routine p))))
  world)

;; Don't worry about the details of how to `tick!` peeps or places yet.

;;   Ok, here's where it gets a bit darker. Although we _did_
;; foreshadow this in the definition of `peep`. And also in the title
;; of the accompanying blog post.

;; A plague is another living thing.
;; It has
;;  - a host (a peep that it's infecting)
;;  - a signature (a token representing its lineage and strain)
;;  - health (how well it's doing inside its host)
;;  - virulence (how likely it is to spread to another host)
;;  - efficiency (how efficient they are at feeding)
;;  - reproduce (a function that returns a new instance to push into a new host)
;;  - and a strategy (a function, possibly closed, that takes
;;    itself and its host peep and mutates)

;; Plagues do not collect points; they score differently.

(defclass plague ()
  ((host :initarg :host :initform nil :accessor host)
   (signature :initarg :host :initform "SIG" :accessor signature)
   (health :initarg :health :initform 10 :accessor health)
   (virulence :initarg :virulence :initform 10 :accessor virulence)
   (efficiency :initarg :efficiency :initform 0.2 :accessor efficiency)
   (reproduce
    :initarg :reproduce
    :initform
    #'plague
    :reader reproduce)
   (strategy
    :initarg :strategy
    :initform
    (lambda (plague peep)
      (feed! plague peep 30))
    :reader strategy)))

(defun plague ()
  (make-instance 'plague))

;; Plagues can `feed!` on peeps or plagues. To feed means to
;; take away some of the targets' health and add some to your own.

(defmethod feed! ((self plague) (peep peep) (amount integer))
  (decf (health peep) amount)
  (incf (health self) (* (efficiency self) amount)))

(defmethod feed! ((self plague) (plague plague) (amount integer))
  (decf (health plague) amount)
  (incf (health self) (* (efficiency self) amount)))

;; Plagues can also `infect!` peeps by `reproduce`ing into them.

(defmethod infect! ((self plague) (peep peep))
  (unless (infected-by? self peep)
    (let ((child (funcall (reproduce self))))
      (setf (host child) peep)
      (push child (plagues peep)))))

(defmethod infected-by? ((self plague) (peep peep))
  (member (signature self) (mapcar #'signature (plagues peep))
	  :test #'string=))

;;  `tick!`ing a plague causes it to weaken and also carry out its strategy.
;; This models the background effect of the immune system of its host.

(defmethod tick! ((plague plague))
  (decf (health plague) 1)
  (funcall (strategy plague) plague (host plague))
  plague)

;;  `tick!`ing a peep means moving them to their next place, and also
;; `tick!`ing any plagues they may have contracted. Also, peeps are
;; resilient; they heal a small amount each time they tick (to a
;; maximum of 100).
;;  If a peep dies, they no longer move. And their plagues probably
;; won't do well. Peeps like to go places. They score points for each
;; place they go to.

(defun dead? (thing) (>= 0 (health thing)))

(defmethod tick! ((peep peep))
  (unless (dead? peep)
    (let ((location (pop (todo peep))))
      (incf (points peep))
      (setf (occupants location) (remove peep (occupants location)))
      (push peep (occupants (or (first (todo peep)) (first (routine peep)))))
      (setf (health peep) (min 100 (+ 5 (health peep))))
      (mapc #'tick! (plagues peep))
      (unless (empty? (todo peep))
	peep))))

;; `tick!`ing a place causes it to score for each `peep` present. And it causes
;; any `plague`s on present `peep`s to try to `infect!` other nearby peeps.
;; Places also lose points for each dead peep they contain.

(defmethod tick! ((place place))
  (incf (points place) (length (occupants place)))
  (loop for peep in (all-peeps place)
     if (dead? peep)
     do (decf (points place) 2)
     else do (loop for plague in (plagues peep)
		do (loop for victim in (remove peep (all-peeps place))
		      if (>= (virulence plague) (random 100))
		      do (infect! plague victim))))
  place)

;;  So, now we've got the basic framework of the game in place. There are three
;; players in this game: places, peeps and plagues.
;;   A plague player automatically loses if they are completely cured, and
;; automatically wins if they manage to kill everyone. That's fairly simple.
;;   A place player wins if they manage to cure the plague. They automatically
;; lose if all the peeps die. Also, fairly simple.
;;   A peep player is trying to survive. If they manage to make it some numer
;; of turns before dying, then we have to score the game instead of declaring
;; an outright winner regardless of game state.

;;   A peep player's score is the total number of points plus remaining health
;; on all of their peeps, minus the number of active plagues on said peeps.
;;   A plague player's score is the total number of health of their plagues,
;; with a multiplier equal to the number of places fully infected by
;; their plague.
;;   A place player's score is the total number of points in their places.

(defun score (world)
  (list :peep (let ((score 0))
		(loop for p in (all-peeps world)
		   unless (dead? p)
		     do (incf score (+ (health p) (points p)))
		   do (decf score (length (plagues p))))
		score)
	:place (let ((score 0))
		 (loop for p in world
		    do (incf score (points p)))
		 score)
	:plague (let ((score 0))
		  (loop for victim in (all-peeps world)
		     do (loop for p in (plaguesvictim)
			   do (incf score (max 0 (health p)))))
		  (loop for target in world
		     if (every
			 (lambda (victim)
			   (not (empty? (plagues victim))))
			 (all-peeps target))
		     do (setf score (* 2  score)))
		  score)))

;;   I think that's all I've got for now. This is definitely an idea I want
;; to run with. At the moment, it's just a tiny, in-repl proof-of-concept,
;; and not particularly fun, but I'm going to try developing it further with an
;; eye towards turning it into an actual web game playable from this site.

;; As always, I'll let you know how it goes.

(defun pick (lst)
  (nth (random (length lst)) lst))

(defun empty? (lst)
  (null lst))




z

Leo Zovic: Zippers And Clj

So recently, I had to use zippers at work. Specifically, the Clojure implementation. There were some close-to-arbitrary transformations I needed to do with some close-to-arbitrary trees and it turned out that zippers were more efficient than the alternatives1.

Using them this way, combined with the general state of the world and my free time, finally tipped me into doing some more Common Lisp development. Before, I go any further, let me be clear about something.

I Like Clojure

Seriously.

Its logo is up top in the language bar, I was one of the inaugural members of the Toronto Clojure User Group, I recommend it as a first lisp you should learn, and have for about six years now. I'm also painfully aware of the shortcomings of Common Lisp, and make no excuses for them.

However.

  • I don't like the JVM. It's slow as balls, its' deployment options are less than ideal for my purposes, its' error system is at best useless, and Clojure without it is unlikely.
  • Clojurescript build incompatiblities are, if anything, worse2.
  • I don't like the underlying licensing decisions.

These are deep reasons to stay away. They're not the sort of thing I can paper over with a library or two. Fixing them would mean a superhuman amount of work poured into the underlying technical and social infrastructure, and I'm not into it. I wouldn't be into it even if the community was interested in heading that way, and near as I can tell, they're not particularly.

Whether or not I think you should learn Clojure as your first3 lisp, it definitely wasn't my first lisp. The more uniform, mostly-better-thought-out interface, lack of historical baggage and functional data structures are not enough to pull me all the way over.

It is enough for me to start plotting a smash-and-grab of as much of the stuff I like as I can carry. Which is exactly what clj represents. As of this writing, it defines and exports exactly four symbols: if-let, when-let, -> and ->>. This is a tiny beginning of the list, and I fully plan to put something more substantial together using cl-hamt, named-readtables, test-utils and possibly optima. Stay tuned to that repo if you're interested, but it's not the focus today.

cl-zipper

The thing that percipitated this thought was having used the Clojure Zipper implementation. So, obviously, this is something I want next time I need to manipulate trees in Common Lisp. The paper is here, and unless you have a terminal phobia of datastructures4, you should go read it. It's six pages, they're light, and one of them taken up by the intro and references.

The operations defined in the paper are left, right, up, down, insert_right, insert_left, insert_down and delete. There's a few conveniences defined for the Clojure version, and I've implemented some of my own stuff too. Lets go through the main file in almost-literate style.

First up, we have constructors.

(defstruct path
  (left) (path) (right))

(defstruct loc
  (node)
  (path)

  (fn-branch?)
  (fn-children)
  (fn-make-node))

;;;;;;;;;; Constructors
(defun zipper (branch? children make-node root)
  (make-loc
   :node root
   :fn-branch? branch? :fn-children children :fn-make-node make-node))

(defmethod make-zipper ((thing list))
  (zipper #'listp #'identity (lambda (node children) (declare (ignore node)) children) thing))

(defun make-node (zipper children)
  (funcall (loc-fn-make-node zipper) zipper children))

You can see influence from both clojure.zip and the paper here. I'm taking the lead from the paper by explicitly separating the path triple our from the loc definition. However, I'm not explicitly defining my own type tree the way that Huet does. Instead, I'm going to be dealing with assorted lisp trees. These could be implemented as lists, vectors, hashes, or any number of other formats. I'm going to implement a few type-distpatching built-ins, including the make-zipper list method above, but the basic zipper function just needs to take an interface as input in the form of branch?, children and make-node arguments. This is the same solution that the Clojure implementation went with, and I see no reason to go a different way. The only material difference is that theirs uses the Clojure metadata system, while I explicitly define slots in the loc structure.

Now that we can construct, we need to be able to select.

;;;;;;;;;; Selectors
(defun branch? (zipper) (funcall (loc-fn-branch? zipper) (loc-node zipper)))
(defun children (zipper)
  (funcall
   (loc-fn-children zipper)
   (loc-node zipper)))
(defun node (zipper) (loc-node zipper))
(defun path (zipper) (loc-path zipper))

(defun lefts (zipper)
  (when (loc-path zipper)
    (reverse (path-left (loc-path zipper)))))

(defun rights (zipper)
  (when (loc-path zipper)
    (path-right (loc-path zipper))))

The basic navigation is four functions; down, up, left and right

;;;;;;;;;; Navigation
;;;;;;;;;;;;;;; Basic navigation
(defun down (zipper)
  (when (children zipper)
    (let ((fresh (copy-loc zipper)))
      (setf (loc-node fresh) (first (children zipper))
	    (loc-path fresh)
	    (make-path
	     :left nil
	     :path (loc-path zipper)
	     :right (rest (children zipper))))
      fresh)))

(defun up (zipper)
  (when (path zipper)
    (let ((fresh (copy-loc zipper)))
      (setf (loc-node fresh)
	    (make-node
	     zipper (append
		     (reverse (path-left (path zipper)))
		     (cons (loc-node zipper)
			   (path-right (path zipper)))))
	    (loc-path fresh) (path-path (path zipper)))
      fresh)))

(defun left (zipper)
  (when (and (path zipper) (path-left (path zipper)))
    (let ((fresh (copy-loc zipper)))
      (setf (loc-node fresh) (first (path-left (path zipper)))
	    (loc-path fresh)
	    (make-path
	     :left (rest (path-left (path zipper)))
	     :path (path-path (path zipper))
	     :right (cons (loc-node zipper) (path-right (path zipper)))))
      fresh)))

(defun right (zipper)
  (when (and (path zipper) (path-right (path zipper)))
    (let ((fresh (copy-loc zipper)))
      (setf (loc-node fresh) (first (path-right (path zipper)))
	    (loc-path fresh)
	    (make-path
	     :left (cons (loc-node zipper) (path-left (path zipper)))
	     :path (path-path (path zipper))
	     :right (rest (path-right (path zipper)))))
      fresh)))

The main difference between this and the paper is that I've chosen nil as my Top representation, which lets me pull the trick of using when to check for the presence of a path, and its' non-Top-ness at the same time.

The bad news is that since Common Lisp doesn't have pervasive functional data structures, I have to explicitly copy locs while moving through a tree. The good news is that the copy is fairly light weight. Effectively, I'm copying out a set of 5 pointers, and could get that down to 3 by defining an intermediate struct.

Hm.

Which I probably should do. Note to self.

Out of those, we get three compound navigation functions. With more probably coming soon. Specifically, I found find useful for the work I did. It's easily externally definable, but would be even easier to bundle along. The ones I've already implemented are root, leftmost and rightmost.

;;;;;;;;;;;;;;; Compound navigation
(defun root (zipper)
  (if-let (z (while zipper #'up))
    (node z)))

(defun leftmost (zipper) (while zipper #'left))

(defun rightmost (zipper) (while zipper #'right))
Each of these involve an intermediate call to while. Which isn't a generic macro; it's a function defined in util.lisp
...
(defun until (zipper f)
  (let ((z zipper))
    (loop for next = (funcall f z) while next
       when next do (setf z next))
    z))
...
As you can see, all it does is repeatedly call a given function on a zipper and return the last non-nil loc result. That's loc, not node, so this doesn't run into the usual Common Lisp conflict of "Did you fail to find a thing, or find the element nil?".

That's the traversals done. Next up, we've got modification, without which this library is fairly useless. The basics are replace, delete and the insert/child twins.

;;;;;;;;;; Modification
(defun replace (zipper node)
  (let ((fresh (copy-loc zipper)))
    (setf (loc-node fresh) node)
    fresh))

(defun delete (zipper)
  (when (path zipper)
    (let ((fresh (copy-loc zipper))
	  (fresh-path (copy-path (loc-path zipper))))
      (cond ((rights zipper)
	     (setf (loc-node fresh) (pop (path-right fresh-path))
		   (loc-path fresh) fresh-path))
	    ((lefts zipper)
	     (setf (loc-node fresh) (pop (path-left fresh-path))
		   (loc-path fresh) fresh-path))
	    (t (setf (loc-path fresh) (path-path fresh-path))))
      fresh)))

(defun insert-child (zipper node)
  (replace
   zipper
   (make-node
    zipper
    (cond ((not (branch? zipper))
	   (list node (node zipper)))
	  ((children zipper)
	   (cons node (children zipper)))
	  (t (list node))))))

(defun append-child (zipper node)
  (replace
   zipper
   (make-node
    zipper
    (cond ((not (branch? zipper))
	   (list (node zipper) node))
	  ((children zipper)
	   (append (children zipper) (list node)))
	  (t (list node))))))

(defun insert-left (zipper node)
  (let ((fresh (copy-loc zipper))
	(fresh-path (copy-path (loc-path zipper))))
    (push node (path-left fresh-path))
    (setf (loc-path fresh) fresh-path)
    fresh))

(defun insert-right (zipper node)
  (let ((fresh (copy-loc zipper))
	(fresh-path (copy-path (loc-path zipper))))
    (push node (path-right fresh-path))
    (setf (loc-path fresh) fresh-path)
    fresh))

The paper defines an insert_down function. It fails on a Leaf node, and otherwise inserts a singleton branch at the given location. The insert/append child functions above also insert nodes at a lower level at the current loc. They give you a choice about whether to insert the new node as the leftmost or rightmost child, and additionally succeed on Leaf nodes by including the leaf value as a child of the new branch.

There are, thus far, three compound modification functions; edit, splice-left and splice-right.

(defun edit (zipper f &rest args)
  (replace zipper (apply f (node zipper) args)))

(defun splice-left (zipper node-list)
  (reduce #'insert-left node-list :initial-value zipper))

(defun splice-right (zipper node-list)
  (reduce #'insert-right (reverse node-list) :initial-value zipper))

edit takes a function instead of a new node, and replaces the node at loc with the result of running that function on the existing node. The splice-* twins are fairly self-explanatory; they're like insert-left/insert-right, but work on multiple nodes rather than single ones.

I haven't yet implemented next, prev and remove because these might relate to the different representation of the traversal end? state. The reason for this seems to be that next/prev/remove assume a depth-first traversal. The reason I'm being weasely here is that I haven't thought about it hard enough to be sure that the end? marker is really necessary. It also seems odd to privilege depth-first over breadth-first traversals; ideally, I think you'd want to be able to support either. Possibly interchangeably.

Minor Housekeeping

That wraps it up for this edition. My immediate intention is to do more work on the cl-zipper and clj libraries, as well as that game I mentioned last time. Ideally, I'd like to up my blogging output too. Probably not to the same volume as I had at my peak, but it was definitely helpful to keep some sort of written journal around for a while. The current state of the world is, hopefully, going to make it easy for me to get more programming time in. All things considered, I'd count that as a win.

  1. Although admittedly, it does require me to explain the concept of zippers to a few other people for maintenance purposes. So ironically, this adds complexity despite being much more technically elegant than other options.
  2. There's a reason that langnostic.js is a raw JS file, rather than compiled from clojurescript source, and that reason is like 90% that the compilation process is nontrivial to set up.
  3. "First", not "only". You can probably make educated guesses about which other ones I think you should learn.
  4. In which case, why are you here? This blog could kill you accidentally with an errant click or two. You should probably just go do something else.




z

CALL FOR NOMINATIONS: The 2019 Theszies (the rec.sport.pro-wrestling Awards)

This is the Call for Nominations for the 2019 Theszie Awards (the rec.sport.pro-wrestling Awards). To nominate candidates for all categories, you may use this form. Nominations are due by January 5, 2019. Finally, to see previous years’ results, click here for 2018, click here for 2017, here for 2016, here for 2015, here for 2014, […]



  • Interactive Fun Time Party
  • The RSPW Awards / The Theszies
  • Wrestling

z

CALL FOR VOTES – The 2019 RSPW Awards (The Theszies)

This is the Call for Votes for the 2019 RSPW (Theszie) Awards. You can vote here. The Theszies are the oldest fan awards in pro wrestling history, going back to 1990 (when Mr. Perfect quite appropriately won Best Wrestler and Junkyard Dog v. Ric Flair at Clash of the Champions XI won Worst Match). They […]



  • Interactive Fun Time Party
  • The RSPW Awards / The Theszies
  • THIS-IS-AWE-SOME (clapclapclapclapclap)
  • Wrestling




z

[tasty review] United Tastes of America by Gabrielle Langholtz, Jenny Bowers, and DL Acken

  Feeling a little peckish? What’s your pleasure? If you’re craving something savory, perhaps we should zip on over to Illinois for some deep dish pizza and pierogies. Something a little more substantial? Well, we could feast on chicken fried steak in Oklahoma and bison burgers in Wyoming, before topping everything off with a platter … Continue reading [tasty review] United Tastes of America by Gabrielle Langholtz, Jenny Bowers, and DL Acken




z

Mr. Gonzi's victory; was the contest necessary?

PM in Marsascala during his tour for support
In todays The Times one can read that PM Lawrence Gonzi gained 96,5 per cent of the vote in the PN leadership contest. It gives The Observer a flashback from the sixties when Leonid Brezhnev gained 105 per cent of the vote in former Soviet Union. That is what can be called a good and fair election! To avoid any misunderstanding; of course yesterday's election can not be regarded otherwise than fair. But was it necessary? Even if Mr. Gonzi felt that he needed to have his leadership confirmed, the outcome of the vote is still not a true and fair view on the situation in The Nationalist Party since Mr. Gonzi was the only candidate. Say for instance that Mr. Debono had challenged Mr. Gonzi regarding the leadership (he has challenged him about almost everything else). Of course Mr. Gonzi would not have gained 96,5 per cent of the vote. That is as certain as it is that Mr. Debone would have lost such a debacle. Mr. Debono has previously tried very hard to commit political suicide and if he had challenged Mr. Gonzi regarding the leadership he would surely have succeeded. One can wonder if all this really was necessary. Mr. Gonzi is the undisputed leader of the Nationalist Party no matter what Mr. Debono tries to do. Even if there are a number of opponents to Mr. Gonzi in the party they are not as stupid as to challenge Mr. Gonzo in this political situation. They would, in that case, have gone down together with Mr. Debono.






















z

Defamiliarizing Faerie

.




The Iron Dragon's Mother received a long, thoughtful, and positive review from Matt Hilliard in the March 30 issue of Strange Horizons. Rather than give you the usual pull-quote carefully excised from the corpus of the text, I thought I'd share with you one of Hilliard's observations:


That raises the question: what is Swanwick up to with this setting? If he wants to write fun faerie stories, why not just write about faeries the normal way? Or, since a valid way to describe this book is to say it’s “about a faerie fighter pilot, but it’s reallyabout living in a corrupt world and dealing with death,” why not just write about corruption and death in the real world where both can be found in abundance? To answer the second question, a common defense of genre fiction is that both fantasy and science fiction give us a different perspective on things that don’t change. They defamiliarize the world around us by situating us in the future or a past that never existed, and in doing so they can teach us things about humanity that we wouldn’t otherwise have known.

It’s been sixty-five years since J. R. R. Tolkien published The Fellowship of the Ring and spawned a host of imitators, and for most of Swanwick’s readers, fantasy has become deeply familiar. If it’s too familiar, it no longer defamiliarizes. What to do? Some authors, such as those of the New Weird, responded by moving away from Tolkien’s folklore influences, pushing into stranger territory. Swanwick has done the opposite, hewing closely to the peoples and monsters of folklore traditions from around the world (albeit with the occasional references to Tolkien himself, as with Caitlin’s brother, named Fingolfinrhod). But by mixing together elves and Gucci handbags, dwarves and cigarettes, or dragons and jet fighters, Swanwick continually shifts the context his reader must use. Whenever you find yourself getting comfortable, the novel suddenly sounds like this: “With the easy, racist phrasing of his class, her brother said, ‘Well, the kobold is in the henhouse now, to be sure’” (p. 289).
Overall, the review is positive, the sort of thing that warms a writer's heart. Hilliard has some negative things to say along the way, but since they're based on a careful reading of the book I actually wrote, I don't see that I have any right to complain.

You can read the whole review here.  Or go to Strange Horizons here and wander around, maybe read a story or two while you're there.

Above: Cleaning office, I came across the above photo of myself at age 23, when I was new to Philadelphia and determined to be a science fiction writer. It captures my mood then pretty well.



*




z

Zero Notebook 1: Cover

.



Look what I found!

Some time ago, I posted every page of the Image Notebook I created to help me imagine the world and people of Industrialized Faerie for The Iron Dragon's Mother. What I didn't mention was that it was actually the second such notebook I'd made. The first notebook I lost--forever, I thought. But as it turned out, it had been misfiled in my office.

This is why you should clean your workspace at least once a decade.

The Zero Notebook, as I think of it, was begun all the way back in 2009. I pasted images from magazines and newspapers into it, created collages, some of which I altered, sought inspiration from the uncanny but visualizable. The end result is something very close to (but not identical with) outsider art.

I'll spare you the bulk of the images. But starting today I'll be posting ten images from the notebook. One on each weekday when I don't have any other news to pass along. This is the first one: the notebook's cover.


And what, you ask, does it mean . . . ?

The eye, of course, represents the eye of a dragon. It's slashed across the oval to create a zero.  The dot to the lower right is meant to suggest that the glyph represents the letter Q.,  though, of course, not exactly. That's because I wasn't looking for Answers. Just Questions.

There are a few (not many) words in the notebook. Here's an entry I ran across that begins with (almost) the cover glyph:

Q. What does the Goddess want?
A. Wrong question.

All of the above carried through into the novel and became a major, if close to undetectable, theme. The Iron Dragon's Mother would have been a very different book if I had started it with a different image.

The crinkly stuff is wide transparent tape, used to seal the image onto the cover. If this notebook ever winds up in somebody's collection, that's going to be a major conservation issue. Not my problem.


Above: First image. Nine to go.


*




z

Zero Notebook 2: Caitlin

.


Here on the inside cover of the Zero Notebook is a first glimpse of Caitlin. It's a photograph of a young Russian doctor and, although it misrepresents Caitlin's ethnicity entirely, it does capture her innate seriousness. Added to which are birds in flight, because flight is in her nature, and a miniature of a painting by Lucian Freud. This last was included for its lack of glossy magazine glamor but also, with a touch of irony, because I knew that the novel would be going deep into Carl Jung territory.


And what, you ask, does it mean . . .?

It doesn't. The page is a first, fumbling-in-the-darkness attempt to find the heart and soul of the novel.


Above: Second image. Eight to go.


*




z

Zero Notebook 3: Jinx

.



Excerpt 3 from the Zero Notebook for The Iron Dragon's Mother.  Jinx is a pretty neat character. I'm sorry I couldn't find a place for her in the novel. She looks like trouble, doesn't she?


And I have to apologize . . .

I promised to post these on every day I didn't have news and then got so caught up on writing chores I lost track of the blog entirely. My bad. I'll do better, I promise.

For a while, anyway. 


Above: Third image. Seven to go.


*




z

Zero Notebook 4: A Vision of God

.




This is the single most important image in the Zero Notebook. As my scrawled notation says: Her first glimpse/vision of Him. It is an image of God.

At this distance, I could not say why I specified Him rather than Her, given that my fictional universe is presided over by the Goddess. Probably I didn't want that fictional level of deniability. 

Below the picture it also says:

To say that the world is a fiction
is not the same as to say it is a lie.

And to the side:

How do you describe what cannot be described?


And what, you ask, does it mean . . . ?

If I knew, I would tell you. 


Above: Fourth image. Six more to go.

*




z

Zero Notebook 5: Hermes/Fire Sprite

.


Another character that didn't make it into The Iron Dragon's Mother. Industrialized Faerie is a rich world. The three novels I've set in it can only only hint at how rich and strange it is.

This image, for a rarity, was hardly altered at all.


And where, you ask, did I find this. . . ?

The image came from the Body Works show that toured the world some years ago. A large number of corpses were flayed and then carefully preserved, in order to display the wonders of anatomy. The show was controversial at the time because the corpses came from China and there were those who claimed the bodies hadn't been voluntarily donated but those of criminals who had died in prison. The truth of the matter was impossible to ascertain.

The show, however, was extremely popular. My son, Sean Swanwick, worked for a summer as a guide when it was displayed at the Franklin Institute and he told me that they had to watch the people touring it like hawks... Every now and then, someone would try to snap off a finger or other appendage to take home as a souvenir.


Above: Image five. Five more to go.


*




z

Zero Notebook 6: Mother Eve

.


She never appears in person in The Iron Dragon's Mother, but Mother Eve is central to the entire enterprise. Unsettling, isn't she?

Judith Berman once told me that most of the First People have Trickster tales. But of the hundreds of tribes in North America, only two--and they small tribes--have a female trickster. The female trickster is, apparently, difficult for people to imagine.

So you can imagine my delight when I found one right inside my own culture.


But what, you ask, does it mean . . .?

Trickster is a strange and difficult character, neither a good guy nor an evil one. She exists somewhere in between, a creator of chaos and a provider of a special Something that it seems human beings require. It might be corn and it might be fire. Trickster gets blamed for a lot of the woes of existence, but it seems that without him/her, we're skunked.

I wonder if Pandora was originally a Trickster,  before they allegorized her to hell and back? It bears thinking on.


Above: Image Six. Four to go.


*




z

Zero Notebook 7: Helen

.

Introducing Helen. There's more to her than meets the eye.

Written upside-down--so they won't necessarily be taken as gospel by any readers are three quick notes scrawled to myself:

Mother as Mind Spider

Storyteller as Spider & Weaver

Chrone as Spider

I apologize for the misspelling of "crone." But I was writing (and thinking) too fast to care much for accuracy.


But what, you ask, does it mean . . . ?

The influence of Louise Bourgeois is pretty obvious here. Late in life, she created those wonderful, terrifyingly realistic giant spiders with long steel needles at the end of their legs and said that they were all about her mother. Who made a living repairing tapestries, using long steel needles. So it's not the slap in her face it might seem.

I liked the spider representing the archetypal woman-as-maker, which fit Helen right down to the ground. I was also fighting a fight all the way through with received archetypal images of women were were almost all pretty or dainty or passive. I wanted to get at that primal fierceness that lurks inside us all.

And, ounce for ounce, you don't get much fiercer than a spider.


And tomorrow and Friday . . .

There will be news.


Above: Seventh image. Three to go.


*




z

Zero Notebook 8: Frog

.


Originally, this was going to be a character named Frog--one who never materialized in The Iron Dragon's Mother. A wood-fey, obviously, and possibly a marsh-weller.

But look at that wistful, lost expression. I think this guy eventually became Fingolfinrhod. I really do.


Above: Image Eight. Two more to go.


*




z

Zero Notebook 9: Dragon Skull

0



Dragons are, as everybody knows, half fighter jet and half fire spirit.

Here's the skull of one.


Above: Image Nine. One more to go.


*




z

Zero Notebook 10: Helen

.



Our revels now are ended. These our images, as I foretold you, were all spirits and are melted into air, into thin air...

But before we go, one more page, the back inside cover to be specific. It contains two more images of Helen. One is a publicity shot from a period she was going to leave out of the autobiography she never wrote, when she made a brief, ill-fated stab at acting. The other is from a dark period in her middle age.

She was far better-looking than she'd ever admit to being.


And what, you ask, does it mean . . . ?

To find that out, you're just going to have to read The Iron Dragon's Mother, now aren't you?


Above: Tenth image. Tout finis!

*




z

Wisconsin asks Alvarez, Chryst, Gard to take pay cut

Wisconsin officials believe a plan of reducing compensation to highest-earning employees should help save the athletic department about $2.8 million.




z

Pocket-Sized #1005: “Creepiness”

Creepiness In this Pocket-Sized episode #1005, Marc Abrahams shows an unfamiliar research study to Jean Berko Gleason. Dramatic readings and reactions ensue. The research mentioned in this episode is featured in the special Psychology issue (vol. 26, #1) of the Annals of Improbable Research magazine. Remember, our Patreon donors, on most levels, get access to each podcast episode before it is made public. 1. […]




z

Crazy-seeming research, now and then, turns up something true and beautiful

Crazy-seeming research, every now and then, leads to something really, really wonder-filled. In this case, the discovery of something long-predicted (by Einstein) but seemingly impossible to perceive: gravity waves. (HT Maggie Lettvin)




z

A new comic (in 2 languages) about Ig Nobel Prize winners

A new comic strip—in Russian and in English—about some of the curious characters who have won Ig Nobel Prizes. The series appears on Instagram.




z

Pocket-Sized #1006: “Hot Sauce Aggression”

Hot Sauce Aggression In this Pocket-Sized episode #1006, Marc Abrahams shows an unfamiliar research study to Dany Adams. Dramatic readings and reactions ensue. The research mentioned in this episode is featured in the special Ig: the Triumph of Miss Sweetie Poo issue (Vol. 7, #1) of the Annals of Improbable Research Magazine. Remember, our Patreon donors, on most levels, get […]




z

Pocket-Sized #1007: “Bereitschaftspotential”

Bereitschaftspotential In this Pocket-Sized episode #1007, Marc Abrahams shows an unfamiliar research study to Jean Berko Gleason. Dramatic readings and reactions ensue. The research mentioned in this episode is featured in the special Psychology issue (vol. 26, #1) of the Annals of Improbable Research magazine. Remember, our Patreon donors, on most levels, get access to each podcast episode before it is made public. 1. […]




z

Zoom fatigue

There are dozens of articles Out There on "Zoom fatigue", with a wide range of ideas about causes and cures. Gianpiero Petriglieri offered the BBC a couple of hypotheses about why "Zoom calls drain your energy": Being on a video call requires more focus than a face-to-face chat, says Petriglieri. Video chats mean we need […]



  • Psychology of language


z

Zombie Strippers Porn Star Dancing

Zombie Strippers has got to be hands down one of the cheesiet, oddest, zombie movies movies I have ever seen