Author Archives: Eric MacAdie

Clojure rand functions

Here are some examples of Clojure random functions.

 

You’re welcome.

A Hacker News Comment About Emacs

I have started using emacs a bit more lately. I spent a bit of time upgrading packages and getting CIDER to work. I would like to share a comment that was left by someone¬† going by “maehwasu” (perhaps a disciple of Deganawida) on Hacker News on August 26, 2015 (or whatever day was 818 days ago from today).

OP is getting hate, but I write a lot of Clojure code in Emacs, and I find the following commands cover 97%+ of my usage, maybe more. For config I use Emacs Live out-of-the-box, and remap Command on OSX to be my Ctrl. That’s it.

C-a, C-e, C-b, C-f, C-p, C-n, C-v, M-v for line/screen maneuvering.

C-o for Ace-jump to go to the start of any words I see on the page.

C-d to delete. C-s to search for words not on the page.

C-k, C-y, and also how to use them with paredit to yank whole s-expression chunks.

Buffer switching and killing.

File saving and opening.

I teach the above to any friends who want to learn Emacs/Clojure/LISP, leaving out a few other features like whole word deletion and more advanced paredit. With halfway decent aptitude and a little practice, they become productive very quickly (within a few hours, which is a pretty good investment relative to “normal” text editors in my book).

You’re welcome.

2017-11-19 Update

I am still looking at HugSQL. I started messing around with the quoting option in the connection macro. I noticed that I was not able to get any SQL injection samples to work through HugSQL. (It was a bit odd to try to intentionally do SQL injection after years of trying to prevent it.) I think the Postgres JDBC driver takes care of SQL injection.

To test this, I started looking at Migratus (and its leiningen plugin as well) to make a database in MySQL. I am more of a Postgres guy, so it took a while to get things right. Plus I think that Migratus has to do things a bit differently than regular SQL. I think that creating a table and creating a trigger for that table need to be two separate migrations.

I also had problems with foreign keys. With one foreign key, I got the table name wrong. I had to google the generic (and useless) error message. That led me to googling a few more steps. I had to log in as root, run the command

and look in that wall of text for a section labelled “LATEST FOREIGN KEY ERROR”.¬† The cause was buried in there. If MySQL is saving some text about the cause in this object, why can’t MySQL just print it out to the prompt instead of forcing me to go through all these other steps?

I might do a Migratus project with Postgres just to see if this small, irritating problem happens there too.

Another thing while working on all of this is I have used pg_dump a few times. I found a page online with examples that mostly work. Maybe I have Postgres configured differently, but I have found that for pg_dump, I have to add a few options to get it to work. The –help says that –password is unnecessary, that you should be prompted for it automatically. I have found that I need to add that, as well as –port and –host (even though I have been running it on localhost).

You’re welcome.

2017-11-12 Update

This weekend I planned on starting a Luminus app. But before too long I started looking at the database parts. This led me to look at HugSQL, based on a project outlined on a page hosted by a company called Compose.

I did a few things that are not in the article, incorporating a few more things I learned about HugSQL. I might add it to my Clojure app repo on Github in a few days.

Last week I mentioned I found a project that is a Clojure wrapper for Deeplearning4J. I did some searching on the Clojure subreddit, and I found a reference to a page about using Clojure on the Deeplearning4J website. Apparently there is an “official” port of Deeplearning4J to Clojure here. No offense to the other guy, but I think I will look at the official project first. I feel it is best to start with the official way of doing things before trying something unofficial. But it is always good to have options.

You’re welcome.

2017-11-06 Update

One thing I did this weekend was get permalinks working again on my blog. I got an SSL certificate from Let’s Encrypt several months ago, and I was not able to get permalinks to work. It bothered me for the longest time. Problem solved.

Not much on the Clojure API front.

I did look at Deeplearning4J, a deep learning framework written in Java. I cloned their repo of examples, and I got some of them working with gradle files, and learned a bit more about Gradle in the process. You can use a GPU, or a CPU. No messing with CUDA if you don’t want to.

There is even a Clojure wrapper for Deeplearning4J as well.

I had a post about using CPUs and GPUs from JVM languages for math/science/AI a while back. Since then, I have gotten both Neanderthal and Deeplearning4J to work on my system. I did mention Bytedeco, which is used by Deeplearning4J and a few other libraries. I looked at some of the Javadoc, and they use a LOT of static methods (see here for an example). I may leave Bytedeco for others and use some of the higher-level libraries, like Deeplearning4J. I think a lot of static methods is not idiomatic Java. I might consult “Effective Java” later for a second opinion.

I am going to include below one of the build.gradle files that I used to get some of the Deeplearning4J examples to work.

You’re welcome.

 

Recent REPL Values

This post will look at a few dynamic vars to look at recent return values in the Clojure REPL.

 

You’re welcome.

Working with list*

Today’s look into the Clojure API is a post on list*, and how it differs from list and conj.

list* takes as its args elements you want to add to a collection, followed by the collection. If the elements you are adding are primitives, it will return a flat list, simply adding the elements to the collection. Like conj, it adds the elements to the front of the list. Unlike conj, list* always returns a list, even if you give it a vector. If you are adding two collections, you will not get a flat list.

list takes elements to make into a list. If use this to add an element and a list, you will get a nested list.

 

You’re welcome.