Skip to content

Latest commit

 

History

History
executable file
·
2809 lines (1932 loc) · 177 KB

log.org

File metadata and controls

executable file
·
2809 lines (1932 loc) · 177 KB

100 days of code challenge 2018

20181229 - Day 106: TicTacToe for Virtual Study Group

Thoughts for today

Walking through a nicely functional approach to the TicTacToe game for the Clojure study group.

https://youtu.be/_eO7EsXO2XE

Code from today

Activities in detail

Functional TicTacToe for Clojure virtual study group

Added a few changes to the original code I saw in the videos by Brian Wills to make the board and players easier to read.

Also make the play-game function the required arguments of board and player-sequence, so that the function explicitly uses arguments rather than shared values. Using arguments also means that play-game can be called with different board states, this is useful for testing especially if a computer opponent was added as an option to the game play.

It would be cool to make an AI for both players and get the output from the game of two AI players shown. Would like to build a simulation like that seen at the end of the War Games movie, although this would look better as a web page rather than command line.

20181224 - Day 101: An extra day of code

Thoughts for today

Added some more 4Clojure solutions

Got a Logitech MX Ergo trackball mouse today and it is so nice to use. It is a trackball, so the mouse itself stays static on the desk meaning I dont need to move my hand around and reducing RSI. It also means I dont need a lot of space to use the mouse either. The trackball is tilted so my hand is in more comfortable position, the same position I maintain with my tented Model01 keyboard.

Just noticed that def supports a doctring, just like defn. Adding a string after the name in the def expression will be used as the docstring, assuming there is another value after the string (otherwise the name is just bound to the string).

Code from today

4Clojure

Activities in detail

4Clojure

Running tests and test report buffer

I use ~, t a~ to run all tests and the test report buffer will display in place of an existing buffer if the test buffer is not already showing. This is normal behaviour as I understand it. The test buffer should be the active window (has the cursor) so pressing q will quit the test report and show you the buffer that was in the window previously (eg. your repl). If you have the test report buffer shown in a window, then any new test report should always appear there.

If you find this behaviour not to your liking, you could look into Spacemacs Window Purpose layer to define a configuration to guide Emacs placement of windows (this is not something I have tried yet)

20181223 - Day 100: 4Clojure

Thoughts for today

100 days of code challenge completed. Was it worth it? Well yes, it got me coding almost every day, and overall I certainly achieved more than 100 hours of coding, probably more like several 100 hours of coding. The only thing I didnt do was work on a specific project every day, but that would have felt like work and I enjoyed having a break from that routine.

Will I do a 100 days of code challenge again? Not sure, its quite a hard thing to be consistent with. I will certainly keep a developer journal from now on as it has been very useful.

Write up of the 4Clojure exercises I covered in yesterdays Clojure study group broadcast.

Popped out for a few essentials in the last day I am prepared to go shopping before the holidays :)

Code from today

Activities in detail

4Clojure solutions write up

Continuing to write up a description on how I solved each 4Clojure exercise, explaining how I thought about the problem and different approaches possible.

Today was a write up and elaboration on the exercises I covered in yesterdays Clojure study group broadcast.

20181222 - Day 99: Clojure study group

Thoughts for today

Walked through 4Clojure challenges number 16 to 22 in the Clojure virtual study group broadcast today.

https://youtu.be/8u8y73zh0w0

Code from today

Activities in detail

Wrote up previous 4Clojure solutions, #12 to #15

Lots of fun with sequences and sequence related functions. Also included two exercises on defining your own functions.

20181221 - Day 98: Coaching and 4Clojure 53

Thoughts for today

Took Poppy to the vets for a checkup on her teeth, apart from a bit of plaque build up, they are fine. More teeth brushing for Poppy.

Cycled into Wagamama Southbank for another coaching session, getting my teeth stuck into 4Clojure challenge #53, a tricky one eventually solved with partition and partition-all.

Code from today

Activities in detail

Coaching - 4Clojure #53

Ouch, this was quite a tricky problem and very easy to get caught up in imperative thinking.

Trying to do this using loop/recur and reduce approach became very complex and we didnt get that working in the end.

I started a more functional approach along the right lines with partitioning up the data set so each combination of pairs could be compared to see if the second value was higher than the first. It took a bit of experiementing to realise I could also partition again using a function that grouped the pairs until the pairs stopped increasing. This second partitioning really put the data in to a shape that made it easy to process. Redundant data was removed and then the remaining partiions sorted by size (count) and the largest continuous sequence found. Then the partitions just needed to be flattened to get the right shape of data as a result.

2018120 - Day 97: Planning 2019 and 4Clojure

Thoughts for today

Planning activities for 2019, including ClojureBridge London events.

Code from today

Activities in detail

4Clojure exercise #51 - advanced destructuring

Another chance to read up about destructuring. Destructuring is a great way to reduce the amount of code you need to write by using pattern matching. We use destructuring to define local names from data structures, both in let functions and function definitions.

The challenge itself was fairly straight forward, just demonstrating a nested destructuring example.

20181219 - Day 96: User Feedback session & 4Clojure exercises

Thoughts for today

User feedback session for an interesting AI product. It was useful to hear from one of the users of the tool. However, a lot of distraction came from the team, especially in random discussions and discussions about how the tool should be used. This seemed a little about face, as we should be focusing more on how the user is working and fitting the tool around them. The more training we need to give to the users, the greater barrier there would be to adoption.

Code from today

Activities in detail

4Clojure exercises

As I was travelling on the train, I carried on documenting the solution to 4Clojure exercises.

20181218 - Day 95: Team Lunch - 4Clojure exercises

Thoughts for today

Team winter lunch with the team I will be working with in the new year. The venue was a very basic restaurant but with nice food. There are some interesting dynamics in the team, so will need to figure out how to work with them.

Code from today

Activities in detail

Team Lunch

Some awkwardness from the team as most people were meeting for the first time. I asked lots of questions and tried to make connections…

4Clojure exercises

Carried on adding to the 4Clojure repository of solution write-ups. Discussing challenge #49 Split a sequence.

There was a fairly easy solution using take and drop. However, with a little digging into the `clojure.core` the `juxt` function was a great way to show some abstraction over the drop and take.

20181217 - Day 94: Coaching and Emacs talk at Linux in London

Thoughts for today

Cycled into London today on the Brompton and my Tannus tyres still going strong. I finally got a moment to clean them too.

Another very productive coaching day in Wagamama today, covering the inside out approach to writing Clojure. I pushed 3 out of the 6 exercise we completed to Github.

Cycled over to SkillsMatter to give (finish writing) my Emacs for your digital life talk for Linux in London.

Code from today

Activities in detail

Coaching in Clojure using 4Clojure.com

Covered several Easy level challenges

Discussed the thinking approach to solving 4Clojure challenges and problems in general. Breaking down problems into very simple parts, solving simple parts and then building them up to solve the larger problem. Much easier to spot errors and find code that does not quite work.

Challenges in 4Clojure seem to ask for quite specific forms of result, eg, you must return a set or a vector rather than a list. This can be a little distracting as many times its simply the values inside the form that are important and where the test is actually taking place. In extremely simplistic terms you can still think of all collections as a sequence, although everything but a list has extra symantics and features you can use.

Worked through challenges #46 to #51 during the coaching session.

Emacs for your digital life

Presentation for the Linux in London meetup group. Lots of festive cheer, swag and I even won a reusable tea cup!

The aim of the talk was to show off the advantages of Emacs, so I created my presentation using org-mode.

See ~/Documents/emacs-spacemacs.org

20181216 - Day 93: Clojure Study group - ClojureScript reagent website with SVG

Thoughts for today

Extremely tired today.

Code from today

Activities in detail

Simple ClojureScript front end website with reagent

Walking through the basic concepts of building a front-end website using ClojureScript and reagent, a react-style library.

20181215 - Day 92: Clojure Hack day

Thoughts for today

Clojure Hack day was quite a small event however it gave us a chance to work on our own projects. Worked with Mani on some basic Clojure skills. Als worked on building a simple ClojureScript React style website with our primary school student (accompanied by her mom)

I also did a little more work with Scalable Vector Graphics, in the system monitor project I started a while ago.

SkillsMatter were kind enough to invite us to join in the event, however, there was some issue with food and SkillsMatter did initially exclude the Clojure group although eventually we were included in the event again.

Code from today

Activities in detail

Work on the service monitor application and using SVG graphics

Created a rough version of the CIDER logo using Clojure SVG (hiccup) sytax. Taking the HTML code for the logo, converted it to the Clojure SVG syntax.

20181214 - Day 91: Chasing references and 4Clojure #16

Thoughts for today

Chasing references for my next potential employers

Quick write up about 4Clojure exercise #16 - Hello world.

Code from today

Activities in detail

4Clojure challenge #16 Hello World

Discussing the str function to join values into a string.

Also covering how to write a simple function definition with fn and call that function inline. For completeness, added the short form for a function definition using the reader macro #()

20181213 - Day 90: What will be my next role?

Thoughts for today

Considering my options for my next role. There have been a lot of really interesting roles I have interviewed for. There is one that seems to require the widest use of my skills.

Code from today

Activities in detail

4Clojure Challenge #11 - conj with maps

Exploring the joining of maps and vectors into a map. Also explored some possible error conditions that can occur when using maps, such as incomplete pairs of keys and values.

20181212 - Day 89: Meeting Clojure data science company

Thoughts for today

A second meeting with Cervest, a very interesting data science company supported by Clojure tooling.

Also met with All Street Research who are looking to disrupt the financial industry and building systems in Clojure.

Did some 4Clojure on the train home.

Code from today

Activities in detail

4Clojure Challenge #9 Conj with sets

A very simple challenge using conj to add values to a set.

4Clojure Challenge #10 Intro to maps

A quick look at creating and extracting values from a map.

20181211 - Day 88: Clojure driven finance startup and 4Clojure

Thoughts for today

A lunch with a another company with Clojure roles, cycling to and from the meeting on the Bromptom. This time its Be-Social, a finance startup that is building an app to make spending money a more social activity and enabling friends and colleagues to share bills and other expenses.

Another 4Clojure challenge, this time #8 an introduction to sets.

Code from today

Activities in detail

4Clojure Challenge #8 introduction into sets

A quick bit of coding to experiment a little with sets. A set in Clojure represents a unique set of values, the order is not guaranteed and is actually not important, its the uniqueness that is important. You could always pull the values out and sort them if you needed something with there.

The contains? function is useful to return a boolean result as to if a value is within the set, or you can simply use the set as a function which returns the value if its present in the set or nil if not.

20181210 - Day 87: Coaching and uSwitch dojo

Thoughts for today

Another coaching session in Wagamama, very healthy and relaxing way to learn and teach Clojure.

Code from today

Activities in detail

Coaching session - 4Clojure #41

Challenge #41 is quite a fun one. Looking at the first and last test of the challenge we are given a sequential set of numbers, so it seems you could just write a filter function (or remove) and a specific function to only return the right values.

The middle test uses keywords, so there is no uniform way of removing elements of the collection based on their value. So instead we have to do remove elements by position (so following the spirit of nth).

Once you discover the partition function the problem becomes much easier to solve, as you can group the elements by their position in the collection. You can also step through a collection at a size different to the partition size you want to create. So with a partition of 2 and a step of 3 we can quickly get the shape of data we wanted. Then its just a case of tidying up the data to match the result using the flatten function.

https://github.com/jr0cket/four-clojure/blob/master/src/four_clojure/041_drop_every_nth_item.clj

Clojure dojo - Advent of Code day 9

Collective approach to solving the day 9 challenge of the Advent of Code. There was a lot of discussion around what the challenge actually was and the different ways to solve it. There were possibly a few too many people in our group and although this did lead to some very interesting discussions, we didnt get around to actually solving the problem fully.

Two versions of the solution were added to the jr0cket/advent-of-code-2018 repository

20181209 - Day 86: Coaching and advent of code challenges

Thoughts for today

Cleaned up the code from the first days Advent of Code challenge.

Mentoring my Clojure friend in the USA.

Code from today

20181208 - Day 85: MeetAMentor Clojure Study group

Thoughts for today

Inspired by the broadcasting by Tim Pote of his solutions to Advent of Code, I did my own spin of the first day of challenges.

Code from today

Activities in detail

Advent of code day one

A new Leiningen project created with the default template. Updated licence to Creative Commons.

lein new advent-of-code-2018

The first part of day one is a simple reduce + over the specific data set of frequency adjustments. Added the unique data set for day one using a different namespace as its a long data set.

To see if there was any performance difference with using either apply or reduce functions, gathered timing and bench marking results using the advent of code data set. Results show that apply is faster in this instance.

Part two was tricky as we need to manage state while we process the frequency-changes. We need to keep track of the frequencies that we adjust the device to each time.

I tried out the imperative and mutable solution (DONT DO THIS AT HOME!) that Tim Pote discussed in his broadcast and it worked, although did not feel at all like Clojure.

Then I took a functional approach with recursion, using loop and recur at a pretty low level of abstraction. Again that worked, although the code is a little procedural and certainly not getting the most out of Clojure.

The design was evolved to using reduce and then further to use reductions to create all the intermediary results of the reduce. This made a pretty great abstraction on the design and a really simple expression. One thing that was missing was a function similar to distinct except we wanted to keep just the duplicates, so a simple helper function was added.

20181207 - Day 84: Preparing for Virtual Study group

Thoughts for today

Really impressed with the first day of live streaming advent of code by Tim Pote. Tim took the opportunity to not just solve the problem, but discuss the different ways to approach the problem in Clojure: recursion, reduction and sequence operators.

Created and advertise the virtual study group for this weekend.

Prepare Advent of Code challenges for the Virtual Study group on Saturday

Code from today

Activities in detail

4Clojure challenges

Discussed the solutions to 4Clojure challenges 5, 6 and 7. Useful to remember that collection types are less important when comparing values as its the values inside those collections that are being compared. Often just returning a list or a vector makes no difference to the result.

20181206 - Day 83: Interview and 4Clojure

Thoughts for today

Meeting with the founders of All Street Research, a very interesting Financial services company, developing Artificial Intelligence systems in Clojure.

Documenting some interesting 4Clojure challenges.

Code from today

Activities in detail

4Clojure challenges

Described in detail the possible solutions to challenges 2 to 4.

https://github.com/jr0cket/four-clojure

Challenge 4 had an interesting sideline investigation of calling a keyword with arguments. Its assumed that calling the keyword :a has the same function signature as calling the function called keyword. So when calling (:a :b :c) the :b argument is taken as a namespace and the :c argument is the name of the keyword, which is then returned as the result.

20181205 - Day 82: Organising my 4Clojure solutions

Thoughts for today

Not a lot of energy today after 3 full days of events and 126km on the Brompton.

Started a repository for 4Clojure solutions, discussing the different ways they can be solved and any interesting approaches.

Code from today

jr0cket/4Clojure repository

Activities in detail

Created a new 4Clojure repository

lein new four-clojure

Added solution and discussion around challenge #1 - Nothing but the truth

20181204 - Day 81: ClojureX day 2

Thoughts for today

Everything ran much smoother today at the conference and I finally got my line-up for the panel.

Overall the conference went well. Unfortunately SkillsMatter mis-communicated that this was our biggest conference to date, this was incorrect as although we were well over 160 people, we did not break the 220 record from a few years ago.

All the videos from day one are already published on the SkillsMatter website and most of day two videos are there as well.

Had a great catch up with the speakers at the end of the day at the ‘speakers drinks and nibbles’ area. Some comments about this making the speakers a lot less accessible, which was obvious.

No time for coding today as I was exhausted after running the conference and cycling home.

20181203 - Day 80: ClojureX day 1

Thoughts for today

Lots of small challenges to face today with the ClojureX conference, the most noticeable issue being the stage placement which blocked the view of the screen by the speaker for the audience on the left hand side.

Started day one of Advent of Code and completed the first part.

Code from today

Advent of Code day one, part one

Activities in detail

Advent of Code day one, part one

I like the Advent of Code challenges as they have a nice engaging story to read as you try solving the problem. For the first part of the first day I did spend more time reading the problem description though, as it turns out the answer was very simple.

In part one, it sets the scene that you are falling through time and space with only a little device to help stabalise you. The device needs to be tuned to a particular frequency, but you dont know what. So the challenge gives you 100 frequency adjustments, unique to your own login to Advent of Code. The first part of the challenge is simply to total all those values together.

To solve the problem, I copied all the numbers into a vector and added them all up using reduce +.

20181202 - Day 79: London Clojurians workshop - Kafka and Spec

Thoughts for today

At the Clojure workshop today for a Kafka and clojure.spec workshop.

The kafka workshop showed us how to send information via a publisher and pull information from kafka using a consumer, all from within Clojure using the gregor library

The spec from the ground up workshop was a very detailed journey with lots of examples and exercises, for both defining and testing specs.

Code from today

Activities in detail

London Clojurians workshop

I organised a workshop the day before the ClojureX conference in London, to give a chance to work with Clojure developers outside of London.

There was a great turn out, especially as it was a Sunday. The venue provided by uSwitch was lovely, very posh and very comfy. It was just big enough for everyone and it was a very collaborative day.

Aleksandar ran an excellent Kafka session, first covering the essential theory, then diving into coding examples with Clojure driving Kafka producers and consumers. A Kafka instance was provided in a self-contained docker file and the code examples were on Github.

Deon ran a very detailed workshop on Clojure spec, the new library that provides a detailed and testable contract around you functions and data structures. Deon gave a brief introduction to Spec and then provided a series of challenges (in GitHub branches) to help us build up a series of different contracts and tests using spec. All the challenges and their solutions are on GitHub, in the spec from the ground up repository.

20181201 - Day 78: Clojure Study group - TDD Clacks

Thoughts for today

The fifth Clojure study group broadcast today was live coding a Test Driven Development approach to solving the Clacks encoder/decoder.

Also had another VR experience with Polybius on the PS4.

Code from today

Activities in detail

Clacks encoder/decoder - TDD approach

Broadcast a live coding session where the Test Driven Development approach was taken to write an encoder / decoder using the Clacks notation.

Clojure study group #5 broadcast

20181130 - Day 77: Coaching and Spacemacs cheatsheet

Thoughts for today

Spend a couple of hours coaching on hangouts today, guiding the installation of Spacemacs, enhancing the Clojure experience and how to start learning to use Vim-style editing. Added a Clojure Cheatsheet to the Practicalli Spacemacs book.

Activities in detail

Added a Clojure Cheatsheet to practicalli spacemacs

Learning Spacemacs does take a little time, as there are so many really useful features. To help focus the learning and not drown in features, I created a very terse cheatsheet to cover what I believe to be the absolute basics of using Spacemacs for Clojure development.

Updated Virtual Clojure study guide

Updated week 5 of the Clojure study guide. For the fifth week we will do some Test Driven Development.

20181129 - Day 76: ClojureX and CIDER debugging practice

Thoughts for today

Catching up with the volunteers giving the Clojure workshops this week. Also confirming the venue is equipped with everything required. I will be taking some power extensions (20 sockets).

Suggested a topic for the ClojureX panel: Spreading the spirit of Clojure to the other conference organisers, along with some suggested people to have on the panel.

Starting to get into the Cider debugger which is a very simple to use tool to trace value changes as you step through a function call. This debugger is especially useful for iterative and recursive functions.

Code from today

Activities in detail

Cleaned my .spacemacs configuration file

My .spacemacs configuration file was a little messy, especially the dotspacemacs/user-config section.

I moved all the older configuration sections and Emacs style custom keybindings to the bottom of the user-config section. Eventually these will all go once they are documented in the reference section of my Practicalli Spacemacs book.

Published the cleaned up version of the .spacemacs configuration file to my Github gists.

Cider debugger practice

CIDER includes a debugger that allows you to instrument a single function or all functions in a namespace.

Cider debugging in action

~, d b~ instruments a function for debugging, creating breakpoints so you can step through each evaluation and value in the function when it is called.

Call the instrumented function as normal and a menu appears above the function definition.

n steps the cursor through the function, showing the value of each symbol or expression evaluation in turn. You can step through the whole execution of the function or stop using q.

Juraj Martinka has a nice video showing the cider debugger in action.

The also a fledgling project called Sayid that adds even more detailed debugging, however, the CIDER debugger is a really useful place to start debugging Clojure.

20181128 - Day 75: Working on books & VR games in Playstation 4

Thoughts for today

Wow, I just got a PS4 with VR headset and oh my is it emersive. I got the game Ploybuis from Llamasoft and it is amazing playing it just on the TV, but in VR it is unbelievably awesome. Watch the video on the website for just a small taste of how amazing this game is. Please do not watch the video if you suffer illness from strobing lights.

Also fitted my Beeline smart navigation device to the Brompton, so just need to get out of the house and try it. It has a decent sized display for a bike and shows you the general direction you are heading. Its linked to Strava and Google maps, so you can set a pre-defined route or you can set a destination and let the Beeline suggest turns you can talk along the route. Hopefully this is a bit less annoying than the Google maps voice directions updates when I take alternative turns than suggested.

Added some more content to the books.

20181127 - Day 74: Refactor 4Clojure Compress a sequence using partition

Thoughts for today

Although we had a solution for the 4Clojure challenge 30, compressing a sequence, I felt there was a different approach using a function called partition. So today I refactored the code and found a nice elegant alternative.

Activities in detail

Refactored 4Clojure #30 using partition-by identity

Created a much more elegant and idiomatic solution to 4Clojure #30, Compress a sequence challenge. Rather than try to iterate over the collection and only return the unique values, if you partition by identity then all values are grouped together, so you only need to take one of each to create the correct result.

Analyse the problem.

I thought that I could divide up the pattern as a way to identify duplicates. partition by two creates pairs but doesnt help with identifying duplicates

(partition 2 [1 1 2 3 3 2 2 3])
;; => ((1 1) (2 3) (3 2) (2 3))

partition by 2, but only stepping through by 1 creates all the possible sequence of pairs its now easy to see the duplicates

(partition 2 1 [1 1 2 3 3 2 2 3])
;; => ((1 1) (1 2) (2 3) (3 3) (3 2) (2 2) (2 3))

so if we filter out the duplicates then we should be close

(filter
 #(not= (first %) (second %))
 (partition 2 1 [1 1 2 3 3 2 2 3]))
;; => ((1 2) (2 3) (3 2) (2 3))

The structure is not quite right, so lets flatten it

(flatten
 (filter
  #(not= (first %) (second %))
  (partition 2 1 [1 1 2 3 3 2 2 3])))
;; => (1 2 2 3 3 2 2 3)

Oh, thats not right. It feels close, but how to merge correctly?

changing track a little lets use a variation of partition called partition-by and use the identity function to create a sequence for each value

(partition-by identity [1 1 2 3 3 2 2 3])
;; => ((1 1) (2) (3 3) (2 2) (3))

Then we can get the first value from each sequence

(map
 first
 (partition-by identity [1 1 2 3 3 2 2 3]))
;; => (1 2 3 2 3)

This works for the vector of vectors test too

(map
 first
 (partition-by identity [[1 2] [1 2] [3 4] [1 2]]))
;; => ([1 2] [3 4] [1 2])

But it doesnt quite work for a string, but its so close

(map
 first
 (partition-by identity "Leeeeeerrroyyy"))
;; => (\L \e \r \o \y)

so it seems we need to treat the results slightly differently two results are a collection, one is a sequence of characters. If we test the result to see if it contains characters then we can post-process the result, reducing it to a string. So lets put the result of our partition into a local name then process the result if it contains chars.

((fn [pattern]
   (let [compressed (map
                     first
                     (partition-by identity pattern))]
     (if (char? (first compressed))
       (reduce str compressed)
       compressed)))
 "Leeeeeerrroyyy")
;; => "Leroy"

Now try the function the the other two tests.

((fn [pattern]
   (let [compressed (map
                     first
                     (partition-by identity pattern))]
     (if (char? (first compressed))
       (reduce str compressed)
       compressed)))
 [1 1 2 3 3 2 2 3])
;; => (1 2 3 2 3)


((fn [pattern]
   (let [compressed (map
                     first
                     (partition-by identity pattern))]
     (if (char? (first compressed))
       (reduce str compressed)
       compressed)))
 [[1 2] [1 2] [3 4] [1 2]])
;; => ([1 2] [3 4] [1 2])

The test that uses a string type, also has a call to the result that will convert it from a sequence of characters into a string. So there is no need for a particular test for the type so we can simplify the result.

(fn [pattern]
  (map first (partition-by identity pattern)))

Submitted answer to 4Clojure

(fn [pattern]
  (map first (partition-by identity pattern)))

20181126 - Day 73: Coaching, dojo and 4Clojure

Thoughts for today

Face to face coaching in Wagamama today, covering some of the 4Clojure exercises

Went to the Thoughtworks Clojure dojo and worked on some more 4Clojure exercises. Got a bit entrenched in #30 Compress a sequence.

Code from today

Activities in detail

Solving 4Clojure number 30 - compress a sequence

The 4Clojure challenge 30 is to compress a sequence with three tests.

http://www.4clojure.com/problem/30

Write a function which removes consecutive duplicates from a sequence.

(= (apply str (__ “Leeeeeerrroyyy”)) “Leroy”) (= (__ [1 1 2 3 3 2 2 3]) ‘(1 2 3 2 3)) (= (__ [[1 2] [1 2] [3 4] [1 2]]) ‘([1 2] [3 4] [1 2]))

(apply str ( #(reduce (fn [reslist listvalue]
                        (if (not= (last reslist) listvalue)
                          (conj reslist listvalue)
                          reslist))
               [] %)
               "Leeeeeerrroyyy"))

20181125 - Day 72: Virtual Clojure study group & Coaching

Thoughts for today

Ran the fourth virtual study group, discussing apps with maps as a way to think about how to model information with Clojure

Caught up with my friend in the east coast USA for some coaching. Today we looked at the Duct library from James Reeves. The nice thing about Duct is that it is very data focused. We got a duct website up an running from Spacemacs very easily, its just lein new duct project-name, open the source file in Spacemacs and then run cider-jack-in, ~,’~

Code from today

***

Activities in detail

Apps with Maps - Clojure study group

Looked at defining data structures using Clojure maps (hash-map) which is a key-value pair data structure (like json but much more flexible in the type of content you can use as keys and values.

Discussed how to get information out of maps, using the get and get-in functions. Also showed that keywords and maps can be used as functions, which can sometimes be useful when writing short inline functions, eg. conditional functions with map or filter functions.

See the video: Clojure Study group #4 - working with data in Clojure hash-map

20181124 - Day 71: London Java Community conference

Thoughts for today

Attended the excellent London Java Community conference, which is an unconference style event. The event started with a talk from Simon Ritter on Java 11 whilst I worked with the other organisers to assemble the schedule from the talk suggestions. There was a great selection of talks which were grouped into the themes Architecture, AI & Machine Learning, Core Java, JVM languages, agile practices and self improvement.

./images/london-java-community-conference-2018-schedule.png

I had the chance to broadcast two talks from the Conference, a lightning talk on broardcasting and a live Clojure hacking session called Clojure loves data

20181123 - Day 70: Prepare talks for LJC and Virtual Study group

Thoughts for today

Created code examples for a Clojure talk at the LJC conference.

Code from today

***

Activities in detail

Clojure loves data talk for the LJC conference

Its the LJC conference tomorrow, so I created some code examples to hack on for my talk. The talk will be walking through the code, evaluating it to show the results and discussing how Clojure takes a functional and data focused approach to design.

20181122 - day 69: Interviews and clojure.test basics

thoughts for today

Second interview

London Clojurians meetup at Funding circle

Wrote a quick overview of the testing libraries and test runners available for Clojure.

Added a quick introduction into clojure.test, to be expanded on soon.

activities in detail

New: Working with maps

The basics of working with hash-map collections, including techniques for iterating over the maps.

New: Overview of testing in clojure - initial draft

Create a quick overview of the libraries and test runners available for Clojure. Will extend this section in future to identify commonly used libraries and tools.

New: Simple introduction to testing with clojure.test

A simple introduction to testing with clojure.test, covering assertions, testing function, naming of test function and namespaces.

Clojure.test is the most commonly used test framework as it is shipped with Clojure already.

20181121 - day 68: Interviews

thoughts for today

Today is the first job interview I have had for 15 months and only the fourth interview in the last 6 years, so will be interesting to see how prepared I am.

Turns out it was a great interview, I really enjoyed it. There are still a few more steps in the process, but a very good way to start and helps build my confidence.

More work on the code examples in the Clojure->Code repository to support the Practicalli Clojure book and a first draft of the chapter on Macros. There is much more I can add to the discussion of macros and how to write them, but for now its important to define when to use them and the constraints around their use.

activities in detail

ClojureBridge London exercises and solution discussions

Exercises from the ClojureBridge London workshop and a discussion on how those exercises were solved.

Add: Section on Macros

A brief explanation of macros and suggestions of where to use them.

20181120 - Day 67: Clojure->Code exercises

Thoughts for today

Continuing to practice Clojure code by working through and organising my Clojure Through Code examples.

Activities in detail

Defining and generating ascii codes for an alphabet

Examples of how to define a collection that represents the ascii codes for an alphabet.

Generating ascii codes given a starting reference.

Update: ascii code generator - simplified

Use of a for loop is not required as map can be used to join two collections together, in this case the collection that is the English language alphabet and the generated range of ascii characters.

The range of ascii characters is a sequential whole number series, starting from the given ascii code. So to generate the ascii number collection, range function is provided the start code value and a calculation of the end code value.

Add: Palindrome checker in functional concepts section

Various approaches to writing a palindrome checker.

20181119 - Day 66: Practicalli Clojure - core.async ideas

Thoughts for today

More work on the Practicalli Clojure book, this time some thoughts on what to include for a core.async section.

Activities in detail

New: core.async section - very basic start and brain dump

Started a new section on core.async

Several example projects come to mind in order to explain how to use core.async

  • Bike assembly line - some tasks can be done in parrallel, but not all
  • Toy car assembly - summary of ideas from PurelyFunctional.tv
  • Clacks messenger - visualise the Clack towers using the light patterns encoder-decoder code from earlier sections.

20181118 - Day 65: Coaching and Practicalli Clojure book

Thoughts for today

Coaching this evening, revisiting the Hoplon project but unfortunate it doesnt seem to run from CIDER. Not sure why its broken.

Discussed the libraries that have been moved into the clj-commons Github organisation and submitted an issue to add the Github pages link to the description of the clj-commons.github.io repository.

Discussed Finite state machines in Clojure and libraries that help define finite state machines. Finite state machines libraries include:

A new idea for a future coaching session is to try the Duct project for building a server side application and also use a Finite State Machine to model the UI. Inspiration comes from the blog: Restate your UI using state machines to simplify user interface development

More work on the Practicalli Clojure book.

Activities in detail

Added Clojure naming conventions

Described with examples the common naming conventions used in Clojure.

Added Clojure overview in 10 big ideas

Added Stuart Halloway’s 10 big ideas (although there are 11) as a way to think about the fundamental concepts that underpin Clojure.

New: Clojure in 15 minutes

Covering the syntax of the Clojure language with some relatively simple examples.

20181117 - Day 64: Clojure Study group and Zulip signup

Thoughts for today

Third broadcast of the Clojure virtual study group, covering structural editing and the first 15 problems from 4Clojure.

Joined the Clojurians community on Zulip, an open source version of Slack. Zulip makes conversations more effective by adding the concept of topics to streams (streams are channels in Slack). Discussions within a Stream are all within a topic, helping focus those conversations and making it much easier to catch up with those conversations after they have happened.

Code from today

Structural editing example - clojure->code

Activities in detail

Zulip open source chat alternative to Slack - Spacemacs stream

I signed up to the clojurians.zulipchat.com community and I really like the UI, especially the concept of putting messages in a stream within a topic. Streams are channels in Slack. When you post a message in a stream, you supply a topic for the message. The message displays in chronological order in the stream, however clicking on the topic name in the left hand navigation, you can view only the messages for that topic.

Virtual Clojure Study Group #3 - Structural editing and 4Clojure

Covered the basics of structural editing using Spacemacs.

Discussed the first 15 4Clojure problems and discussed how to help solve problems by looking at the `clojure.core` function documentation and source code.

20181116 - Day 63: Practicalli Clojure updates

Thoughts for today

Working on the Thinking Functionally section of the Practicalli Clojure book

Activities in detail

Updated Thinking Functionally section to use Klipse

Use Klipse to enable live example code for the Thinking Functionally section, allowing the reader to experiment with the code examples in the page.

Updated recursion page in Thinking Functionally section

Discussed the constructs available in Clojure for recursion, loop and recur, named function calling itself, map reduce etc, for

Added examples of these approaches to recursion.

Very rough notes on Transducers

Transducers are a very efficient way to transform data, especially complex transformations.

20181115 - Day 62: Redis Days conference

Thoughts for today

Applying for jobs today as well as being at the Redis Days conference. No time for code today. Day 62 - at RedisDay conference

Submitted Emacs talk to Linux In London community.

Activities in detail

Applying for several jobs

Still using Google docs for my CV as it generates a nice looking PDF file and I can always find the documents easily, regardless of which computer I am using (so long as there is Internet access).

Eventually I will write my CV in org-mode and get that to generate some really nice PDF and Latex output files. I can then keep everything on Github (although not sure about sharing this sort of thing publicly in case dodgy recruitment consultancies try and abuse it. I think that is low risk, but will think more about it.

Day 62 - at RedisDay conference

Lots of interesting talks and some very interesting people to talk to.

Applied for a few jobs, mostly Clojure and one Developer Relations role.

Submitted Emacs talk to Linux In London community.

20181114 - Day 61: Practicalli Clojure updates

Thoughts for today

Updated the Practicalli Clojure book to use Version 3 of gitbook. Tweaked the styles to use a similar style to the improved ClojureBridge London styles.

Activities in detail

Updated Gitbook configuration to version 3 and tweaked plugins

Updated the book.json configuration of Gitbook to use version 3 and above.

Removed older plugins no longer used - exercises, quizzes, sunlight-highlighter.

Added plugins

  • simpletabs - for tab sections with in a page, eg. for operating system specific instructions in the developer tools section
  • youtube - adding embedded YouTube videos by just specifying the URL
  • wide-page - set the page width to be wider (narrower margin either side of each page). This is very useful for larger and wide screen displays.

Ran gitbook install to update the plugins in the Gitbook directory.

Updated to match latest Practicalli CSS styles on website

The ClojureBridge London workshop has been used to improve the style used by the Practicalli series of books. Bringing Practicalli Clojure in line with this style.

20181113 - Day 60: 4Clojure code from dojo

Thoughts for today

Expanded on the code created during the Coding dojo, detailing the design decisions that went into solving the problems.

Activities in detail

4Clojure #18 Sequences - understanding filter function

4Clojure problem #18 can be easily solved by evaluating the filter expression in the REPL.

I describe how the filter function works and compare it to other functions that have related behaviour. This gives a more complete understanding of the filter function.

4Clojure #26 - Fibonacci Sequence

Analysis of the classic problem of generating the Fibonacci Sequence. The approach taken was to add the last two values of the sequence to create the next number, starting with a seed value of [1 1].

Detailed how the design was evolved using a simple loop recur iteration, showing the incremental changes in the design until an answer was found.

The local names in the code base were kept of reasonable size to be meaningful, but could have been converted to single characters to get a slightly lower golf score (although that isn’t important).

4Clojure #61 - Map Construction - decomposing zipmap

I like the 4Clojure problems where you have a restriction, as its a great opportunity to learn about the restricted function (or functions).

In this example, zipmap is restricted as it is the exact function that would solve the problem.

By looking at the implementation of zipmap and analysing the problem, a design was evolved that solved the challenge and helped us understand how zipmap works. This will be useful in understanding when to apply zipmap.

The incremental steps taken in this design show how conj and reduce functions can work together as well as how they can be substituted by the into function.

20181112 - Day 59: Practicalli Clojure updates

Thoughts for today

Started on the update process of the Practicalli Clojure book, there is a lot of work to do to get it where I want it to be.

Clojure dojo at uSwitch, working on some interesting 4Clojure challenges

Activities in detail

Added study guide for the virtual study group I run

Study guide is evolving, although covers the first few weeks specific sessions. There is also suggestions of topics to be covered in the future.

Included logos for YouTube Live broadcasts, hangouts and recorded broadcasts.

New version of Development Tools for Clojure development

Using the content developed for ClojureBridge London the development tools section has been completely overhauled and should be much simpler to follow.

Moved the existing content to the end in case there is something extra that is worth factoring into the new content.

20181111 - Day 58: ClojureBridge editor user guides - Spacemacs

Thoughts for today

Writing the Spacemacs editor guide for ClojureBridge.

Updating the study plan for the Clojure Virtual Study Group (Virtualli Clojure? or just make it part of Practicalli).

Activities in detail

Spacemacs editor user guide

Embed the YouTube video created previously on how to use the Clojure REPL in Spacemacs.

Described the actions in the video, along with the most used keybindings for starting a REPL, evaluating code and changing namespaces.

Added links to Spacemacs documentation and to Practicalli Spacemacs.

ClojureBridge content updates - improving clarity of exercises

After a recent run through with a new student, some of the exercise descriptions seemed vague, as did some of the explanations in the answers.

Updated the time to numbers exercise in simple-values section Updated description of reading values from a sequence in collections section Updated average age of languages exercies in collections section

20181110 - Day 57: ClojureBridge editor user guides - Atom & ProtoREPL

Thoughts for today

Broadcasting the second virtual study group for Clojure and created a logo for Live broadcasts and hangouts, using Inkscape.

Writing the editor guides for ClojureBridge London to describe what I did in the videos and provide a simple reference.

Activities in detail

Organised Gitbook plugins alphabetically

Arrange the plugins in alphabetically order within book.json making it easier to review.

A standard alphabetical order provides easier to use diffs when compared to the book.json configuration in Gitbook book projects I am developing.

Atom and ProtoREPL editor guide

Providing an embedded view of the YouTube video I created a couple of days ago.

Described how to start a Clojure REPL for ProtoREPL, the most common ways to evaluate code and changing to a different namespace.

Keybindings for ProtoREPL are provided as a quick reference.

Added images for MacOSX install, missing from the deployment guide commits.

YouTube logos with Inkscape

I wanted to add a graphical image to the Virtual Study Guide section of Practicalli Clojure, so students could easy find the recordings, live broadcasts and hangout links.

In the spirit of broadcasting my work, I recorded a video of how I created the first logo using Inkscape and some images found on WikiMedia.

<iframe width=”560” height=”315” src=”https://www.youtube.com/embed/Ki7C17FPPnQ” frameborder=”0” allow=”accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture” allowfullscreen></iframe>

20181109 - Day 56: MeetAMentor exercises and YouTube broadcasting solved

Thoughts for today

Preparing the ClojureBridge London exercises into the REPL in order to review them in the next hangout for MeetAMentor Clojure study group.

Finally figured out how to manage events and start hangouts in YouTube. Realised its not possible to change the type of streaming, so for now just using hangouts rather than my own streaming software. Will try Open Broadcaster System (OBS) at some point.

Code from today

ClojureBridge exercises in the REPL

Activities in detail

YouTube Live Streaming with Hangouts on Air

Open YouTube Creator classic Live Streaming Events

https://www.youtube.com/my_live_events

Create an event to either start now or schedule

Click on the New live event button

Enter the basic info about the event

Do not change the event Type (default Quick)

Once the event has been created, you cannot change the event Type (and there is no way to delete an event it seems)

Getting the hangout link

In the Live Streaming events list, click the Start Hangouts On Air button. This opens the hangout but does not start broadcasting.

In the hangout popup window, click the person icon to get a link to join the hangout.

Start broadcasting

Only start broadcasting once you are ready, as once you stop the broadcast it cannot be started again.

20181108 - Day 55: DevRelCon London

Thoughts for today

Its DevRelCon London conference today and a chance to catch up with some friends in that community.

Code from today

Activities in detail

DevRelCon: Getting Intentional about educating developers

The award wining Joe Nash gave a great talk on how developers learn today, discussing why they are looking for a complete learning experience.

Developers have always been self learning, even if they went to University. Self-learning is a requirement for a developing your career and keeping things interesting. When learning you want a great experience and developers are investing in online courses and learning via video tutorials has seen a huge growth.

So what is a great experience?

The learning should connect to the individual learner. They should know what they are going to learn, what they should know before they start learning (pre-requisites) and where to learn that. They should also gain a sense of mastery once they have finished the learning lesson, in that they know what they can do with their new skill. That skill should be clearly connected to the overall think you are trying to teach the developer.

Organise content into easily digestible pieces that allow developers to learn specific aspects of the topic. Developers will learn at their own pace and can have quite different goals that are relevant. Each learning path should be self-contained in that it can be completed with a reasonable amount of effort, in a reasonable amount of time and without additional requirements (except the pre-requisites).

Developers learn by doing, so practice is vital part of the learning tools. With online courses this practice should be built in and the most effective courses are learning by exercises. This practice should be tightly coupled with fast and relevant feeback to ensure that the developer is making progress. Without timely and useful feedback it is likely that a developer will get frustrated and either change what they are learning or move to another approach to learning (eg. if they are externally motivated to still learn)

Practice builds up confidence and moments to Reflect help to cement the wider picture of all the things you have learnt. So exercises to pull from individual learning steps into a larger exercise can be valuable to demonstrate the big picture.

20181107 - Day 54: ClojureBridge London basic editor use videos

Thoughts for today

Created two videos showing the very basics of how to use editors for REPL driven development in Clojure, for Spacemacs and Atom & ProtoREPL

Feeling quite unwell most of today, so didnt get any time for coding

Code from today

ClojureBridge London

Activities in detail

ClojureBridge London basic editor use videos

To make it easier for the attendees (and coaches) for ClojureBridge London, I’m creating minimal guides on how to use the recommended editors.

The guides are kept small so they do not overwhelm those new to coding and cover just the essential actions, opening a Clojure file / project, starting a REPL and evaluating code. I also included how to change to the namespace of a project, as editors typically start in the `user` namespace.

Atom & ProtoREPL basic user guide

Spacemacs basic user guide

20181106 - Day 53: ClojureBridge London Editor install guides ?

Thoughts for today

Code from today

***

Activities in detail

***

20181105 - Day 52: YouTube Channel Banner design and Design Journal discussion

Thoughts for today

Getting creative with images and visuals today. As I have been creating more video content on my YouTube Channel, it was time for a visual update. So I fired up Inkscape and got creative.

In the past I have created some infographics as developer guides to Git and Heroku, to help people learn those tools.

Code from today

Activities in detail

Designing a new banner image for my YouTube channel

Imagery, banners and logos for the Practicalli series of books and other communication channels where Clojure is taught by John Stevenson.

I am not a graphic designer, however, with the use of Inkscape and Scalable Vector Graphics, I can create some nice visualisations of information and themes.

## YouTube channel banner Practicalli Spacemacs playlist contains the all the videos created for the Practicalli Spacemacs book.

I have also started running a Clojure study group via the MeetAMentor community, using Hangouts On Air, which uses my Youtube account and imagery. So I have updated my YouTube banner from a nice picture of my cat, to a simple representation of the topics I cover in my channel.

YouTube can be viewed on different devices and each one is supposed to have a different size (although when actually testing this, it seems that YouTube uses pretty much the same part of the banner image regardless of media).

Initially I just created a design with the Logo’s, however, this felt a little too simplified and would not have said anything to those who didnt recognise the logos.

The design was refactored to place the names the logos represented under each logo. The font used was Ubuntu as its an elegant font to use. The colour of each name was taken from the predominant colour of the logo it describes. There was not much difference between the Green and Blue of the Clojure logo but Green seemed to work better for the text.

The finished banner design can be seen via the Imagery Design Github repository and on my YouTube channel.

Design Journal discussion from my REPL Driven Development article

On day 49 I published an article on REPL Driven Development and had some interesting comments, so I replied this morning.

Juraj Martinka left the following feedback: The idea of Design Journal sounds interesting. However, it seems there can be a lot of clutter eventually and that those examples can easily get out of sync. Do you really use this idea in your production code? How do other programmers/colleagues react to such code? Do you think it’s really the right medium for capturing design decisions (and ‘roads not taken’)?

My reply to Juraj’s feeback was:

A design journal is also talked about by Stuart Halloway in the “Running with Scissors talk” I believe and certainly in the apropos_cast podcast. It was good to hear I am not the only one doing this.

As I continually use these examples for further development of any code base and as REPL based tests for my understanding of what the code does, then the examples are always in sync. If something is part of a road not travelled, then it is documented so, at the point that it happens. Lazyness is for sequences, not developers :)

If sections become less relevant, it is an option to transfer these examples to a separate design document and simply include a link to the relevant section as a comment in the source code.

I dont consider the journal clutter, although this is quite a subjective point I agree. No one has raised this point when I used these technique until now, however, it is a good point that the design journal should be well written.

What code goes into production is defined by the team I work with, as yet though I havent come across any reasons why not to include this in what is shipped.

I would say the design journal is a very useful and interactive approach for capturing design decisions. What the right approach actually is will be up to the team working on the code base. I suggest this approach is more correct than not capturing these decisions at all.

Certainly this information could be moved into a design document, assuming the team were prepared to constantly update such a document. Literate programming design documents using Klipse or Org-mode babel would give live documentation that included an active repl, allowing you to get the feedback from code without having to switch back and forth between documentation and code editor (switching like this is one of the reasons documentation goes stale).

20181104 - Day 51: Over half way there

Thoughts for today

Code from today

***

Activities in detail

***

20181103 - Day 50: London Clojurians events update and Practicalli Clojure

Thoughts for today

First MeetAMentor Clojure study group hangout went pretty well, although I had problems with YouTube initially as I couldnt open the YouTube website in Chrome.

Code from today

*** repl.it clojure in 15 minutes

Activities in detail

*** First MeetAMentor Clojure study group hangout

20181102 - Day 49: Practicalli Clojure

Thoughts for today

Code from today

***

Activities in detail

My approach to REPL driven development

20181101 - Day 48: Practicalli Clojure

Thoughts for today

Code from today

***

Activities in detail

***

20181031 - Day 47: Working on MeetAMentor Study group content

Thoughts for today

Assembling the Clojure study group content for the first week.

Code from today

Activities in detail

MeetAMentor Clojure study group content

The first hangout will be used to give an overview of Cljoure, how its used by companies and a quick tour of the basic syntax.

Created an overview of the Clojure syntax, with some relatively simple Clojure code examples.

20181030 - Day 46: Clojure dojo

Thoughts for today

In the dojo this evening, one group hacked on Scalable Vector Graphics with Clojure, using my Tic-Tac-Toe game as a basis.

Code from today

Update: Added Helm Transient state to Buffer tidy up section

Activities in detail

Update: Added Helm Transient state to Buffer tidy up section

Added section suggesting Helm Transient state should you have many buffers to work on.

Tweaked the state Keybinding and the suggested Gnome keybinding on the Helm Transient State section.

20181029 - Day 45: New Tannus Tyres and Clojure Study group curriculum

Thoughts for today

Defined a curriculum for a Clojure Study Group, as part of the Meet A Mentor community.

Collected the Tannus tyres for my Brompton bike and fitted them ready for riding to the Clojure dojo tomorrow at Thoughtworks.

Some more hacking on Spacemacs book.

Code from today

Activities in detail

Defining a plan for the Clojure Study Group (Meet A Mentor community)

I suggest the followng schedule for the Clojure study group and would appreciate your feedback, especially as to the topics and level of the plan. Start date is either 3rd or Sunday 4th November (based on your feedback)

Week1: Overview of Clojure - covers the syntax, a few common functions, how to start learning Clojure and REPL driven development. Homework: practice writing some simple Clojure.

Week2: Tooling and practising - briefly covers the different editors that give a good Clojure experience, resources for practising Clojure (4Clojure, Exorcism, CodeWars). Homework: some 4Clojure exercises

Week3: Data Structures and Immutability - understanding how to model the world with immutable data (values) Homework: writing a simple encoder/decoder challenge and more 4Clojure exercises

Week4-8: Thinking Functionally - writing your own (pure) functions, using sequences, lisp comprehension, higher order functions, functional composition. Homework: various small challenges and 4Clojure exercises.

If there is interest, we can also start a project to build a web application in Clojure (or a full stack app with Clojure/ClojureScript) at any point after the first week.

New: Git Blame to review commit history

SPC g b opens a buffer showing the commit history of the current file, by author of each commit.

RET will show the details of the commit under the cursor.

20181028 - Day 44: Spacemacs book improvements

Thoughts for today

Stocking up on healthy food for the winter and Brexit fallout. Ordered lots of chickpeas, soyabeans, mung beans, butter beans, black rice, apricots, dates, and spices to make sauces with.

Then hacked on the Spacemacs book some more.

Code from today

Added: Version control change highlighting

Update: Magit section and status refresh keybinding

Activities in detail

Added: Version control change highlighting

Described two methods of highlighting changes, fringe and smeargle.

Update: Magit section and status refresh keybinding

Updated the section names in Magit for clarity

Added `g r` keybinding to refresh the magit status buffer.

20181027 - Day 43: Spacemacs book improvements

Thoughts for today

Some quick hacking on the Spacemacs book

Code from today

Update: Vim tips for developers & Speaking Vim

Update: Used Spacemacs keybindings for Clojure Inspector

Activities in detail

Update: Vim tips for developers & Speaking Vim

Moved the more-vim section to vim-tips-for-developers, defining keybindings and tips specifically useful for working with code.

Added surround to speaking-vim action section and put actions, modifiers and text objects in alphabetical order to make them easier to learn.

Update: Used Spacemacs keybindings for Clojure Inspector

Noticed the Inspector was using the M-RET keybinding form, rather than SPC.

20181026 - Day 42: Funding London-Clojurians via OpenCollective and hacking on Spacemacs book

Thoughts for today

A tweet by Martin … who created Clojureverse let me know about OpenCollective, a way to fund open source and community based organisations. So I set up an OpenCollective for London Clojurians.

Code from today

***

Activities in detail

Update: Vim quick reference and tips pages

Refactor the grouping of keybindings and tips into a logical order, to make them easier to discover and hopefully learn. This curating of Vim keybindings and tips will be put into a video (or small series) on getting the most out of Vim style editing in Emacs.

Precursor - a ClojureScript app for collaborative design

Used Precursor app to create a simple sketch of the Status Monitor app I am building. Precursor is a collaborative sketch tool that feels very modern and looks great, its also pretty easy to use. I would still use Inkscape for infograms, developer guides and other single page graphics as there are many more features, however, Precusor seems much more effective for sketching out ideas and of course collaborating in real time.

Precursor is also written in ClojureScript and there was a short but interesting article from its author about ClojureScript as a product design tool.

Funding London Clojurians community

Created a London-Clojurians meetup on OpenCollective as a first step to providing a facility for people and companies to donate to the London Clojurians community.

A budget has been added of $300 to cover basic expenses for the year, which breaks down as Meetup.com expenses and stickers for LondonClojurians and ClojureBridge.

20181025 - Day 41: Spacemacs videos - narrowing, iedit, yasnippets

Thoughts for today

I had a few issues with the Internet connection today, so I created some short screencasts on using Spacemacs. I am back on line and the videos are being uploaded. I am getting more comfortable doing short videos without the need for a lot of preparation. When ever I see a situation that suits a video, I make one (and avoid pontificating about it).

Added to the Spacemacs book, an overview of the Sayid debugger and Vim tips for Clojure developers, especially around simulation of basic structured editing using surround.

Code from today

Activities in detail

Youtube Videos

20181024 - Day 40: Coaching, ClojureBridge and orgmode fun

Thoughts for today

Coaching a new student today using the ClojureBridge workshop. Just an hour for the first session in which I gave an overview of Clojure and supported them through some simple exercises.

Testing out how well org-mode images display when pushed to Github.

Discovered SPC n + and SPC n - to increment and decrement numbers. When creating a new journal entry I copy from a previous day and paste it as the current day so I have the same structure (I should use a snippet instead). To update today’s entry from day 39 to day 40, rather than changing the word with cw and typing in 40, I jumped to 39 (SPC j j 9) and used SPC n + to update the number.

Code from today

Refactor: Exercise time to numbers - clearer wording

Activities in detail

ClojureBridge London workshop - refactor: Exercise time to numbers - clearer wording

Refactored the descriptions for the challenges to remove some ambiguity

Adding images in orgmode and defining their size

I am using more images in the log so its handy to see them displayed rather than just as links.

~, T i~ will toggle the display of images in Spacemacs

. i l pops up a prompt to create link from either a web address or a local file name, followed by a prompt for the link text. Selecting text before calling org-insert-link will use that as the default link text.

Any previously used links will be remembered and presented in a helm list, so you can easily narrow down to the link you wish.

Defining images size in orgmode

The att_org attribute can be used to add meta data to your image, including the :width or :height of an image.

So if an image is 400 pixels but is too small, you could set the display size for the image to 80 pixels using #+attr_org: :width 800

./images/circleci-clojure-start-build.png

It will be interesting to see if the meta data is picked up by Github when it renders the orgmode file.

If the attr_org does not work then there is also attr_html which I assume is used when exporting an org-mode file to HTML.

20081023 - Day 39: Applying Bootstrap to the Status Monitor

Thoughts for today

Looking at some Hiccup tips to improve the way I use the library. Adding a better look to the Status monitor front page with some Bootstrap magic.

Code from today

Activities in detail

Hiccup in action

Hiccup is a very easy to use library and I find it so much better than writing HTML directly. As Hiccup is defined as a data structure it is very easy to edit and manipulate using the structured editing tools that come with Clojure editors. As Hiccup is just data structures its also easy to generate them with Clojure code.

The Hiccup library API is clearly defined, the documentation could do with examples though. Luckily the Internet has lots of examples. There is also a selection of Hiccup tips from PurelyFunctional.tv.

Adding Bootstrap to the front page

Updated the form to use BootStrap to make it more usable and have a better aesthetic.

Although Hiccup is a little short on examples, it is generating HTML so its fairly easy to figure out what needs to be created. This holds true for Bootstrap too. Much of the time its a simple case of just adding the right style in the right place. Styles are just a map so its easy enough to just copy the name from Bootstrap documentation and add that style to your tags.

Just using a simple form works okay, but doesnt look very nice.

status-dashboard-data-centre-location-form-dropdown-basic.png

By adding some Bootstrap styles, the page looks a lot better. Simple drop-down form in bootstrap

Inside the form I added a div with the style form-group as there are multiple form elements, a label and a select (drop-down).

The button is using the hiccup.form/submit-button function with the style btn-outline-primary applied. Without the form-group div there would not be any space between the button and the select drop-down.

[:body
 ;; An invisible container to create a default margin at each side of the web page
 [:div {:class "container"}

  ;; Page Header using a large central banner, called a Jumbotron
  [:div {:class "jumbotron"}
   [:h1 "Mock Status Monitor Dashboard"]]

  ;; Key systems to monitor displayed in a single bootstrap row, with 3 columns.
  [:div {:class "row"}
   [:div {:class "col-md-12"}
    [:h2 "ACME Infrastructure Locations"]
    [:form {:action "/dashboard"}
     [:div {:class "form-group"}
      [:label "Choose data centre location to view"]
      [:select {:class "form-control"}
       (for [location data-centre-locations]
         [:option {:value (:name location)} (:name location)])]]
     (web-form/submit-button {:class "btn btn-outline-primary" :name "submit"} "View Dashboard")
     ]]]

  ] ;; End of :div container
 ] ;; End of :body

Fixed tests for status monitor

As I updated the resulting page from the / route, then I updated the tests to reflect the new content. I also remembered to run the tests before committing and pushing to CircleCI. My build is now passing on CircleCI, yay!

Add tests to check for body title and that the page includes Bootstrap style sheets and a Jumbotron.

These tests are more about how to write tests than what should be tested, so may be a little brittle.

20081022 - Day 38: Event organising and Status Monitor locations

Thoughts for today

Organising ClojureX free workshops for the 2nd December. We have an clojure.spec from the ground up confirmed and I am planning on giving an intro to Clojure CLI and figwheel.main for building (and testing) ClojureScript applications. This would be based on the Figwheel Tutorial.

Reached out to ClojureBridge Bilbao chapter today and offered to mentor them through their first event, https://www.magnet.coop/clojure-bridge-bilbao.

Started planning ClojureBridge London events for 2019, the first hopefully at the end of January or early February and the second event for mid-May.

Worked on the Status monitor, adding a simple drop-down and then form to select a specific data centre location.

Code from today

Activities in detail

Added welcome page

A basic welcome page for the default route, /. Welcome pages is an hiccup html5 page that uses bootstrap for style.

Added a drop-down to select data centre locations

Using hiccup drop-down function I hard coded a drop-down component with two locations for data centres.

[:div {:class "jumbotron"}
   [:h1 "Mock Status Monitor Dashboard"]]

 ;; Key systems to monitor displayed in a single bootstrap row, with 3 columns.
 [:div {:class "row"}
  [:div {:class "col-md-12"}
   [:h2 "ACME Infrastructure Locations"]
   (web-form/drop-down ["London" "New York"] ["London" "New York"]) ]]

Changed data centre location to form

Changed the hard coded drop down to be a generated form. Defined a collection of data centre locations to generate the form from.

;; Data centre locations
(def data-centre-locations
  [{:name "London"    :latitude 42 :longtitude 24}
   {:name "New York"  :latitude 42 :longtitude 24}
   {:name "Singapore" :latitude 42 :longtitude 24}])

 ;; Main page for application

  [:div {:class "row"}
    [:div {:class "col-md-12"}
      [:h2 "ACME Infrastructure Locations"]
      (web-form/drop-down ["London" "New York"] ["London" "New York"]) ]]
      [:form {:action "/dashboard"}
        [:td
          [:select
            (for [location data-centre-locations]
              [:option {:value (:name location)} (:name location)])]
          [:input {:type "submit"} "Monitor Location"]]]]]

20081021 - Day 37: Spacemacs Videos for Helm and Magit

Thoughts for today

Finally fixed the build on the Status Monitor app and continued to work on the SVG library.

Added beginner friendly issues to the ClojureBridge London task board, specifically to write a simple user guide for the most common Clojure editors.

Asked Alexa to “play classical music” and it was pretty good mixture. I discovered I can also ask Alexa what the name of the song is that is currently playing (handy when I am in the flow of typing). I switched to rock music when I started feeling sleepy.

Code from today

Activities in detail

Fixed the build: Experiment left uncommented

I left some experimental code in the previous commit without putting into a comment. After breaking the build twice, I should look at automating the running of tests locally. It has given me a reason to go and look at the clojure.core.spec.alpha specifications.

Namespace requires and aliases

Required libraries should be given a contextually meaningful name as an alias, helping to identify the purpose of functions defined outside of the namespace.

Giving meaningful context helps code to be understood by any person reading the code. It is also easier to search for usage of functions from that context in the current project.

Aliases are rarely typed more than once in full as Clojure editors have auto-complete, so there is no benefit to short of single character aliases.

(ns status-monitor.handler
  (:require [hiccup.page :refer :as web-page]
            [hiccup.form :refer :as web-form]))

In very commonly used libraries or very highly used functions through out the code, refer those functions explicitly

(ns naming.is.hard
  (:require [compojure.core :refer [defroutes GET POST]]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))

Refactor namespace alias - compojure.core

The compojure template required the compojure.core library by referring all functions from that namespace. While this does give convienience of just using the function name without a namespace, it does mean many functions not used are included.

(ns status-monitor.handler
  (:require [compojure.core :refer :all]))

Using this form also raises a warning from the Joker linting tool that I have running in Spacemacs.

To be more specific when using the compojure.core library, I changed the require to refer the specific functions / macros used, defroutes and GET

(ns status-monitor.handler
  (:require [compojure.core :refer [defroutes GET]]))

Stating exactly which functions you are using from each library helps with maintaining the code as well as minimising unknown conflicts.

Updated Hiccup requires alias and function calls

Changed requires for hiccup.page and hiccup.form to use a specific alias name, rather than using :refer :all

Thinking of the intent of each library, I chose the following alias names

[hiccup.page :refer :as web-page]
[hiccup.form :refer :as web-form]

The monitor-dashboard function was updated to use the new alias on functions from these two libraries.

No functions are actually used from hiccup.core, it only includes html and h anyway, so the hiccup.core require has been removed.

Broke the build again, spec driven error from lein test

In my eagerness to update the hiccup libraries with a meaningful alias, I forgot to remove the :refer directive. I also forgot to run the tests before committing the change. So when I pushed the commit to Github, I got the following error from CircleCI.

The most interesting parts of the error message were these two lines showing that clojure.alpha.spec library is being used to test namespace definitions:

Exception in thread "main" clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec:

fails spec: :clojure.core.specs.alpha/ns-form at:

[:args] predicate: (cat :docstring (? string?)
                        :attr-map (? map?)
                        :clauses :clojure.core.specs.alpha/ns-clauses),

The ns-clauses specification is define in clojure.alpha.spec as

(s/def ::ns-clauses
  (s/* (s/alt :refer-clojure ::ns-refer-clojure
              :require ::ns-require
              :import ::ns-import
              :use ::ns-use
              :refer ::ns-refer
              :load ::ns-load
              :gen-class ::ns-gen-class)))

The ns-clauses spec looks for the :require keyword and compares its value to the spec for ::ns-require which is defined ass

(s/def ::ns-require
  (s/spec (s/cat :clause #{:require}
                 :body (s/+ (s/alt :libspec ::libspec
                                   :prefix-list ::prefix-list
                                   :flag #{:reload :reload-all :verbose})))))

The ::ns-require checks for a library name using :libspec which is defined by the spec ::libspec

(s/def ::libspec
  (s/alt :lib simple-symbol?
         :lib+opts (s/spec (s/cat :lib simple-symbol?
                                  :options (s/keys* :opt-un [::as ::refer])))))

This is where I believe the error is being detected as I was using both ::as and ::refer in my namespace definition.

The full error message was reported in CircleCI status-monitor build #13, which I formatted for easier reading:

Exception in thread "main" clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec:

In: [1] val:
((:require [compojure.core :refer [defroutes GET]]
           [compojure.route :as route]
           [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
           [hiccup.page :refer :as web-page]
           [hiccup.form :refer :as web-form]
           [status-monitor.svg-components :as svg-components]))

fails spec: :clojure.core.specs.alpha/ns-form at:

[:args] predicate: (cat :docstring (? string?) :attr-map (? map?) :clauses :clojure.core.specs.alpha/ns-clauses),

Extra input

#:clojure.spec.alpha
  {:problems
   [{:path [:args],
     :reason "Extra input",
     :pred (clojure.spec.alpha/cat :docstring (clojure.spec.alpha/? clojure.core/string?)
                                   :attr-map (clojure.spec.alpha/? clojure.core/map?)
                                   :clauses :clojure.core.specs.alpha/ns-clauses),
     :val
     ((:require [compojure.core :refer [defroutes GET]]
                [compojure.route :as route]
                [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
                [hiccup.page :refer :as web-page]
                [hiccup.form :refer :as web-form]
                [status-monitor.svg-components :as svg-components])),
     :via [:clojure.core.specs.alpha/ns-form],
     :in [1]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x4565a70a "clojure.spec.alpha$regex_spec_impl$reify__2436@4565a70a"],
   :value (status-monitor.handler
           (:require [compojure.core :refer [defroutes GET]]
                     [compojure.route :as route]
                     [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
                     [hiccup.page :refer :as web-page] [hiccup.form :refer :as web-form]
                     [status-monitor.svg-components :as svg-components])),
   :args (status-monitor.handler
          (:require [compojure.core :refer [defroutes GET]]
                    [compojure.route :as route]
                    [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
                    [hiccup.page :refer :as web-page]
                    [hiccup.form :refer :as web-form]
                    [status-monitor.svg-components :as svg-components]))},

compiling:(status_monitor/handler.clj:1:1)

20081020 - Day 36: Marching for democracy

Thoughts for today

Joined the People’s Vote march today and it was huge, one of the biggest gathering of people I have ever experienced. Over 700,000 people as a rough estimate on the day, however, it felt like more than 1 million people. It took around 4 hours for everyone to make it from Park Lane to Parliament Square, which is normally a 30 minute stroll. It was a wonderful day and everyone was very supportive and friendly. It restored my faith in humanity and wiped away the depression that Brexit had induced in me.

I did some coding on the ClojureBridge User Guide for Spacemacs.

Code from today

Activities in detail

***

20081019 - Day 35: Preparing some Coaching code

Thoughts for today

How do you break out of an iteration in Clojure, when you are iterating over a large data set and you realise you no longer want the results.

I had a play with my Clojure Through Code examples and experimented with a Palindrome checker.

Code from today

Activities in detail

***

20081018 - Day 34: Spacemacs Videos for Helm and Magit

Thoughts for today

Today is Cosmic Cuttlefish day, the release of Ubuntu 18.10. I’ve been using Ubuntu 18.10 and its pretty snappy as a desktop and uses less memory. Will wait a few weeks before updating my main laptop.

I created two more videos for the Practicalli Spacemacs playlist on my YouTube channel. One on using Magit to easily try out pull requests, the other to delete multiple buffers easily with Helm transient state.

I had a look at https://github.com/Unrepl/spiral, an Emacs Clojure IDE that uses Socket REPL via UNREPL protocol. It has some nice usability concepts that are shown on the project page. Its sill a young project, so wont replace CIDER for me at the moment. There has been a discussion about merging this work into CIDER though. There is also the ultimate guide to REPLs that is an interesting read.

Code from today

Activities in detail

Ubuntu theme for spacemacs

Trying out the Ubuntu theme for Spacemacs. It looks pretty good, although I might want to tone down some of the colours and make them a little darker.

Spacemacs Ubuntu theme - org-mode link example

Spacemacs Helm Transient State menu video

I’ve started using Helm Transient state menu more often, opening with M-SPC when you have a helm popup open. I find the transient state useful for navigating through the list with just j and k. However, the transient state menu is really great for running actions over multiple files. Combining the pattern based searching with marking files (T marks all files listed for a particular pattern) makes it really easy to kill lots of Magit buffers that never seem to close properly.

I created a quick 2 minute 30 second video on Helm Transient State for killing multiple buffers easily.

Update: Helm Transient State - video of killing multiple buffers

Created a video to demonstrate how easy it is to use Helm Transient State to kill multiple buffers of a particular type. In this case removing several magit buffers that didnt close when I used q to quit magit.

Spacemacs Magit - easily fetching pull requests - new video

Magit git client provides an easy way to try out pull requests shared on remote repositories.

Open a file from a project and press SPC g s to open Magic.

b y will popup the current list of pull request from the git project. Selecting a pull request will open git a local branch for that pull request. You can now test all the changes you wish.

Once you are done, you can go back to magit with SPC g s and change back to your previous local branch with b b.

So Magit provides a quick and simple way to collaborate with other developers.

To use Magit with Spacemacs, simply add the git layer to your .spacemacs layer configuration.

https://practicalli.github.io/spacemacs/magit/

I created a quick video of how to use Magit to easily try out pull requests and published it to my Practicalli Spacemacs playlist.

New: Checking out pull requests with Magit

Added a section on using Magit to checkout a new branch that is a pull request on a remote repository (i.e. Github).

Embedded a video from YouTube showing this in action.

20081017 - Day 33: Adding Style to ClojureBridge workshop

Thoughts for today

As I’ve been updating the content in the ClojureBridge London workshop, it needed some more style to make sections stand out further.

I also added the install guide for Spacemacs, including Emacs of course, for Linux, MacOSX and Windows.

Code from today

Activities in detail

More updates on ClojureBridge London workshop

Updated: website style and style related plugins

Some of the content did not stand out very well, especially inline code and code blocks. Added website.css styles to make the code stand out.

Added the wide-page plugin to spread the content wider on the page, so it looks better on a higher resolution monitor. The plugin has a maximum width of 95% which was a bit high, but it was easy to over-ride this by adding a style to the website.css file. A width of 72% looks good and will seek further feedback on this.

Added Spacemacs Install guide

Wrote simple install instructions for 64bit Emacs, minimum version 25 and installing Spacemacs.

20081016 - Day 32: Clojure through code examples and performance tests

Thoughts for today

Hacking on Clojure examples as a break from ClojureBridge London.

Code from today

Activities in detail

Hacking on some examples for my Clojure through code repository, to be used for my Practicalli Clojure book

Performance testing expressions with Criterium

Using the Criterium library to measure the performance of expressions in Clojure. Very useful for analysing parts of your code to see how quick they are to run.

Iteration and list comprehension with for

Modelling a combination lock and calculating all the possible combinations. Then adding a constraint that no combination should contain the same numbers, eg. discard 1,1,1 and 1,1,2, etc.

Fizzbuzz example with core.match

An example of the power of clojure.core.match to solve the classic fizzbuzz game.

The classic fizzbuzz game were you substitute any number cleanly divisible by 3 with fix and any number cleanly divisible by 5 with buzz.

If the number is cleanly divisible by 3 & 5 then substitute fizzbuzz.

Using the require function we include the library ~clojure.core.match~ (match may seem similar to a case statement from other languages). We use match to compare the two results returned from the modulus functions.

(require '[clojure.core.match :refer [match]])

(defn fizzbuzz
  [number]
  (match [(mod number 3) (mod number 5)]
         [0 0] :fizzbuzz
         [0 _] :fizz
         [_ 0] :buzz
         :else number))

This is an example of a simple pattern matching problem.

First we calculate the modulus of the number given as an argument by 3 then the same number by 5. If the modulus value is 0 then the number is divisible exactly without remainder. The result of these two function calls are the elements of a vector.

There are 3 possible patterns to match against, each returns the appropriate value (fizz, buzz, or fizzbuzz). If there is no match, then the original number is returned. The underscore character, _, means that any number will match in that position.

Now we can call fizbuzz for a specfic number

(fizzbuzz 1)
(fizzbuzz 3)
(fizzbuzz 4)
(fizzbuzz 15)

If we want to convert a sequence of numbers, then we can call fizzbuzz over a collection (eg, a vector) of numbers using the map function

(map fizzbuzz [1 2 3 4 5])

We can make a function called play-fizzbuzz to make it easy to use

The function takes the highest number in the range and generates all the numbers from 0 to that number. Finally, we convert the results into strings

(defn play-fizbuzz [max-number]
  (->> (range max-number)
       (map fizzbuzz)
       (map str)))

;; Now, lets call our play-fizzbuzz function with the highest number in the range of numbers we want to play fizzbuzz on.

(play-fizbuzz 30)

20081015 - Day 31: ClojureBridge London workshop install guides

Thoughts for today

More work on the ClojureBridge install guides (as I am on a roll).

Code from today

Activities in detail

Lots of changes to the development environment section of the ClojureBridge London workshop.

Updated atom protoREPL and Proton install guides

Changed files to consistent naming convention

Updated VSCode and Calva section - section comments

Added comments to each section to make changes easier to do by specifically highlighting each operating system section.

Update: Java install - openjdk guides by OS

Updated the installation instructions to use OpenJDK 8 where possible.

Used simpletabs plugin to create a separate tab for each operating system.

Update: Leiningen install guide

Added operating system sections via simpletabs plugin

Added more install options, including GitBash for windows

Moved the checking of the install to the bottom of the page

Updated: Install guides and Editor overviews

Changed the install guide list into a table for each of the common tools (Java, Leiningen, Git).

Added brief overview of each editor to start students thinking about which editor they may want to use.

20081014 - Day 30: Spacemacs Clojure layer hacking continued

Thoughts for today

A wet day is a good day to focus when working at home.

Started a new coaching relationship today with an experienced Python developer. Had a great first catchup over hangouts and defined some tasks to work on.

Testing a pull request to make the REPL and REPL history buffers a better experience - still some work required.

Code from today

Activities in detail

Testing a pull request from Magit

Trying out a pull request as a branch is really easy to do thanks to Magit.

Open a file from the Spacemacs repository, eg .emacs.d/README.org.

Open Magit status, SPC g s

b opens the branch menu y opens a branch from a pull request, prompting you for the URL.

And that is it. As this commit contains elisp changes, then I can go and evaluate the code in a buffer, or restart Spacemacs to pick up the changes. I should create a screen cast for this.

Hacking the Spacemacs Clojure layer

Some more hacking around with a pull request for the Spacemacs Clojure layer, improving the Vim Experience for the Clojure REPL and REPL history buffers. Both these buffers are configured only for Vim Insert or Emacs states, not usable in Vim normal state. This is unfortunate at both these buffers open in Vim normal state, so you have to change state before doing anything

Trying out #11431 pull request I noticed that RET is not working in the REPL buffer. Including n and p navigation in the pull request is really needed in the REPL History buffer, to navigate between expressions, along with replicating the existing vim insert keybindings.

I opened a Clojure source file and started the REPL. I opened the REPL buffer with ~, s s~. Whilst still in Vim normal mode I used ~, P~ to open a buffer with the REPL history. That all works very well.

I cant jump to each expression (as you can with n and p in vim insert mode). However, I can press RET to send the current expression to the REPL buffer and close the REPL history.

With the cursor back in the REPL buffer in Vim normal mode, RET doesnt make the expression evaluate in the REPL buffer, it does nothing. If I switch to Vim insert, i, then of course I can evaluate the expression. I’ve tried a few examples and it seems something is missing.

Multi-line editing in the REPL

I found an example of multi-line editing in the REPL in the #emacs channel, so considering a pull request that does the equivalent of this, but defined in the usual keybinding form in the Clojure layer. RET creates new lines and indents, C-RET evaluates the expression. This works the same way in other tools, eg. Atom, VSCode, LightTable, rebelreadline, etc

(define-key cider-repl-mode-map (kbd "RET") #'cider-repl-newline-and-indent)
(define-key cider-repl-mode-map (kbd "C-<return>") #'cider-repl-return)~~~

Perhaps a :variable can be added to the Clojure layer to allow configuration of a single or multi-line REPL buffer.

20081013 - Day 29: Hacking Spacemacs REPL and History

Thoughts for today

I havent used the REPL history buffer feature much in Spacemacs and today I remembered why. It works great for Emacs state, but doesnt work well for Evil as you have to switch from Vim normal to Vim insert states to do anything.

Luckily someone has started working on a pull request to address this.

I realised the book was a bit out of date regarding the REPL history and history buffer, so gave it a quick update.

Code from today

Activities in detail

Update - Clojure history and cider-repl-history

Added table of keybindings for scrolling backwards and forwards through the REPL buffer history to my personal config, .spacemacs.

Changed keybinding documentation to use unicode arrow keys. Added specific keybindings and commands for working with the cider-repl-history popup buffer.

Hacking the Spacemacs Clojure layer

A new pull request for the Spacemacs Clojure layer was added today, #11431 Clojure enhancements

  1. add a keybinding to open the cider repl history buffer in an evil way
  2. evilfy cider-repl-history-mode-map
  3. allow to send input to a cider repl in normal mode with RET

To summarise the pull reqest, ~, P~ in Vim normal mode in the repl buffer leader would open the repl-history buffer. RET would send the current expression under the cursor to the REPL and close the REPL history buffer. RET in the REPL buffer in Vim Normal mode would evaluate the current expression (without having to go into vim insert state).

Having experimented with the repl-history it is definitely confusing to have to switch to vim insert mode to call the buffer history and again switch to vim insert. I would like to have SPC s h keybinding that opens a buffer with repl history in vim normal mode, which i can navigate quickly between each expression in that history and press RET to push that expression back into the REPL buffer for bonus points you could evaluate the expression just pushed without having to go into vim insert mode.

It would be nice to have different keybindings, one that quits the history after you send the expression (so this is what SPC or RET currently does in vim insert mode), the other vim insert keybindnigs keep the repl history open.

RET is for vim normal mode, so you can evaluate an expression in the repl buffer without having to go into vim normal mode.

My own preference for a REPL history keybinding would be ~, s h~ for major-mode > cider > history. I am not sure how P means history in a mnemonic way, unless it is for Previous? If P is used in cider itself, then I am okay with that. For a top level keybinding for REPL history a meaningful symbol could be used, as is used to start the repl. So you could have ~, s h~ and ~, <~ which both call the repl-history

~, s h~ avoids switching to the repl buffer first to get to the history and especially if somebody would want to eval form again

In cider it is C-c M-p, but this does not fit the mnemonic menu system. ~, s h~ and ~, <~ fits into the existing Spacemacs keybindings and mnemonic menu approach. I would be interested to hear from others as to what they prefer.

Spacemacs Clojure layer related issues: syl20bnr/spacemacs#4124 #4124 Support Emacs lisp keybindings in Clojure mode Emacs lisp has some useful keybindings like “go to end of line and evaluate last sexp” that are absent from the Clojure mode keybindings. Clojure, Enhancement ☺️, Key Bindings

20081012 - Day 28: More ClojureBridge London dev tools

Thoughts for today

If I didnt use Spacemacs, what editor would I use. I havent found a more suitable environment for myself yet, but as I document tools for ClojureBridge London, then hopefully I will have a better view.

Code from today

Activities in detail

Clojure development tools options

I am still trying to decide which tools I like for Clojure development, other than Spacemacs of course.

Atom.io and ProtoREPL are pretty polished, however, the keybindings for ProtoREPL are more complicated than Emacs. Using Proto-mode with ProtoREPL gives more sensible keybindings as it gives a Vim multi-modal editing experience and a Spacemacs style menu. The Proton menu seems to have the basics, but there are some things that could be added (que a pull request, as proton is written in ClojureScript after all).

VisualStudio Code is a pretty slick editor and Calva is the best of several extensions to support Clojure development. I just find VSCode a little tricky to use as I havent read the user guide properly I guess. I would prefer if Calva started a REPL from within VSCode, rather than starting one outside and connect, although it works well. There are Vim extensions for Code too.

I should be able to get a better handle on ProtoREPL and Calva as I put together a simple user guide for ClojureBridge London workshop.

ClojureBridge London workshop updates

Added a distinct Friday section to make it easier to see that the workshop has content for both Friday evening and Saturday.

Created a new install guide for VSCode and Calva extension, using new tabbed format to separate the Operating System specific information.

Updated the ProtoREPL install guide with details on how to configure with Leiningen, which is an important step in the ProtoREPL setup.

20081011 - Day 27: ClojureBridge London dev tools setup

Thoughts for today

I found a nice plugin for Gitbook to have a tabbed section in a page, improving the presentation of a single install page for each of the tools. Any differences in approach, e.g. installing on a particular operating system, can be put in their own tab. It probably shows my bias that I put Ubuntu Linux as the default tab (oops).

Had a catchup with a company interested in getting involved more in the London Clojurians community. We discussed the ClojureBridge London event and other activities that the community does. Now have two ClojureBridge London events in planning for 2019.

Assisting a couple of speakers with their talk titles and descriptions for the ClojureX conference this year. Almost everyone is published on the schedule now.

I will be coaching a new person this weekend, just arranging the details and starting to set expectations.

Code from today

Activities in detail

Update Atom ProtoREPL and Proton development tools

Updated to use the simple tabs plugin to provide a simple way to separate the unique install steps for each operating system.

Added installation instructions for all operating systems.

Added details on how to run and test the installation.

Add Gitbook Plugin - simple tabs

A plugin for adding tabbed sections in a page, useful for separating out specific details in a wider article.

This plugin will be used for the development environment section.

20081010 - Day 26: Spacemacs and ClojureBridge dev tools

Thoughts for today

It is great to hear from people reading your books, blogs, etc. I received some very warm feedback today from a developer who is interested in learning Clojure and is really enjoying my practicalli books. This is great to hear and really helps motivate me to finish those books.

Code from today

Activities in detail

Continued working on the Spacemacs book, organising the debugging section a little better. Added details of how to run Magit in full frame, which I find much easier to work with changes.

Also worked on the development tools install guides for ClojureBridge London. Although we have Klipse REPL built into the workshop material, it doesnt save any work. Obviously Klipse is also not going to be the follow on editor that the students use, so we use the Friday evening of the event installing a Clojure aware editor. The editor tends to be one of Atom.io, VisualStudio Code, Emacs (yes, we have had several students using Emacs, mostly with a Spacemacs setup). Some students that are studying Java are using Intellij, so we also help with installing Cursive.

20081009 - Day 25: Quarter of the way there

Thoughts for today

Added quick reference section for adding unicode characters

Mainly using unicode characters in the content of my books/guides to represent keyboard characters, such as arrow keys. It is assumed that these unicode characters make the keybindings easier to understand.

Code from today

Activities in detail

Spacemacs book updates

I started on using Atom and ProtoREPL for Clojure development when I was coaching a developer who wanted to learn some Clojure. Although I had published the content a while ago, I realised I had not pushed the content to github.

I used this as an opportunity to create a video of using Magit in Spacemacs. The video covered how to create a new local Git repository, create the first commit, add a remote repository and push the commit to the remote. This should be exactly the same for GitLab.

https://www.youtube.com/watch?v=AdEOazt1rD0

I embedded the video in the section on creating a local Git repository

I also took the opportunity to add the very cool Git Timemachine, which provides an easy way to navigate the code commits for a particular file and see the file contents change as you visit each commit. The Git Timemachine is very useful for reviewing how a file has evolved. Its also useful for live coding demos where you dont want to show how a project has evolved, but dont want to waste time doing all the typing.

https://practicalli.github.io/spacemacs/magit/timemachine.html

20081008 - Day 24: Events, events, events

Thoughts for today

Community events are fun and quite a responsibility too. Today we reviewed the speaker schedule for ClojureX, aiming to make the best flow of the talks and ensure we give the best possible experience for the audience and the speakers. Also organising a workshop before the ClojureX conference at uSwitch. We also have a hack day on 15th December along with the Scala community.

The evening was the Clojure dojo at uSwtich were we…

Code from today

Activities in detail

Updating Practicalli website

Added the ClojureBridge London workshop as a link on my Practicalli website. The workshop is complete, unlike most of my other books, so good to show (myself at least) that I can finish one. Will focus more on finishing the Spacemacs book and reworking the Clojure Practicalli book.

Updated all the links to my books to use https rather than http, as this makes Google and other search engines happier.

Clojure dojo - Native Clojure binaries with GraalVM

I paired with a friend who is starting to learn Clojure and we used GraalVM to create a native binary from a Clojure application.

While I set them up with Clojure via brew install clojure and installing Leiningen, I installed GraalVM

GraalVM is just a tarball (Linux, Macosx) that is extracted and the bin directory added to the executable path. It turns out later that I also needed to install zlib to create the native image from my Uberjar file. I assume the Uberjar file used zlib compression, or perhaps the zlib library is used to compress the native binary in some way. Either way, it was just a matter of sudo apt install zlib-dev.

Development of the Clojure app wasnt any different from normal. We did use the Leiningen app template to add code and configuration to allow our Clojure application run from the command line, via java -jar target/uberjar/my-app-standalone.jar

Once the code was written the application was packages using lein uberjar.

By installing GraalVM and putting it up front in the executable path, the GraalVM version of Java is run when running java -version. To check Clojure the application still works on GraalVM we just needed to run it via the command line.

GraalVM has a command to create a native binary

20081007 - Day 23: Spacemacs Sunday

Thoughts for today

Discussing approaches for setting environment variables for Clojure applications. Its quite common to use environment variables for key settings, like the port of your web application using, although using a map for your configuration is more prevalent when there are lots of environment variables to set.

Using keyboard symbols for certain keys can make documentation easier to follow, e.g. for arrow keys. I could use some CSS with the <kbd> tag, although adding html tags makes markdown less clean. Using unicode characters works really well though and of course Spacemacs makes it easy for you to add these characters by name using SPC i u.

Using org-mode continues to be much more fun that markdown for writing this journal. I updated the orgmode section with useful stuff I found. I also just discovered adding (and editing existing) links using ~, i l~. I also looked at the insert orgmode keybinding, but it generates quite a lot of text and I suspect its something that needs to be exported to work with github

@@html:<kbd>@@ <right> @@html:</kbd>@@

Code from today

Activities in detail

Environment variables

Separate environment variable definitions are used when you have a small number of settings, e.g. for PORT, often using the https://github.com/weavejester/environ library.

Using maps is also a good approach, especially where there are a great number of settings for different environments. The https://github.com/juxt/aero library is a nice clean way to specify a collection of environment settings across multiple environments.

In my last project, we deployed in dev, qa, uat and prod environments with multiple services (oracle, tibco, datomic, etc) and used aero to great effect.

Spacemacs - sayid and clj-refactor optional

Sayid debugger package and clj-refactor are no longer loaded by default.

Sayid has caused a few issues with Cider recently so it is left to the user to decide if it is useful for them.

clj-refactor has not been updated in several years and some of its functionality is moving into clojure-mode.

Both these packages can be included by defining their package names as :variables on the clojure layer

Spacemacs - using projectile to manage project files and buffers effectively

Overview of projectile for working with files only from the current project, making it easier to open files and navigate buffers for a project.

Using helm transient state to help tidy up buffers.

Used SPC i u to add unicode characters for arrow keys, e.g.🡄🡇🡅🡆

Spacemacs - Linting

Added a new section on Linting tools, providing a quick overview of linting tools I use for my Clojure projects, Joker and Eastwood.

Joker is simpler to use, thanks to the clojure-lint layer. It does use an external binary, which I placed on my existing executable path. Joker uses a sub-set of Clojure so it may give a few inaccuracies, these are usually false positives on things like macros. There is a way to tell joker to ignore certain symbols though.

Still a bit of work to do on these sections, but they cover the basics.

20081006 - Day 22: Coaching a developer new to Clojure

Thoughts for today

Had a quick look at the many Clojure extensions for VisualStudio Code. [Calva](https://marketplace.visualstudio.com/items?itemName=cospaia.clojure4vscode) seems the most maintained. It requires you to start a repl outside of the editior, which I am not that keen on as it means more complexity. However, it seems to generally be the better choice.

Code from today

Nothing in Github, but example code in activities section of this journal

Activities in detail

A developer considering Clojure reached out to me with the following question.

— I have these two types of class definitions in Java:

public class SomeClass { public void generateFor(SomeArgType argument); } —– or —-

public class SomeClass { public SomeType generateFor(SomeArgType argument); }

How do you write them in Clojure if you even write any such definitions to start with. I know you dont have types or interfaces or classes as such. —

It was an interesting reminder of where I had come from several years ago. OO languages and especially Java have become the main-stay of much application development because its a very stable language (Java) with a highly optomised runtime environment (JVM). My journey into Clojure has allowed me to use a much simpler syntax with barely any boilerplate code. I find it quite challenging to go back to the Java and OO way of thinking.

So, I tried to answer the question with as meaningful an answer as possible, so I just wrote some code and explained how it worked.

— Here is a simple function which would typically be defined in a namespace (a package in Java).

This function just generates a message, so nothing very exciting in this code. First we define a function, as you would define a method, but we dont need to do it in a class. The function takes one argument and returns what ever is the result of the last expression (no need to define an explicit result call.

The If function determines which is the last expression to be called. If the condition, (= feature “function”) - compare the value of feature with the string “function”, is true then use the first line after the condition, if false then use the second line. If is a macro, so acts slightly different to normal function evaluation.

(defn feature-generator
  "I am a very simple function, this is my docstring
  Usually I would tell you something useful about myself"
  [feature]
  (if (= feature "function")
    (str "In Clojure everything is a" " " feature)
    (str "Clojure doesnt use:" " " feature)))

Now we have the function defined, with a name that we can call it by, we can call it anywhere in our namespace (or in another namespace if we add it to that namespace).

Here is the function call, followed by the result as a comment underneath

(feature-generator "objects")
;; => "Clojure doesnt use: objects"

Lets call it again with a different argument

(feature-generator "classes")
;; => "Clojure doesnt use: classes"

And we can use the function call inside another function call… this is how we build up our application.

Here we call the str function that joins two things together to make a string. The first argument to str is the result of a function call, so the Clojure runtime (the REPL) first goes and evaluates that function which is then passed to the str function along with the string as a second argument

(str
 (feature-generator "function")
 ", with persistent data structures, eg maps, vectors")
;; => "In Clojure everything is a function, with persistent data structures, eg maps, vectors"

This is a very quick example of defining your own behaviour in Clojure and calling it.

The other important aspect of Clojure is to model data, for which we use either lists (linked list), vectors (an array), maps (hash map), sets (unique values). We dont need generics here and we dont need to define types of our data (although we can define a specification, usually if we are pulling data from outside of Clojure).

If we were going to model different science fiction worlds, we could construct a data structure as follows

(def starwars
  {:characters
   {:jedi   ["Luke Skywalker"
             "Obiwan Kenobi"]
    :sith   ["Darth Vader"
             "Darth Sideous"]
    :droids ["C3P0"
             "R2D2"]}
   :ships
   {:rebel-alliance  ["Millenium Falcon"
                      "X-wing figher"]
    :imperial-empire ["Intergalactic Cruser"
                      "Destroyer"
                      "Im just making these up now"]}})

We have bound the name starwars to a maps of maps with vectors.

There are lots of functions that help us get or update (creates a new data structure) this data structure

Lets start simple and get a value from the map using a key

(get starwars :characters)
;; => {:jedi ["Luke Skywalker" "Obiwan Kenobi"], :sith ["Darth Vader" "Darth Sideous"], :droids ["C3P0" "R2D2"]}

We can see that the result itself is a map, so we could use another get function around the first to drill down further in the map. Clojure has a function that allows you to traverse the path in the map though.

(get-in starwars [:characters :jedi])
;; => ["Luke Skywalker" "Obiwan Kenobi"]

The developer was appreciative of the detailed answer, however, as this was all over email its hard to know how well they understood the examples. I will suggest some resources they can use to learn.

20181005 - Day 21: Hacking markdown into org-mode

Thoughts for today

Spacemacs org-mode is a much richer experience when it comes to writing when compared to markdown in Emacs. Thanks to Bobby Towers for reminding me that I should be using org-mode to write this journal. Being able to fold up headings in org-mode, add code blocks that evaluate and move sections around easily are well worth the conversion of this file from markdown.

Code from today

Convert log content to org-mode format

Activities in detail

Rename log.md to log.md

This was a simple case of opening Magit SPC g s and renaming the file using the ! keybinding to bring up a prompt that runs any git command you type. There is no specific rename file option in Magit (that I am aware of), so this is a convenient way to run those odd git commands.

Convert markdown content to org-mode

Converting from markdown to org-mode is fairly simple, especially with all the Vim editing tricks I have learnt over the last few weeks.

Source code blocks use the #+BEGIN_SRC directive, rather than three back-tics in markdown. The advantage with org-mode is that your code is syntax highlighted in the editor and actually executable (via org-mode Bable). So it is much easier to establish you have working code in your documentation.

For inline code and shell command references, we can just surround with ~ to highlight as a mono-type font face.

Hyperlinks are the same way around as they are defined in HTML, the link first and then the anchor text. Not sure why markdown is the reverse. The link and anchor text are each surrounded with square brackets, e.g. [http://spacemacs.org] and [Spacemacs], then both are wrapped inside another pair of square brackets to make the link. Org-mode then renders the text so the anchor is now a hyperlink in your text, only showing the anchor text.

How well this all works we will discover when I push this big change to Github.

20181004 - Day 20: Hacking Spacemacs and code folding

Thoughts for today

Spacemacs is infinitely hackable, but learning to use the features it just gives you is much quicker :)

I love writing my Spacemacs book and its great to see others finding it useful.

Code from today

Activities in detail

Spacemacs menus for Vim Normal mode

I keep finding more ways to do things faster, mostly by accident as I pressed the wrong key. I have found a few menus on the keys # * g z that I wanted to investigate and today was the day.

I use g for commenting code g c c and for toggling character case v g ~ or word case SPC v g ~

Code folding

Interesting discussion on how Spacemacs does code folding in the #spacemacs channel of the London Clojurians Slack community. A suggestion was made about folding different levels of code, in a similar manor to org-mode and magit (magit has the stage, file and hunks that can be expanded and collapsed).

I was not particularly convinced that changes were needed at first. After experimenting I did think that the collapsing of function definitions could be made better for me. Currently the argument list is collapsed on a function and it would be really useful to keep that shown, along with the def function-name. If there was a docstring (and there really should be) then that sting would be collapsed too, or just show the first line.

The default code folding uses some Vim magic and I didnt see an easy way to configure the behaviour. It is easy to change code folding to a package called [origami](https://github.com/gregsexton/origami.el#does-it-support-my-favourite-major-mode) which enables you to write your own parser in order to create custom folding for your language.

There is also [evil-vimish-fold](https://github.com/mrkkrp/vimish-fold/blob/master/vimish-fold.el) which some have commented to be really good for every language, however, I dont think this has been added to Spacemacs as a layer yet. I am trying out Origami now, but it seem less useful for Clojure than evil-fold, as folding seems to only work at the top level. I could be doing something wrong, or the Clojure parser for origami needs tweeking. I would love to see the argument list still shown when folding, as an example.

To try the evil-vimish-fold package without a layer, you can add it to your .spacemacs file as follows

  1. add the package name evil-vimish-fold to dotspacemacs-additional-packages
  2. add (evil-vimish-fold-mode 1) to user-config

20181003 - Day 19:

Thoughts for today

Code from today

code

Activities in detail

20181002 - Day 18:

Thoughts for today

Starting to change the HackTheTower website into HackTogetherLDN.

Supporting new speakers at the New Speaker night organised by the London Java Community.

Code from today

HackTogetherLDN updates

https://github.com/HackTogetherLDN/hacktogetherldn.github.io/commit/3a5fc3f4bf2ca33a704f231a6759eed08a0c4e6b

Activities in detail

20181001 - Day 17:

Thoughts for today

Oh my, its October already!

Hacking on my [Practicalli Spacemacs](https://practicalli.github.io/spacemacs) book. Emacs is a continual joy when it comes to optimsing the process of capturing all the wonderful thoughts my brain has.

Code from today

,,,

Activities in detail

20180930 - Day 16: Updating ClojureBridge London content

Thoughts for today

Adding more content and exercises based on the feedback from the ClojureBridge London event.

Code from today

A server side web app that tells you the distance between two cities

Activities in detail

Taking some of the feedback we received from the workshop, I updated some of the examples and exercises in the [ClojureBridge London workshop](https://clojurebridgelondon.github.io/workshop/) and started a guide for the larger example of building a website to show the distance between two cities.

Small exercises and examples

Distance between two cities web app

With the project created, we started the server with lein ring server to check it all worked. To start building the page we added the [hiccup]() library, allowing us write an html web page using just Clojure code. The hiccup.page/html function creates a web page and we define a [:head ] section that contains include-css and include-js functions so we can add bootstrap to our website and use some simple styles to make the site look better.

The data for the countries was defined within a Clojure map, e.g. {:city "London" :latitude 51.5074 :longtitude 0.1278}. We added a dozen cities as maps to a Clojure vector and bound that vector to the symbol locations.

To select the cities from the web interface, we added a form-to function that included two input drop-downs. Using a for statement we iterated over the locations collection and extracted the city name, placing it into the drop down. This gave us a to and from location to select.

Using the submit button to call a results page, we extracted the selected cities from the request params. Then called a function that calculated the distance between two locations using their respective latitude and longtitude positions.


20180929 - Day 15: Coaching ClojureBridge London

Thoughts for today

I get a wonderful warm feeling when helping people get into the software industry, especially when its addressing the balance of voices in that industry. To be able to help those new to development using my favourite language, Clojure, makes it extra special.

Clojure is quite different from most languages, specifically in the way it encourages you to think about the design of your code. The simplicity that is achievable with Clojure is something that continues make me smile every day, even after 8 years of learning and working with Clojure.

The ClojureBridge event had over 20 women enjoying the day. Six women already had some experience coding and one of them had just found out they had got their first job in the industry. The rest of the students were very new. Everyone was very excited about the day and that enthusiasm carried on throughout the day.

Code from today

The student wrote the code today, using examples from my status-monitor app stackoverflow.

Activities in detail

I was coaching 4 women who had some coding experience. Two of them had completed the first 6 levels of the workshop exercise in the afternoon and started building websites using Clojure.

Each student took a slightly different approch. One student followed my [Practicalli Clojure WebApps]() step by step guide to building a server side web application with ring and compojure. The second student used the [leiningen compojure template]() to start building a server side website that calculated the distance between two cities.

With the project created, we started the server with lein ring server to check it all worked. To start building the page we added the [hiccup]() library, allowing us write an html web page using just Clojure code. The hiccup.page/html function creates a web page and we define a [:head ] section that contains include-css and include-js functions so we can add bootstrap to our website and use some simple styles to make the site look better.

The data for the countries was defined within a Clojure map, e.g. {:city "London" :latitude 51.5074 :longtitude 0.1278}. We added a dozen cities as maps to a Clojure vector and bound that vector to the symbol locations.

To select the cities from the web interface, we added a form-to function that included two input drop-downs. Using a for statement we iterated over the locations collection and extracted the city name, placing it into the drop down. This gave us a to and from location to select.

Using the submit button to call a results page, we extracted the selected cities from the request params. Then called a function that calculated the distance between two locations using their respective latitude and longtitude positions.


20180928 - Day 14: Hacking ClojureBridge London

Thoughts for today

Running our 8th ClojureBridge London event to support under represented groups gain experience and build confidence when it comes to codeing.

Updated some of the ClojureBridge content and examples.

Some ClojureX conference management.

Code from today

Activities in detail


20180927 - Day 13: Demo-graphics continued

Thoughts for today

Some more user research. Buiding websitest that tell you something isnt as easy as it seams.

Making good used of Layouts in Spacemacs to organise my work more effectively.

Continued with building up the SVG library

Code from today

Activities in detail

More hacking on the SVG library I have been working on in the status-monitor app. Continuing to define example SVG elements in Clojure.


20180926 - Day 12: Demo-graphics

Thoughts for today

More experimenting with SVG and included some simple HTML. At some stage will need to decide what styles to include inline for HTML elements, what to include as templates and what to define as CSS (and any other / additonal css libraries to use).

Code from today

Demos with SVG and HTML

https://github.com/jr0cket/webapp-status-monitor/commit/93189468fc80938865fb67f4ff6de77f9d4bc724

Activities in detail

Hacking with more SVG graphics and wrapping those graphics with HTML.

Debugging the html output is very easy with the Chrome Inspector.


20180925 - Day 11: Diversity is a balancing act

Thoughts for today

Today was distracted with issues raised around this years ClojureX conference. Although we strive to get as much balance as possible in the speakers for our annual conference and the last few years have been quite successful, unfortunately we only have a few women speakers confirmed this year. We spend time reaching out to under represented groups and supporting them in many ways to get involved with the conference. We do reach out to speakers we want to appear at the conference and this also has a bias to ensure we have a good balance. Although we have been very successful encouraging new speakers to the conference, the representation of those new speakers has not been as broad this year. One of our speakers pulled out of the conference as they understandably felt it was not appropriate to speak, especially as they were pair presenting with a colleague who would have contributed to the balance we strive to achieve. Luckily the speaker had two other colleagues who would bring the same balance that we were hoping for.

Unfortunately this took up most of the day today and didnt leave much time for coding before heading off to run the Coding dojo at Thoughtworks. Unfortunately Yolina who has done a wonderful job of running these events for the last few years was ill. I hope Yolina a swift recovery.

The Clojure code dojo was lots of fun tonight. We had 3 groups of people fairly new to Clojure, working through lots of 4clojure.com exercises. We also had a group creating a notification app for the Park Run events. Unfortunately this popular site does not have a published API, so lots of webscraping with the enlive library was in order. I spent most of the time coaching the teams through the 4Clojure exercises, helping them to think in a functional way. We also had a very interesting discussion around functional design patterns and what if any were the relationships between functional and OO patterns. Our conclusion being that most of the OO patterns provide features that are not available in the language. Understanding functional design or patterns is more about understanding the Clojure (or Lisp) style of functional programming and what is the so called idiomatic approach to Clojure.

I still managed to get some time to work on the Status Monitor, although this was more about defining SVG elements and considering creating a library of SVG components to make it easier to incorporate them in Clojure or ClojureScript projects.

The day ended on a high note with my pull request to the Compojure Leiningen template merged by @weavejester

Code from today

Activities in detail

Not much coding today, so no real detail to cover.

Created a new namespace in the status-monitor application for svg-components. Planning to start converting the Mozilla SVG guide and SVG Elements Reference.


20180924 - Day 10: Mocking has never been easier

Thoughts for today

Refined the tests using the ring.mock.request mocking library that Compojure Leiningen template added when creating the project.

Code from today

Refactor test to use ring.mock.request

https://github.com/jr0cket/webapp-status-monitor/commit/a71781610e800f524ce46dfdb0e18653aea19c2d

Activities in detail

Refining the tests with ring.mock.request

The test from yesterday was not quite as elegant as it could be. Although it showed clearly what it was testing, there was much duplication.

#_(deftest test-monitor-dashboard
  (testing "Test dashboard contains key pieces of information"
    (is (clojure.string/includes?
         (monitor-dashboard {})
         "<title>Area51 Mock Status</title>"))
    (is (clojure.string/includes?
         (monitor-dashboard {})
         "<link href=\"//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\">"))
    (is (clojure.string/includes?
         (monitor-dashboard {}) "<div class=\"jumbotron\"><h1>Mock Status Monitor Dashboard</h1></div>"))
    (is (clojure.string/includes?
         (monitor-dashboard {}) "<h2>Application monitor</h2>"))
    (is (clojure.string/includes?
         (monitor-dashboard {})
         "view-box=\"0 0 100 20\""))))

I refactored the above test to use a let function to create a local binding called response, bound to the value of calling the webapp route /dashboard. This testing the correct flow of our webapp route and its response.

The let name response was bound to the /dashboard response by calling (app (mock/request :get "/dashboard")) from the ring.mock.request mocking library.

The response is a Clojure map which has a key called :body that contains the html output for the web page. So I extract the value using the :boot key.

Added clojure.string to the namespace with an alias string so I could simply call string/includes? instead of clojure.string/includes?. I could refer includes? into the namespace, however, I prefer to be explicit in the use of libraries (unless there is extensive use of specific functions in a namespace that is focused on the context of those functions, i.e. a UI namespace that uses Hiccup).

So, the refactored test now looks a little more streamlined.

(deftest test-monitor-dashboard
  (testing "Test dashboard contains key pieces of information"
    (let [response (app (mock/request :get "/dashboard"))]
      (is (= (:status response) 200))

      (is (string/includes?
          (:body response)
           "<title>Area51 Mock Status</title>"))
      (is (string/includes?
           (:body response)
           "<link href=\"//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\">"))
      (is (string/includes?
           (:body response) "<div class=\"jumbotron\"><h1>Mock Status Monitor Dashboard</h1></div>"))
      (is (string/includes?
           (:body response) "<h2>Application monitor</h2>"))
      (is (string/includes?
           (:body response)
           "view-box=\"0 0 100 20\"")))))

20180923 - Day 9: Testing is fun

Thoughts for today

More testing today and taking a brief look at the mocking framework that Compojure Leiningen template added to the test code generated.

Also has a quick look at eftest from @weavejester which is supposed to be faster and can run more tests in parrallel than just running lein test. I mainly wanted to use it for the coloured output at this stage (as I only have a few tests).

By accident I found the Emacs transpose keybinding is still in Spacemacs today. Instead of pressing M-TAB I was pressing M-t and swapping around the two words either side of the cursor position. The transpose call even jumps over and ignores comments and other separators.

The standard Spacemacs bindings for transpose are as follows:

SPC x t c swap (transpose) the current character with the previous one

SPC x t w swap (transpose) the current word with the previous one

SPC x t l swap (transpose) the current line with the previous one

This is something else to add to my Spacemacs for Clojure development guide.

Code from today

Added eftest plugin

https://github.com/jr0cket/webapp-status-monitor/commit/b5f8b2a83ce9839c7881b4a5b80d8d7911b13fb2

Added tests for monitor dashboard

https://github.com/jr0cket/webapp-status-monitor/commit/d2016c004b9122677986f3933270e900ce59d0a8

Added author and documentation to test namespace

https://github.com/jr0cket/webapp-status-monitor/commit/f5eed17e129ffd2e6c402d1292fb900164129259

Experimenting in the REPL

https://github.com/jr0cket/webapp-status-monitor/commit/bfa92e18ebb5b57c223c6b6851277ee88c1819c7

Updated the Readme to include an ascii text logo

https://github.com/jr0cket/webapp-status-monitor/commit/f8b6bef2486fc972e0f82599b9303c0616ef5195

Activities in detail

Adding an ascii text logo

Perhaps a little superfluous but an easy thing to add is an ascii text logo of the project name. I use the text to ascii art generator (TAAG) and the Fire Font.

The output of the generator was copied into a text block in the project README.md file.

REPL experiement - calling monitor-dashboard function

Confirming the output of the monitor-dashboard function by calling that function via the REPL, using an empty map {} as the function argument.

The monitor-dashboard is currently passive and so does not use any data from the request map.

If the monitor-dashboard function did use data from the request map, we would need to mock that in the call to monitor-dashboard.

Testing monitor-dashboard

Using clojure.string/includes? to see if the result of calling the monitor-dashboard function includes specific sub-strings.

This could be done using the mock framework and put into a let to make the code cleaner.

(deftest test-monitor-dashboard
  (testing "Test dashboard contains key pieces of information"
    (is (clojure.string/includes?
         (monitor-dashboard {})
         "<title>Area51 Mock Status</title>"))
    (is (clojure.string/includes?
         (monitor-dashboard {})
         "<link href=\"//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\">"))
    (is (clojure.string/includes?
         (monitor-dashboard {}) "<div class=\"jumbotron\"><h1>Mock Status Monitor Dashboard</h1></div>"))
    (is (clojure.string/includes?
         (monitor-dashboard {}) "<h2>Application monitor</h2>"))
    (is (clojure.string/includes?
         (monitor-dashboard {})
         "view-box=\"0 0 100 20\""))))

Tomorrow I’ll refactor the above test to use a let value for the response from calling monitor-dashboard. I will also use the (app (mock/request :get "/")) call in the let and compare the :body from the response.

Added eftest plugin for pretty results report

eftest provides a faster testing tool and syntax coloured reporting of results, making it nicer to use that lein test.

Run the tests using the eftest plugin on the command line using lein eftest

The plugin uses several dependencies

[/images/clojure-testing-eftest-dependencies.png][Clojure Leiningen eftest plugin dependencies]

The output in this test run that contains two test failures is very clear to understand and spot the issues easily.

[/images/clojure-testing-eftest-test-run-failures.png][Clojure Leiningen eftest plugin - failing test run]


20180922 - Day 8: Clojure coaching and Testing

Thoughts for today

Started coaching a developer today. It has been a few months since I coached, so am happy to be starting again. Coaching really does help me exercise my mind and it is very enjoyable to guide someone.

One decision taken in the coaching was which continuous integration server to use. I realised I should start writing some tests and set up a CI server for the status monitor project. The simplest approach for a CI server was to use [CircleCI](https://circleci.com/) that provides CI as a service and hooks up easily to Github projects. CircleCI is also written in Clojure, so its great to support them.

Code from today

Added tests for components

https://github.com/jr0cket/webapp-status-monitor/commit/2647704466ea05c3fb6ba3eba46fa28d341000e7

Updated the Readme and added CircleCI status badge

https://github.com/jr0cket/webapp-status-monitor/commit/f7912e1e8151b3c399bd3c4e517d3a7d11709f8e

Activities in detail

Setting up CircleCI for the status-monitor project

There is a really good getting started guide on the CircleCI website.

Adding a project and CircleCI detects the programming language and your operating system.

/images/circleci-add-project-detection.png

Added the sample config.yml to the project as .configci/config.yml. The only change made to the config file was to update the version of Leiningen to 2.8.1 (was version 2.7.1). Once this was added to the project and pushed up to the github repostitory, then we are ready to create a build.

This launches the project on CircleCI and webhooks listen for new commits to the Github repository.

Adding a status badge to the Github readme was very simple too. CircleCI provides the Markdown to add to the README.md page.

Testing status-monitor

The Compojure template comes with a few tests that nicely show how to group tests and give some hints on things to test.

Started adding tests to check the output generated by the visual components I am developing to represent the elements of the dashboard.

Coaching

I created a Slack community specifically for the coaching, so we can keep our discussions around for several months if required. We discussed what was to be achieved (at least initially) from the coaching, tooling and development experiences.


20180921 - Day 7: Clojure advocacy and Spacemacs

Thoughts for today

This morning I had a great conversation with an exciting company that is looking to move to Clojure for key computational parts of their systems. Lots of discussion centred around finding and hiring Clojure developers, for which there are many options.

The rest of the day was spent working on my book [Spacemacs for Clojure development](https://github.com/practicalli/spacemacs-gitbook/).

Code from today

Content and elisp code snippets for my Spacemacs book:

https://github.com/practicalli/spacemacs-gitbook/

Activities in detail

I have been steadily creating content for my book to help developers make the most out of Spacemacs for Clojure development. There is still much content to go, however, there is lots of really useful things I have learnt and added over the last few weeks.

I have also been adding more content ideas in the Github project for the book.


20180920 - Day 6: ClojureBridge London

Thoughts for today

Preparing for the ClojureBridge London event next weekend by reviewing the workshop content and enhancing some of the challenges and sample answers.

Also carried out some user research for developer portals of several financial institues. There was definately a large difference in usability and developer experience between the sites reviewed. Hopefully my comments are of some contructive use and I wasnt overly critical.

Code from today

Code examples and content for the ClojureBridge London workshop

https://github.com/ClojureBridgeLondon/workshop-content-gitbook

Activities in detail

Improved several sections of the ClojureBridge workshop content.


20180919 - Day 5: A very Googley day - Alexa, Android and Googling answers

Thoughts for today

I was at an Amazon for an Alexa workshop building what they refer to as skills, their word for defining the things that you can configure Alexa to do. It was good fun, very well explained and I also won an Echo dot (which should arrive in the post tomorrow).

This evening I coached at Codebar, helping a very bright person with their Augmented Reality application for Android which was written in Kotlin. I can see why experienced Android developers are able to get a great rate for their work, as it feels like a lot of moving parts to build such a native app. They managed to get further with the app and we even got some UI tests instrumented.

Not progress on the Clojure app today, although had a very interesting talk about the need to do more to highlight what makes Clojure so special. I did do some work on this for ClojureBridge London workshop https://clojurebridgelondon.github.io/workshop/introducing-clojure/

Code from today

AWS Lambda function for several Alexa skills:

https://github.com/jr0cket/aws-lambda-jenkins-deployer-alexa/commit/5e601b817c812549104d1a8f14ce7ade23c6c5f9

Activities in detail

Alexa Workshop

To make voice work, the service needs to understand millions of words so that it can accurately interpret what you are saying and have a better chance of doing the right thing. If Alexa doesunt understand the words you say, then its not going to do what you want.

The Alexa Framework can be used to enable any device, not just the devices from Amazon.

They are called skills (rather than voice apps) as we are teaching Alexa to do something specific.


20180918 - Day 4: Are you mocking me :)

Today was a great meetup at Signal Media. Talked about the #100daysofcode challenge I am doing and the experiments with Scalable Vector Graphics. Discussed the case for ClojureScript and Reagent over JavaScript and React.js

Also helped someone on Clojurians Slack write a keybinding for [lispy]() functions lispy-pair and lispy-quote that did not have keybindings defined in the package. Lispy is an alternative to Evil and Smartparents and whilst interesting, its not something I am inclined to try myself.

Thoughts for today

There are so many companies using Clojure I keep finding out about. The TV company Vue.tv uses Clojure for all their data processing around their broadcasting business.

GraphQL in a lambda works surprisingly well according to Alex’s talk. That was really interesting.

Code from today

Status monitor and Scalable Vector graphics

https://github.com/jr0cket/webapp-status-monitor/commit/1c282057c2d1a7433a36ad50b2845c79e788f128

Activities in detail

Mock data generators

I’d like to test out the SVG dashboard with a number of different data sets. Rather than just type a lot of random numbers into the code, I wrote a mock-data generator function. This mock data first returned float values.

(defn mock-data
  "Mock data generator"
  [maximum-value]
  (rand (+ maximum-value 1)))

The mock-data function was refactored to generate either float or integer random data based on the type passed to the mock-data function as an argument.

As the float generated number has multiple decimal places and we only want two for the display, the format function is used to limit the precision of the returning number to 2 decimal places.

(defn mock-data
  "Mock data generator"
  [maximum-value]
  (if (float? maximum-value)
    (format "%.2f" (rand (+ maximum-value 1)))
    (rand-int (+ maximum-value 1))))

Joker linter

As I was experimenting with a mock-data generator in the REPL experiments section, I noticed that Joker reports out of order issues. So it will highlight if you try to call a function before its defined in the file. This happens even if the function has already been evaluated in the repl. This situation does remind me that Joker reads the whole Clojure file each time a change is made.

I am finding Joker invaluable to guard against very silly mistakes and thus avoiding hunting through code for silly mistakes.

More Joker awesomenessness.


20180917 - Day 3: Joker Clojure linter and SVG status bars

Thoughts for today

I had a little excursion into Joker, a linter for Clojure. Someone was having problems getting the clojure-lint layer to work in Spacemacs, so I though I would give it a try and see if I could help. I really like the feedback I get from the Joker linter, its very clearly presented and is very fast.

I like coding interfaces with Scalable Vector Graphics (SVG) as the graphics are defined as data structures (when using the hiccup syntax). So SVG is really easy to use with Clojure. It requires a little trial and error as its not specifically documented as far as I can tell, but having a repl means is really quick to experiment.

Code from today

Defined a status bar component using Hiccup syntax to generate SVG

https://github.com/jr0cket/webapp-status-monitor/commit/4d7925184c8cf181f0addfb8fb829844ba56002d https://github.com/jr0cket/webapp-status-monitor/commit/17efddc7233fb134b107c89f88fe3875ff40f83c

Activities in detail

Continuing the status-monitor webapp

I added some mock status bars to my status-monitor application, using hiccup and [Scalable Vector Graphics (SVG)](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) to add some colour and design to the page.

There is a bit of a challenge with using SVG with the Hiccup syntax, as it does not seem to be documented anywhere. However, its not that hard to work out by looking at the [SVG elements in HTML](https://developer.mozilla.org/en-US/docs/Web/SVG/Element). We are generating HTML after all.

I did find some SVG projects that may be interesting to try: > Tikkba for the creation and the dynamic modification of SVG documents > analemma for generating charts and Scalable Vector Graphics (SVG) > dali for representing the SVG graphics format. It allows the creation and manipulation of SVG files. The syntax used to describe the graphical elements is based on hiccup with a few extensions > svg-wrangler a collection of Clojure functions to help assemble SVG images via hiccup data structures

Joker linter and clojure-lint layer in Spacemacs

I setup on Joker on ubuntu by downloading a pre-compiled linux binary and placing it in ~~/bin~ which is already on my executable path.

Added the clojure-lint layer to .spacemacs configuration file and restarted Spacemacs with SPC q r.

Opened my status-monitor status-monitor.handler namespace and it showed me where I had been less clear with my code straight away.

If I call a function with the wrong number of argument then Joker will put an orange dot in the margin. That’s so awesome.

I will refactor a few things that Joker found tomorrow, such especially refining the namespace refer.


20180916 - Day 2: Investigating compojure-template and lein-ring

Today was more a journey of discovery on how projects from the compojure-template can be run and how the lein-ring plugin works.

Thoughts for today

I really appreciated the work done by all Open Source project owners and maintainers, especially @weavejester who has created so many great projects for Clojure.

I didnt write a lot of code today, but felt I learnt some really invaluable information. It also feels good to give back to an open source project, no matter how big or small the contribution.

Not having to concern myself with a delivery date for my project allowed me the feedom to dive into the projects and tools I have been using for quite a while. This has given me a much better understanding of how to get the most out of them and help me teach other developers how to use them. It is also way more fun.

Code from today

I submitted a [pull request](weavejester/compojure-template#25) to update the each library dependency to their latest stable version in the compojure-template.

Activities in detail

Here is what I got up to in a lot more detail.

compojure-template pull request

When creating a new project from the [compojure-template]() yesterday I noticed that the version of libraries used in the template were a little dated. Those versions stil work, but I decided to create a pull request with the latest stable versions of those libraries.

weavejester/compojure-template#25

There was an existing pull request to update the libraries dependencies, however, that was also out of date.

The compojure-template project only describes how to run a generated project using the lein-ring plugin, using lein ring server. The lein-ring project readme describes how to run the project from the Java command line, but there is no reference to this information on the compojure-template project. Again, I spotted a pull request to add these details to the readme so I added a thumbs up reaction with hope the maintainer will accept the pull request.

Digging deeper into lein-ring plugin

It is common in Clojure projects to define a -main function that is the start point to running the application. However, the compojure-template doesnt generate a project with a -main function, instead it defines a Var called app that is the start of our application.

The reason for this approach is so that the compojure application can be packaged into a Java Web Archive (WAR) file and dropped into an existing Java Application Server (Tomcat, Jett, etc.). This is the traditional approach to deploying a JVM webapp.

The lein-ring plugin adds a task called ring to Leiningen, so you can start the application on the command line using

lein ring server

Running the compojure project using lein-ring plugin starts an embedded Jetty web application server and passes the app to that running process to start listening for http requests.

Running as a stand alone application

With the rise in Cloud computing it is more common to run each application in its own embedded server, rather than deploying mulitple apps on a single applicaton server. This new approach enables vertical scaling and parallel processing, something Clojure is an excellent language for.

Rather than write our own -main function to call Jetty, we can ask lein-ring plugin to do it for us. A -main function is boilerplate code after all.

Use the lein-ring version of lein uberjar to generate a JAR file

lein ring uberjar

Taking a look at the contents of the generated JAR file we can see the additions made by the plugin.

> I use Spacemacs to open the Jar file as it will list all the files and let me read each text file it contains.

An application entry point has been added to the meta-inf/manifest.mf by specifying Main-Class: status_monitor.handler.main

Hold on though… we didnt have a main namespace in our code, so how does that work?

Well, lein-ring had created a file for that namespace with a -main function within it. Here is the code contained within this automatically generated namespace.

(do
  (clojure.core/ns status-monitor.handler.main
    (:gen-class))

  (clojure.core/defn -main []
    ((do
       (clojure.core/require (quote ring.server.leiningen))

       (clojure.core/resolve (quote ring.server.leiningen/serve)))
     (quote {:ring
             {:handler status-monitor.handler/app,
              :open-browser? false,
              :stacktraces? false,
              :auto-reload? false,
              :auto-refresh? false}}))))

The code requires the namespace ring.server.leiningen so ic can run the serve function that takes the app as an argument. serve will run an embedded jetty server and run our app within.

As uberjar is typically used to deply your application to a remote server (e.g. uat, production), then development features are set to false. We dont really want a browser window to be opened when we run the app on a production server.


20180915 - Day 1: Staus Monitor mock website (server side) -

Started a simple status monitor application to collate monitoring information from different sources into one simple web dashboard.

Thoughts from today

The compojure template is easy to get started with, it just works with the help of the lein-ring plugin. The plugin takes the app defined in the src/status_monitor/handler.clj file and passes it to an embedded Jetty application server. The plugin abstracts this detail away, making the project easy to run and less code to write.

This abstraction does make it a little harder to understand how this application actually runs and there is a lack of information on the template website.

Code from today

https://github.com/jr0cket/webapp-status-monitor

Details of today’s activities

New compojure project and dependency version updates

Started a new project using the Leiningen [compojure-template](https://github.com/weavejester/compojure-template)

lein new compojure status-monitor

This created a project using the ring and compojure libraries and Clojure 1.8.0

:dependencies [[org.clojure/clojure "1.8.0"]
               [compojure "1.5.1"]
               [ring/ring-defaults "0.2.1"]]

The project was updated to use the creative commons licence, rather than the deffault Eclipse public license which has is more restrictive.

Version 1.9.0 is now the current stable version of Clojure, so that has been updated in the dependencies.

The lein-compojure template is very simple to get started with, although it seems the libraries are a little behind the latest. The project runs successfully without upgrading versions. It is usually better to use the latest stable versions of these libraries to pick up any fixes.

The latest stable versions were found via https://clojars.org/.

> Consider submitting a pull request to update the lein-compojure template project on Github.

Running the REPL from Spacemacs

Although the project runs well from the command line using the lein-ring plugin, we dont get the full benefit of the REPL until we connect our editor to the REPL. With the Compojure template you need to run the repl from Spacemacs as there is no way to connect to the REPL port from Spacemacs when the project is run with lein ring server.

Using the keybinding ~, ‘~ is a quick way to start the repl in Spacemacs.

Enhancing the webpage

The website is a litle basic in terms of output, so I added Bootstrap CSS and JavaScript libraries to the project as a simple way to make the output look a little more professional.

To use Bootstrap easily and avoid writing lots of html code, I used the Hiccup library. Hiccup allows you to generate html code from Clojure vectors that contain Clojure keywords representing html tags. Generating an html h1 header and its text is written as [:h1 "I am an HTML header"].

Using Clojure syntax in this way, makes it much easier to type. Using this syntax also makes it easy to use structured editing with your code.

The project needs to include Hiccup library as a dependency. Using the clj-refactor tools in Emacs, I added the hiccup dependencies and also hotloaded it into the already running repl.

Added Hiccup and Bootstrap to create a better web page

Created the basics of our monitor dashboard page without writing html direct.

Added the Hiccup library to generate html from Clojure data structures and keywords.

Using the hiccup.page/html5 function we created a page that allows us to include the Bootstrap CSS and JavaScript libraries. Hiccup allows us to include CSS styles in the data structures, or more usefully refer to the Bootstrap styles by name.


20180914 - Day 0: 14th September, 2016

Test out my development environment is working. For the exercises I will be using Spacemacs, a community configuration for Emacs that also provides a comprehensive set of Vim states (Evil mode) that make editing code more effective.

Spacemacs is configured to use the Clojure layer, which pulls in CIDER packages, providing a comprehensive Clojure development environment that is equivalent to the features of an IDE without the resource requirements.

I will use Spacemacs for all coding and documentation for this 100 days challenge. Along the way I will document my usage of Spacemacs and useful practices in the online guide: [Practicalli Spacemacs](https://practicalli.github.io/spacemacs).

Today’s Progress

As today is just a check of my environment, then no progress to report yet.

Thoughts

I am a little nervous about this challenge as it will demonstrate just how much coding skill I currently have. My imposter syndome is kicking in a little as I think about it. However, the excitement of emersing myself in Clojure coding for 100 days is over-riding this nervousness and hopefully this will continue to the end of the challenge.

Link to work

Practicalli Spacemacs My Github repository for 100 Days Of Clojure Code