March 2020 Update

I have not made any more progress on “The Seasoned Schemer”.

My employer has offered some training in Java 8 and Spring Boot microservices, so I will spend time on that.

I may also start looking into building a web app with Grails. I would like to maintain my Groovy/Grails knowledge. I will probably build a quick app in Grails and then redo it in Clojure/Luminus. I will also look into making some rules with the Clara rules engine. One reason I want to make a web app is that I think it would be a good way to enter data for use by a rules engine.

You’re welcome.

Chapter 9 of ‘The Little Schemer’

I finally finished chaper 9 of The Little Schemer. This was about partial functions, total functions, and ended with the applicative-order Y combinator.

Frankly, what I understood in this chapter I did not see the point of, and I am not sure there is much point in the parts I do not understand. I think a total function returns a unique value for every input, and partial functions do not. Some of the functions they described as partial sometimes did not return values. Which to me sounds like a badly-designed function.

Maybe Godel’s incompleteness theorem has seeped into our collective consciousness to such a degree that the idea that some functions cannot be computed seems obvious.

Maybe I am not smart enough to be one of those super high-level math/language theory people. I realize I do not have the inclination to do so. I do not have much interest in conjectures about functions that do not return values. I will have to ask a few people I know who have been through SICP if this is the sort of thing in that book. I will finish The Little Schemer and go on to The Seasoned Schemer in a while.

I went through the part about the Y-combinator a second time, and I am not too sure I understand it or see the point. Is there a point? According to some guy named Mike, the point of the Y-combinator is:  The Y combinator allows us to define recursive functions in computer languages that do not have built-in support for recursive functions, but that do support first-class functions.

Are there languages that fit that description? I did some googling, and I found a Hacker News discussion about “The Why of Y” on Dreamsongs (an interesting website I hope to explore in depth someday). As one commenter points out, the article goes into the How of Y, but never the Why.

The Seasoned Schemer says you only need to understand the first eight chapters of The Little Schemer to go through TSS. So hopefully I should be fine. I was hoping to get through TLS more quickly. I am more busy at work, and chapters 8 and 9 were a lot harder (and had more concepts that were new to me) than the first seven.

I have not gone through these yet, but here are a few more links I found about total and partial functions:

You’re welcome.

Update on ‘The Little Schemer’

I am almost through with The Little Schemer. I got through the first seven chapters fairly quickly. There are no exercises per se. They will ask questions, invite you to figure out the answer, and show you. I admit, a few times I peeked, but only after trying to get it myself.

There were a few things in chapter 8 that were mind-bending. One was using higher-order functions for code-reuse.

In chapter 3, the authors introduce a few functions. One is “rember”, which removes an element (or member) from a list:

Another is “insertR”, which inserts a new element to the right of an old element in a list:

The third is “insertL”, which inserts a new element to the left of an old element:

The functions are pretty much identical. In chapter 8, they make a base function, and then make three more to cover the three different requirements.

It works just like the original:

This reminds me of something that Eric Normand showed in Purely Functional, where he puts anonymous functions in the values of a map. I wrote about that in August of 2018.

The truly mind-bending part was the “collectors”. Dark arts, these are.

They define a function that does the usual removing of members. It takes an additional parameter which is a function that does some calculations/manipulations on the resulting list. But in the recursive calls, the function uses inline lambdas to make additional collections.

Here is their explanation from page 140; the function is (multirember&co a lat f), where “a” is an atom, “lat” is a list of atoms, and “f’ is a function: It looks at every atom of the lat to see whether it is eq? to a. Those atoms that are not are collected in one list ls1 ; the others for which the answer is true are collected in a second list ls2 . Finally, it determines the value of (f ls1 ls2 ).

Here is the multirember&co function:

Here is the function we will use in our test:

The second argument is unused in last-friend. So when you use last-friend, it will count how many elements are not equal to the first argument. If it returned the length of y, it would tell us how many times the first argument is in the list.

Here are the tests in Racket:

Later, they use collectors on functions that work on multi-level lists. There is a recursive call within the collector.

I think I understand this, but I am not entirely sure about it. I was able to figure out some of the collector examples as they went along. Truly this is unholy power.

You’re welcome.

On To The Little Books

I finished the poker program from Chapter 15 of Simply Scheme, and I finished Chapter 24.

I have decided I am willing to let MengSince1996 be the King of Berkeley, and move on to Daniel Friedman’s “Little” books.

The first is “The Little Schemer“. This seems to deal with recursion. The first sequel is “The Seasoned Schemer“. The co-author of these books is Matthias Felleisen, one of the founders of Racket. On his Northeastern University page, he states that “The Seasoned Schemer” deals with higher-order functions, set! and continuations.

Next is “The Reasoned Schemer“. This bridges functional programming and logic programming. I work with a rules engine in my day job. I wonder if that is what this is about.

The next book is “The Little Prover“. According to the book’s page on the MIT Press site, this book “introduces inductive proofs as a way to determine facts about computer programs.” Honestly, I am not too clear what that means at this point.

The most recent book in the series is “The Little Typer“. For this book, Friedman and co-author David Thrane Christiansen made a language for the book using Racket.

I will probably use Racket for all these books instead of straight Scheme because I want to be able to run a tests and not type and re-type function invocations every time I make a change. In order to use tests, I had to require the R6RS packages into a program using “#lang racket/base”. I do not think there is a way to use the Racket unit test libraries in an R6RS program. So there are a lot of prefixes.

I like prefixes before function names. It is a bit more typing, and maybe it is not as clean, but I like to know where everything is coming from. One of the things that I did not like about Rails was there were no import or require statements. Everything was everywhere. That made tutorials look very interesting, but it was frustrating finding documentation for classes if you wanted to see what else the gems could do.

I plan on getting through these faster than I took to get through Simply Scheme.

See also my mentions of these books in a post from a few years ago.

You’re welcome.

More Progress On Simply Scheme

I am closer to finishing Simply Scheme. I have completed almost all the regular chapters.

Most of the other people who have github repos for Simply Scheme have not gotten as far as I have. It’s me, buntine, and some guy in New Zealand named MengSince1996. I might go back to the poker project in chapter 15 and finish that; then it will just be me and Meng. As soon as I get through chapter 24.

To be honest, I am not too clear that I learned a whole lot. I admit, some of the exercises were pretty hard, but overall a lot of the main concepts were not new to me. I had done a few other Scheme tutorials before Simply Scheme, and I have been working with Clojure on and off for a while, so I was already familiar with higher-order functions.

I did learn more about recursion, especially tail recursion. I tried to make all my recursive functions tail-recursive. This made them longer that the non-recursive versions, but I think it is a good practice to get into. Recursion is not a hard concept, but I still think it helps to go through exercises like, “Do this weird thing with recursion.”

There was an answer on Stack Exchange about tail recursion; someone wrote that you should prefer using higher-order functions, and go with tail recursion as a last resort. I assume this person was referring to the built-in higher-order functions, like map, reduce and filter. Simply Scheme threw a lot of things at you where the Big Three would not work (like filtering out the first instance of a predicate but leaving any others). Sometimes you just gotta recur. Interestingly, I think that the Big Three themselves rely on recursion. I have not been able to find the Common Lisp or Racket implementations of the Big Three, but I did find a page for a course at Aalborg University in Denmark that gives source code for the Big Three (there is one page with map and filter, and another page with reduce. Chapter 19 of Simply Scheme also gives the Big Three, with some hints in Chapter 14.

I did get a bit tripped up with lists. There were a few times I sent a function a pair instead of a list. (Yes, I know this could be a problem if I go forward with most Lisps; the Clojure community seems to prefer vectors over lists.) The way the Lisp family handles lists is different than any other language. I think in most languages, you add stuff to the end. In Lisps, although many Lisps have “append” functions, I think the preferred way to make lists is to use “cons” to add to the front.

It is interesting the way languages use the same word to mean different things, or different words for the same thing. An array in C, C++ or Java does not exist in Ruby (at least, not when I was using it). What Ruby calls an array is like a list in Java. Clojure lists are like Common Lisp/Scheme lists, and vectors in Lisps are like lists in Java. I should probably find a book on data structures and learn more about this stuff.

Maybe I was ready for SICP from the beginning.

You’re welcome.

2019-09-08: Thoughts On August Austin JUG Meeting

The most recent Austin JUG meeting was on August 27: “The Evolution of Java and the Developer Community with Heather VanCura“.

A big chunk of the talk was about the JCP, how it has been streamlined, and how to get involved. She did talk about the future of Java, as well as mention some of the sub-projects withing OpenJDK. She mentioned Valhalla, which is about developing general language features, Panama, which will make connecting with native code easier, and Loom, which will make concurrency easier to use.

In addition to lighter threads, Loom will have continuations and tail-call elimination. I think this is another data point in support of my thesis that languages are becoming more like Lisp, and the industry has been expending a lot of time re-inventing the wheel.

I think she mentioned that they are moving a lot of projects from Mercurial to git.

A lot of the questions afterward were about the support model for Oracle JDK vs OpenKDK and binary compatibility between code compiled with different versions of the JDK. There were some questions about getting involved in the JCP and contributing to a JSR, but not as many as more technical questions. From what I remember, she had more information about JCP/JSR questions than other topics. Maybe Oracle needs to send someone out to talk about support and binary compatibility.

She said there were some organizations running on JDK 4 and earlier, which only made me feel slight less depressed that I did before.

Someone asked if other JVM languages were involved in the JCP. She said yes, but the only one that popped into her mind was JRuby, which was also depressing. I still think JRuby is a solution looking for a problem. If you want a dynamic, agile scripting language on the JVM, use Groovy. That is what it was invented for. Java devs using JRuby are jumping though a bunch of hoops they do not have to jump through just to impress their Ruby friends. Sort of like CNN hiring conservative whack jobs to grab some of Fox’s audience; it’s just not worth it. Besides, mixing chocolate and peanut butter might sound great in a Reese’s Pieces commercial. That does not mean it is a good idea all the time.

I have noticed a trend that when people give presentations about why they picked a particular JVM language, Groovy is rarely on the list. I have seen Ceylon get more attention. When I ask people why Groovy was not on their list, they say they have never heard of if. I always think, “If that is any indication how good you are at due diligence, it’s a good think you’re not a lawyer.”

But I digress. Tomorrow is the Austin Clojure meetup. A few of the Clojure people were there. They might show up tomorrow and offer some opinions. She also gave this talk to the Houston JUG the next day. I might email a few people and get their opinion.

Bottom line: Good talk, but I don’t think the things she spent the most time covering are the questions that Java developers and organizations are most concerned with. If you are a Java developer, things like binary compatibility and support will determine what JDK you use for development and deployment. But you do not need to be involved in the JCP.

You’re welcome.

2019-08-13: Thoughts On Simply Scheme

I may not finish the rest of Simply Scheme.

Chapter 22 deals with files and I/O, and some of the exercises and examples are not working. Simply Scheme came out just after R5RS, but I cannot find anything about a specific version. It might even be running R4RS.

I guess the I/O functions work differently in different implementations. Or perhaps Racket is handling things differently. My goal of completing 100% of Simply Scheme will not happen.

I do not know what I will do next. The options are: The Little Schemer books, How To Design Programs, climb Mount SICP, or get back to Clojure.

You’re welcome.

Thoughts On Lisp And Racket

I plan on writing about why I am interested in the Lisp family of languages. It will probably come out in stages.

But first, I will write about some recent events. (This is a bit all over the place.)

A few weeks ago there was a lot of traffic on the Racket Users mailing list about a proposal by Racket core developer Matthew Flatt called “Racket2“. They are thinking about changes, with one goal to increase the user base.

One proposal was to change the syntax and move away from s-expressions. The current syntax would be “#lang racket”, and the new syntax would be “#lang racket2” (or whatever it winds up being called). This has caused a lot of debate.

Some people (including myself) came to Racket because it is part of the Lisp family. And s-expressions are part of that. I have met a lot of people who said that they could do things with Lisp 20, 30 years ago that languages either cannot do today, or could only do recently. Many languages are influenced by Lisp, yet Lisp does not feel the need to be influenced by anybody else. (An exception might be OOP, one of the few ideas that did not start in the Lisp family, and is very easy to implement in Lisp.)

I grew up near Chicago, and the population kept expanding westward. People would complain that their suburb was too crowded, so they would pave over more farmland, and expand the next suburb, and ten years later this would repeat. I always thought that maybe we should learn to design cities and towns better so we don’t cut into our food supply and stop making the same mistakes over and over again. Eventually we will run out of land. Or people will be commuting from the Quad Cities.

I remember when the hot thing was to do Java/Spring/Hibernate. Then Rails came along, and a lot of Java people went to Rails because they could build apps faster. And then they got tired of the magic and the monolith and the lack of multi-threading and now a lot are going to Elixir. Granted, not all Rails people came from Java, and not all of them are going to Elixir, but there are a lot of them who took the Java-Rails-Elixir path. In other words, there are a lot of people who dumped unmanageable apps on other people for the new cool, hip language twice in the span of a decade.[Note 1]

And then there is the JavaScript community. Constantly churning out new frameworks and libraries and entire languages that transpile to JavaScript so they do not have to deal with JavaScript directly. And the whole time Lisp people have been in their corner just doing their thing.

There is a lot of churning in IT/CS, but not a lot of learning. It looks to me like the Lisp community knows something the rest of the world does not. They are not searching for the next hot thing. They seem to understand things on a deeper level than other communities. Perhaps “enlightenment” is not an overwrought term to use.

No other language has people claiming what the Lisp people claim. Many langs claim to be influenced by Lisp, or try to do things that Lisp can do, or do things that started in Lisp (which is just about everything but OOP). But the Lisp crowd doesn’t see a need to be like other languages. It’s like fat people want to date fit people, but fit people do not want to date fat people.

Norvig asks if Lisp is still unique. More languages have features that at some point only existed in Lisp. (Paul Graham also lists some Lisp features.) I get the impression that Norvig thinks that the world does not need Lisp anymore. Perhaps a better interpretation is that a lot of time and energy has gone into re-inventing the wheel. Here is a wheel in Lisp: (). See what I did there?

Granted, maybe this was inevitable. C and UNIX were given away for free, and for a time Lisp was only available on specialized and more expensive hardware.

But if languages are becoming more and more like Lisp, maybe we should just cut to the chase and use some variant of Lisp.

I am one of those people who came to Racket because it is a Lisp. I feel that I should be better at creating/using software and general problem solving than I am, and I guess you could say I am looking for the fabled Lisp enlightenment. Maybe saying Lisp is the language of the gods is overwrought, but nobody ever said that JavaScript made them smarter, or that they learned a lot using anything by Microsoft.

It seems like everybody wants the capabilities that s-expressions give them, without actually using s-expressions. It has been tried, and nobody has been able to get it to work. Even if you could, why bother? Why go through the effort to invent a language that can do the things that Lisp can do? I think it would be easier to just learn to program with s-expressions (which frankly are not as hard as some people seem to think). A lot of the suggested alternatives usually end up looking like Python. If you want to use Python, then go use Python.

There was one person on the Racket users mailing list who wrote that parentheses make his head hurt. He also wrote that he found arguments from “parenthistas” to be condescending. And he is a PhD student in CompSci. Frankly, if you are a PhD student in CS and you do not grasp parentheses, then you deserve condescension. I am not claiming to be the foremost Lisp expert, and I am sure you can find Lisp code that makes my head hurt. But you can find impenetrable code in any language. But in all seriousness, s-expressions just do not seem as hard as some people make them out to be.

In “The Evolution of Lisp“, written around 1993, Richard Gabriel and Guy Steele predicted this would happen: People would suggest alternative syntaxes to Lisp, and the suggestions would be rejected. There have been a couple of SFRIs for this in Scheme. They never seem to go anywhere. From Gabriel and Steele:
On the other hand, precisely because Lisp makes it easy to play with program representations, it is always easy for the novice to experiment with alternative notations. Therefore we expect future generations of Lisp programmers to continue to reinvent Algol-style syntax for Lisp, over and over and over again, and we are equally confident that they will continue, after an initial period of infatuation, to reject it. (Perhaps this process should be regarded as a rite of passage for Lisp hackers.)

I think it should be regarded as an IQ test. People have done this, and it has never caught on. Why will it be different this time? Also: What if the people who are in Racket for the Lispiness leave and you do NOT gain new users?

Back to Racket: What do I think Racket should do to increase its user base?

1. Do something about Dr Racket.
I use racket-mode with emacs, which may not be the most beginner-friendly way to use Racket. But DrRacket looks kind of cartoonish in a way. It’s clean, I’ll grant that. Maybe I am the only person who does not like it. Maybe I expect an IDE to look more like IntelliJ, or Eclipse, or Visual Studio.

2. Focus more on libraries, frameworks, and applications. I read the Racket Manifesto, and I know that it is intended to be “a programming language for creating new programming languages”. But it also claims to have “batteries included”. Which is it?

I know some say language oriented programming is Racket’s strong suit. But to some people, it can make Racket look more cumbersome and less powerful. It is a nice thing to have when you need it, but do you always need it? Why can’t Racket solve problems out of the box? If it is powerful enough to create new languages, then you should be able to do something with plain old Racket.

In other languages, when you ask how to do something, many times you are pointed to a library or framework. In Racket, you might get told to “write a language.” People want to make applications, not languages.

I think the reason Rails was so successful was not just that it had a lot of magic, but that it was a nice default answer. Back then, the major languages for web programming were PHP, where you did have to do everything yourself, or Java, which had (and still has) a lot of frameworks. After Rails came along, if you asked how to make a web application in Ruby, the answer was: Try Rails. It wasn’t the only option, but it was a nice default. I think the Racket community should focus on building libraries, frameworks, and applications that people can use in Racket.

3. Related to the above comment: Does Racket want to be a teaching language? Or a language used by professional developers? Are these two goals possible at the same time?

4. I think being immutable by default is a good idea.

5. Can Racket do more with GPUs? I think these will become more important going forward.

[Note 1] Another thing that bugs me is that for a long time, Java developers said that Java was faster than Ruby, and criticized Ruby for not being able to execute multiple threads. Rails developers responded that the speed of the developer was more important than the speed of the runtime, and that WRT threads, they could just send stuff to a message broker. And unlike Java, Ruby had metaprogramming, which some derided as “magic”; Rails devs said they were just envious.

Now, lots of Rails devs are moving to Elixir because it’s fast, it can handle multiple threads, and a lot of the Rails magic was changing core Ruby classes which caused a lot of problems. In other words, Rails developers left Rails due to the criticisms that they all said were invalid a few years ago.

You’re welcome.

2019-07-23: Site Update

I might start posting more shorter posts more frequently. I have been thinking about writing some longer posts on a few topics, but I have not gotten started. Perhaps putting smaller posts online and then combining them later is the way to go.

I also might start posting more images on the site as well. Even if they have nothing to do with the text. Someone suggested it in one of the few useful comments that I get. I might post some art, since I think I should know more about art. I should probably know more about a lot of things.

You’re welcome.