tammy makes things

Welcome Back!

Welcome back to Tammy’s corner of the Internet. I’m currently respinning this site to be less blogging-focused and more project-focused, so expect blog posts to be infrequent. In the meantime, please use the links at the left side of the page to navigate what’s here.

Tammy's CircuitPython 2022 Thoughts

Over on the Adafruit Blog, there’s a call for thoughts about the state of CircuitPython, a recap of 2021, and our thoughts about 2022. Although my 2021 got sort of blown out of the water by the pandemic and my Major Health Crisis(tm), I’m renewing my focus for 2022. So although I’m not recapping the dumpster fire that was 2021 for me, I’ll share a few thoughts about the current state of play, what I’d like to see in 2022, and a few of the places I’m putting my focus. CircuitPython and Microcontrollers: Holy Cow To say that it’s an amazing and wondrous time to be a maker is, to put it mildly, a bit of an understatement. The variety of hardware that’s available, and what you can get compared to the cost, are staggering. Consider this: the Circuit Playground Bluefruit has about 30 times the processing power of my first home computer, includes a raft of sensors and connectivity, and costs $25 (about 1/65th of the price of that first computer). There are both cheaper and more capable micros out there than the Bluefruit, of course. In fact, the array of microcontrollers and sensors and other building blocks available today is staggering; sometimes it’s hard to know which one to use! I really think that CircuitPython has been, and continues to be, a game-changer for the hardware maker community. Python is accessible, well-documented and overall well supported, and I think writing code in Python and copying a script file to your device feels like a lower barrier to entry than the Arduino or FreeRTOS workflows. That flexibility and range of options is not without its attendant challenges, though. I find it’s sometimes hard to pick a board for my projects. Should I use a Circuit Playground? An ItsyBitsy? Which one? The SAMD? The nRF52840? Or maybe I should try the new hotness and use an RP2040.I guess having too many good choices to pick from is a good problem to have… Things I’d Like to Work On In 2022 Here in no particular order are some of the things I’d like to work on in 2022: CircuitPython Dependency Management Tools: CircUp helps a lot with keeping the libraries on my CircuitPython boards updated, but it’s less of a help for me in getting the right libraries installed in the first place. In a perfect world, my CircuitPython scripts could include metadata (“I’ll be running on a Circuit Playground Bluefruit and I need the following libraries”), and there’d be an automated way to install those things and their dependencies. Something like pyproject.toml but for CircuitPython. I started a hacky Python script to do some of this, and I’d like to see if I can refactor it into something that could be added to CircUp. Twitch Maker Streaming!: I love the fact that Twitch has grown so far beyond just video games. I follow a number of musicians on Twitch, as well as folks cooking, coding, doing magic…the list goes on. I’m planning to start streaming maker content on Twitch (hopefully by the end of February) with a focus on doing stuff with CircuitPython. My Twitch stream is aiming to be live by the end of February, so follow now if you’re interested. CircuitPython Hardware for Music: I’m really interested in exploring sound synthesis, MIDI, and the other musical capabilities of CircuitPython and microcontrollers. I’ve seen some cool projects out there already, but I’d like to explore what’s possible. CircuitPython for Magic: One of my friends, infoXczar, performs magic on Twitch. I’ve been brainstorming with him, and I think there are some cool opportunities at the intersection of magic, microcontroller technology, and devices that can communicate with the Internet. I’d like to explore that. Getting Better With displayio_: There’s a lot of documentation out there now, but I still feel like there’s room for some tutorials which draw all of them together. I don’t know if it’s documenting my own projects from thought process through execution, or if it’s a more focused beginner’s “here’s how to make sense of all these docs and get started” guide, but I’d like to figure that out. Contributing More to the Community: I’d like to make some contributions to the CircuitPython libraries this year. I’d also like to see if there are opportunities to contribute to the core of CircuitPython itself, since I’ve improved my C/C++ skills since the last time I looked at that. But whatever the details, part of the renewed focus on what matters to me is going to be finding ways to get a lot more active in the community. Design a CircuitPython Board: This one is a bit of a stretch goal, but I’m working on filling in gaps in my basic electronics knowledge (and updating what I do know for the new world we live in). I’d like to get better at PCB design and working with SMT parts, and one way I’d like to do that is to design a CircuitPython-compatible board and make at least one. It doesn’t have to be better than boards on the market, and it doesn’t have to be practical to manufacture in quantity, but I think designing and building a one-off board would be an interesting challenge and a good excuse to really learn KiCAD. So, there we have it! It’s an exciting time to be a part of the CircuitPython maker community, and I’m looking forward to getting more involved in 2022.

Yes, Yes, Another Reboot...

Yes, yes, I know…another year, another blog reboot. So, where have I been, and what’s been going on? Suffice it to say that 2021 was a wiiiiiiild ride for me. Aside from the continuing aftermath of the pandemic (which included a layoff from my employer of nearly seven years and starting a new job), 2021 included a rather serious health crisis. Or, as I like to put it, I survived an assassination attempt perpetrated against me by my body. You know those pharmaceutical ads that say ““rare but serious side effects have been reported””? I had one of those one-in-a-million rare side effects to a relatively widely used and generally safe medication, and it very nearly killed me. My Primary Care Provider’s first words when he saw the hospital records? “I’ll be really honest, I’m not sure how you were conscious to call 9-1-1. With these lab numbers, you should have been in a coma.” But, after three days in the ICU and six months of hard work, I’m happy to report that my health has stabilized. In fact, with regard to one of my chronic health conditions, I’m in a much better place now than I’ve been in years. And with the realization of just how very close I came to dying, I’m realigning my focus and priorities, and doing a lot of things I’ve been wanting to do for a long while. More making, more writing, more music. And yes, blogging again, hopefully on a more regular cadence. I have a bunch of other fun stuff planned for 2022, about which more to come. I’m also switching my blog engine again, from cryogen to Pelican. I’m doing a lot more Python stuff, both personally and professionally, these days, and it just seemed a better fit for my needs right now. There’s lots more to come, including migrating my old content to the new site and writing about some exciting new projects I’ve got going on. So stay tuned!

On New Years and New Beginnings

As you might have noticed, this blog has been quiet for a while. I had lots of good stuff happening last year, and lots of ideas planned. But then…well, life happened. The COVID-19 pandemic hit, I was laid of from my job (after nearly seven years), I started a new job, and things got busy. The new year has brought a little breathing room, and I’d started thinking about how to get going with the blog again. So it was very timely indeed that I read a blog post by Edidiong Asikpo, a developer and blogger from Nigeria, titled The Importance of Blogging as a Developer. It’s definitely worth a read, but it got me thinking about my own reasons why I wanted to blog, and why I want to resume the habit. Here are some of my reasons: It helps me hone my skills and develop new ones They say that one of the best ways to deeply learn a skill is to try to teach it to someone else. That’s why the mantra in medical school is “see one, do one, teach one”. I’ve found it takes solid mastery of a concept to be able to explain it in a clear, concise, coherent way. So, blogging about things I already know is a good way to strengthen and clarify my understanding in my own head. Blogging is also a good excuse to learn new things. If I have topics I’m interested in, the opportunity to blog about them is a great motivator for taking some time to dive in and learn about them. It’s a chance to give back and connect with the community Let’s face it: When I’m looking for the answer to a technical question, a good portion of the time, Google will surface a blog post someone has written about the topic. Writing my own blog is a chance to add my own knowledge, experience, and opinions to this vast global storehouse of knowledge. Writing a blog also gives me an excuse to read other tech blogs, connect with other tech people, and share/amplify other voices in the community. I enjoy writing and teaching There’s not a lot to say here. Like many techies (especially, I think, those on the autism and ADHD spectra) I’ve got a slightly repressed teacher inside of me. I think it comes from finally being in a place in my life where people want to hear about the nerdy things I’m interested in. So my blog – where I can write about whatever interests me, and there’s nobody telling me it’s boring or weird – is a space to let that side of me out. It’s a visible marketing tool To be clear, I’m not actively marketing anything in particular at the moment. I’m not job–hunting, and I’m not selling anything. But both of those things will likely change at some point in the future. Having a corpus of blog content that shows both who I am and how I think as a technologist, and how I communicate technical ideas, is a very handy and useful thing. All of which is a long way of saying that I’m back, and working to cultivate a regular cadence of blog posts in 2021. (I’m aiming for 1-2 posts per week, but we’ll see how that goes). My new job is as a Data Engineer for a health insurance company, so you’ll likely see more data-related stuff in the mix of posts, but I expect things to continue to be as varied as my personal and professional interests are. So, how about it? Bloggers, what are your reasons for blogging? Readers, what keeps you coming back? And what topics are you interested in hearing more (or less) about in 2021? Sound off in the comments!

Why Clojure?

This is going to be the first post in a series about Clojure and how to get started with it. In this post, I’ll talk about what Clojure is, why it’s interesting to learn, and how to get a Clojure environment set up on your system. In subsequent posts, I’ll dive into the basics of Clojure and give you some pointers for how to get started with it. What is Clojure? Clojure is a functional programming language suitable for general purpose programming tasks. It’s a dialect of Lisp which runs on top of the Java virtual machine. Clojure was developed by Rich Hickey in 2007, and is actively maintained by a community overseen by Rich. How and why did you learn about Clojure? I admit I’m a bit late to the Clojure party, relatively speaking. I first heard of Clojure while reading The Unicorn Project, a novel of DevOps and software development by Gene Kim. Maxine, the protagonist of the novel, is a fan of Clojure, and reading the novel convinced me to give it a look. Some of the things about Clojure that I found interesting included: Clojure is a language in the Lisp family. Although I’m not religious about my development tools, as I’ve mentioned before, I am a fan of Emacs, which I’ve used on and off since college. I think you can’t really use Emacs for very long without learning at least a bit of Emacs Lisp, so I was already familiar with Lisp languages. This does shorten the learning curve a bit. Clojure provides a REPL, and a lot of development happens there. I’ve long been a fan of languages with good REPLs, and the way they enable a sort of interactive, exploratory style of code development. And the REPL is pretty central to both the “how” and “why” of Clojure development. Clojure is cross-platform, and sits on top of the JVM. This gives it a lot of power and flexibility. There’s also a large and active community and ecosystem of Clojure add-ons and stuff. And the cross-platform, JVM-based environemnt makes getting an environment set up easy. Clojure is a functional programming language. There’s a lot of reasons why functional programming is a desirable thing, but as Maxine notes in The Unicorn Project, one of the most important is that data in Clojure is immutable. This prevents a lot of the bugs that come up in non-functional languages. My general agnosticism about tools means I don’t necessarily think Clojure is the tool for every problem, but I do think it’s a viable solution for a lot of stuff and therefore worth having in my toolbelt. Clojure has a browser-based scripting version. It’s called ClojureScript, and ClojureScript can be compiled to standard Javascript. This gives you a unified and coherent platform for client, server, and desktop development. Clojure is a new, fun thing that I didn’t already know. Hey, I’m a nerd and I have ADHD, so I’m susceptible to the “ooh, shiny” syndrome. What can I say? Getting Clojure set up on your system Luckily, getting a Clojure environment set up on your system is relatively easy, thanks to development environments like Leiningen. Here’s what you need to do to get Clojure running on your system: Install prerequisites. You’ll need to make sure you have a Java Virtual Machine on your system. JDK 8 or JDK 11 are the supported versions, and changes in later versions will produce random weird errors. I found that I needed to use one of the official Oracle builds because the OpenJDK version is missing some SSL certificates, and that breaks the downloading of Clojure extensions and libraries. Installing git and a good terminal program is also a good idea. (I’m using tilix on Linux. I suggest Windows Terminal on Windows, and iTerm2 on OS X.) Download and install Leiningen. This is super easy and mostly automated. The leiningen website has instructions. You’ll need to make sure the JDK tools are installed and in your path for this to work. Check that your setup is working. Run the command lein version. You should see a message like this: 1 Leiningen 2.9.3 on Java 1.8.0_251 Java HotSpot(TM) 64-Bit Server VM Set up your editor/IDE. I’ll talk about this in the next section, but using an editor with good Clojure integration is super important for a good development experience. Clojure editor/IDE integration As I mentioned above, one of the features of Clojure that makes developing with it so fun – and powerful – is that a lot of development is done in an exploratory fashion with the REPL. We’ll see this in subsequent installments of my tutorial. But what this means is that you want to configure your editor with good Clojure integration, including an integrated REPL. Here are some choices you can use: Emacs users should install CIDER. There’s some customization you might want to do, but the CIDER installation guide will get you going. Visual Studio Code users can pick from a few extensions, but the most well–integrated and easy-to-install choice I’ve found is Calva. vi/vim users might want to start here. You might also find tmux and tmuxinator to be helpful tools. Sublime Text users would do well to take a look at Greg Williams’s guide. Atom users might benefit from Jacek Schae’s guide. If you want a purpose–built IDE for Clojure development, take a look at JetBrains Cursive and Nightcode. I haven’t used either of these, but they seem to be highly regarded. If you use another editor or development tool, you’re on your own, I’m afraid. But you should look for something that lets you run Leiningen commands, has a built–in terminal or shell, and that has integration with the Clojure REPL. Some add-ons for Leiningen There are a couple of add-ons for Leiningen that I’ve found are super helpful from a development perspective: lein-cprint colorizes the output in the Leiningen REPL and makes it easier to read. debux gives you some easy trace-based debugging helpers. lein-autoreload automatically reloads the REPL when you make changes to your source files. rebel-readline adds command history and editing to the Clojure REPL. You can install these by creating a new file in $HOME/.lein/profiles.clj and adding the following to it: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 { :user { :plugins [ [cider/cider-nrepl "0.24.0"] [lein-cprint "1.3.3"] [philoskim/debux "0.6.5"] [lein-autoreload "0.1.1"] [com.jakemccrary/lein-test-refresh "0.24.1"] ] :dependencies [ [com.bhauman/rebel-readline "0.1.4"] ] :aliases { "rebl" ["trampoline" "run" "-m" "rebel-readline.main"] } } Once you’ve created this file, run the command lein deps to install all the bits and pieces. That’s it! You’re up and running. If you want to play a bit before my next tutorial, you can spin up a REPL with lein repl and try some of the examples from the Programming at the REPL guide.

The Fibonacci Sequence in Clojure

I was playing around this morning, and I decided to see what I could find about implementing the Fibonacci sequence in Clojure. For those unfamiliar with the Fibonacci sequence, which is named for a 13th-century Italian mathematician, it is a deceptively simple mathematical sequence where each term is constructed by the following rules: If n = 0, then fib(n) = 0 If n = 1, then fib(n) = 1 Otherwise, fib(n) = fib(n-1) + fib(n-2) Traditionally, fib(n) is constrained to the set of positive integers. This sequence doesn’t at first seem earth–shatteringly complex or interesting, but it turns out to describe all sorts of things in nature, such as the arrangement of leaves on stems, petals on flowers, and the family trees of bees. It also shows up in many other places in the fields of mathematics, computer science, and even music. Implementing the Fibonacci sequence in various programming languages is a common exercise. A common solution uses recursion. A simple recursive solution to calculate the Fibonacci sequence in Clojure might look like this: 1 2 3 4 5 6 7 8 9 10 (defn recursive-fibonacci "Recursive implementation of the Fibonacci sequence." [n] (cond (= n 0) 0 (= n 1) 1 :else (+ (recursive-fibonacci (- n 1)) (recursive-fibonacci (- n 2))))) (map recursive-fibonacci [0 1 2 3 4 5 6 7 8 9]) You might implement something like this and think your job is done. But the recursive solution has two big problems: It’s verrrry slow, and if you give it a very big value of n, the Java Virtual Machine in which your Clojure code is running will eventually run out of heap space and crash. So let’s look at a couple other ways we could solve this problem in Clojure. Tail Recursion Tail recursion allows the runtime to reuse memory locations for each subsequent call to our function. In Clojure, this is accomplished by the recur form, which might look like this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (defn tail-recursive-fibonacci "Tail-recursive version of the fibonacci sequence." [n] (if (> n 1) (loop [x 1 fib0 0 fib1 1] (if (< x n) (recur (inc x) fib1 (+ fib0 fib1)) fib1)) n)) (map tail-recursive-fibonacci [0 1 2 3 4 5 6 7 8 9]) What’s happening here? The recur form in Clojure implements tail recursion. So, let’s look at what happens if we invoke (tail-recursive-fibonacci 6): On entry, n=6 (so we do the looping thing instead of just returning n) Now we go through the loop: x = 1, fib0 = 0, fib1 = 1 x = 2, fib0 = 1, fib1 = 1 x = 3, fib0 = 1, fib1 = 2 x = 4, fib0 = 2, fib1 = 3 x = 5, fib0 = 3, fib1 = 5 x = 6, fib0 = 5, fib1 = 8 We’ve got our answer, (tail-recursive-fibonacci 6) = 8. This is more memory-efficient and won’t crash if you give it a bigger number for n, but let’s look at a couple of more idiomatic ways to solve the problem. Using lazy-seq A lazy sequence essentially creates an iterable sequence whose values are calculated as needed and then cached. This is more efficient than a recursive function, and also runs faster. We can create a lazy sequence using the lazy-seq form. The lazy sequence version of the Fibonacci sequence looks like this: 1 2 3 4 5 6 7 (def lazy-sequence-fibonacci "Create a lazy sequence version of the Fibonacci sequence." ( (fn fib [a b] (lazy-seq (cons a (fib b (+ a b))))) 0 1)) (take 10 lazy-sequence-fibonacci) Something to notice here is that we’re using def instead of defn. This is because we’re not creating a function; rather, we’re creating a sequence that provides the next element each time we access it. (That’s also why I’ve switched my sample invocations from here out to use take instead of map - ClojureScript was giving me errors in the browser. I guess you can’t take something that’s not “seqable” in ClojureScript.) Looping with lazy-cat Clojure also provides the lazy-cat form, which is a shortcut that essentially does a concat inside of a lazy-seq to collect our results. Here’s what the Fibonacci sequence looks like with lazy-cat: 1 2 3 4 5 (def lazy-cat-fibonacci (lazy-cat [0 1] (map + (rest lazy-cat-fibonacci) lazy-cat-fibonacci))) (take 10 lazy-cat-fibonacci) Looping with iterate One more example. This one uses the iterate form. iterate takes a sequence, and on each iteration it returns the next value from the sequence and also a closure that will return the next element. It looks like this: 1 2 3 4 (def seq-iterate-fibonacci (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))) (take 10 seq-iterate-fibonacci) Comparing Performance To be honest, I’m new enough to Clojure that I’m not sure I totally understand the relative advantages and disadvantages of lazy-seq, lazy-cat and iterate, and why you’d use one versus the others. (I’m going to try to work it out, and then I’ll do another blog post!) But I did time the execution speed of these various methods, collecting the first 80 Fibonacci numbers from each. Here’s what I got running my test code in the REPL: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Clojure 1.10.1 user=> (load-file "fib.clj") *********************************************************************** * Fibonacci Sequence - Clojure Implementation Tester * *********************************************************************** => recursive fibonacci - 50 repetitions: "Elapsed time: 0.036135 msecs" => tail recursive fibonacci - 50 repetitions: "Elapsed time: 0.004389 msecs" => lazy-seq fibonacci - 50 repetitions: "Elapsed time: 0.004584 msecs" => lazy-cat fibonacci - 50 repetitions: "Elapsed time: 0.003567 msecs" => iterate fibonacci - 50 repetitions: "Elapsed time: 0.004653 msecs" true user=> There wasn’t a lot of performance variation in my tests, except that the recursive implementation was consistently a LOT slower (913% slower, in this test run.) Even if I don’t yet understand the reasons for picking between these various ways of solving the same problem, I do have a better understanding of the tools at my disposal.

A Simple Portable Prototyping Station

On Twitter recently, I posted some photos of a little portable prototyping station I threw together. Henry Moore asked for some details and a parts list, so I thought I’d throw together a quick blog post about it. Design Goals My goals for designing this little prototyping station were: I wanted something that could be relatively portable, so I could take it into my living room or otherwise away from my worktable. I wanted something tailored to the kinds of stuff I build. I wanted lots of prototyping space (I’m currently working through the book The Art of Electronics and doing some of the experiments. As much as possible, I wanted something I could build with parts I already had on hand. This forced some of my component choices in ways you might not experience if you’re buying new stuff. With that in mind, here’s what I came up with: Pretty handy, huh? Let’s talk a bit about what’s onboard. The Hardware The base of the protoboard was something I found on Amazon (linked in the parts list below). I could have easily designed something custom fit and 3-D printed it, but I was going for speed here and my Fusion 360 and OpenSCAD skills would have made that take longer than I’d have liked. Microcontroller In the upper left area is a microcontroller, since I do lots of stuff with microcontrollers. (Really, who doesn’t, anymore?) I threw an Adafruit Metro M4 Express into this spot because I had it handy and it’s powerful enough to handle most all of the things I want to prototype. Like everything else on the prototyping station, it’s held on with foam double-sided tape, so I can easily swap it out for something else if I want to later. Power Distribution The next area of the board is my power distribution block. I had a tiny little breadboard lying around, so I ran a bunch of stuff over to it: The 3.3VDC and 5VDC outputs from the Metro M4 Express; The 3.3VDC output from the I2C/SPI interface (see below); 4.5V DC from an Adafruit AA Battery holder (connected to the board with a JST breadboard adapter); Enough extra space to jumper in the output from my benchtop adjustable power supply. This way I can jumper whatever power I want into the breadboard’s power buses, depending on what I’m working on and what’s available. (If I’m not connected to USB, the Metro M4 and the I2C interface aren’t providing power, obviously.) I2C/SPI Interface Next up is my I2C/SPI interface, so I can test sensor-based stuff and whatnot easily. I used an Adafruit FT232Hhere because it was what I had handy, but an Excamera I2Cmini or any other similar device would work here too. Again, I jumpered the power outputs of this over to the power distribution block so I could use them if wanted. Prototyping Area And lastly, the breadboards for prototyping space. Again, I used what I had handy. To simplify the connections between the prototyping area and the power distribution block, I’ve jumpered the positive and negative rails at the top of the breadboards together. I’ve left the bottom rails un-jumpered and unconnected to the top ones, because sometimes I run the I2C signals (SDA and SCL) or SPI signals (MISO and MOSI) along here. Ideas For the Future It might be nice to custom design and print a base that fits and has better mounting for all the components. Everything here is held on with double-sided tape, but designing something with the right screw holes would be nicer aesthetically. Something else I’d probably do if I respin this is to create some more space for more breadboards. Some is good, more is better, right? Finally, I’d like to include a couple of other things – a function generator, a small 3.3V and 5V regulated power supply, a LiPo battery and charger. None of these is essential, but they’d be useful add-ons. But then, at that point I’m basically redesigning the old Heathkit ET-3100 and it might just be easier to buy one of those and add microcontrollers. So there you have it - my quick-and-dirty portable prototyping station. If you build your own version, let me know! I’d love to see what you come up with. Parts List Base board. I used this one from Amazon, but you have lots of options here. Solderless breadboards. I used two of something like these and two of something like these. Microcontroller. Mine was the Adafruit Metro M4 Express. (I’ve linked to the current board, but mine is older and doesn’t include WiFi.) I2C/SPI Interface. I used the Adafruit FT232H Breakout. Battery Holder. I used this one, which also required a JST breadboard adapter. Double-sided tape. I used Scotch foam mounting tape and stacked up multiple layers of tape as needed to make everything fit.

Literate Emacs Configuration in org-mode

If you use emacs at all, you’ll quickly discover that it’s much more than just a text editor. Emacs is a software development platform, too, and as such it’s nearly endlessly customizable. One result of this extensibility is that, if you use emacs very much, your customization file (named .emacs.d/init.el) tends to grow and quickly becomes hard to manage. Enter org-mode. Originally begun as an outlining tool, org-mode has acquired a ton of additional functionality, including the capability for literate programming. In a nutshell, literate programming allows you to combine code and documentation into a single file. With emacs and org-mode, you can combine snippets of code and documentation into a single .org file, and then tangle that file to produce the code which emacs actually runs and documentation (in HTML, LaTeX, or other formats). You can see my emacs configuration on github. My emacs configuration is located in the file init.org. You can look at that file if you want details, but what I’d like to show you here is a step-by-step guide to creating your own emacs configuration with org-mode, including automatically tangling your init.org file when it’s modified. Ready? Let’s go! Install Emacs. Instructions for various platforms are here. As of 04/2020, you should install Emacs 26. A version of org-mode is bundled with Emacs, so no installation is needed there. If you have an existing .emacs.d directory, rename it and create an empty one. This directory should live in your home directory (on Linux and MacOS X systems). On Windows systems, consult this guide to work out where your home directory lives. Inside the .emacs.d directory, create a file named init.el. Paste in the following code to that file: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This file replaces itself with the actual configuration at first run. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; We can't tangle without org! (require 'org) (defvar user/init-org-file (concat user-emacs-directory "init.org")) (defvar user/init-el-file (concat user-emacs-directory "init.el")) (find-file user/init-org-file) (org-babel-tangle) (load-file user/init-el-file) (byte-compile-file user/init-el-file) This “seed” init file will cause emacs to load the init.org file, “tangle” it to produce a new init.el and byte-compile the new init.el file for faster execution. Also inside the .emacs.d directory, create a new file called init.org. This file will contain all your emacs customizations and documentation. Inside your init.org you can put as much documentation as you want (following the org-mode markup syntax. You can also put Emacs Lisp code blocks, which will be extracted into the init.el file when your init.org is tangled. Each code block should begin with a line like this: 1 #+begin_src emacs-lisp And end with a line like this: 1 #+end_src These markers tell Emacs and org-mode how to extract the code. I’ll talk about what should go into this file in a moment. Copy init.el to init.el.firstrun. This step is optional, but since tangling the org file overwrites the seed init.el I like to keep a copy around. Check your .emacs.d into source code control. If you’re using git, you’ll want to do something like this after you’ve created your repo and checked in your init.org and init.el files, since the contents of init.el are automatically overwritten: 1 git update-index --assume-unchanged init.el Once you’ve created your init.org file, launch Emacs. Emacs will read your init.org, tangle it and create a new init.el (replacing the seed created in step 3), compile it to init.elc and then load it. After this initial compliation, I find it’s a good idea to exit and restart emacs. So, what goes in your init.org file? I like to start with the following, in order: An emacs mode-line and header block for the org file. This tells Emacs what kind of file it is, and includes some org-mode options useful if you decide to typeset your configuration with LaTeX. The first few lines of my init.org look like this: -*- mode: org; fill-column: 78; -*- #+TITLE: Emacs configuration file #+AUTHOR: Tammy Cravit #+DATE: Time-stamp: <2020-04-05 10:08:30 tammy> #+BABEL: :cache yes #+LATEX_HEADER: \usepackage{parskip} #+LATEX_HEADER: \usepackage{inconsolata} #+LATEX_HEADER: \usepackage[utf8]{inputenc} #+PROPERTY: header-args :tangle init.el If you do plan on using LaTeX to typeset your documentation, you should also install the Inconsolata font. The auto-tangling code. This bit of Emacs lisp magic – which is included into your init.el file and thereby automatically loaded – tells Emacs to automatically tangle init.org and produce a new init.el file every time the init.org file is saved. #+begin_src emacs-lisp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Automatically tangle init.org on save to produce init.el ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar user/init-org-file (concat user-emacs-directory "init.org")) (defvar user/init-el-file (concat user-emacs-directory "init.el")) (defun tangle-init () "If the current buffer is 'init.org' the code-blocks are tangled, and the tangled file is compiled." (when (equal (buffer-file-name) (expand-file-name user/init-org-file )) ;; Avoid running hooks when tangling. (let ((prog-mode-hook nil)) (org-babel-tangle) (byte-compile-file user/init-el-file)))) (add-hook 'after-save-hook 'tangle-init) #+end_src The rest of your Emacs configuration. I like to structure this part of the file with headings for each functional area, and to intersperse descriptions of each customization or group of customizations in with the code blocks. Here’s an example of a bit of the UI customization from my init.org: *** UI Customizations Show the full path in the title bar. #+begin_src emacs-lisp (setq-default frame-title-format "%b (%f)") #+end_src Disable the font popup menu. #+begin_src emacs-lisp (global-set-key (kbd "s-t") '(lambda () (interactive))) #+end_src ***** Frame Size/Position Set the initial window size and position if we're running in a GUI. If we only have one monitor (like on an undocked laptop) we'll start the window maximized. #+begin_src emacs-lisp (if window-system (progn (if (eq tlc/number-of-displays 1) ;; One monitor - make the window shorter and mazimize it (setq initial-frame-alist '((top . 5) (left . 5) (width . 132) (height . 28) (fullscreen . maximized))) ;; Multiple monitors - taller window, not maximized (setq initial-frame-alist '((top . 15) (left . 15) (width . 132) (height . 38)))) (setq default-frame-alist initial-frame-alist))) #+end_src As you can see, the code and documentation can be fluidly and easily mixed, and documented code listings can be easily produced. This is the primary payoff of going to all this trouble. I won’t talk about what specifically you should put into your init.org. Everyone sets up Emacs differently for their needs and preferences. The Emacs Wiki has links to some good examples. You can also look at my configuration for inspiration. But again, remember that my needs and preferences might not match yours! One more quick tip: If you want a specific block of code in your init.org file to be written to a file other than init.org (for example, if you want to create specific configurations for specific systems you use), you can include :tangle filename.el at the end of a #+begin_src line. So in my init.org, I have code like the following: *** Load OS-specific files This defines a system-specific file by OS type (Windows, Mac, etc.) so specific settings can be overridden. #+begin_src emacs-lisp (let ((system-file (concat user-emacs-directory "settings-os-" (subst-char-in-string ?/ ?- (symbol-name system-type)) ".el"))) (if (file-exists-p system-file) (load-file system-file))) #+end_src ***** System-Specific FIle - Linux #+begin_src emacs-lisp :tangle settings-os-gnu-linux.el ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; OS-specific settings - Linux ;; Tangled from init.org - do not modify directly ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (do-some-customization) (provide 'settings-os-gnu-linux) #+end_src ***** System-Specific File - Windows #+begin_src emacs-lisp :tangle settings-os-windows-nt.el ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; OS-specific settings - Windows ;; Tangled from init.org - do not modify directly ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (provide 'settings-os-windows-nt) #+end_src If you have some code in your init.org that you want to keep but that you don’t want to output to your init.el (for example, if you want to temporarily disable a customization but you don’t want to throw it away), you can write this: #+begin_src emacs-lisp :tangle no ;; This code will not get written to your init.el file. (do-stuff) #end_src So there you have it! I know there’s some initial overhead in getting this set up, but I find that being able to comprehensively document my code (with formatting and hyperlinks and stuff) makes it MUCH easier to understand later. And this capability isn’t limited to just your Emacs configuration - you can write code in many languages and tangle out your source files and documentation automatically! The org-mode manual has lots more information about how this works.

Everything Old Is New Again

I’ve been doing some retooling of my blog (while I’ve been on furlough from my day job because of COVID-19). I’m now using cryogen, a Clojure-based static site generator, rather than the Python-based Pelican(site generator that previously powered it. I’ll be honest – the switch was more motivated by my desire to learn Clojure than by any limitation or dislike of Pelican. And, predictably (because, after all, it’s me we’re talking about), I’ve spent the past couple of days hacking on the cryogen code to make it work the way I want to. I can now run the command lein new-post in my blog tree to make a new post (and be prompted for some parameters), for example. Like I said, my hacking was about 3% motivated by workflow and 97% by the desire to learn some Clojure. But along the way, I started thinking about how the pendulum swings in technology, and how everything old is new again. It’s a fascinating pattern, and I’ve been in the tech world long enough to see it play out over and over again. Some examples: The Cloud. When I first started having access to “real computers” in college, the holy grail were big mainframes that we accessed using PCs or relatively “dumb” terminals. I remember the thrill of having accounts on my university’s big server systems, such as an IBM 3090, a VAX and a big Sun Microsystems SPARCCenter 2000. Then we spent a couple of decades on the whole client/server model of putting all the computing power in PCs. And now the pendulum is swinging, back toward big servers in “the cloud” – really, just a fancy word for “other people’s computers” – accessed from our less powerful and less scalable local systems. I’m actually writing this post from my iPad, connected to my cloud (Linux) server through an ssh/mosh connection. Object-Oriented Programming. Back in the old days, programming languages were “procedural”. You wrote routines and strung them together to make programs. Languages like COBOL, FORTRAN, and C dominated. Then we discovered the idea of object-oriented programming — modeling the real world in our programs, creating virtual “objects” that had properties and actions associated with them. This was good in many ways, and we soon had new languages such as Ruby and Python, and variants of old ones, like C++ and Objective-C and even Object Cobol. And while it was true that these new ways of thinking about programming enabled us to do all sorts of new and wonderful things, they were also not without their downsides. Now functional programming is a hot topic again, with new languages like Erlang and OCaml joining old standards again. (Clojure is a dialect of Lisp, which has been around since 1958!) Artificial Intelligence. Broadly, this term has swept up a lot of stuff involving making computers “smarter”. AIhas undergone waves of popularity followed by disappointment since the discipline was first started in the 1950s. Neural networks, which attempted to simulate the behavior of the brain’s individual neurons, were at the heart of one such wave. Rule-based expert systems were another. Now we have machine learning as the wave of the future, with all sorts of tech lumped in under that umbrella. In thinking about these cycles, and in making this (non-exhaustive) list, I think there are a few common threads that drive the pendulum swings: Technologist and computer people think about problems in need of solutions. Procedural programming had challenges, so we came up with new paradigms and ways of architecting technology. But of course, those will have challenges too, because they were designed by humans. So we try to solve this problems, and along the way create yet more new problems (or sometimes re-create older ones). Technology people tend to be susceptible to the “ooh, shiny!” phenomenon. We discover the cool, trendy, hip new thing and everyone jumps on the bandwagon. And then, a few years later, the next new shiny thing comes along, and the older stuff gets abandoned. I think Classic ASP and PHP are good examples here. We tech people sometimes seek to solve “problems” without fully understanding why the thing creating the problem works the way it does. The proliferation of NoSQL databases is a good example. There are good reasons why a document-oriented database like MongoDB or a key-value database such as Riak can and should be used. But if you try to build an e-commerce application solely on MongoDB, you’ll quickly discover that order processing in a database environment with the property of eventual consistency can get you into trouble if you’re not careful. That’s not to say we should stop innovating, of course. We do tend to come up with new solutions to problems, and in a lot of ways that’s brought about a wonderful world of more and more powerful, capable, and usable technology. Consider the Cray-2 supercomputer of the mid-1980s. It took up a large room, cost millions of dollars to buy and operate, and required special liquid coolant to run without melting into slag. It was also less powerful than my iPhone XS, which cost less than $1,000 and fits in my pocket. Decades of innovation allowed us to miniaturize that amount of computing power, and we can do amazing and positive things because of it. What we should do, then, is simple: Create the new tools, but don’t forget about the old ones either. And when we’re building something, pick the right tool for the job. You can drive a nail with the side of a chainsaw, and if you hit a tree with a hammer enough times you might be able to make it fall over. But are those really the right tools for the job? Just because you have a shiny new hammer, that doesn’t make every problem a nail. The other thing, which I alluded to in a previous post, is simply this: Don’t make the mistake of getting religious about your tools. Right now I’m learning and using Clojure, and I’m finding it works well for the kinds of programs I like to write and the way I work. Does that mean everyone should drop C# and Python and Ruby and switch to it? For that matter, does that mean I will stop using other languages and tools? Of course not. Right now, I’m doing a lot of my programming in Emacs, especially since it has good tools for Clojure programming. Does that mean I’m uninstalling VSCode and PyCharm? Nope. It’s an and, not an or. Pick the tools that make you productive, but don’t assume everyone else should pick the same tools as you. Horses for courses and all that. The pendulum swings back and forth on a lot of these issues, but one thing is certain. Each swing of the pendulum brings new tools, new capabilities, new solutions, new possibilities. A large part of why I enjoy the new tech so much is because I appreciate the foundation it’s built on. So really, the pendulum doesn’t arc back and forth so much as it traces an ever-rising spiral. And that’s what makes technology so exciting!

Of Emacs and Tools

For those who aren’t familiar,Emacs is a text eeditor - and much more. First created in 1976, Emacs is built - and extensible - in the Lisp programming language. And this gives it an enormous amount of power. People have extended Emacs to include e-mail and newsgroup functionality, full-featured IDEs for programming, even an outlining solution that’s become a life organizer and document publishing tool. I’ve been using Emacs on-and-off for decades, and I’ve recently been getting org-mode set up for both organizing my life and for some writing projects. I’ll be blogging more about that, but that’s not what I want to talk about today. Today my thoughts are about the tools we use — hardware, software, and otherwise — and about tool wars. a When I was in college (more years ago than I care to admit) Linux was in its infancy. Home computers were just starting to join the Internet, and a lot of us that used Unix-based computers did so through a command–line interface and a dial-up terminal program. Back then, which text editor you used — Emacs or vi — was a topic of debate, argument, and sometimes holy war. Though the tech landscape has changed enormously since then, one of the continuing dynamics I still see is people arguing fervently online about which tool is “the best”. Python vs. Ruby vs. CLojure vs. whatever other programming language. Arduino vs. CircuitPython vs. C/C++. The best USB soldering iron. The right soldering station. The perfect 3-D printer and the One True slicing and modeling choices. But I think these arguments all miss the point. Frankly, I don’t believe there’s One True Choice for any tool. I keep coming back to Emacs because I’ve been using it for nearly 30 years. For me, it’s comfortable, like a well-worn pair of jeans. That doesn’t mean I use it exclusively – I’m fairly comfortable with vi and TextMate and SublimeText too. I think VSCode is fantastic and use it regularly. 3-D modeling software? I have FreeCAD and OpenSCAD and Fusion 360 and use them all. In short, I’m a big fan of picking the right tool for the job and the user. What does that look like? For me, the right tool is: The tool that has the capability to do what you need it to. Ideally without requiring you to use it in ways it wasn’t well designed for. You can pound a nail with the side of a chainsaw (but you might break the chainsaw). You can make a tree fall down if you hit it with a hammer enough times. That doesn’t mean those are the right tools for those jobs. This is why my grandfather had so many different hammers and saws in his workshop – he was a big fan of having exactly the right tool for each job. The tool that gets out of your way. This doesn’t mean it necessarily just works out of the box. I’ve done a lot of tweaking and coding to make Emacs work the way I want it to. But when I’m in the groove, writing a blog post or hacking on code or capturing notes from a meeting? In those moments I don’t want to have to think about the tool. I just want it to enable me to do what I need to. The tool that you feel comfortable with. This is the big one. I remember being in my Grandpa’s workshop with him as a small child. He was working on something and had a large, heavy hammer out. One I could barely lift. So he had a smaller, lighter hammer in the shop too. That was my hammer, and when I wanted to build something he’d bring it out. He never argued that his hammer was the One True Hammer, that I should just suck it up and use that one. The right tool for me wasn’t the right tool for him – and that’s okay. That’s why there are many different tools. As I said, I’m going to be doing some blogging about Emacs in amidst my other writings. If you use Emacs, hopefully they’ll be of interest. But if not, if you use other tools you’re happy with? That’s totally fine. Tools are the means to an end, not the end in and of itself. (At least, not unless tool-building is the end you’re working toward). Use what enables you to get the thing done. At the end of the day, that is the true bottom line.