Category Archives: Lisp

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.

2018-09-30 Update: Clojure Web and AI

I am still going through Purely Functional. It is interesting that there are so many ways to define a function in Clojure. I wonder if all functional languages are like that.

I have decided to spend time looking into making web apps in Clojure. I know that AI is big, and it would be nice for Clojure to be a force in that space, but things seem to have changed since I blogged about it in May.

The guy who wrote Guildsman is no longer updating it. I don’t know what is going on with dl4clj. (Granted, I haven’t emailed the guy.) The Deeplearning4J site said that was the official Clojure library for Deeplearning4J. It looks like they are now part of the Eclipse Project, and they totally redid their site. And in my opinion, not very well. There are lots of things that look like links on their FAQ page, but nothing happens when you click them. They have a gitter chat. I will try looking into that sometime. The search on gitter is not that great. I think you have to go day-by-day. Here is the link for the archive on 2018-09-26. Cortex still looks like it is or will be a ghost town. If only someone could make all this stuff less complicated.

I will get more into web apps. I know a lot of people think that mobile is the future, but I think web apps will be around for a while. When the iPad came out in 2010, all the Apple fanboys said that within five years we would all be using iPads for everything all the time. But that did not happen. At my job, we all use laptops. When I go to tech meetups, people still use laptops. Gamers are still into desktops.

Sidenote: One thing that I find odd and frustrating is that while 15-20 years ago a lot of technology people thought they were so smart and sophisticated for not trusting Microsoft (or IBM, or Oracle), yet ever since the iPhone came out, those same people won’t say the sun is out until Apple says so. Yet tech people used to make fun of the suits for not thinking the sun is out unless MS said so. Was I wrong to believe in open source?

For one thing, web browsers are on more devices. Phones, tablets and laptops/desktops can all use web apps, but laptops and desktops cannot use mobile apps. Plus I have a hard time typing on phones, and dealing with passwords on phones is very frustrating for me. I prefer dealing with passwords in a password manager or a spreadsheet or an encrypted file. I prefer keeping track of logins and passwords that way rather than deal with a bunch of apps on a phone.

And EVERYBODY makes an app. My bank. My insurance company. The company that processes my rent payments. Which I could make using the app from my credit card company. There is an app for all those stupid scooters all over Austin. Every mom-and-pop Indian place here has an app. My gym has an app. Everybody that Robert Llewellyn talks to on “Fully Charged” has an app. I know my phone is old, but I don’t have a lot of space. I would rather use that space for pictures than yet another app that I might only use one time.

Laptops have bigger screens, bigger keyboards, more hard drive space, more memory; since when did Americans want less?

So there was a thread on the Clojure Google group recently about web apps. A lot of libraries were mentioned. I will go with Luminus first. He walks you through what libraries you need, and you can pick and choose which ones you want to use. Others that were mentioned: Pedestal, Yada, Integrant, and Duct.

I know a lot of Clojure people (and Lispers in general; should we call them Lispters?) don’t like frameworks. They prefer libraries. I never liked the answer “go use libraries.” Nobody ever tells you what libraries to use. I think a lot of people want to be able to produce something quickly that they can see, and frameworks do that. People always like to contrast the “stringing together libraries” approach with Rails. I think that while something like Rails has a lot of “magic” and can do a lot of things for you, magic was not the only reason Rails took off.

What I think helped Rails is that it gave people a default answer. Back then, there was PHP: not a language anybody really loves, and you have to do everything yourself every damn time. “How do you make an app in PHP? From the ground up. Every stinking time.” And you have Java: Lots of frameworks, some of them viable and widely used, some niche. How do you know you are making a good choice and your framework won’t be abandoned later? “How do I make a web app in Java? Pick a framework. We got plenty: A, B, C, D, etc, etc. And then pick a servlet engine. We got a lot of those too!”

“How do I make a web app with Ruby? Use Rails. Go here and do this.” The shortest and most useful answer. Granted, there are/were other frameworks in Ruby, so if you don’t like Rails you have options. But I think having a default answer is the way to go. Choice is great when you understand the choices.

Some people want to make an app, and then go under the hood.

You’re welcome.

Clojure And Gradle Update

I am putting twitter-retriever-gradle on hold. I spent a couple of hours trying to send JVM system properties to the clojureRun task, and I couldn’t figure it out.

I raised an issue on the github repo for the Clojure Gradle plug-in. They made a suggestion, and it did not work out. I was using a few libraries that could use system properties for configuration. That is not the only way to do things, but with Gradle my other option was to have multiple copies of the same file all over the repo. I would rather not do that.

I might ask on the Gradle forum. But for now, I think I will move on to something else.

I think Gradle works well for Groovy and Java. It seems a bit harder to use for Clojure. Back to Purely Functional.

You’re welcome.

Clojure With Gradle: twitter-retriever-gradle

I took my twitter-retriever project and reworked it to use Gradle. It is as twitter-retriever-gradle.

To a certain degree, this may just be about satisfying my curiosity. But then again, you might find yourself at a company that uses a lot of JVM languages and everyone knows gradle. Plus I think that a lot of people in the Clojure community are not too thrilled about having to deploy one monster uberjar. With Gradle, you can keep your jars separate.

Before I go any further, let’s go over some issues. I was not able to get the tests to work. The directory structure is different than leiningen, and I had to make a copy of a file. I was not able to use environ for some reason, so I had to hard-code the database info (a lot of Clojure libraries assume you are using lein or boot; to be fair, Clojure people usually are). I will try again; I might just go with cprop [Note 1].

This requires the nebula-clojure-plugin. The Nebula plugins are Gradle plugins made by Netflix. This plugin does not have a lot of documentation. I had to search the source code to see how to do some things. It adds the tasks “clojureRun”, “clojureRepl” and “clojureTest”. You can still call “clean” and “build” as before. I also enabled the application plugin, so “distZip” works.

First thing you have to do is move the files in src/clojure to src/main/clojure.

You can run it two different ways. One is directly with Gradle:

I think you have everything after the –fn in a single quote.

You can also use the application plugin. You specify the main class in build.gradle. I found out you can also put in a few command line args as well. For Clojure, your main function will not change, so you can add that along with clojure.main:

Then run “gradle distZip”, and it will create a tar and a zip file in build/distributions. Expand these, and run the script in the “bin” directory. You can add further command line args when you run it:

For database access, I am using conman, which under its hood uses hugsql. You put your SQL statements in an SQL file which is read in. I put the file on the classpath at “twitter_retriever/sql/statements.sql” (which in this case was $PROJECT/src/main/clojure/twitter_retriever/sql/statements.sql). Gradle could find that when I ran it with the “gradle” command on the command line. But to run it from the expanded zip file that was produced by the distZip command, that did not work. I had to make a copy of the file at $PROJECT/resources/twitter_retriever/sql/statements.sql. Each location only worked for one run method, so I need two copies. I will see if I can get this to work with one file. cprop might help here.

I could not get the tests to run. (First off, the tests must go into src/test/clojure.) It kept having an issue finding statements.sql on the classpath. I tried putting it into src/test/resources/twitter_retriever/sql, but that did not help. Again, cprop might take care of this.

I did not try running a REPL with “gradle clojureRepl”. I was able to use a REPL and do a few things by calling M-x cider-jack-in in an emacs file. When I did, a little option popped up at the bottom asking me if I was using lein or gradle.

So the experiment was not a complete success, but there is some potential.

You’re welcome.

Note 1: I am leaning towards cprop for the regular twitter-retriever. Like the crop README says: What if you have 100 args? That’s 100 properties to put in the environment.

2018-09-06: Notes On Leiningen

I started another tutorial on Purely Functional. One thing I learned is you should put a “:main” option in your lein project.clj.

When you start a Clojure REPL, by default you will go into the “user” namespace. From here you could call “require” on any namespace in your project.clj or any namespace that comes with Clojure, and use their functions. But to go to another namespace and have access to everything, you need to specify a “:main” option.

One of his lessons is about using Clojure to work with JSON, using a repo called AnApiOfIceAndFire, after the book series “Game Of Boobs” is based on. His project is a-game-of-json. He puts the JSON into some maps in the a-game-of-json.core namespace using the core Clojure function defonce. I went into that namespace, and I was unable to access that map. I couldn’t even call core functions like “+”.

Here is an example session:

This was not a problem in the “Introduction To Clojure” lesson, so I looked at that repo’s project.clj.

Here are the last two items in the project.clj file’s map:

After some editing, I figured out that the way to get access to all the functions is to add the “:main” key/value pair. After that, everything seemed fine.

I did this with twitter-retriever, and I was able to call core functions in all the namespaces I defined. I was even able to access clj-time.local, and call a few core functions in that namespace. I used “in-ns” to make a new namespace, but I was not able to call any of the core functions. Maybe my config is a bit off.

But “user” was available to me without any problems.

You’re welcome.

2018-08-29 Update: Anonymous Functions and Kafka

I am still going through the tutorials on Purely Functional. It is taking longer than I thought. I might start going through Luminus at the same time as well. I think that building something while going through the lessons are a better way to learn.

In one of the lessons on Purely Functional, there is an interesting use of anonymous functions.

In version 3.17 of core.clj, we saw this in the function add:

We see a call to “cond”. It uses the type of the ingredient to decide which function to call.

In version 3.18 of core.clj, he adds a map with anonymous functions:

In version 3.19 of core.clj, he gets the functions out of the map and sets them equal to a symbol, replacing the cond:

I will also look into Apache Kafka. I went to the Apache Kafka meetup recently. I think it will be important going forward.

You’re welcome.

2018-06-17 Update

I am still going through the tutorials on Purely Functional. There is nothing new to me in the intro videos, but I am getting practice with the REPL and emacs.

The project that I am on is downsizing. I might leave my employer and try my luck in the big, bad world. At one point I told my manager that I was interested in Lisp and Clojure. I probably mentioned that Lisp is one of the oldest languages and also not widely used. At a recent meeting, he said that I was interested in “legacy” technology. I plan on writing a post about why I am interested in Lisp and Clojure. While Lisp is one of the first programming languages invented, I don’t think it is appropriate to call it “legacy”. Lisp can adapt to any paradigm. “Legacy” has a negative connotation.

Part of the appeal of Lisp is that it seems like languages in the C family are becoming more like Lisp and Smalltalk over time. I have written this on this blog a few times. I mentioned it to some people once in Chicago, and they thought it was an interesting insight.

You’re welcome.