Archive for the ‘Development process’ Category

Over the last several years I’ve written quite a few posts on DCI in various fora. Especially in response to someone trying to learn DCI. I’ve come upon the same problem over and over again and last night it happened once more. Essentially, it comes to this line of Q&A

Q: “I’ve started learning DCI and want to understand how it’s superior to OO could you please write an example so that I can understand”
A: “There are quite a few examples on http://fulloo.info/Examples. Have you studied those?”
Q: “Yes, but those didn’t compare OO and DCI, so I still don’t understand. Could you please write an example that will help me understand?”

The questioner is genuine in his wish to understand DCI but the line of questioning is in my view odd, but trying to tell anyone that, will usually end with an unfruitful discussion about the mentors way of teaching.

This post is me trying to shed some light on why this line of questioning doesn’t lead to the desired outcome for the questioner and to give an alternate approach.

Let’s try something else than a paradigm shift because they are inherently hard.  Let’s try comparing encryption schemes

Q: “I’ve started learning encryption and I’ve seen AES and DES. I don’t understand why AES is better than DES, I need an example that shows why”

A: “I could give you an example of a text encrypted with both but you want to be able to see why one is better than the result from the other. They are different in how they accomplish the result. If you understood some of the theory, such as entropy we could probably have an informed discussion”

Q: “I don’t want to have a theory discussion, I just need an example”

A: “There are plenty of examples out there, have you studied those?”

Q: “Yes, but they didn’t tell me why AES is better than DES”

A: “No and that’s because the difference is in the process if you studied some of the theory and experimented a bit we could have an informed discussion”

Q: “I don’t want to discuss the theory I want to understand it from looking at the result”

 

I don’t think anyone believes you would learn encryption from looking at the result. Even for extremely simple stuff. Stuff we can teach to small kids you can’t even as an adult learn from looking at the result. Below I’ve represented a concept you know, in an unfamiliar notation. It’s extremely simple and you even know the concept and theory, but I’m confident that you will have a pretty hard time answering the question

3 3 44

44 11 6

44 2 9

3 44 88

3 2 5

88 44 ?

 

 

It’s simple math. Stuff my daughter was able to do in her head before starting in school. But from looking at the examples you didn’t learn much. However, if you know just a little number theory and know the notation I’ve used, then it would be very easy for me to explain addition to you. Let’s repeat: This is a simple addition, none of the results are larger than 9 and you couldn’t understand it from five examples. However, if we had spent 25s for you to understand the notation and maybe 1 minute to understand numbers (if you didn’t already) then I could explain addition to you in 10s and you could use the examples to test your understanding. That is what examples are for. You test your understanding against them. Maybe your understanding matches and maybe it doesn’t. If it doesn’t you are likely to have a ton of informed questions that can help you further, but those are all questions you wouldn’t have been able to ask if you didn’t understand the basic theory.

Now imagine that we are not talking about the addition of one digit positive integer but an entire believe system.  First of all to discus which is more suitable we need to agree on what’s suitable. If we can agree on that we can then discuss which believe system is more stable. So let’s just say for now that we agree that comprehensibility makes a programming paradigm more suitable. Then we need to agree on what makes code comprehensible. There’s quite some research and theory into what makes something hard or difficult to reason about and theories can be found in  Neuro-/psychology, didactics. Philosophy and Neurology but also in math. The first four can tell us how we learn, remember and understand information, whereas the latter can tell us about abstraction and compression and other more abstract perspectives on information theory. If I can’t make you understand single digit math in five complete examples, then how am I going to show differences in comprehensibility based on theories in at least 5 different branches of science spanning both human and natural sciences, in one example that has to be small and therefor can have no chance of being complete?

 

I’m all for challenges, but this one is not one I think I’m going to solve presently. This is made even harder because most of the people coming to learn DCI has a preconceived idea that they know what OO is, however they usually know so technical merits that has nothing to do with the mainly psychological background and basis for OO. So they’ll first have to admit that what they thought they knew about OO is at best a half truth and sometimes even a lie.

 

If you have come this far you must be tenacious and I promise I’m almost done. I will wrap up with a step by step guide to understanding of DCI

  1. Accept that what you know about OO, probably has very little to do with the foundation of OO. After all the inventor of OO claims there’s only one real OO system in the world (the internet)
  2. Either familiarize yourself with research into how we learn, modeling and information theory or take the easy route and accept the postulates from authorities at face value
  3. Read articles about how to apply DCI, there’s a few on this site with likes to even more
  4. Experiment and don’t forget to reflect upon the result
  5. Ask questions based on your experiments and reflections
  6. Publish the resulting examples, at best as part of the Trygve repository
  7. Repeat step 2-5 until you gained the level of understanding you desire

Working on a project where we need more control of our development environment and especially needed a way to make sure that configurations were consistent across all developers machines and our test environment I look into setting up a vagrant environment.

I started out by installing vagrant on my windows machine and after installing I wanted to set up our environment to use  Ubuntu boxes and in the vagrant cloud I found a box I could use named hashicorp/precise64. So to add this box to my local Vagrant environment I ran

$ vagrant box add hashicorp/precise64

Howver the download was blogged by a proxy, so instead I downloaded it and installed from file

$ vagrant box add --name="hashicorp/prcise64" file:///fully/qualified/path/to/file

After adding the box I updated the Vagrantfile to look like this

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
end

To check that everything was working I saved the file and ran

$ vagrant up

This worked like a charm and I followed up with

$ vagrant ssh

but alas this requires an ssh client. Vagrant will suggest several that can be used and I chose to install cygwin

after installing cygwin I ran the ssh command again. and got a ssh session to my default box. Vagrant is smart enough to let you ssh to the default box if there’s just one. When you get to having a multi-machine setup you will need to provide the name of the box you wish to ssh to like so

$ vagrant ssh webserver

to ssh to a box named webserver

By now Id installed

  • Vagrant
  • cygwin

The first thing I wanted to do was update the box so I ran

$ sudo apt-get update

but again this was block by the corporate proxy.

Searching around the net trying to figure out how to configure vagrant to use a given proxy. It turns out there’s a plugin called vagrant-proxyconf and to install plugin ins in vagrant you would typically run

$ vagrant plugin install vagrant-proxyconf

however that still requires vagrant to be able to authenticate towards the proxy so I ended up downloading the gem. The latest version was  version 1.4 which I found on from rubygems.org. When you want to install a plugin from source vagrant will let you do so

$ vagrant plugin install vagrant-proxyconf --plugin-source file://fully/qualified/path/vagrant-proxyconf-1.4.0.gem

this will install from the newly downloaded gem instead of those getting around the proxies blocking the usual way to install plugins. So now it was time to set up the proxy for use by the box. This is a simple change to the Vagrantfile

if Vagrant.has_plugin?("vagrant-proxyconf")
    config.proxy.http     = "http://192.168.56.1:3128/"
    config.proxy.https    = "http://192.168.56.1:3128/"
    config.proxy.no_proxy = "localhost,127.0.0.1, 192.168.56.*"
  end

The check to see if the plugin is not required and I found that while debugging it’s actually a good thing not to check because then you will know whether it’s because the installation of the plugin failed or your error is in the configuration itself. However for portability it’s a good thing to check for the plugin. The Vagrantfile is supposed to be something you can share across various environments and some of those might not need the plugin.

So now we should be able to ssh into the box again and update. However for the changes to take place we need to reload the box

$ vagrant reload

and when the reload is done we can ssh to the box again and run apt-get update. However when the proxy requires NTLM authentication this will fail because even though the proxy is now configured correctly for the box it can authenticate and will get a HTTP 407 back. This particular step took me quite sometime to resolve but there’s a solution to the problem called CNTLM. I thought about installing it on the boxes and then repackaging the boxes making them self contained or to install CNTLM on the host. I decided for the latter because I then would have a setup that would allow for other applications to use this same infrastructure. The down side of course being that everyone in the project will need to install CNTLM on their host as well. The installation was pretty strain forward. In the ini file I had to change a few things

  • user name
  • password
  • domain
  • address CNTLM should listen to. If you follow the rest of the examples here it should listen to 192.168.56.1:3128
  • corporate proxy

After getting it to work I highly recommend to follow the CNTLM recommendation of hashing your credentials

after installing CNTLM I once again opened a ssh-session to the box and once again I was blocked. This time it was not so much the proxy but the network. For the box to be able to connect to the CNTLM proxy I needed to configure a host only network. Which is a network the box can use to communicate with the host and vice verse. It’ rather simple to setup and simply requires a change to the Vagrantfile. Add the below line somewhere in the configuration block

config.vm.network "private_network", ip: "192.168.56.2"

This will give the box a static IP of 192.168.56.56 and since the host by default will have a static IP of 192.168.56.1 they are on the same subnet and should be able to communicate but we’re not their yet. You will need to setup a firewall rule on the host. There’s a good guide on how to set this up that helped me to be found on serverfault.com.

Now with that in place you should finally be able to access the outside world from your vagrant boxes.

To sum up

  1. Download and Install vagrant
  2. Download the box you require from the cloud
  3. Add the box with
    $ vagrant box add --name="name of box" file:///fully/qualified/path/to/file
  4. install cygwin (including the ssh package)
  5. install cntlm and configure it
  6. download vagrant-proxyconf from rubygems.org
  7. install the plugin with
    $ vagrant plugin install vagrant-proxyconf --plugin-source file://fully/qualified/path/vagrant-proxyconf-1.4.0.gem
  8. configure the proxy in the Vagrantfile to point to your CNTLM proxy (see example above)
  9. Add an internal network between guest and host by adding this line to the Vagrantfile
    config.vm.network "private_network", ip: "192.168.56.2"
  10. open the firewall on host for the guest to be able to connect to CNTLM (guide)