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.

Thoughts On Apps And Devices

In my last post, I wrote about the future of devices and web apps versus AI. These topics have since come up again in conversation and during my web browsing.

A guy named David A. Wheeler wrote a post titled “Do not install or develop mobile apps unless you have to“. Granted, I wrote about AI, but he still had some good points.

He mentioned that a phone app can get a lot of info about you from your phone, and there are more privacy concerns than with a web app. Also, Apple and Google will take a cut of your revenue. Apple can remove apps from the app store.

If you make a web app, you have more control. And you have reduced costs. With mobile apps, you have to make one for IOS and one for Android. Since most companies make web and mobile apps, that is usually three apps. You have to make sure your app works with different versions of the OSes. When I was in Chicago, I knew a mobile developer who had a few dozen phones. Granted, there are some ways to make one app that can work on IOS and Android (Appcelerator Titanium, RhoMobile Suite, React_Native, Apache_Cordova, Xamarin). All you got to do is pick one. And hope it does not get discontinued. Or beholden to some company run by a guy who looks like a robot.

But if you go with a web app, you just have to make one. According to Dave Wheeler, the UK government has dropped mobile development. And they are soooo much happier. Less cost, more control.

At the Emacs meetup, someone mentioned that we might stop using laptops and desktops, and go with phones. One person said we might just plug our phones (or some future version of them) into terminals. I have heard this before, but I don’t know how it would work.

Would we run apps installed on our phones? As I wrote before, laptops have more memory and hard drive space. On a phone, the memory does double duty. I don’t think that the phones will ever be as powerful as laptops and desktops. Or would our phones authenticate us to our apps on the cloud, and load them onto the terminal? Or would we run them on the cloud?

And what OS would we use? Would we be limited to IOS and Android? Or whatever the cloud provider gives us? I like being able to run Linux on my local machine.

One problem with these scenarios is I have multiple laptops, but only one phone. How would I use more than one if I have to

I do not like the idea of my phone being my primary device. I know banks, brokerages and insurance firms offer mobile apps. I know phones and apps have security, but I am amazed at how often I hear about people losing their phones, or dropping them in the toilet. (Seriously? Why do people bring their phones into the bathroom?) I have seen quite a few phones lying around where I work. I generally do not lose my phone, but I do not like to use it to manage my money. That just seems like a bad idea.

Maybe we would have small, portable hard drives we would plug into terminals instead of plugging in phones. Granted, I just mentioned that portability can be bad. But maybe that would make it easier to get a better CPU, more memory, or a better monitor.

One device type that has become popular is the “all-in-one”, where the memory and hard drive are part of the monitor. I do not think you can add memory to these things. But I see them a lot. I had to upgrade my phone, and the store had these.

I still do not think the death of desktops is upon us. Gamers and artists love desktops. (They are called “desktops”, but a lot of people put theirs on the floor.) Laptops are still pretty common. I think these “all-in-one” computers are a new type of desktop. If you have a job that can be done at a desk, you will probably be using a laptop, desktop machine, or an all-in-one for a while.

I cannot remember who said this, but someone older than me pointed out that using a web browser to do everything on the cloud was similar to a dumb terminal connecting to a mainframe. We had come full circle. Perhaps at some point, the client-server model will come back.

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.