Monthly Archives: May 2015

Erlang Thursday – queue:head/1

Today’s Erlang Thursday continues to dig into the Okasaki API of Erlang’s queue module, and take a look at queue:head/1.

queue:head/1 takes a queue as it’s first argument, and returns the first item in the queue.

Queue = queue:from_list([1, 2, 3, 4, 5]).
% {[5,4],[1,2,3]}
queue:head(Queue).
% 1
Queue.
% {[5,4],[1,2,3]}

As we can see in the example above, queue:head/1 function does not modify the original queue at all, but just returns the first item.

Because queue:head/1 only returns the value found at the head of the queue, and not a tagged tuple, it raises an error if we try to get the head item from an empty queue.

EmptyQueue = queue:new().
% {[],[]}
queue:head(EmptyQueue).
%** exception error: empty
%     in function  queue:head/1
%        called as queue:head({[],[]})

To be safe, and not get the error raised on an empty queue, the queue module also defines a function queue:is_empty/1 that you can use to check if a queue is empty.

queue:is_empty(EmptyQueue).
% true

Like queue:cons/2, and other functions of the Okasaki API, there is also a function queue:daeh (head backwards), to get the last item from the queue, as well as an alias for queue:daeh/1 of queue:last/1.

queue:daeh(Queue).
% 5
queue:last(Queue).
% 5

Both queue:daeh/1 and queue:last/1 also raise an error of empty if you call them with an empty queue as the argument.

queue:daeh(EmptyQueue).
% ** exception error: empty
%      in function  queue:get_r/1
%         called as queue:get_r({[],[]})
queue:last(EmptyQueue).
% ** exception error: empty
%      in function  queue:get_r/1
%         called as queue:get_r({[],[]})

And if we look at the error that is raised on queue:daeh/1 and queue:last/1, we see that the error is coming from queue:get_r/1 from the Extended API. If we look at the behavior of queue:get_r/1 it looks like queue:tail/1 and queue:daeh/1 are indeed just aliases for queue:get_r/1.

queue:get_r(Queue).
% 5
queue:get_r(EmptyQueue).
% ** exception error: empty
%      in function  queue:get_r/1
%         called as queue:get_r({[],[]})
queue:get_r(Queue).
% 5
Queue.
% {[5,4],[1,2,3]}

–Proctor

Ruby Tuesday – Array#pop

In today’s Ruby Tuesday we continue from last week’s post on Array#push and cover Array#pop.

Array#pop will remove the last element from an Array, and return that element.

[1, 2, 3, 4, 5].pop
# => 5
[:a, :b, :c, :d, :e].pop
# => :e

By assigning a new array to a variable, and then calling pop on the array, we can see that it does in fact mutate the array, and the last item is no longer there.

stack = [1, 2, 3, 4, 5]
# => [1, 2, 3, 4, 5]
stack.pop
# => 5
stack
# => [1, 2, 3, 4]

Ruby makes the decision to return nil if you call Array#pop on an empty array instead of raising an exception.

[].pop
# => nil

While being safer as far as not causing an exception, it does introduce some danger, as you can keep calling pop on an empty array and it will keep returning nils

10.times{ empty_array.pop }
=> 10

Another potential way there is some danger, is that if you just use Array#pop by itself, you can’t distinguish between an empty array, and an array with nils.

stack_with_nils = [1, nil, 2, nil]
=> [1, nil, 2, nil]
[14] pry(main)> stack_with_nils.pop
=> nil
[15] pry(main)> stack_with_nils
=> [1, nil, 2]

And unlike Array#push, which returns self, Array#pop returns the element popped, which will not allow you to chain commands like Array#push does.

[:a, :b, :c, :d, :e].pop.pop
# NoMethodError: undefined method `pop' for :e:Symbol
# from (pry):4:in `__pry__'

If you wish to pop multiple items from the end of the array, you can pass in a non-negative integer value to Array#pop. When passing a number of items to remove, Array#pop returns a list, with the earlier items popped off the array at the back of the list, and the most recent items at the front of the array.

[:a, :b, :c, :d, :e].pop 3
# => [:c, :d, :e]
third, second, first = [:a, :b, :c, :d, :e].pop 3
# => [:c, :d, :e]
first
# => :e
second
# => :d
third
# => :c

–Proctor

Erlang Thursday – queue:cons/2

Today’s Erlang Thursday digs a little into the queue module, and we cover queue:cons/2 from the Okasaki API.

queue:cons/2 takes a item and a queue, and will return a new queue with the item at the head of the queue.

queue:cons(7, queue:new()).
% {[],[7]}
queue:cons(3, queue:cons(7, queue:new())).
% {[7],[3]}
queue:cons(nil, queue:new()).
% {[],[nil]}
queue:cons(5, queue:from_list([7, 9, 13, 21])).
% {[21],[5,7,9,13]}

If we try to pass a list in to queue:cons/2, we see that it does want a queue, and will not do an implicit conversion of a list to a queue.

queue:cons(5, [1, 2, 3, 4]).
% ** exception error: bad argument
%      in function  queue:in_r/2
%         called as queue:in_r(5,[1,2,3,4])

As the queue is setup to be a double ended queue, the Okasaki API also provides a counter function queue:snoc/2, that adds an item to the tail of the queue passed in. Note that the argument order is swapped between queue:snoc/2 and queue:cons/2; queue:snoc/2 takes the queue as the first argument, and the item to add at the tail as the second argument.

queue:snoc(queue:new(), 5).
% {[5],[]}
queue:snoc(queue:from_list([7]), 5).
% {[5],[7]}
queue:snoc(queue:snoc(queue:new(), 7), 5).
% {[5],[7]}
queue:snoc(queue:from_list([7, 9, 13, 21]), 5).
% {[5,21],[7,9,13]}

–Proctor

Giving an Intro to Erlang workshop at LambdaConf 2015

Just a quick post letting anyone who is going to be at LambdaConf 2015 this weekend in Boulder, Colorado.

I will be there giving an Intro to Erlang workshop on this coming Friday, the 22nd of May, so if you are going make sure to look for me around there at least. 😀

Feel free to track me down and say hi, as I would love to meet you as well. The offer is open for you to chat me up about Erlang specifically, functional programming in general, or what ever else we might find interesting.

And if you are going and we meet up, I might just have some Functional Geekery stickers to give away.

Look forward to seeing you there.

–Proctor

Ruby Tuesday – Array#push

Today’s Ruby Tuesday is on Array#push.

Array#push takes a item and appends that item to an existing Array.

[].push 1
# => [1]
[3, 7, 5].push 1
# => [3, 7, 5, 1]
[3, 7, 5].push []
# => [3, 7, 5, []]
[3, 7, 5].push nil
# => [3, 7, 5, nil]

Array#push also returns itself as the return value, allowing you to chain together calls.

[3, 7, 5].push(2).push(8).push(6)
# => [3, 7, 5, 2, 8, 6]
q = [3, 7, 5]
# => [3, 7, 5]
q.push(2).push(8).push(6)
# => [3, 7, 5, 2, 8, 6]
q
# => [3, 7, 5, 2, 8, 6]

You can also pass more than one argument to Array#push, and it will push each of those items to the Array in turn.

[3, 7, 5].push(2, 8, 6)
# => [3, 7, 5, 2, 8, 6]
[3, 7, 5].push(*[2, 8, 6])
# => [3, 7, 5, 2, 8, 6]

–Proctor

Erlang Thursday – filelib:is_file/1

Today’s Erlang Thursday is filelib:is_file/1.

filelib:is_file/1 takes a string representing a filename, and returns a true or false depending on if the name refers to a file or directory.

This can be useful if you are having to read from a configuration file and need to ensure that the file or directory exists before trying to process it, so that you can give a nice error message before quitting, instead of just causing a system error to be raised.

filelib:is_file("foo").
% false
filelib:is_file("junk").
% true
filelib:is_file("tmp").
% true
filelib:is_file("tempmp").
% false
filelib:is_file("temp").
% true
filelib:is_file("/usr/local/bin").
% true
filelib:is_file("/usr/local/var").
% true
filelib:is_file("/usr/local/vars").
% false
filelib:is_file(".").
% true
filelib:is_file("..").
% true

filelib:is_file/1 can also take a atom, or even a deeplist(), representing the filename as well.

filelib:is_file(foo).
% false
filelib:is_file(junk).
% true
filelib:is_file(["/usr", ['/local', '/bin']]).
% true

–Proctor

Ruby Tuesday – File::exist?

Today’s Ruby Tuesday is on File::exist?.

There are times when you want to know if a given file or directory exists; usually this is captured from some kind of configuration file, and you want to make sure the item exists before you want to try to process that path so you can give a nice error. Enter File::exist?.

File::exist? will check to see if the file or directory passed as an argument can be seen by Ruby.

File.exist? "foo"
# => false
File.exist? "junk"
# => true
File.exist? "/usr/local/bin"
# => true
File.exist? "/usr/local/junk"
# => false
File.exist? "."
# => true
File.exist? ".."
# => true

–Proctor

Erlang Thursday – calendar:iso_week_number/1

Today’s Erlang Thursday is on calendar:iso_week_number/1.

calendar:iso_week_number/1 takes a date tuple as an argument, and returns a tuple of the year and week number. The year is the year passed as the date tuple, and the week number is an integer between 1 and 53.

calendar:iso_week_number({2015, 05, 04}).
{2015,19}
calendar:iso_week_number({2015, 05, 03}).
{2015,18}

If we use this week as an example, we can see that a week starts on Monday (the 4th of May), where the Sunday before (May 3rd) was the previous week.

We see that January 1st falls on the first week of the year, no surprise there, and that the 31st of December for 2015, is on the 53rd week of the year.

calendar:iso_week_number({2015, 1, 1}).
{2015,1}
calendar:iso_week_number({2015, 12, 31}).
{2015,53}

Having a 53rd week of the year sounds surprising at first, because everyone talks about 52 weeks in a year, until you realize that sometimes December 31st sometimes falls at the very beginning of a week, causing it to be the 53rd week, since it is only a partial week.

–Proctor

Ruby Tuesday – Date#cweek

Today’s Ruby Tuesday is on Date#cweek.

Date#cweek returns a integer value representing the week of the year that the date falls on. The return value is an integer between 1 and 53.

Date.new(2015, 5, 3).cweek
# => 18
Date.new(2015, 5, 4).cweek
# => 19

If we use this week as an example, we can see that a week starts on Monday (the 4th of May), where the Sunday before (May 3rd) was the previous week.

We see that January 1st falls on the first week of the year, no surprise there, and that the 31st of December for 2015, is on the 53rd week of the year.

Date.new(2015, 1, 1).cweek
# => 1
Date.new(2015, 12, 31).cweek
# => 53

Having a 53rd week of the year sounds suprising at first, because everyone talks about 52 weeks in a year, until you realize that sometimes December 31st sometimes falls at the very beginning of a week, causing it to be the 53rd week, since it is only a partial week.

–Proctor