Wednesday, August 14, 2013

List of programming languages where immutability is default

Here is the list:
  1. Erlang
  2. Haskell
  3. OCaml
  4. F#
  5. Clojure
If you are aware of other programming languages that provide immutable data structures by default, please contribute to this list by posting a comment.

Wednesday, July 03, 2013

Getting my feet wet with Clojure's core.logic

Yesterday I read a nice article about implementing Event Sourcing in Clojure. The domain that the author had chosen to illustrate the concept was the rock-paper-scissors game. The compare-moves multimethod seemed a bit ugly to me, so I thought it would be a great opportunity to try logic programming in Clojure. Here is what I did:

1. Create a new Clojure project using Leiningen:
2. Add clojure.core.logic to project dependencies list:
3. Tell Leiningen to install the dependencies:
4. Write the rules of the rock-paper-scissors game in src/rock_paper_scissors/core.clj:
5. Start a REPL and play a little:
I hope you enjoy the declarative style! I surely do and will certainly continue my exploration of the awesome world of logic programming.

Saturday, December 22, 2012

Clojure, Selenium-WebDriver, and PhantomJS

The following is a small manual of how to setup PhantomJS and use it from Clojure via clj-webdriver  - Clojure API for Selenium-WebDriver.


1. Start a new project using Leiningen:

2. Download PhantomJS from http://phantomjs.org/download.html and unpack it into your project's directory:

3. Now add the following to your project.clj file:


By the way, there is an awesome Leiningen plugin that checks if your dependencies are up to date.

4. Tell Leiningen to update dependencies:

5. Now let's start a REPL to check if everything's in its right place:

Hope it works! If not, ping me and I'll update the tutorial.

Wednesday, October 31, 2012

What to ask a client before you start creating their website?

Recently, I was asked by a friend of mine to create a website for a local travel agency. It's certainly not the hardest thing to do, but I decided to make something differently this time.

Before starting implementing anything I asked my potential customer the following four questions:

  • Why have you decided to create a website?
  • What problems should it solve?
  • Who are the potential visitors of the website?
  • What is unique about your website?
Each question was asked with some intent. Now, I will try to explain it.

Why have you decided to create a website?

All decisions we make are emotional in nature. Especially decision about buying something. The rationalization comes only after we've made it on emotional level. The strongest commitment one can make about a decision is to find a logical reason to make it.
The most important thing you need to figure out before starting anything is what caused your potential client to buy a website. If you find it, then you can easily assess the strength of commitment the person have made and how far they are going to go with it. You don't want a client that calls you next morning to cancel a project because they are no longer sure if it's a good idea. Ain't you?

What problems should it solve?

Website without a clear set of problems to solve is doomed to join the endless army of zombies that nobody wants to meet with. Also, without problems to solve you have no goals to achieve and no way to measure how far your solution is from the ideal one the customer has dreamt about. If so, why don't you ask about them beforehand to ensure that there are some?

Who are the potential visitors of the website?

Every website intended to have some audience, otherwise it's just a useless and strange way to spend time and money. To attract the audience you need to understand it. Ideally, you should be a part of it. How could you make any design decision without knowing who and how will judge them?

What is unique about your website?

There are literally thousands of travel agencies around the world. Good part of them have websites. In such market conditions it is vital for a website to have some unique content, otherwise it can't get to first few pages of search results and might equally not exist at all. There is no point in spending money and time on a website that nobody will ever find.


If you found this list useful and are interested in improving it, please don't hesitate to criticize it heartlessly!

Friday, July 27, 2012

Sending ICQ messages via Jabber-to-ICQ transport (JRuby + Smack API)


Lets assume that you already have JRuby on your machine. To gain access to Java libraries distributed via Maven you need to install a special gem :


jruby -S gem install ruby-maven


Then you should install Smack API library:


jruby -S gem install mvn:org.igniterealtime.smack:smack


Please notice the special prefix "mvn:". You can also use it in Bundler's Gemfile to reference Java libraries once you have ruby-maven gem installed.


Now lets write a simple program to utilize the just installed library. Make sure you already have a valid Jabber and ICQ account. Also don't forget to register the latter via some Jabber-to-ICQ transport.


require 'java'
require 'rubygems'
require 'mvn:org.igniterealtime.smack:smack'

jabber_server = "jabber.dn.ua"
jabber_account_id = "my_jabber_id"
jabber_account_password = "**********"

icq_transport_server = "icq.jabber.dn.ua"
icq_account_id = "1234567890"

conn = org.jivesoftware.smack.XMPPConnection.new(jabber_server)
conn.connect
conn.login(jabber_account_id, jabber_account_password)

cm = conn.chat_manager

def self.processMessage(chat, message)
  puts message
end

chat = cm.create_chat("#{icq_account_id}@#{icq_transport_server}", self)
chat.send_message("Hello!")


To find more about Smack API check its page.

Thursday, June 28, 2012

Making variable dynamic in Clojure

As a full-time Ruby developer studying Clojure I was curious how one can monkey-patch 3rd-party's code in the runtime. The answer is to utilize Clojure's dynamic scoping to redefine a variable that holds a reference to the function of interest. But starting from version 1.3 only variables that are explicitly tagged by ^:dynamic meta tag can be dynamically bind (usage of lexical scoping has positive performance impact).

So, maybe we could change variable metadata to make the variable dynamic. Unfortunately, changing metadata using alter-meta! doesn't trigger its re-evaluation. Consider the following:

user=> (def x 42)
#'user/x

user=> (alter-meta! #'x assoc :dynamic true)
{:ns #, :name x, :dynamic true, :line 1, :file "NO_SOURCE_PATH"}

user=> (.isDynamic #'x)
false

user=> (binding [x 32] (println x))
IllegalStateException Can't dynamically bind non-dynamic var: user/x clojure.lang.Var.pushThreadBindings (Var.java:353)

Instead we can call .setDynamic directly:

user=> (.setDynamic #'x)
#'user/x

user=> (binding [x 32] (println x))
32
nil

If you want to redefine variables temporarily, without making them dynamic (e.g., for mocking out functions during testing), you can use new functions that were added to cover such use case - with-redefs-fn and with-redefs.

Thursday, April 05, 2012

Adding Norwegian (Bokmål) Dictionary to JetBrains RubyMine on Ubuntu

Firstly, install the aspell-no package:

sudo apt-get install aspell-no

Secondly, convert the just installed Norwegian Bokmål dictionary to the format appropriate for RubyMine:

aspell --lang nb dump master | aspell --lang nb expand | tr ' ' '\n' > nb.dic

Thirdly, open the RubyMine settings dialog, find "Spelling" in the "Project Settings" section and switch to the "Dictionaries" tab. Then press "Add" in the "Custom Dictionaries Folder" section and choose the folder where you've just created the nb.dic file.

The process of converting and adding dictionary for any other language should be similar.