One more example why SVN sucked

The worst part of SVN is that it’s got lots of .svn folders hidden in every single versioned directory. It has never occurred to me how terrible an idea this is until I delete a directory. I had this weird deja vu that I’m going to regret issuing that rm -rf command but I did so anyway. It’s versioned, I tell myself.

Ah, but there’s a catch

No. Once I did that I spend the next 30 minutes trying several commands to recover it, such as svn revert and svn update. They don’t work because the current directory’s .svn folder is still there and it’s just silly SVN’s way of knowing its there. Every command to revert led me, falsely, to believe my folders are all still there.

So I downloaded an entire new copy of the files I just deleted and put them back. That failed as the files I have restored manually don’t have the .svn folders. I tried committing the restored copies and the SVN server will just say the “Commit failed” with the reason “Server sent unexpected return value (405 Method Not Allowed) in response to MKCOL request for ‘…'”.

Don’t tell me what I can’t do!

Well… The thing is I wasn’t convinced. In an act of folly I deleted the parent directory which now resulted in the whole project just dead basically. Fantastic.

I should add that at this moment it all came back to me. I am certain this SHITuation happens to me at least a dozen time especially when I’m half awake.

As least Git doesn’t have that issue. Every time I use SVN, I have this feeling I’m walking on thin rope fearing to offend the Tiki gods. I guess I’m just not smart enough for SVN.

Babies know right from wrong?

So it seems babies do know what’s better for them:

Psychologists say babies know right from wrong even at six months

The research was carried out by a team led by Paul Bloom, professor of psychology at the Infant Cognition Center at Yale University in Connecticut in the US, and used the ability to differentiate between unhelpful and helpful behavior as their indicator of moral judgement. The results contradict the theories of Sigmund Freud and others, who thought human beings start out as “amoral animals”, or a moral blank state…

In one experiment babies between six and ten months old were repeatedly shown a puppet show featuring wooden shapes with eyes. A red ball attempts to climb a hill and is aided at times by a yellow triangle that helps it up the hill by getting behind it and pushing. At other times the red ball is forced back down the hill by a blue square. After watching the puppet show at least six times the babies were asked to choose a character. An overwhelming majority (over 80%) chose the helpful figure. Prof. Bloom said it was not a subtle statistical trend as “just about all the babies reached for the good guy.”

In another experiment the babies were shown a toy dog puppet attempting to open a box, with a friendly teddy bear helping the dog, and an unfriendly teddy thwarting his efforts by sitting on him. After watching at least half a dozen times the babies were given the opportunity to choose one of the teddy bears. The majority chose the helpful teddy.

Bloom said there is mounting scientific evidence that this may not be true and that “some sense of good and evil seems to be bred in the bone.” (Source: Psysorg)

Interesting results although I don’t think this is a good experiment to find out whether babies know how to choose right from wrong.

Introduction of SML and SML/NJ

This is much inspired by the well-written A Gentle Introduction to ML by Andrew Cumming, Computer Studies, Napier University, Edinburgh. I have written this in a rush, so please forgive my mistakes by correcting me if you spot any.

This is not a gentle introduction to programming. I assume you have existing knowledge of a programming language and understand recursion. I am a student pursuing Computing & Information Systems degree from Goldsmiths, University of London external studies programme, via Singapore Institute of Management. My language preferences are PHP and Python. I do not have prior experience in SML or any pure functional programming language (but I do use lambda) so this tutorial is written partly to further my knowledge on the functional programming language – SML. That said, this tutorial introduces the SML language from a slightly imperative point of view.

From what I know about SML

I didn’t research much on SML, but this is from Wikipedia:

Standard ML (SML) is a general-purpose, modular, functional programming language with compile-time type checking and type inference. It is popular among compiler writers and programming language researchers, as well as in the development of theorem provers.

SML is a modern descendant of the ML programming language used in the Logic for Computable Functions (LCF) theorem-proving project. It is distinctive among widely used languages in that it has a formal specification, given as typing rules and operational semantics in The Definition of Standard ML (1990, revised and simplified as The Definition of Standard ML (Revised) in 1997). (Source: Wikipedia)

Python has multiple implementations like CPython, PyPy and Jython, SML too has multiple implementations which includes SML/NJ, MLton and Moscow ML.

My SML environment

I install SML/NJ in my Windows machine. I use Windows 7 predominantly but SML/NJ works in all major operating systems. For any editing of SML files, I prefer to use Notepad++ which can do some syntax highlights for .sml files in CAML. It’s quite similar in coloring to SML. To aid my learning, I also svn-co-ed out the SML repository but that’s not necessary. This tutorial uses SML/NJ implementation so be sure to have it at least if you are interested in following it through.

Downloading and installing SML/NJ

You can get a copy of SML/NJ here. Just choose the latest available version to download. I then choose to download the one for Microsoft Windows – smlnj.msi. It’s right at the bottom.

Installing SML/NJ is rather easy, just follow through the steps and you’re done.

Different filetypes that SML uses

You can check out the things SML/NJ installs. It’s a bunch of .cm files littered around.

  • .sml files are the source files for SML.
  • .sig files are the signatures of the methods in  the corresponding SML files.
  • .cm files are SML/NJ’s Compilation Manager files. Think of them as compiled files for the .sml.

Honestly I don’t really like the way the folders are organized but that’s not really for me to decide.

Go next

Using the SML/NJ interactive shell

Go to Command Prompt. Then type “sml” and hit your Enter key. You should see something like this:

SML command prompt windows 7

As you can see, I am using “Standard ML of New Jersey v110.69 [built: Wed Dec 31 23:09:16 2008]”. If you want to load an SML source file, type:

[code lang=”bash”]sml “myfile.sml”[/code]

This is helpful for small assignments like the one I am doing right now.

The SML/NJ interactive shell resembles that of Python and Ruby’s. You can type in expressions from the shell and receive immediate feedback. Great for learning the language. Much of this tutorial revolves around using the interactive shell.

To quit the interactive shell, press CTRL+Z and then Enter. This would exit the SML/NJ interactive shell and bring you back to the Windows command prompt.

Let’s try some expressions

We begin by asking SML/NJ how does it do (note that each expression terminates with a semi-colon):

[code lang=”bash”]Standard ML of New Jersey v110.69 [built: Wed Dec 31 23:09:16 2008]
– “How do you do?”;
val it = “How do you do?” : string
-[/code]

SML/NJ returns back that it’s fine:

[code lang=”bash”]val it = “How do you do?” : string[/code]

This is to represent that the last evaluation is “How do you do?” and it is a string. All expressions evaluated are assigned to “it” if not otherwise assigned to any symbol.

Try some of the following:

  • 1 + 1;
  • 1.0 + 1.0;
  • 1.0 + 1;

Here’s what you should be seeing:

[code lang=”bash”]- 1 + 1;
val it = 2 : int
– 1.0 + 1.0;
val it = 2.0 : real
– 1.0 + 1;
stdIn:5.1-5.8 Error: operator and operand don’t agree [literal]
operator domain: real * real
operand: real * int
in expression:
1.0 + 1
-[/code]

Let’s analyze what the above means for us. “1” is an integer. And the “+” is an infix function that allows for an integer on the left and an integer on the right. “+” is for integer or real addition. The second evaluation take “1.0 + 1.0” and returns “2.0” (a real). In the third evaluation “1.0 + 1″ results in an error. Let’s try to analyze the rather confusing error message:

[code lang=”bash”]- 1.0 + 1;
stdIn:5.1-5.8 Error: operator and operand don’t agree [literal]
operator domain: real * real
operand: real * int
in expression:
1.0 + 1
-[/code]

“stdIn:5.1-5.8” is informing the user where the fault occurred, it says that it starts from line 5 character 1 to line 5 character 8. “1.0 + 1;” happens to be my 5th evaluation using the interactive shell and if you do the counting, character 1 to 8 is basically all of “1.0 + 1;”. Now why did it fail?

It turns out the “+” requires the left and right side to be of the same type, either int or real but not a mixture. SML/NJ returns the operator (“+”) domain to tell the user “+” has some rules to follow and it is not complied with.

Basic mathematical operators

These are the various mathematical operators of SML/NJ. I urge you to try out some expressions before you proceed to get the feel of how it works. It’s a little different from the usual programming languages due to the type restrictions but you should get the hang of it in no time. Some of the operators are only for either int or real.

Operator Purpose int real Example
+ Addition Y Y 1 + 1 is 2
Substraction Y Y 3.0 – 1.0 is 2.0
* Multiplication Y Y 3.2 * 2.0 is 6.4
/ Division N Y 3.2 / 2.0 is 1.6
div Division Y N 3 div 2 is 1
mod modulo Y N 13 div 5 is 3

These typical mathematical operators are referred to as infix operators because the operator is in between 2 operands like this: 3 + 5. The infix operator is + and the operands are 3 and 5. Now try this evaluating: (op +)(3, 5);

[code lang=”bash”]- 3 + 5;
val it = 8 : int
– op+ (3, 5);
val it = 8 : int[/code]

Recognize that both evaluations are similar. We’ve just converted the infix to a prefix operator using the “op” keyword.

Basic types

There are basically 4 main types – int, real, char and string. To denote a negative value, use “~”. Therefore “~1.3” is a negative real value. String is denoted with double quotes as shown in the table.

Type Example
int ~3
real 712.13
char #”c”
string “how do you do?”

Note that for character, we can only put in a character of length 1.

String concatenation

String concatenation is done using a caret (^) like the following:

[code lang=”bash”]- “I am ” ^ “fine.”;
val it = “I am fine.” : string[/code]

Now, once again if we mix the types, we will get an error:

[code lang=”bash”]- “Ans ” ^ (1 + 1);
stdIn:20.1-20.17 Error: operator and operand don’t agree [literal]
operator domain: string * string
operand: string * int
in expression:
“Ans ” ^ (1 + 1)[/code]

Looks like SML/NJ is angry again. Try interpreting the error yourself. Can you figure what’s wrong?

The val, the fn and the fun

We previously asked SML how did it do:

[code lang=”bash”]Standard ML of New Jersey v110.69 [built: Wed Dec 31 23:09:16 2008]
– “How do you do?”;
val it = “How do you do?” : string
-[/code]

SML assign “How do you do?” to the symbol ‘it’. ‘it’ always stores the last evaluation binded.

The val keyword

[code lang=”bash”]- val greeting = “How do you do?”;
val greeting = “How do you do?” : string
-[/code]

Using the ‘val’ keyword you can bind “How do you do?” to the symbol ‘greeting’. Now we try to bind an integer to ‘greeting’.

[code lang=”bash”]- val greeting = 1;
val greeting = 1 : int
– greeting = 1;
val it = true : bool
-[/code]

Now you can we attempt (and successfully) binded 1 to the symbol ‘greeting’ which seconds ago used to be a string. ‘greeting’ cannot be mutated, you can however bind a new item to ‘greeting’. Note that using “greeting = 1” checks for equality and is not an assignment.

Writing a function

To write a function, we can use write as follows:

[code lang=”bash”]- fn x => x + 1;
val it = fn : int -> int
– it 24;
val it = 25 : int
-[/code]

The above function adds 1 to argument we input. We can call the function using ‘it 25’ since ‘it’ holds the value of last item used. The function is somewhat anonymous right now, and the next time we call ‘it’, it is no longer holds a function. What good is a function without a name. We can bind a function to a symbol using the ‘val’ keyword as shown below:

[code lang=”bash”]- val add_one = fn x => x + 1;
val add_one = fn : int -> int
– add_one 3;
val it = 4 : int
-[/code]

Now let’s take a look at the simple function we wrote:

[code lang=”bash”]- val add_one = fn x => x + 1;
val add_one = fn : int -> int
-[/code]

This function takes in 1 object ‘x’ as a parameter. The function evaluates ‘x + 1’ and returns the value. This function is then bind to the symbol ‘add_one’. On evaluation of the sentence, SML returns:

[code lang=”bash”]val add_one = fn : int -> int[/code]

This can be read as add_one is a symbol that holds a function. The function takes in a type ‘int’ and returns a type ‘int’. How does SML know what type to return?

Previously, we see that “1.0 + 1;” cannot be evaluated as ‘+’ requires both sides to be the same type. Since the function performs ‘x + 1’ and the right side is an int type, x must be an int type too and so has got to be its return type.

SML does this form of implicit typing all the time, it saves you from typing your symbols. We’ll see type inference again later.

The fun keyword

The ‘fun’ keyword is used in this way:

[code lang=”bash”]- fun add_one x = x + 1;
val add_one = fn : int -> int
-[/code]

Notice the difference with using the val keyword:

[code lang=”bash”]- val add_one = fn x => x + 1;
val add_one = fn : int -> int
-[/code]

The type of the function is exactly the same: int -> int

You can think of the ‘fun’ keyword as an alternate syntax to the ‘val’ keyword. Take note of the difference between the keyword ‘fun’ and ‘fn’. Virtually no one bind functions using the ‘val’ keyword since ‘fun’ looks a lot neater. The reason why ‘val’ is being introduced first is to stress that functions are similar to types like int and real. They can be bind to any symbol as would an integer.

From this point, we are going to use the ‘fun’ keyword.

That’s all for this lesson

This lesson is a little shorter but there’s lots of practice and try out yourself. There’s no learning without trying.

Badly done project

It’s late at night and I am still coding my project. Worst of all is that the code that I am (possibly) more proud of than the rest of the code I have is the isNumeric function:

[code lang=”javascript”]var isNumeric = function isNumeric (s) {
return !isNaN(parseFloat(s));
}[/code]

There, here is it. The rest of the code very well deserves to be deleted. Unpresentable, at best.

I can never get Twisted to work

It’s time to abort. My project is quite some trouble. I left the implementation to the very last stage. Apparently that is quite a bad idea. I have the following greeting message staring at me:

[code lang=”bash”]kahwee@ubuntu:~/Project/src$ python twisted.py
Traceback (most recent call last):
File “twisted.py”, line 1, in
from twisted.internet import protocol, reactor
File “/home/kahwee/Project/src/twisted.py”, line 1, in
from twisted.internet import protocol, reactor
ImportError: No module named internet[/code]

I can never figure out why I can’t install Twisted. In the end I give up. Don’t have much time left. Tick tock tick tock. I am using Ubuntu 10.04.