Author Archives: Eric MacAdie

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.

2019-06-30 Update

I am up to chapter 19 in Simply Scheme. This chapter is higher-order functions.

I looked into a couple of other Clojure web frameworks this month. Someone did a presentation on Duct at the Austin Clojure meetup a while back. I might have to look at James Reeves’ presentation on Integrant at Skills Matter, since Duct is built on Integrant. (That presentation is hard to search for; if you search for “Integrant”, you get anything to do with “integration”.)

There is a tutorial on Duct by someone at Circle Ci that I was kind of able to follow. Until I saw this code:

I am not too clear what that does. Perhaps knowing more about Integrant will help. (There are also other presentations on Duct at Skills Matter here and here.)

There is also Clojure on Coast (Github repo here, website here). I think the aim is to be Rails for Clojure. I might try this out too. I would really like to work with Clara Rules, and I think a web app might be the best way to enter data.

Or I might just stick with Luminus.

You’re welcome.

2019-05-31 Update: Passwords

I have written about websites with passphrase generators and generating passwords and passphrases locally (particularly on this page and this post). I have decided to just use KeePassXC for password management.

I started using it on my personal laptop, and I really like it. I back the file up onto a thumb drive on a regular basis, or at least when I make changes. I have a few entries for other information, like my car’s license plate and VIN number in case I ever need them. I also have an entry for my shoe size, since I don’t buy shoes too often, but it is nice to have the info readily available when I need it.

The hard drive on my work laptop crashed, and I had to request access to everything again. I downloaded KeePassXC on my work laptop, and I use that and it has made everything easier. I also back it up to the company’s OneDrive, so I will not be locked out of anything again.

I know everybody wants to do everything online all the time, but I really like having my password database in a local file that I can control.

You’re welcome.

 

2019-04-07: Done with Chapter 15 of Simply Scheme

I am done with chapter 15 of Simply Scheme. I have been working through SS for a while. Sometimes I come home from work, and I do not feel like doing anything. Or I get stuck and take a break.

I took a break when I got to chapter 9. Then I started back up, and flew through lambdas and recursion. I started making my answers tail-recursive, so mine were a bit bigger than other repos I found with answers. They do not cover tail recursion in the text, but I thought it was a good idea to work on it. I got stuck on question 5 in Chapter 15. I ported my answers to Clojure, then to Racket (with the emacs Racket mode). Eventually I wound up back at the question I had problems with.

I spent a lot of time on it, and I think the problem was that I was trying both do it with tail recursion and to follow the text’s recommendation, which is NOT tail-recursive. I was having no luck with the “Leap of Faith”, so I decided to try solving the problem with higher-order functions, and then port the answers to recursion. In Chapter 14, they have a section called “How To Use Recursive Patterns” in which they show how to use recursion to do every/map, keep/filter and accumulate/reduce. Doing it that way, I solved the problem pretty quickly.

I think I read somewhere that if you have the choice to use recursion or higher-order functions, you should use higher order functions.

I ran some tests comparing my solutions (one with recursion and one with every) with someone who followed the text’s recommended solution. Usually theirs was a bit faster. But if you give the functions a number with 8 digits, mine are noticeably faster.

At first I thought that “tail recursion” meant that the “tail call” had to be at the bottom of a function. I kind of thought that is what people meant when they said the recursive call had to be the last thing called. But you can have tail recursion even in every branch of a cond or an if statement.

Here are a couple of implementations of factorial fromĀ a CS course at the University of Washington:

This is not tail-recursive. For Lisp languages, you can tell what order things are called in by starting at the innermost parens and working outward. First, the minus function is called. Then the recursive “factorial” function is called. Then the multiply function is called. Then the system leaves the function.

Here is a tail-recursive version:

First off, you need another argument for your function. Think of having one as an “input” (which in this case gets decremented to 0 with each call) and an “output” (or accumulator), which holds the increasing total. If we look at the line in “acc-factorial” where it calls itself, it calls the minus and multiply functions, and THEN makes a recursive call. And that call would cause the system to exit the function (or that instance of the function). In the first function, it makes the recursive call, then it makes the call to multiply, and THEN it exits the function.

I hope I understood that. I am not going to name-and-shame, but while writing this I found a gist on github that the author claimed was a tail-recursive factorial in Scheme, but it looks more like the first example I posted from UWash and not the second. So either our mystery gist-er misunderstands tail-recursion, or I do.

You’re welcome.

2019-03-14 Update: Simply Scheme, Simply Clojure, Simply Racket

I have been taking a break from Simply Scheme. I got stumped on one of the exercises. I started doing the exercises in Clojure for a couple of reasons. One is that is the most commercially viable Lisp out there right now. Another reason is that I want to run automated tests. I would like to be able to quickly run a function multiple times with different inputs. I was typing and re-typing the same calls over and over. Or I could just use tests.

I do not know how to do tests in Scheme. I was using Chicken Scheme for Simply Scheme. There are a few “eggs” for testing, but the instructions were not that great. Also some of them were not working on the version of Chicken that I was using for Simply Scheme. I use Chicken on Ubuntu and Cygwin, and not directly; they are a bit behind the official version. I did find out recently there is an SFRI for testing. It is implemented by Kawa, so perhaps I could have used Kawa. I do not plan on building any apps with Scheme, or using it long-term. It is just a vehicle for enlightenment. I do not know what the most common test libraries are, and I do not want to spend time on something that I might not be able to use later. Clojure has testing out of the box.

I also started looking into using Racket. I have thought about it before, since there are a lot of language modules for Racket. There is one for Simply Scheme. I also found out about an Emacs mode for Racket. I am just running some tests from some .rkt files, but from what I understand, this is intended to be a replacement for Dr Racket. I do not know how to make an app with Racket, but right now I do not need much. I think I might be better off going with Racket, even if I am using a Scheme language module. While Racket is pretty rare, it is used more than Scheme.

So I have started a project using Racket and the Simply Scheme library to do the Simply Scheme exercises. Maybe someday I will do SICP in Racket, and become a Little, Reasoned or Seasoned Racketeer.

You’re welcome.

Image from ImgFlip, assumed allowed under Fair Use.

2019-02-27 Update: Web Apps and Multimethods

I have started looking at the tutorial for Luminus, the Clojure web framework. I am thinking about making a web app that sends data to Clara, the Clojure rules engine.

I have started looking at the tutorial for Luminus, the Clojure web framework. I am thinking about making a web app that sends data to Clara, the Clojure rules engine.

I have also started a github sub-project simply-clojure, which is a port of Simply Scheme to Clojure. I used multimethods, based on the use seen in Clojure For the Brave and True.

One of the functions that comes with Simply Scheme is appearances, which “returns the number of times its first argument appears as a member of its second argument”. It works with “words” and “sentences”. A “word” in SS is any type of data with a single member; it could be a number or a string with one word. A “sentence” is basically a list.

It can handle various datatypes. For Clojure, I decided to use multimethods. I think they can only take one argument, so I cheated and used a map.

Here are the tests:

Code highlighted at http://hilite.me/.

You’re welcome.

2019-01-09 Update

I recently attended the first meeting of the Austin Kotlin Meetup. I might keep going in the future. I am kind of on the fence about Kotlin. It is nicer than Java, at least Java as most companies use it today.

I get the impression there are a lot of teams using old versions of Java, and old versions of Spring. They might solve a lot of their pain by upgrading and not really have any need to go to a new language. I wish I knew a way to get teams to upgrade. When Java came out, it was the sleek language (vis a vis C++); now it is the old chestnut. Rails has gone through the same cycle. If companies have fallen behind on Java, and fallen behind on Rails, will going to Kotlin really make things better? Maybe Kotlin teams will get bogged down by legacy Kotlin in ten years. Do we need more languages? Why can’t we just be more intelligent about the languages we use? (And since languages seem to becoming more like Lisp, perhaps we should just go to some dialect of Lisp.)

At one point in the meeting, someone asked what makes a language a “functional language”. I thought a language is considered “functional” when a function can be sent as an argument to another function, or a function can return a new function. One person mentioned immutability. Another mentioned tail-call optimization.

I have been working a bit more on Simply Scheme. Chapters 9 and 10 dealt with lambdas and higher-order functions. I think I am understanding functional programming, but I do not feel like I am getting the enlightenment that people keep talking about. Perhaps this is because I have been exposed to these concepts for a while now.

One reason I doubt I am becoming enlightened is sometimes my answers are larger than other people’s. I can make something that works, but it is not always elegant and minimal.

Another reason I doubt my potential enlightenment is that I am not sure it is making me a better programmer at my job. We are running JDK 6, we are using XML to configure Spring, and there is logic in the views. I am not sure how understanding higher-order functions will help me improve things. There are a lot of things I cannot change. I think it should be re-written from the ground up. Perhaps I will get more insights when I finish Simply Scheme.

Frankly, I think a lot of people where I work do not understand a lot of this stuff and have not been exposed to a lot of these concepts. (Most people I talk to have never even heard of Lisp, or Smalltalk, or Erlang or Scala, or Ruby.) I was not exposed to it for a long time, and I did not understand it at first either. When you are surrounded by people who think that the Gang Of Four patterns are the height of technological sophistication, it is easy to think that is the way things should be done. Part of the issue is that the functional programming community does not explain a lot of this stuff very well. I do not think that state is bad, or that changing state is bad. And side effects are hard to avoid if you want a program to be useful. I/O is a side effect, and it is important. I think the real issue is that state changes and side effects can cause problems if they happen when you do not intend for them to happen, and it is better to explicitly control them.

I am considering taking another break from Simply Scheme and making some web apps in Clojure. Perhaps I should work on getting better in the technologies I want to work in, and go for enlightenment later.

The viability of web apps showed up on Hacker News a few times the past few weeks: “Start with a Website, Not a Mobile App” and “Ask HN: Is web development still a viable career choice?” I will look at these a bit and comment more later.

Going back to chapters 9 and 10 of Simply Scheme.: They showed a neat trick to use lambda to wrap a higher-order function that only takes one argument (like every, keep and accumulate, which are their versions of Clojure’s map, filter and reduce) and put it in an anonymous function so it can take two or more arguments. Pretty slick.

Note: To search the c2.com wiki, try the search page.