2022-01 Austin Emacs Meetup

Last week there was another meeting of EmacsATX, the Austin Emacs Meetup.

I discovered that the two most recent write-ups were included in Sacha Chua’s Emacs news roundup. I guess that makes me the unofficial scribe.

If you have read any of these recent write-ups, you will not be surprised to read there was no set agenda. Do not make this a drinking game. However, The Organizer [Note 1] did ask for topics at the beginning rather than at the end.

Member #1 [Note 2] spoke about sockets and domain sockets for about ten minutes. When we decided to start talking about Emacs, there was some silence.

Member #2 started talking about projects in Doom Emacs. Their Org file had different level in different font sizes. Their Emacs terminal looked like a tag cloud. I do not know much about projects in Emacs. I will add that to my ever-growing to-do list in my ever-growing Org file. I have worked with projects before (Maven, Gradle, Rails, etc), but I am just not sure what Emacs has to offer. Perhaps there is an EmacsConf video that talks about projects. I just started going through the EmacsConf videos; I am on the third for 2013.

Member #2 also talked about circadian. It is a mode that changes your theme based on the time of day.

Members #2 and #3 started talking about themes. Both of them worked on themes. Member #3 pointed out that many themes do things differently, and if you switch themes that some of the attributes of the first theme are still in the system. Perhaps something could be done about the process of making themes.

Lastly people started comparing Clojure to Emacs Lisp. The consensus was most people liked Clojure better, mostly due to its data structures and destructuring abilities. The Organizer implemented the Clojure comment macro in Emacs Lisp.

You’re welcome.

Note 1: “The Organizer” does sound like it could be a cool nickname if you know how to work it. “I am here to kick ass and run through our agenda, and as usual we don’t have an agenda.”

Note 2: I give people numbers since I do not know if they want their names in this write-up. Think of it as the stoner’s version of the Chatham House Rule. I figured that numbers are a little clearer than “someone said this, and someone else said that, and a third person said something else”. For the record, there were about seven people there.

Image from Gospels Codex 56, a 9th century manuscript of the  Archbishop’s Diocesan and Cathedral Library in Cologne, Germany, assumed allowed under Public Domain.

Climbing Mount SICP

I have decided to focus more on Clojure, and start working on How To Design Programs (aka “HtDP”), and then onto Structure and Interpretation of Computer Programs (aka “SICP”). HtDP is written by the founders of the Racket project, and SICP uses Scheme (one of the authors, Gerald Sussman, invented Scheme along with Guy L. Steele; I think Scheme was Steele’s PhD thesis).

I looked one last time into The Reasoned Schemer. I changed to a different KanRen library. More of the examples worked, but this book is really not coming together for me as quickly as the other ones did. I think I will put aside the “Little” books, at least for the time being. I think it might be time to get ready to climb Mount SICP.

Many people have said that SICP is a good way to “level up” (as the gamer kids put it). Many people have said it gave them something like the famous “Lisp enlightenment”, that it altered their perception of how to make software and made them better. As the Teach Yourself CS site put it: Because SICP is unique in its ability—at least potentially—to alter your fundamental beliefs about computers and programming. Not everybody will experience this. Some will hate the book, others won’t get past the first few pages. But the potential reward makes it worth trying.

SICP is an introductory CS text used at MIT. The general consensus is that you will get more out of it if you have been in software development for a few years. It is a bit much for most people right off the bat. I have been through Simply Scheme, which states in the last chapter that it is intended to prepare you for SICP. HtDP was made as an alternative to SICP; the authors felt that SICP requires a lot of higher math, and if they made a less math-heavy alternative they could introduce more people to CS and help them become better programmers.

One of the authors of Simply Scheme wrote an essay entitled “Why Structure and Interpretation of Computer Programs matters”. He states that unlike other introductory textbooks, SICP does not spend a lot of time on the syntax of a specific language, but instead teaches broader concepts. Someone at the local Clojure meetup once said to me that if you can work through the problems in SICP, “you can solve any problem with parentheses”. In other words, you learn how to design programs.

A few years back, MIT (and a few other schools using SICP) replaced Scheme and SICP with other texts that use Python. Sussman said there were a few reasons for this. One is that he and Harold Abelson (one of the other co-authors of SICP) were tired of teaching the course after more than 15 or so years. Another reason is that SICP was designed for programmers who would make systems from the ground of using smaller components. Now a lot of programming is just linking or wiring together components that are black boxes. Sussman called it “programming by poking”. You could contrast this with the SICP style of “analysis-by-synthesis”. The site Lambda The Ultimate has a post with a link to a now-extinct blog post, but there is a quote that summarizes the ideas nicely. There is also a link to a thread on Hacker News. This have come up several times on Hacker News and Reddit.

There is a section in the preface to Simply Scheme that covers this:

There are two schools of thought about teaching computer science. We might caricature the two views this way:

  • The conservative view: Computer programs have become too large and complex to encompass in a human mind. Therefore, the job of computer science education is to teach people how to discipline their work in such a way that 500 mediocre programmers can join together and produce a program that correctly meets its specification.
  • The radical view: Computer programs have become too large and complex to encompass in a human mind. Therefore, the job of computer science education is to teach people how to expand their minds so that the programs can fit, by learning to think in a vocabulary of larger, more powerful, more flexible ideas than the obvious ones. Each unit of programming thought must have a big payoff in the capabilities of the program.

(I think you could also call these the “business mindset”, and the “engineering mindset”: Do things in a way that the suits think they understand, or actually knowing what you are doing.)

Per a comment on the Lambda The Ultimate post, one of the authors of HtDP said that other departments sent students to their CS intro course to learn how to think. That is where I want to go. I feel that “programming by poking” is what I have been doing. I feel like I should be better at this than I am, and that there has to be a better way of doing things. Where “progress” isn’t just learning yet another vendor’s product.

Why not level up? Why settle for poor understanding? As one of the commenters on Hacker News put it: What about the people who make the black boxes? How do you know they know what they are doing? If you could learn to solve any problem with parentheses, why wouldn’t you?

The obligatory links (I have not gone through most of these):

You’re welcome.

Image from “Evangelia quattuor, pars”, an 11th century manuscript housed at the Bibliothèque nationale de France. Source gallica.bnf.fr / BnF; image assumed allowed under Public Domain.

2021-12 Emacs Meetup and Other Thoughts

It is time for another update on Austin Emacs, along with some observations.

There was a meeting of the Austin Emacs Meetup early in the month. As always, there was no set topic.

There was some discussion of the Emacs Docs website. Generally the feedback was positive.

One guy started demonstrating Org Roam. It looks pretty interesting, but for now I am still getting the hang of plain Org. He also showed us a couple of packages: gh-notify for managing GitHub notifications (I have no idea if it works with git outside of GitHub) and code-review.

There was also a lot of discussion around zettelkasten. Here is the Wikipedia page. Here is a site telling you how to do it; it’s hosted in Germany, so I guess it’s the official zettlekasten site. Zettlekasten.org is a site by a group that tried to put a knowledge management system on the blockchain. It does not look like there has been any activity for a while. Perhaps you can use your coins to buy a non-fungible Olive Garden.

I mentioned again I plan on going through the EmacsConf videos from prior years, as well as for 2021. None of us had started looking at the 2021 videos. Some of them look interesting. I mentioned that there were two that I thought I would not find interesting: The use of Org mode syntax outside of GNU/Emacs by Karl Voit, who has a few good pages/posts about Emacs and Org on his site, and Extending the “model” of Emacs to other applications. An Emacs conference discouraging the use of Emacs seems a bit odd. I will give them all a chance, but on the surface I don’t think I will like those two.

Every time there is a thread about Org mode on Hacker News, there is always some jackass complaining that Org does not work on mobile. Frankly, I have little interest in mobile. I like the bigger keyboard and bigger screen on my laptop. I hate typing on a phone, and I do not want to clutter my phone with a lot of apps. I do use the clock/stopwatch app a lot, but that is it. I don’t need to use it for banking, credit cards, paying utility bills, paying for gas, or getting an app for every store I walk into. And while I am interested in technology, I have no desire to ever do any job on my phone.

I think doing Org on a phone is stupid. Yes, you have to learn Emacs, but that also yields benefits. There was a thread on Hacker News asking why so many coders still use Vim and Emacs. A few comments pointed out that in the past decade, we have seen a few editors come and go: Sublime, Atom, Light Table. Now it’s VS Code, but who knows how long it will last? (And frankly I do not trust Microsoft one bit.) Meanwhile, while everybody else was changing their workflow every couple of years, the Vim and Emacs people kept doing what they were doing. On a phone, you will always be limited by the small screen, and whatever limitations Apple, Google or Microsoft put on you. With Emacs, the sky is the limit.

I think people should stop trying to get Org working on mobile, and just use it where it does work. Sort of like everybody should learn how to read S-expressions and stop trying to make Lisp into Python (see here and here). A lot of people want the capabilities that S-expressions give you without using S-expressions, so they create wrappers and languages around it. It just seems like it would be easier to use S-expressions.

Like Lisp, Emacs is different than everything else, takes a lot of effort at first to get comfortable with, but after a point continues to yield dividends. As opposed to a lot of GUI and mobile apps, which seem easy at first, but eventually you hit a wall. Maybe I am trying to live life on hard mode, but I think this is the way to go. Although I am not doing accounting in plain text (see Hacker News posts about plain text here, here, here, here, and here is a link to the Plain Text Project).

At the Emacs meetup I mentioned a thread I saw on the website for Obsidian, which is another knowledge management system using Markdown. The thread starting with someone asking why they chose obsidian over Emacs. One person said that they couldn’t use Emacs on mobile. They needed seven apps to replace Emacs. That is the point of learning Emacs, and why I am not interested in mobile.

I am still converting all my text files into org files, and choosing where to put headings and how to group them. This is taking longer than I thought. I have a lot of deep thoughts. But I am in org mode every day. Ideally I would like a job where I am in Emacs all day. I am getting really tired of using MS Office, or MS anything.

You’re welcome.

Image from “Evangelia quattuor [Les quatre Évangiles, en latin]”, a 10th century manuscript housed at the Bibliothèque nationale de France. Source gallica.bnf.fr / BnF; image assumed allowed under Public Domain.

2021-11 Emacs Meetup

There was a meeting of EmacsATX, the Austin Emacs meetup, last week. There was no set agenda.

I started off by mentioning that while I have not continued working through Rainer Konig’s Org tutorial, I was using Org a lot more. I am using it to keep track of tasks. I am converting a lot of text files into org files, since a lot of topics in the files appear and re-appear. I also mentioned that I had started using the Emacs Desktop to save sessions. A lot of people were not familiar with that term. I don’t know why Emacs calls the file that saves session information the “Desktop”. Perhaps that is a holdover from the PDP-11 days. I used to keep an instance of JEdit open, and I am slowly phasing that over to an instance that uses the desktop. I also made an alias with “–no-desktop” so other instances to not try to use the desktop file. Since a lot of email is happening on GMail and Outlook, and the Emacs browser is not the greatest, it might be hard to do everything in Emacs these days. But I am using it more and more.

I am also using Org to write this post.

Anyway, one guy ranted about MELPA. He might make a blog post about it. I know some people do not think that Emacs handles packages and dependencies very well, but from what I have read, it used to be worse than it is today.

A few people talked about using LSP, the Language Server Protocol with Emacs. It started with VSCode. I think the idea is to make it easier for an editor to work with different programming languages. I don’t know if this makes language modes unnecessary in Emacs.

There is nothing planned for the next meeting. I pointed out that since EmacsConf 2021 is between now and then, we could watch the videos on our own and talk about them. A few people seemed to like that idea. I have a task tree in an Org file to watch the videos from prior years. This was the first meeting in a few months in which Sacha Chua, the organizer of EmacsConf, was not present.

You’re welcome.

Image from Poussay Gospels, a 10th century manuscript now housed in the Bibliothèque Nationale de France, image from Biblissima Portal, assumed allowed under Public Domain. Luke’s symbol was an ox; it kind of looks like St Ignucius giving him Emacs.

2021-10-13 Update

Lately I have not done much programming on my own time or learning new things.

I have been updating my site with images. I found a few sites with images from medieval manuscripts, and I have been adding them to this site. One commenter mentioned there should be more visual variety on this site. I do not have a much in the way of artistic skills, so I decided to go with stuff that is in the public domain.

The images usually do not have anything to do with the content of the post, so if you don’t see a connection, there probably isn’t any.

I got a lot of the images from Wikimedia, and a lot from various state and national libraries in the USA and Europe. I am not affiliated with any of these sites.

Plus I don’t know a lot about art, and this seemed like a good way to learn a bit more about it. I like manuscripts from the start of the Carolingian period to about the twelfth century. Then a lot of stuff starts to look like greeting cards. But Byzantine, Armenian and Georgian manuscripts maintain their quality for a few more centuries.

The only downside to medieval art is they aren’t making any more of it. At some point, I might have to learn some libraries for generative art.

More Lisp/Racket/Clojure coming soon, perhaps with Go or Elixir as well.

You’re welcome.

Image from Cycle of miniatures, a 12th century manuscript housed in the Benediktinerkollegium in Sarnen, Switzerland; image from e-codices, assumed allowed under Public Domain.

2021-05-31 Update

I did not do much with any programming projects this past month.

I got through The Seasoned Schemer. Not all of the code worked for some reason. I barrelled through it pretty quick. I might go through The Reasoned Schemer.

I have been looking at Go. I made a new bookmarks folder for my Go bookmarks. I think I need to be well-versed in a non-JVM language, and the contenders are Go and Elixir. One thing that I do not like about Elixir is that it seems like you have to know some Erlang and know about the Erlang VM. One think that I am not liking about non-Java JVM languages is that it seems like you have to know some Java to be useful. And it looks like Kotlin is going with the Spring/Hibernate route for web applications; those are parts of the Java ecosystem I am trying to get away from. Vert.x looks interesting, and does not seem to use Hibernate or Spring, but it is not commonly used. If I am going to go with something less common, I might as well branch away from the JVM. That said, I will still look into Clojure.

I have been working more on the Org Mode course by Rainer König. I plan on going through that some more. Hopefully this will transform my life.

You’re welcome.

Image from Biblia Latina (Vulgata): Evangelia, made in Fleury around 820. There are several places in France named Fluery; the source is not clear which one this manuscript is from. The manuscript is at Burgerbibliothek of Berne  (Wikipedia page here), image from e-Codices, assumed allowed under Fair Use.

2021-04-11 Update

I know I said I was going to focus on Clojure, but I looked at some other things in the past week.

I am looking into some Amazon certification for AWS. There is a big push to get certified at my current employer, and I would like to do something different.

I started the org-mode tutorial from Udemy.

I also looked at The Seasoned Schemer. I think that having already gone through Simply Scheme I may have gotten some of the concepts. A lot of it deals with recursion.

Chapter 12 dealt with “letrec”. letrec is like let, but instead of binding a name to a variable or data, you can bind a name to a function, and you can call that function recursively.

One thing this can allow you to do is it can relieve you of the need to call a helper function. In Simply Scheme, I made all the functions tail-recursive. To do this, you usually need a parameter that is the “accumulator” or the output (see this answer on Stack Overflow or my post here).

In The Seasoned Schemer, they use letrec for functions in which one argument does not change and one does, such as checking if an atom is a member of a list, or performing a union of two lists:

(define (union-letrec s1 s2)
      ([U (lambda (set-1)
            (cond [(null? set-1) s2]
                  [(ss-sc:member? (car set-1) s2) (U (cdr set-1))]
                  [else (cons (car set-1) (U (cdr set-1)))]))])
    (U s1)))

I know I think the whole argument about Lisp/Scheme being hard to read because of all the parentheses is usually exaggerated, here I think for these letrec examples there might be something to it. These were hard to type correctly from the book. For example, the internal function has to be after the “(set-1)” which is the argument to the “lambda”, but before the closing parens for “lambda”. And the call to the internal function has to be before the closing call to “letrec”. You can have multiple functions defined in a “letrec”, and your call to the internal functions can be in a cond.

A helper function to do the actual work with tail-recursion might be more lines of code, but I think it is easier to understand.

Chapter 13 is about let/cc, combining let with “call-with-current-continuation”. I think some people consider this Scheme’s defining feature.

They have a function rember-upto-last which takes an atom and a list of atoms and removes everything in the list before the last instance of the atom as well as the atom.

Here it is:

(define (rember-upto-last a lat)
  (let/cc skip
          ([R (lambda (lat)
                (cond [(null? lat) '()]
                      [(ss-sc:equal5? (car lat) a) 
                       (skip (R (cdr lat)))
                       ; (R (cdr lat))
                      [else (cons (car lat) (R (cdr lat)))]))])
          (R lat))))

Here is a tail-recursive version:

(define (rember-upto-last-r a lat)
  (let/cc skip
          ([R (lambda (lat outp)
                (ss-sc:display-all "Calling R w/lat: " lat 
                                   " and outp: " outp)
                (cond [(null? lat) (reverse outp)]
                      [(ss-sc:equal5? (car lat) a) 
                         (skip (R (cdr lat) '()))
                         ;(R (cdr lat) '())
                      [else (R (cdr lat) (cons (car lat) outp))]))])
        (R lat '()))))

Both of these have a commented out call to “(R (cdr lat)” (with a second arg in the tail-recursive version) below the call to “skip”.[Note 1]. In the tail-recursive version, either  call gives the proper result. In the regular version, we are building our answer through a chain of calls to “cons”. The “skip” eliminates all the pending “cons” calls, and the function is called anew with whatever the then-current values are. In the tail-recursive version, we can get rid of those “pending” values ourselves.

I think Java might get continuations soon.

You’re welcome.

[Note 1]: For some reason, the code formatter I am using does not always color comments correctly. In all variants of Lisp that I have seen, comments start with a semi-colon.

Image from Psalterium Gallicanum with Cantica, a 9th century manuscript from the monastery of St. Gall, housed at Central Library of Zurich. Image from e-Codices. This image is assumed to be allowed under Fair Use.

2021-03-28 Update

There is not a whole lot to report this month. I have not had a lot of time to look at Clojure.

You’re welcome.

Image from Collected Fragments Volume II from the Abbey Library of St. Gall, written around the 8th century from the monastery of St. Gall. Image from e-Codices. This image is assumed to be allowed under Fair Use.

Every and Any in Clojure

Today we look at a few functions in Clojure that take predicates and look at collections: any?, every?, not-every? and not-any?

any? seems to return true for any argument. According to the docs, it is used for clojure.spec. Maybe when I learn more about spec, that will make sense. You would think a function called “any?” would be useful if you had a collection of numbers, and wanted to know if any of them are odd, or greater than 10, or something like that. Perhaps they could have given it a better name than “any?”

every?, not-any? and not-every? behave as you would expect them to. You can always simulate “intuituve-any?” by calling “not-any?” and then calling “not”.

user> (def evens [2 4 6 8])
user> (def evens-with-9 [2 3 4 6 8 9])
user> (every? even? evens)
user> (every? even? evens-with-9)
user> (not-every? even? evens)
user> (not-every? even? evens-with-9)
user> (not-every? odd? evens)
user> (not-every? odd? evens-with-9)
user> (not-any? odd? evens)
user> (not-any? odd? evens-with-9)
user> (any? 'g)
user> (any? nil)
user> (not (not-any? odd? evens))
user> (not (not-any? odd? evens-with-9))

You’re welcome.

Image from the Rheinau Psalter, a 13th century manuscript housed at Central Library of Zurich. Image from e-Codices. This image is assumed to be allowed under Fair Use.

Reduce In Clojure

The last of the Big Three Higher Order Functions in Clojure is reduce. In other languages it is called fold, accumulate, aggregate, compress or inject.

Sometimes reduce is compared to aggregate functions in databases, like average, count, sum, min or max. These functions take multiple values, and produce one value. Some functions in Clojure, like the four main math functions (+, -, * and /) are processed through reduce if they are called with more than two values.

I would like to point out that unlike the other aggregation functions that databases have, “average” cannot be done with reduce. To do an average, you sum the amounts, and then divide by the number of elements. No implementation of reduce (or fold or whatever you call it) keeps track of the number of elements and allows for an additional operation at the end. Maybe some languages or implementations have a reduce and an enhanced-reduce to cover this case.

The first parameter to Clojure’s reduce is a function that takes two parameters. There is an optional parameter that is an initial value, and the last argument is the collection you want to process. Reduce takes either the option initial value and the first element of the collection, or the first two elements of the collection, and passes them to the function. The output of the function is then used along with the next element in the collection. Reduce keeps using the output from the previous element and the next element as arguments to the function until the collection is exhausted.

I cannot find it now, but I remember reading somewhere that reduce can be hard to understand because “reduce” is frankly not a good name for it, and there are many functions that do what reduce does. As stated, some of the functions in Clojure (like max, min, and some math functions) call reduce. So you are actually using reduce a lot under the covers.

There is a cartoon about this. A teacher gives a student a few chances to say what is “2 + 3” equal to. The student says it equal to “2 + 3” and it is also equal to “3 + 2”. The student gets an F. The cartoon ends with: “Sad fact: many math teachers do not know the difference between equality and reduction.” I admit I do not either. A lot of the cartoons are about Haskell, which I have no desire to learn.

;; call + on a bunch of numbers
user> (+ 1 2 3 4 5 6)
;; winning with "the duce"
user> (reduce + [1 2 3 4 5 6])
;; using 0 for initial value
user> (reduce + 0 [1 2 3 4 5 6])
;; use 0 for +, 1 for *, or you will get incorrect results
user> (reduce + 1 [1 2 3 4 5 6])
;; define a function to explain reduce w/print statements
user> (defn add-with-print [x y]          
  (println "x is " x ", y is " y  ", (+ x y) is " (+ x y))
  (+ x y))
;; use w/just collection
user> (reduce add-with-print [1 2 3 4 5 6])
x is  1 , y is  2 , (+ x y) is  3           
x is  3 , y is  3 , (+ x y) is  6           
x is  6 , y is  4 , (+ x y) is  10          
x is  10 , y is  5 , (+ x y) is  15         
x is  15 , y is  6 , (+ x y) is  21         
;; use w/0 as initial value
user> (reduce add-with-print 0 [1 2 3 4 5 6])
x is  0 , y is  1 , (+ x y) is  1           
x is  1 , y is  2 , (+ x y) is  3           
x is  3 , y is  3 , (+ x y) is  6           
x is  6 , y is  4 , (+ x y) is  10          
x is  10 , y is  5 , (+ x y) is  15         
x is  15 , y is  6 , (+ x y) is  21         
;; use with 1 as initial value
user> (reduce add-with-print 1 [1 2 3 4 5 6])
x is  1 , y is  1 , (+ x y) is  2           
x is  2 , y is  2 , (+ x y) is  4           
x is  4 , y is  3 , (+ x y) is  7           
x is  7 , y is  4 , (+ x y) is  11          
x is  11 , y is  5 , (+ x y) is  16         
x is  16 , y is  6 , (+ x y) is  22         

You’re welcome.

Update 2022-02-10_22:33:14: I just read a post by Rich Hickey about transducers in which he talks a bit about reduce. The function you send to reduce takes two arguments: the result-so-far and the next item in the collection, and returns the next result-so-far.

Image from  Aurora Consurgens, a 15th century manuscript housed at Central Library of Zurich. Image from e-Codices. This image is assumed to be allowed under Fair Use.