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:

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:

Here is a tail-recursive version:

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.

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”.

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.

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.

You’re welcome.

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.

Focusing On Clojure

I have decided to focus on Clojure going forward.

I think of all the Lisps, Clojure right now has the most momentum. And I got a couple of inquiries about Clojure positions.

I have been going through the Clojure API, inspired by an article called “One Weird Trick To Become a Clojure Expert“. The article advocates going through the API alphabetically. Maybe I should have done that, but I think I might be better off going through a few books.

I know at some point I have to stop learning and start making something. But I think that going through the API might not be the best way. And the two are not mutually exclusive.

One of the books I will go through is the third edition of Programming Clojure. One of the co-authors is Alex Miller, who helps make Clojure at Cognitect. Clojure does things differently than other languages, and if anyone can explain it, it is the people at Cognitect. The same publishing company has a book called Getting Clojure, which is written by Russ Olsen, who also works at Cognitect.

Reading books by Cognitect employees is one way you can get Clojure.

You’re welcome.

The Map Function In Clojure

The next member of the Big Three Higher Order Functions is “map“.

I don’t think “map” is a good name for it because 1. There is a data structure named “map” (which has different names in different languages) and 2. I don’t think it is the most descriptive name for it. “apply-to-every” or “apply-to-all” might be better.

The “map” function takes a function and one or more collections, and applies the function to each member in the collection. In Clojure, if you send multiple collections, they will be concatenated into one output collection.

I think the reason it is called “map” is that you are using a function to map a collection onto another collection.

Clojure also has “mapv” which does the same thing as “map” except that it returns a vector, and “mapcat” which takes functions that take collections as arguments. The functions sent to map and mapv take single arguments (if you send one collection) or multiple args, but not collections.

You’re welcome.

Maps In Clojure

I was planning on looking into Clojure’s map function, the second of the Big Three Higher-Order Functions. But looking over my Clojure API page, I noticed there were a few functions with the word “map” in it that I had not gone over yet that deal with the map data structure.

Just as “map” is a noun and a verb in Clojure, the map data structure goes by different names in different programming languages: associative array, map, dictionary, symbol table, hash, hash table.

Anyway, I have looked at some of these functions earlier, but here are some more functions dealing with maps:

You’re welcome.

Clojure Filter

The first higher-order function in Clojure I will look at is filter. It takes a predicate and a collection. It returns all the members of the collection for which the predicate is true. The docs say that it takes a “predicate”, but that predicate duty is frequently fulfilled by a function.

I tried calling filter with “true” as the predicate, and it did not work. I guess in Clojure (and probably all Lisps), a predicate is just a function that returns a boolean.

Filter is one of the Big Three Higher-Order Functions, the other two being Map and Reduce. This one actually has a name that describes what it does.

Clojure has two versions of filter: filter and filterv. The difference is that filter returns a lazy sequence, and filterv returns a vector.

If filter is called with just the predicate, it will return a transducer. I will cover transducers later.

There are also another “filter” function in the clojure.core.reducers namespace. It takes the same arguments as the core filter, but when I tried it in a REPL I got an error. After looking at the Clojure page on reducers, I think the functions in that namespace only work if you chain them together.

You’re welcome.

2021-02-07 Update

I completed an introductory Kotlin tutorial on Pluralsight.

Kotlin seems like an okay language. The one tutorial I went through did not touch on Kotlin Native, or Android, or web programming. I get the impression that Kotlin is mostly used for Android. I have little interest in mobile apps. And from what I read from a reliable source, Android apps are getting more complex (see here and here).

So I might put off learning more Kotlin for a while. Kotlin Native looks very interesting, but it is not covered at Pluralsight. Kotlin Native might be a less-painful way to do embedded programming. It would be really interesting if it could be used in robotics. I think that would open up robotics programming to a lot of developers.

WRT the language itself, I am kind of neutral. Every time the instructor said, “Here is something you can do in Kotlin that you cannot do in Java”, it was always something you could do in Groovy that you could not do in Java. Java is adding more features all the time.

I have started going through some of the “What’s new in Java X”, since honestly my Java skills are out of date.

There was a conference at CME about JVM languages about 10 years ago. One Groovy programmer said that as Java got more features, Groovy might become superfluous. To a certain degree, that seems to be happening.

Granted, it might appear that way to me since the Austin Groovy/Grails Meetup stopped meeting long before everything else stopped. And Ken Kousen does not mention Groovy a lot in his newsletter, and there has not been a new episode of the Groovy Podcast since 2020-08. I like Groovy, but why fight the tide? If Ken Kousen is spending time on other things, perhaps that is a sign of the times. I am already shaking one fist at the clouds by looking into Lisp.

One thing that I think held Groovy back is that you really have to know Java in order to use it. Knowing some C will probably help you with Ruby, but I think Ruby shields newbies from C better than Groovy does with Java. I think this is also true of Kotlin, but not as much.

Granted, from what I heard about the origins of Groovy, making Java easier without necessarily replacing seems like it was the point. But for someone who is new to JVM languages (or programming altogther), they kind of have to learn two languages at once. Plus when a lot of people get tired of Java, they tend to stay away from JVM languages altogether.

Maybe I should have found a way to keep the Austin Groovy group going.

I was hoping to get through as much Kotlin and Java on Pluralsight as I could before my subscription expires. But I might just renew it for a year so I do not put as much pressure on myself, and I can also spend time on other things.

Like Clojure. I got a few feelers about Clojure jobs, so I think I will get back to going through the functions in the core Clojure API. I made a list of functions that seem to take functions as arguments or return functions, or take predicates. I think I will look at some of those, since those are the functional parts of Clojure.

I found a tutorial on Clojure Spec (article here, Hacker News comments here), and some of it was new to me. It looks like Clojure is starting to encourage keywords to have namespaces.

You’re welcome.

2021-01-10 Update

I finished the Pluralsight tutorial on Elixir.

I know it was just one tutorial, but I do not think I am sold on Elixir yet. Granted, I know the Erlang VM is good for multi-threading, and it is better to use abstractions for that then dealing with threads directly, like Java does. One count count against Go is that it seems like the multi-threading support is at a lower level. Then again, I think Go in general is lower level.

One thing I find interesting is that Elixir allows you to overload a function with the same number and type of arguments as an alternative to convoluted cond statements (Elixir has “if” and “else”, but you cannot have more than two choices; for “if..else if…else” you use “cond”.)

The example in the tutorial was printing out the song “100 bottles of beer on the wall.” You can use the same code to handle 100 down to 3, but you need to handle 2 and 1 slightly differently. So you could do this:

I do not know if any other language allows that. Maybe Ruby does and I don’t remember or never encountered it.

Another feature that I like is doctests. You can put iex commands in your documentation (“iex” is the interactive Elixir shell), and you need to start them with the “iex>” prompt. When you run your automated tests, Elixir will also run the iex commands in your documentation, so your docs will always have up-to-date examples.

It was just one tutorial, so there was not much about actors or processes. My subscription is up in a few months, and while I am satisified, I do not think I will renew because I plan on getting up to speed on Java and Kotlin by then.

One thing I do not like is the inconsistency. You can put parentheses around a functions arguments. Or not. And like Go and the C family, if you use operators then the arguments are placed differently than they are for functions. An example is “2 + 3” as opposed to “2.add(3)” or “add(2, 3)”. I know the latter two are more typing, but I prefer consistency and clarity over conciseness.

I think I prefer braces over “do…end”.

And I do have a few concerns about the community of Elixir. Back in 2015, there were a lot of articles from mostly Ruby/Rails people who were gushing about how they loved Elixir. Some of their arguments were technical. But a lot of them said that Elixir is new and it all feels the way Ruby and Rails felt a decade before. Do you want to chase the new car smell, or do you want to solve problems?

A few people even pointed out that just as Dave Thomas wrote one of the first books on Ruby, he wrote one on Elixir. Would a guy who started a publishing company want you to learn a new language? Why wouldn’t he?

And speaking of problems: While not everyone has the same path, a lot of people went from Java/Spring/Hibernate to Ruby/Rails and now to Elixir/Phoenix. They have abandoned hard-to-maintain apps for the new hotness twice in a decade. And when they want to Ruby/Rails, some of the criticisms were that it was slow, did not handle multi-threading (I do not know if Ruby still has the global interpreter lock issue) and a lot of critics said that the magic of metaprogramming would cause problems in the long run.

The Ruby/Rails crowd said that developer speed is more important than runtime speed, that they could just send requests to a message broker, and the magic helped them get solutions out faster.

Now they are going to Elixir because it’s faster than Ruby, Elixir can handle multi-threading, and they are tired of dealing with logic spread out across an unmaintainable monolith. In other words, Elixir solves problems that they kept telling the Java crowd were not problems. From “U mad, bro?” to “Eff this” without even acknowledging the critics were right.

I am not against learning new things. But do we need to learn new things just to say we are learning new things? Maybe we need to do some of the old things better. I think a lot of Java apps would be easier to deal with if (like the one I work with) they were upgraded and refactored to use newer versions of Java/Spring/Hibernate. It would be painful, but not changing these apps is painful, and porting to a new language would be painful. And leaving a language for the newest, hottest thing just leaves a problem for someone else. I keep running into old Lispers and Smalltalkers talk about all the things they could do 20, 30 years ago, and I keep wishing there was a way to break the cycle.

Maybe Rails apps will always be impossible monoliths (I am out of the Rails scene, so I don’t know). Sometimes you are better off walking away, especially if the suits won’t allow refactoring for “business” reasons. (It seems like “business” is always used as a reason to say “No” to things that will make my life easier.)

There are some interesting things in Elixir/Erlang land. Is it possible to implement the “Let it crash” philosophy in other languages? A lot of people seem to chase the “new tech sugar high”, and it seems like Lispers had answers all along.

Plus, when I look at companies that use Elixir, it seems like a lot of social media/web 2.0/gig economy companies, or “$BLAH_BLAH for X” companies copying the latest money-losing unicorn out of “the Valley”. Not a lot of large corporations. I am not exactly Mr Corporate, but when I look at some of the lists of clients of Rails/Elixir consulting firms, I think to myself, “If all of these companies went under, I wouldn’t care and it would have no effect on my life.” A lot of hipsters may hate the idea of working for a bank, or an insurance company or a utility, and while trying to survive the yearly purge is draining, people actually the services those companies provide. At least some of them in the case of banks.

If you are an Erlang/Elixir person reading this, you might be thinking “You got A wrong”, or “You should read B” or “You should talk to C”. Maybe. I have limited time. For now, if I pick a new direction, I would try Go before Elixir.

You’re welcome.

Here are some notes from 2015 or so that I looked at to write this, with comments and more recent links:

Has a link to a tweet that says:
#ElixirConf has a similar vibe to Ruby confs of ~10yrs ago. Excitement. Cool stuff being hacked on. Very thought provoking and energising.

Cutting Corners or Why Rails May Kill Ruby

Says monkey patching is killing Ruby

“What’s more, it’s just a blast in the same way that I felt when I first started playing with Ruby.”

“Like with Ruby 12 years ago, once again I feel that this new platform is so much better than the other solutions. And it is not just a gut feeling, there are rational arguments to back it up.”
What would be more rational is to not change languages every stinking decade.
“Another similarity is that Dave Thomas is also excited about Elixir and has written a book about the language.”
Are you being played here?


tl;dr Phoenix showed 10.63x more throughput over Rails when performing the same task, with a fraction of CPU load
Hmmm. When it was Ruby vs Java 10 years ago, performance was not that important. Now it is.

Blog post on Let It Crash: https://www.amberbit.com/blog/2019/7/26/the-misunderstanding-of-let-it-crash/

Another one, stating that a lot of Erlang/Elixir people do not understand “Let It Crash”: http://stratus3d.com/blog/2020/01/20/applying-the-let-it-crash-philosophy-outside-erlang/