Data Structures in Clojure and Elixir: Lists, Tuples, Vectors

In my free time I've been learning more Elixir, and I've already been doing Clojure for awhile now. I am going to write this blog post to compare/contrast the data structures available in both languages as well as a few functions you can use. Just for fun and so I can keep it in my head.

List / Vector

This is aslso known as an array in some languages. This is a collection of items, in which case order is generally depended on to access items. When I am explaining this to new developers I describe it as a bookshelf, each book on the shelf is an element.


We have two kinds of these in Elixir, a Tuple and a List. A Tuple is fast and intended to be for short (<= 4 items) and a List is stored as Linked List. It is much slower than a Tuple because it is stored as a Linked List (if you are not familiar, under the hood, each item in the list has a pointer to the next item).

Lists are defined using [] Here's what it looks like:

iex(1)> favorites = ["bbq", "tacos", "pizza"]
["bbq", "tacos", "pizza"]

Then some methods to access items in a list:

iex(2)>, 0)

iex(4)>, 2) "pizza"

iex(5)> List.first(favorites) "bbq"

iex(6)> List.last(favorites) "pizza"

iex(7)> length(favorites) 3

Notice that length is not part of any namespace, it's part of Kernel which doesn't need prefix of module name (as you might expect) … it is the same place that def, defmodule, if and hd are defined.

A tuple is define with { }:

iex(7)> not_favorites = {"shrimp", "squid", "octopus"}
{"shrimp", "squid", "octopus"}

Then accessing elements is like this:

iex(7)> not_favorites = {"shrimp", "squid", "octopus"}
{"shrimp", "squid", "octopus"}

iex(8)> elem(not_favorites, 0) # index of first item is 0 "shrimp"

iex(9)> elem(not_favorites, 2) # index of third item is 2 "octopus"

iex(10)> tuple_size(not_favorites) 3

Tuples are often used as return values from functions and for pattern matching in case statements. I dont often see the elements of a tuple accessed with elem, most of the time I've seen it decontructed with pattern matching. But if you need it, you that is how you do it.


Clojure has two kinds of sequential containers … Vectors and Lists. A vector is more efficient adding to the end, where as a list (think single linked lists) is more efficient adding to the front.

user=> (def favorites ["pizza" "tacos" "cake"])

user=> (def not-favorites '("squid" "shrimp" "octopus")) #'user/not-favorites

user=> (first favorites) "pizza"

user=> (rest not-favorites) ("shrimp" "octopus")

The ' in front of a list tells clojure don't evaluate this right now.. which you'll see why next.

Take this code:

(def name "nola")

It defines a value of “nola” which you can refer to as “name”. It's not exactly like a variable that you might thing of from other languages, but for now lets say it is close.

However notice something about a list and code:

user=> (count '(1 2 3))

user=> (count '(def name "nola")) 3

user=> (first '(def name "nola")) def

user=> (rest '(def name "nola")) (name "nola")

This code is defining a value called name to be nola … is itself a list. So you may hear Clojure people chant “code is data. data is code.” and this is what they are talking about. It took me awhile to get it then it seemed so simple.

Next post I will talk about Sets in Elixir and Clojure.

Managing My Tasks

Some one asked me how I manage my tasks and I showed him but I thought it would make for a good blog post. I'm not saying I am the perfect solution but this is what works for me.

For long term storage of projects, tasks and ideas I use Omnifocus. I have used it for 7 years. I initially got a free copy of the Mac app because I know someone who works there but since then I've paid for updates and bought it for iPhone and iPad. It is really handy for whatever device I have in my hand at the moment. They provide a sync service so all my apps are in sync. I can put ideas into the Omnifocus “inbox” via my phone then later put them in the right place when I am on my mac. Omnifocus is only available on apple platforms.

The key feature for me with Omnifocus is the Review Tab, which I often use the iPad. It steps through each project allowing you to change due dates for tasks, flag, or delete.

No system will work unless you have a way to review! You can use a spreadsheet, stack of index cards (See hipster pda) or trello. But unless you review regularly it is junk. The fact this is one of the side tabs in Omnifocus is Review is the #1 reason I have used it this long.

If you are disciplined enough to review without that, then good for you. Maybe you don't need Omnifocus :).

For very short term (ie todo this week) I've used a variety of things. Trello. Google Spreadsheets. Index cards … right now I have been using org mode in emacs partly for fun to learn it. I commit the files to github in a private repo. I use org-pomadoro to set a 25 minute timer (especially when I really need to focus) and it makes a log section under the task.

This time last year, I was using index cards. One per project, with tasks written out. When I was working on a project I would put that card on top to remind me to stay focused. When I was done, I recorded the project done in OmniFocus and threw the card away.

And even longer ago, I used Google Spreadsheets. I had one tab per project with the tasks listed out. It was easy to get to on multiple devices (hard to edit on a phone but not impossible).

I get bored easy, so maybe thats why I switch my short term tasks planning, but that keeps it fun.

Anyways, hope I've given you some ideas on manging your own tasks, both long term and short term :)

What I Wished I knew

A few things I wish I knew when I started my career as a software developer.

Go to User Groups! I was working for 2-3 years before I got the courage to go to my first user group. Now I currently run one, and have in the past run more than one. Get out there and meet people, if it is a long commute to the meeting or you have little kids at home (often an excuse/reason I hear) then maybe only go every 2-3 months. It is a sacrifice you must make for your career.

This one has occasionally blocked me: The language you did when you started doesn't have to be the one you are doing now. People change and the language they used at one time (PHP) may not appeal to them anymore and IT IS OK TO CHANGE. And when you do, you don't need to make a big deal about it. I've seen some recent “I'm done with ruby! and here's why it sucks” posts. If you are done with Ruby, then fine.. just go :) You probably don't even need to write a blog post on why.

I see friends/associates of mine that are relentless on making their favorite language do things that maybe is not best, when other languages are better. It is such a waste of time, energy and resources. So don't get too tied to the langauge because it may not be best for all things. Learn the principles and concepts of a language so learning another is just a matter of syntax and idioms.

I hoped I made you think about a few things and maybe save you some disappointment. What did you learn that you wished you knew when you started?

Interview Prep

I recently went through this process so I thought it would be good to share what I think are good things to do to prepare for an interview.


Arrive early, sit in your car or outside and walk in 15 mins before (I'm kind of paranoid, so I get there 30 mins before usually). Ask me about a job I didn't get (years ago) because I was late. Hey, I had a good reason, they changed the time on me and mentioned it an attachment (not the body of the email) that I didn't notice was there. To help with miscommunications, email your contact the day before and confirm time, date, place. Ask about parking or landmarks around the office so you can be sure you are in the right place.

Bring a bottle of water. It's crazy, but sometimes you are not offered a drink! Always good to bring some just in case.

Bring some printouts of your resume just in case. One of the last interviews I had, they had printouts of what was on linkedin which was a more abbreviated version of my resume. Don't know why they didn't have my actualy resume, but I immediately regretting not having print copies. In the past I've had a nice folder for my resumes and pen too like this leather portfolio.

Dress up, at least with nice pants and a shirt. I think the only time I wore jeans to an interview is on a second interview when I saw around me everyone was in shorts the first time. While you are there, glance around to see how everyone else is dressed so you know what to wear on your first day. Bring a sweatshirt/jacket in case it's cold in the office.


Make sure you tell the recruiter or initial interviewer what you want to do. You wouldn't believe it this, but one job I said I wanted to do Ruby and after 4 hours and 9 people, they told me they didn't have that much ruby. I was pretty mad to have my time wasted.

Or another time, someone comes recruiting at a cojure conference, I do a code challenge (in clojure) and interview for 4 hours (including 30mins talking about my clojure code challenge) … only to have them say I was too specialized and they want someone to do python and Go. Also a frustrating experience! If they would have only asked me, “hey you are great on clojure, but how do you feel about go and python?".

One more… one place they wanted ruby and I talked about my 11 years of Ruby and also 4 years ago I also started learning clojure for new challenges. He didn't continue the interview process, afraid he'd hire me and I'd leave for clojure. Well, sorry for being a polyglot! I'm hoping this was just a rare case and not everyone is so narrow minded. Also, there are no clojure jobs in Austin (everyone who does it in Austin is remote!).

Yep, next interviews I clarified what I wanted to do and what they needed and tried to gauge how they felt about being a polyglot..


I know you might not use Big O Notation and analysis In Real Life very often, so even I forget it form time to time. But when you are set to start interviewing, learn it or review it.

Do some exercism or codewars exercises to review for the language you think you will be tested on. Find a friend and do some pair programming so you can get the hang of talking about your code as you write. Practice setting up a project. I remember doing a couple new Clojure apps and setting up a library and the tests for the library and getting all the paths and names correct. With ruby, setup a new project and install minitest and make sure you can make a module and a test and it just works.

Google ‘list of questions to ask at an interview’ and get some ideas. One question that I found in that manner is asking your interviewer “What challenges do you think I will face in this position?” which revealed a little more about the position than I knew before.

Don't complain about your last job(s) .. it doesn't matter at this point and you don't want to look like you are a whiner. If they ask why you left your last job, go ahead and say why but keep it to facts not emotion.

Hopefully these will help you land your next job .. Do you have any tips?

Coding on Car Trips

I have a big family scattered through the United States, so we do road trips. My husband drives while I code :) On my last road trip I wrote these notes:

Bring some things to do that don't require wifi. If you have a codeschool account, download some of the videos to watch. You may not have the bandwidth to do the exercises and play along but you can at least watch the videos.

Plan on sitting in the back of the car/van so you can be away from the front windows – it can be so bright! it makes it hard to see the screen. For my Expedition I have some window cling screens to block the bright sun (and keep it cooler in the back!) and it works pretty well.

Bring an extra laptop charger. I usually travel with two, one in my bag and one in my suitcase. Because of that ONE time I left my charger in the hotel and I needed it for a presentation! When I am in the hotel I use the one in the suitcase, other places I use the one in my bag. Same goes with other chargers (phone, ipad etc).

I have this adapter to plug in my laptop and my usb cables.

Use your Ipad (or other tablet) to read tech books or look up code. To that end, get some good books, you can use search and it is almost as good as looking up docs online.

Listen to Podcasts. Here's a list of my favorite podcasts. Just make sure to download them ahead of time if you are in the waste lands of West Texas where they don't have cell phone towers.

Koans, I have a list of koans which are small tests to complete to help you learn coding.

Brainstorming, you may find the somewhat quietness of a roadtrip to be a perfect time to brainstorm and come up with ideas.

Happy Travels

Tagging in Robot Framework

I talked about the awesome robot framework in the previous post and I wanted to talk about Tagging since I think this is very useful.

Tagging is one way to group tests so you run a subset of tests. In your test case, add this:

Homepage Loads
  [Tags]  smoke
  Open Homepage
  Element Should Be Visible  ${FIND_LOGO}
  [Teardown]  Close Browser

Results to run just one tag:

▶ robot --include smoke youtube.robot
Youtube :: A test to demo testing YouTube
Homepage Loads                                                        | PASS |
Search Loads Results                                                  | PASS |
Youtube :: A test to demo testing YouTube                             | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed

You can create a focus so it is easy to run that one test as you are developing it. I have used a similar technique when working on rspec tests. When the test works as you wanted, remove the focus tag. :)

When you look at the report you can see the tags assigned to teach tests. This report was run on all tests. Screenshot

Automation Testing with Robot Framework

On one of my projects recently, I was tasked with finding an automation framework. Looking at my options..

  • Cucumber (ruby, although other languages could be used)
  • Capybara / Rspec (ruby)
  • Robot Framework (python)

All of the options for web testing use either Selenium or Watir. I have only did a little with Watir, so I focused on something with Selenium for my first pass of experimentation.

I love testing if you know anything about me, I'm nuts about testing. Front End Testing however has been fruitless IMHO .. until a few years ago I discovered page objects and it became tolerable to do frontend testing. My projects changed and I didn't really do much for a few years with web frontend testing.

Recently I have been looking into Python and discovered Robot Framework, meant to test a variety of things in addition to the web. The Selenium2 package is especially nice.

You can have a robot script as a text field, in a TSV, or other types of strutured text. I find the text file works for me.

Here we can define a Test Case:

Homepage Loads
  Open Browser  Firefox
  Element Should Be Visible  id=yt-masthead-logo-fragment 
  [Teardown]  Close Browser

This script opens the browser to youtube using firefox. Then checks that element located by id=yt-masthead-logo-fragment is visible (ie on the page, not display: none).

you must make sure to have two spaces between the elements

Open Browser` `Firefox

Or it won't be able to parse. I guess this is when having it in a spreadsheet (TSV) would come in handy. But it's not too bad to get the hang of. Plus if you use nice editors like PyCharm and the Robot Framework Plugin, it has nice syntax highlighting for you.

Running the test case like this:

robot youtube.robot

And results look like this:

▶ robot youtube.robot
Youtube :: A test to demo testing YouTube
Homepage Loads                                                        | PASS |
Youtube :: A test to demo testing YouTube                             | PASS |
1 critical tests, 1 passed, 0 failed
1 tests total, 1 passed, 0 failed
Output:  robot-demo/output.xml
Log:     robot-demo/log.html
Report:  robot-demo/report.html

There that is just a taste of what it can do. If you want to see what all you need installed you can see my robot demo and some more complex tests. More testing posts to come on this, I think this is a very excellent framework … even if it is not ruby :)

My Favorite Tech Podcasts

I saw someone asking about tech podcasts recently and I named off a few, but I think it is easier to put it in a blog post :) Ordered in roughly the order I am into at the moment :)

General Tech

  • The Changelog - open source discussions, interviews with a wide varity of languages
  • DotNetRocks - You might think it is all about .NET but it is not, they cover a wide variety of topics.
  • Functional Geekery - Wide variety of topics on Functional Languages.




  • defn podcast - The hosts are hillarious on this podcast and I enjoy the banter, mostly interviews with clojure developers
  • Cognicast - Hosts are from Cognitect, the “stewards of the clojure language”.



  • Ruby Rogues - I listen sometimes, I generally browse the topics to see if it looks interesting.

Game Development


  • Two Keto Dudes - About the Keto way of eating. BACON BACON!!! Also I am a bacontarian. :)
  • Into The Nexus - About Blizzard's game Heroes of the Storm

using jshint

Javascript. It's a language that some of us love to hate, me occasionally. Here's a few notes to myself to make JS a little better :)

Use these settings in JSHint to avoid instanity:

file: .jshintrc
  "flagname" : true

If you have settings that apply to only your test environment you can put those in test/.jshintrc (maybe allowing global var for your test function) .. you can extend a confiuration in another file with this option `"extends” : “../.jshintrc”

Sometimes you just can't please everyone, including the linter. Here's how to ignore blocks or lines from the linter:

To ignore a block of code use

/* jshint ignore:start */
/* jshint ignore:end */

to just ignore a single line:

myBadJsHere // jshint ignore:line

Obviously you shouldn't let the linter ignore code but you may have a good reason to do so.

Handy thing to have in your .jshintrc file:


1 != “1” right? comparing a number to a string? no, JS says sure its the same using automatic type conversion. Use this flag to warn you and remind you to use triple equals to not do automagic type conversion.

Switch statements

This was just a neat thing I learned today, in JS switch/case statements you need to do a return or break or you will fall through to the next option. Leave a note for the next guy that says you did mean to fall through with a comment /* falls through */ and you will silence the warning from jslint. Kinda cool, huh?

Use Strict

"use strict";

This tells javascript to cut the funny business and not be so helpful and error when stuff should error.

I picked up some of these tips watching Pluralsight: JavaScript Best Practices

Thanks for humoring me as I write these notes to myself :)

Ruby like Python

I did python.. awhile back, it was like ruby in some ways and in some ways not. So I picked one, I went full blown into Ruby. Recently I've seen lots of job postings for Python so I figured I'd give it another go :)


In Python:

>>> message = "hello world"

>>> message[0:5] 'hello'

>>> message[6:] 'world'

Then in ruby

2.4.0 :001 > message = "hello world"
 => "hello world"

2.4.0 :002 > message[0..5] => "hello "

2.4.0 :003 > message[6..-1] => "world"

Eveything in ruby is an object and objects have methods. String has a method slice, aliased to [] (cool!) and the .. is a range. You could use a comma but there is so way to tell it to use the end unless using a range. If you look at the params for the slice method it is a fixnum or fixnum, fixnum or a range. It can also take a string (if you use the method name) but that is a strange use.

2.4.0 :005 > message
 => "hello world"

2.4.0 :006 > message.slice("ello") => "ello"

2.4.0 :007 > message => "hello world"

2.4.0 :008 > message.slice!("ello") => "ello"

2.4.0 :009 > message => "h world"

Unless you use slice! (bang) does it actually change/do anything remotely interesting. Probably I would find a more clear way to do it than using slice with a string.

Well this is just one aspect of the differences and I am not sure if there are differences in the versions of python too.