Little Improvements Add Up

All Irreal readers, I’m sure, are familiar with the power of compounding if only because they know about “compound interest.” Every now and then, Paul Graham (re)tweets an interesting mathematical fact. The last example I wrote about is the fact that any well-shuffled card deck is almost certainly unique in the history of the universe. Recently, he offered this fact about compounding:

Much like the size of \(52!\), this doesn’t seem too surprising at first glance but consider: if you can improve some skill—a musical instrument, programming ability, typing speed, whatever—by just 1% a day, at the end of the year you will have improved 3,778%.

Posted in General | Tagged | Leave a comment

Zamansky: ClojureScript 2

I’ve written a few posts lately about working in the Slime and Geiser environments to write and experiment with Common Lisp and Scheme code. What’s great about them is that they enable an “interactive programming” style where you can try out small code snippets to see what happens and build those small snippets into larger bodies of code. The snippets can be as small as a single expression. My two go to examples of this are the beginning of Magnar Sveen’s Web Rebels talk and Kris Jenkins video on building a Spotify client. You can find links to both of those in this post from 2013.

Of course, you can write Elisp this way too and the other great thing about Slime and Geiser is that they, too, run in Emacs. That means you can write, test, debug, and run your code from the comfort of Emacs. Why would you want to write code any other way?

Mike Zamansky has been experimenting with another language that enjoys a similar environment: ClojureScript. As with Common Lisp and Scheme, Emacs provides an interactive environment for ClojureScript: Bozhidar Batsov’s excellent Cider. In his second video on ClojureScript, Zamansky continues with the application he started in Using Emacs 63 that I wrote about here.

The video isn’t really about using Emacs but Emacs nevertheless plays a large and important role. Zamansky shows how easy it is to try things out and track down bugs while working on an application. Because Zamansky is a ClojureScript n00b, the ability to try something to see if it does what he expected and change things if it doesn’t is invaluable. It’s another example of the power of interactive programming.

The video is just short of 26 and a half minutes so you’ll definitely need to schedule some time but I found it interesting, enjoyable, and well worth time time.

Posted in General | Tagged | Leave a comment

Ebook Stupidity

I haven’t written about the publishing industry for some time but a recent post by hoakley over at The Eclectic Light Company has reignited my rage. Publishers have been doing things the same way for hundreds of years and don’t seem able to adapt to the changing landscape. This isn’t just about ebooks—although that’s a large part of it. Even with physical books they’re letting companies like Amazon eat their lunch.

It gets much worse with ebooks. Amazon convinced them that they must use DRM and as a result Amazon was able at the same time to lock in their customers and effectively corner the ebook market. That, in turn, means that the publishers pretty much have to meet Amazon’s terms. All because of their addiction to DRM.

Hoakley’s post, Publishers determined to kill electronic books, explores the publishers’ most recent chapter in their slow motion suicide. His post was inspired by the publishers’ latest Pyrrhic victory in Europe’s high court, the CJEU. The court ruled that, yes, it is a copyright violation to sell used ebooks. That, as hoakley says, is the publishers proving to their customers that their ebooks are worthless.

Judging from the comments to hoakley’s post, people are not amused. Almost all of them say that they routinely remove DRM from their ebooks to protect themselves from the publisher going out of business or deciding that they don’t want to maintain their authorization servers anymore. Some of them said that they won’t buy ebooks with DRM and that the problem would be solved if everyone followed suit.

Everyone will not follow suit, of course, and even if they did it’s not clear the publishers would care. I suspect that they would be happier if ebooks would just go away and they could get back to the way things have always been. The publishers’ rank and file apparently understand all this but the bean counters in charge simply can’t get over the notion that everybody would just steal their books if they weren’t protected with DRM. They don’t seem to know or care that everyone who would do that is already doing it by downloading a copy from which someone has removed the DRM. As usual, the honest people suffer while the dishonest are not deterred in the least.

Posted in General | Tagged , | Leave a comment

Emacs Modifier Keys on the Mac

If you’re an Emacs user who works primarily on some sort of Mac, you may be interested in a post by Nick Drozd in which he suggests a keyboard layout for avoiding pinky fatigue and all that goes with it. The TD;DR is that he switches the ⌘ Cmd and Ctrl keys in Emacs and then maps Caps Lock to Ctrl at the system level. That gives you a Ctrl and Meta key on both sides of the keyboard and they can both be reached with a thumb rather than a pinky finger. Drozd gives you the Emacs settings for switching Ctrl and ⌘ Cmd and, of course, you can map Caps Lock to Ctrl by clicking on the Modifier Keys button on the Keyboard pane of System Preferences→Keyboard. Drozd’s settings also map the fn key to Hyper. I’ve used that to give me a Hyper key for many years and really like it. It doesn’t interfere with the system function keys so you have the best of both worlds.

I haven’t tried this yet because I’m worried that it will mess up my muscle memory for the ⌘ Cmd key. It’s probably not a big deal so I’m still considering it. If you’re not worried about such things, give Drozd’s system a try. It’s easy to set up and easy to back out if you decide you don’t like it.

Posted in General | Tagged | Leave a comment

The Undo-tree Bugs

One of my favorite packages is undo-tree. It makes a “many branched” sequence of changes easy to fix but to tell the truth the most valuable thing about it for me is the sensible redo functionality. It’s always worked perfectly for me and is a valuable tool in my Emacs toolkit.

Oddly, though, I keep seeing tweets and blog posts about it being unreliable. Given my success with it, I didn’t pay too much attention to the reports of errors but did wonder if there was anything to them. Now the author, Toby Cubitt, has published a very informative post that addresses the purported errors and what’s really going on.

Cubitt’s problem is that he couldn’t reproduce the problems and no one could provide him with a recipe for reproducing them. There were two problems. The most common was that sometimes undo-tree would report that there were no further changes to undo even though all the changes to the buffer hadn’t been undone. Finally, someone was able to provide Cubitt with a recipe for reproducing the error and Cubitt found that there was no problem with the code—it was behaving exactly as documented—but that the real issue was “user expectations.” Emacs keeps the changes on an undo ring and when the entries are exhausted, the oldest entries are overwritten. Cubitt fixed this by increasing the default size of the ring (by a factor of 1,000) and by providing a bit more feedback to the user when data is lost.

The second problem is that occasionally the undo data would get corrupted. No one has yet been able to reproduce that error but Cubitt has an hypothesis that it’s caused by a race conditions between undo-tree and Emacs’ low level garbage collection code. He made a some changes to reduce the likelihood of this happening and made a new release.

Cubitt’s post has many more details and includes a nice explanation on how undo-tree works. If you’re an undo-tree user, it’s definitely worth reading. If you’re not an undo-tree user and have been hesitating because of its purported instability, there’s no longer any reason to hesitate. As far as I’m concerned, even if Cubitt hasn’t eradicated all of the bugs, undo-tree’s benefits are more than worth an occasional error.

Posted in General | Tagged | Leave a comment

Zamansky 63: ClojureScript

Mike Zamansky has another video up in his Using Emacs Series. This video is a little different from his usual fare in that it’s more about using ClojureScript than Emacs, although Emacs does play a prominent role.

If you follow Zamansky’s blog you know that he’s been learning and experimenting with Clojure and ClojureScript lately. This video is his effort the flatten the learning curve a bit for other n00bs by explaining some of the things he had trouble figuring out. I know nothing about ClojureScript so I can’t comment intelligently on the content of the video but I did find it interesting.

I don’t do much front end work either so I also don’t know a lot about writing HTML or generating Web pages. What I found especially interesting about the video was how easy it is to make, debug, and try experimental changes with ClojureScript. If I were going to start writing Web apps, I’m pretty sure I’d prefer learning and using ClojureScript over learning and using JavaScript. Using Cider means that once you’ve got everything installed, you can work entirely in Emacs. It’s a lot like using Slime except that your “output” is going to your browser, which updates in real time as you make changes. It looks like a very comfortable environment in which to do interactive programming.

Depending on feedback, Zamansky may do some more videos on ClojureScript so if you’re interested, be sure to let him know in the comments. The video is 33 minutes, 42 seconds so you’ll need to schedule some time.

Posted in General | Tagged | Leave a comment

Will Federally Financed Research Have to Be Open Access?

Will research that the U.S. Federal Government pays for have to be open access? Betteridge’s Law of Headlines says the answer must be “no” but there’s a rumor—just a rumor—that the White House is about to extend the Obama Administration’s rule that federally funded research must be freely available a year after publication to require that federally funded research be open access immediately.

Again, this is just a rumor but the publishers and—to their shame—many professional societies are losing their minds and demanding that the proposal be withdrawn. They’re forecasting all sorts of doom if the policy is implemented. About the only good thing you can say about their reactions is that at least they haven’t said, “Think of the children.” Of course, it’s still early days.

According to the Gizmodo story at the link, federally funding is responsible for 44% of basic research so there’s a lot at stake. My take is that if such a rule is mandated, it will force the publishers to adopt a new business model. The most common suggestion is that publishers get paid up front: the universities or other research organizations would pay to have the papers published and the publishers would make them immediately available.

That idea more or less preserves the current situation but is that a worthy goal? Is there really any reason we need to print and store paper copies of the research in our current digital world? If you accept that we don’t, then what, exactly, are the publishers contributing? Virtually all of their labor—editors, reviewers, and content providers—is from volunteers. They do have staff that (maybe) tweak the LaTeX input of the papers and they do provide the servers that house the digital copies but most of their employees are on the business end.

Universities pay truly staggering amounts for subscriptions to these journals (until they refused to renew their subscriptions, The University of California was paying Elsevier \$11 million a year). If every organization publishing research contributed a modest amount, they could easily provide the servers and staff to run them. Doubtless that’s a little over simplified but it does merit thought.

Posted in General | Tagged | Leave a comment

A Palindrome Predicate Coda

As I wrote yesterday, I upgraded my Common Lisp environment to SBCL 2.0 so of course I wanted to try it out. Writing Lisp programs in the excellent Slime environment that Emacs provides is truly a pleasure that I haven’t enjoyed nearly enough lately.

The natural thing to play around with is the palindrome predicates that I wrote about last month. That code was written in Scheme and produced some surprising results. If you read and enjoyed that post, be sure to check out the comments. Chris Wellons did a deep dive into what was going on in Guile that caused the surprising results. It’s definitely worth reading if only to appreciate Wellons’ virtuosity.

I rewrote the two predicates in Common Lisp and reran the benchmarks from the original post.

(defun palindrome-r-p (str)
  "Recursive version of a palindrome predicate."
  (let ((len (length str)))
    (cond
      ((zerop len) t)
      ((= len 1) t)
      ((not (eq (aref str 0) (aref str (1- len)))) nil)
      (t (palindrome-r-p (subseq str 1 (1- len)))))))

(defun palindrome-i-p (str)
  "Interative version of a palindrome predicate."
  (do ((left 0 (1+ left))
       (right (1- (length str)) (1- right))
       (palindromep t))
      ((or (>= left right) (not palindromep)) palindromep)
    (setf palindromep (eq (aref str left) (aref str right)))))

(defconstant str (make-string 100000 :initial-element #\x))

(defun bench (rcnt f)
  "Run f rcnt times with timing."
  (time
   (do ((i rcnt (1- i)))
       ((zerop i) t)
     (funcall f str))))

with the results

SB-SPROF> (bench 10 #'palindrome-i-p)
Evaluation took:
  0.006 seconds of real time
  0.006490 seconds of total run time (0.006487 user, 0.000003 system)
  100.00% CPU
  18,167,680 processor cycles
  0 bytes consed

T

  SB-SPROF> (bench 10 #'palindrome-r-p)
  Evaluation took:
    46.223 seconds of real time
    46.627848 seconds of total run time (44.819204 user, 1.808644 system)
    [ Run times consist of 14.377 seconds GC time, and 32.251 seconds non-GC time. ]
    100.88% CPU
    129,420,331,778 processor cycles
    99,994,412,160 bytes consed

  T

The timing for the recursive version shows why I ran the loop 10 times instead of 1000 as I did with Guile.

SBCL is an industrial strength Lisp that compiles to native code and has true tail recursion so if you haven’t read Wellons’ commentary to the original post, you might be surprised at the comparative speeds. The problem, of course, is that unlike Guile, Common Lisp always allocates a new sequence for a subsequence and never shares storage with the old sequence. The problem, then, is almost certainly that each (recursive) call to palindrome-r-p is allocating new storage and copying the substring into it.

Of course, one of our cardinal commandments is to avoid statements like the last and invoke the profiler:

CL-USER> (require :sb-sprof)
("SB-SPROF")
CL-USER> (in-package :sb-sprof)
#<PACKAGE "SB-SPROF">

SB-SPROF> (with-profiling (:reset t :sample-interval .00001) (palindrome-r-p str))
Profiler sample vector full (15,506 traces / approximately 499,999 samples), doubling the size
Profiler sample vector full (31,019 traces / approximately 999,997 samples), doubling the size
T
SB-SPROF> (report)

Number of samples:   50000
Sample interval:     0.00001 seconds
Total sampling time: 0.5 seconds
Number of cycles:    0
Sampled threads:
 #<SB-THREAD:THREAD "new-repl-thread" RUNNING {1002BC7883}>

           Self        Total        Cumul
  Nr  Count     %  Count     %  Count     %    Calls  Function
------------------------------------------------------------------------
   1  34735  69.5  34735  69.5  34735  69.5        -  SB-KERNEL:UB32-BASH-COPY
   2  14592  29.2  49975  99.9  49327  98.7        -  SB-KERNEL:VECTOR-SUBSEQ*
   3    647   1.3    647   1.3  49974  99.9        -  "foreign function __pthread_sigmask"
   4      9   0.0  49997 100.0  49983 100.0        -  PALINDROME-R-P
   5      6   0.0      6   0.0  49989 100.0        -  SB-KERNEL:HAIRY-DATA-VECTOR-REF/CHECK-BOUNDS
   6      1   0.0      1   0.0  49990 100.0        -  (SB-VM::OPTIMIZED-DATA-VECTOR-REF CHARACTER)
   7      1   0.0      1   0.0  49991 100.0        -  (FLET SB-THREAD::EXEC :IN SB-KERNEL::POST-GC)
   8      1   0.0      1   0.0  49992 100.0        -  "foreign function pthread_getspecific"
   9      0   0.0  50000 100.0  49992 100.0        -  "Unknown component: #x2276F230"
  10      0   0.0  50000 100.0  49992 100.0        -  SWANK::EVAL-REGION
  11      0   0.0  50000 100.0  49992 100.0        -  (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL)
  12      0   0.0  50000 100.0  49992 100.0        -  SWANK-REPL::TRACK-PACKAGE
  13      0   0.0  50000 100.0  49992 100.0        -  SWANK::CALL-WITH-RETRY-RESTART
  14      0   0.0  50000 100.0  49992 100.0        -  SWANK/SBCL::CALL-WITH-DEBOOTSTRAPPING
  15      0   0.0  50000 100.0  49992 100.0        -  SWANK::CALL-WITH-BUFFER-SYNTAX
  16      0   0.0  50000 100.0  49992 100.0        -  SWANK-REPL::REPL-EVAL
  17      0   0.0  50000 100.0  49992 100.0        -  SIMPLE-EVAL-IN-LEXENV
  18      0   0.0  50000 100.0  49992 100.0        -  EVAL
  19      0   0.0  50000 100.0  49992 100.0        -  SWANK:EVAL-FOR-EMACS
  20      0   0.0  50000 100.0  49992 100.0        -  SWANK::PROCESS-REQUESTS
  21      0   0.0  50000 100.0  49992 100.0        -  (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS)
  22      0   0.0  50000 100.0  49992 100.0        -  SWANK/SBCL::CALL-WITH-BREAK-HOOK
  23      0   0.0  50000 100.0  49992 100.0        -  (FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/jcs/quicklisp/dists/quicklisp/software/slime-v2.22/swank/sbcl.lisp")
  24      0   0.0  50000 100.0  49992 100.0        -  SWANK::CALL-WITH-BINDINGS
  25      0   0.0  50000 100.0  49992 100.0        -  SWANK::HANDLE-REQUESTS
  26      0   0.0  50000 100.0  49992 100.0        -  (FLET SB-UNIX::BODY :IN SB-THREAD::NEW-LISP-THREAD-TRAMPOLINE)
  27      0   0.0  50000 100.0  49992 100.0        -  (FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::NEW-LISP-THREAD-TRAMPOLINE)
  28      0   0.0  50000 100.0  49992 100.0        -  (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::NEW-LISP-THREAD-TRAMPOLINE)
  29      0   0.0  50000 100.0  49992 100.0        -  (FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-THREAD::CALL-WITH-MUTEX)
  30      0   0.0  50000 100.0  49992 100.0        -  SB-THREAD::CALL-WITH-MUTEX
  31      0   0.0  50000 100.0  49992 100.0        -  SB-THREAD::NEW-LISP-THREAD-TRAMPOLINE
  32      0   0.0  50000 100.0  49992 100.0        -  "foreign function call_into_lisp"
  33      0   0.0  50000 100.0  49992 100.0        -  "foreign function new_thread_trampoline"
  34      0   0.0    649   1.3  49992 100.0        -  "foreign function signal_emulation_wrapper"
  35      0   0.0      3   0.0  49992 100.0        -  "foreign function maybe_gc"
  36      0   0.0      3   0.0  49992 100.0        -  "foreign function interrupt_handle_pending"
------------------------------------------------------------------------
          8   0.0                                     elsewhere
#<CALL-GRAPH 50000 samples {1017C52A13}>

You can consult Section 16.2 of the SBCL manual for the details but what the profiling report says is that 99.9% of the time was spent in subseq and most of that was spent copying data.

The take away from all of this is that if you’re using Lisp and a frequently called function needs to take a substring, you might want to avoid subseq if you can. The other takeaway is that Guile’s implementation of substring with its copy-on-modify semantics is a real win.

Posted in General | Tagged , , , | Leave a comment

SBCL 2.0.0

Steel Bank Common Lisp has a new version out. I haven’t been writing much Common Lisp lately so I haven’t kept the software up to date. SBCL makes a new release every month and I always compile from source so it takes a tiny bit of effort to stay on the bleeding edge. Despite their aggressive release schedule, SBCL is very slow to make major releases so when I saw that they’d released SBCL 2.0.0, I knew it was time to upgrade. There’s been a bunch of optimizations, enhancements, and bug fixes so be sure to follow the link to see what’s new.

As usual, the compilation and exhaustive tests ran without any problems. I fired up a Slime session and played around with it a bit. I’d forgotten what a pleasurable experience SBCL/Slime/Emacs can be. You do everything from the comfort of Emacs but still have the power of an industrial strength Lisp environment at your fingertips. If you’re already an Emacser and would like to try out Common Lisp, this combination is ideal: it’s all free—as in beer and freedom—and easy to install. You can even get SBCL binaries if you don’t want to compile your own but except for Linux and Windows, the binaries are usually a few (monthly) releases behind so it pays to compile your own if you’re on a Mac or Unix system.

Posted in General | Tagged , , , | Leave a comment

Is Cash Still King?

As most of you know by now, I’m very interested in being able to pay for everything with my phone and not having to carry around credit cards, let alone cash. I’m also aware that not everyone shares that desire so I was interested in this Kontra tweet:

I was a bit surprised that cash appeared to remain so popular so I did a little digging. I read the actual Federal Reserve Bank of San Francisco report and, of course, it doesn’t support the “Cash Is King” conclusion drawn by the press.

The report is based on a 2017 survey of 2,848 “nationally representative” people. The first thing you notice is that the use of cash predominates only in the sense that it is used more often than any other single payment type. When you combine credit cards, debit cards, and electronic payments you see that while cash and checks represents 36% of payments, credit/debit cards and electronic payments represent 58% so payments are, in fact, mostly cashless. The results, as you’d expect, vary with age. Older people tend to use more cash, while the under 34 cohort uses the least.

The comments to the “Cash Is King” report mostly poke fun at the US for being so backward in their payment methods. People from all over the world chimed in to say that of course they use contactless payment methods and mostly don’t bother carrying cash. On the other hand, a reddit discussion of that report—mostly by Americans—say that they also use contactless payments for almost everything and most say they also don’t bother carrying cash except maybe for emergencies. Some commenters say that when they do use cash, it’s for amounts less than \$10 and then only because the store wouldn’t accept cards for amounts less than that.

I haven’t run across the “no credit cards for less than \$10” in some time and even when I did, it was almost always a Mom & Pop shop. The chains have long ago given up on minimum amounts for credit charges.

The TL;DR of this longish post is that Betteridge’s law holds in this case and we can answer the question in the title with, “No.”

Posted in General | Tagged | Leave a comment