Incompleteness Theorem and the Value of Programming Paradigms

Monday, August 12, 2013

Crisis of Mathematics Foundation


Recently, I am reading about computational mathematics and its history. One interesting topic is the crisis of mathematics' foundations in the early 1900s. This summary is my interpretation. In this episode, mathematician David Hilbert becomes worried that his field's foundations, proof by logic and axioms, is crumbling. Why does he think so? People have found paradoxes, unexplainable situations which arise by following his basic set of tools. This opens his field attack, to be called 'nothing more than useful tools', rather than 'essential truths of the universe'. Everyone wants to spend their time on subjects of importance, right?

So, if his field's basic tools, its axioms and theories, were complete and true, the mechanics of any one thing could be explained and calculated. However, simple paradoxes are found which his field can't explain. For example, the barber paradox is a logic puzzle which is an application of Russell's paradox, in set theory. Set theory mathematicians build theories which can explain the relationships between everything. If you ask a set theorist to explain the barber paradox, he will start to question whether his system's basic tools 'make sense'.

So you can see that if the usefulness of the basic tools of a mathematician's field are questioned as illogical, he will worry that he is spending his time building a useless system and search to extend his rules to cover this logical hole.

Perceived Crisis of Programming Tools


Does this story sound similar to you? I'm a computer programmer, and I often read blogs and such from other programmers. If you don't know, most programmer's discussion topics are "language X is better than language Y", or "tool X is better than tool Y". This is not bad, since a good programmer always asks "Can I do this better?". Of course he must listen when another programmer says "This way is better".

So, what's the answer? Which language is best? There is so much discussion on this topic, so someone surely has found an answer. Sadly, no. If you ask a rational and experienced programmer, he will have decided that "The right language depends on the problem you are solving".

Kurt Gödel's Logical Discovery


Back to the world of mathematics. Hilbert, like a good programmer, wanted to work with a perfect set of tools, a perfect set of axioms and theorems. What is a "perfect" set of axioms? It is a consistent and complete set, such that they can be composed to explain anything. So, Hilbert is asking for a single set of terms, a single language, to use for all mathematics. Is this possible?

To answer Hilbert, mathematician Kurt Gödel proved something interesting about mathematical logic. He showed that inherent limitation exist of any set of tools, that is, any system of axioms used for natural number arithmetic. In his incompleteness theorems, he proved that if you create a set of all consistent and true axioms, it can not explain all truths. That is, as a user of these axioms, there will always be statements which you know are true, but you can not prove them using your set of axioms.

(Side-note: This theorem has been referenced as an axiom to prove many things, from 'god exists and you need faith' to 'math and logic is useless'. However, I believe I am correct to say that these useages are incorrect because the logic in Gödel's theorem means the theorem can only be applied to systems of arithmetic and in the context of systematically generating a complete set of axioms.)

Judging Legitimacy of New Languages


How is this related to programming paradigms? Consider this extrapolation I made (possibly illogical, but still interesting) from Gödel's idea. Suppose: I have a statement which I know is true, but I can't prove it using our set of axioms. What to do? After looking closely, I see that I can slightly modify one of our axioms to create a new one, thereby enabling me to prove my statement. Can I do this? Is my new branch of math a legitimate one? I say yes; if it can be used to correctly describe the problem in a cleaner, more consistent way, then yes, its legitimacy is decided by its practicality and usefuless.

This story isn't wholly based in my imagination. Consider Hyperbolic geometry, which is a relatively new field of mathematics. It takes classical geometry, modifies a single axiom (changing the definition of parallel), and calls it a new kind of math. This new system of geometry is very practical, as it provides tools to solve previously-undescribable problems. Some of these problems are listed in this discussion.

Changing a Single Axiom in Programming Languages


How awesome. By changing a single basic assumption, a new way of thinking is developed to easily explain difficult things. In my opinion, this is exactly the criteria we should use to decide whether a new programming language should be used. A useful programming language should obey a single practical philosophy, that is, a single set of axioms.

For instance, consider Clojure. Traditional programming is based on manipulating variable values through a series of subroutines. Based on years of experience, the creator of Clojure decided that this idea of mutable state is really bad for modern applications, which is more and more using concurrently-running processes. Clojure restricts a programmer to immutable state, which theoretically makes writing programs using shared state safer and easier.

Another example is Erlang. Traditional programming is based on creating one executable program or process to run on a single machine. The practical world of software development created the notion of software services, such as web services, which should be always available. The creators of Erlang decided this idea is essential. By constructing their language around this core idea, they decided that pure functions and fault-tolerant processes are implied essences. By restricting a programmer to use only these ideas, Erlang programs theoretically have few concurrency-based bugs and very little downtime in production.

Final Thoughts


Difficult problems can become trivial problems if we change a single rule of the game. Applied to programming languages, I believe this requires more than adding a library to support this idea. Essential to injecting a new paradigm into a language is restricting the parts of the language which run contrary to the paradigm. John Carmack mentioned his recent research on functional programming languages in his recent talk at his QuakeCon 2013 keynote talk. He supports this idea of restricting a programmer when following a new paradigm:

    "Everything that is syntactically legal that the compiler will accept will eventually wind up in your codebase."

    "Languages talk about multi-paradigm as if it's a good thing, but multi-paradigm means you can always do the bad thing if you feel you really need to."

To liberally interpret his words, tool designers care about supporting a certain way of problem-solving, whereas programmers care about quickly and directly solving the problem at hand.

Build Your First Ruby on Rails App

Sunday, February 3, 2013

Foreword

I am interested in learning Ruby and its Rails website framework for two reasons:
1) To build quick websites.
2) Ruby seems like a useful tool.

This code article will simply be my notes from the Dreamforce 2013 developer session named "Hands-on Ruby on Rails - Build your First App". Here is its recording on YouTube that I'll be using, here are the slides on SlideShare, and here is the code artifacts on GitHub.


Session Agenda

  • Introduction to Ruby, Rails, and Heroku
  • Getting Started
  • Building a Blogging App
  • Deploying to Heroku
  • Q&A

Intro to Ruby and Rails

  • Ruby was created in 1995 by a Japanese guy known as Matz.
  • Ruby designed to be a cross-platform, simple scripting language.
  • Rails is a web app framework which uses MVC, which helps organize code.
  • Rails is designed to be simple by using fewer config files and good architectural patterns.
  • Rails uses routes, which means it is easy to make a RESTful web app.
  • Rails has a mantra - convention over configuration. One of those is directory structures:

    • app/controllers
    • app/helpers
    • app/mailers
    • app/models
    • app/views
    • config/
    • db/

Getting Started with Heroku

  • Heroku is nice and you should use it.

  • Install Rails Tools

    • Install Heroku Toolbelt (CLI, Foreman, Git) - (I previously had installed)
    • Install RVM, RubyGems, and also Homebrew if on Mac
    • Install Ruby 1.9.2 (I previously had installed)
    • Install Rails
    • Install PostgreSQL
    • Heroku Quickstart

Installing rvm

The speaker assumes the audience already had Rails installed. I do not, however, so I'll install that now. I'll be using the RailsApps install guide.

This guide recommends using rvm to manage Ruby and Rails versions. Why do we want rvm? It manages your app's libraries and frameworks which simplifies upgrading versions. First, rvm downloads and installs Ruby versions and gem versions into its repository which is in the ~/.rvm directory. Then, rvm sets all references to these, which is how your app finds them, such as the PATH.

  • Install rvm
      $ \curl -L https://get.rvm.io | bash -s stable --ruby
      

Quick rvm Tutorial

To specify and maintain the version of Ruby we want to use, specify the version like this. (Note: To see all Ruby versions that rvm supports, execute rvm list known.)

$ rvm 1.9.2-head

rvm enables you to create a 'gemset' to manage versions of dependencies, such as libraries or frameworks. Before upgrading to a new version of Rails, the guide recommends using rvm to create a gemset container in which to test it.

$ rvm gemset create rails222 rails126

With a gemset for the new Rails version, you can switch to that container and install Rails inside it.

$ rvm 1.9.2-head@rails222
$ gem install rails -v 2.2.2

$ rvm 1.9.2-head@rails126
$ gem install rails -v 1.2.6

Now that a gemset is defined for each version of the Rails gem, we can switch to each version of Rails like this.

$ rvm 1.9.2-head@rails222
$ rails --version   # Rails 2.2.2

$ rvm 1.9.2-head@rails126
$ rails --version   # Rails 1.2.6

Installing Rails

While we won't be using these advanced features of rvm, knowing the extent of this tool is still useful. We will be using just one feature of rvm, which is to install the latest Ruby version. If you didn't already do it, install the latest Ruby like this.

  • Install the Latest Ruby

    $ rvm 1.9.2-head
    

Now that we have the latest Ruby, we can continue following the Rails install guide here at the 'Install Rails 3.2.11' section.

The rvm package includes RubyGems, which is a package manager for Ruby. This tool makes it easy to use frameworks and libraries that exist in the Ruby ecosystem by centrally hosting various versions of registered packages or arbitrary code. We will use RubyGems to install the Rails package.

  • Install Rails

    $ gem install rails
    $ rails -v
    

I am using Ubuntu 12.04. Rails will attempt to use SQLite as a default database solution. Bundler will install the sqlite3 Ruby package, which is the Ruby interface code to the SQLite database software. If the SQLite software doesn't exist on the system, this Ruby package can't interface with it, and will cause an error. I haven't installed any database software yet, so generating a default Rails app will fail. To solve this, we need to install the sqllite3 database software using apt-get.

  • Install SQLite

    $ sudo apt-get install sqlite3 libsqlite3-dev
    

Using Rails

Rails is not only a web app framework, but it is also a code generator. Rails can generate a complex application that has many components. Because these components work together out of the box, your job as a web app dev is to customize the app, rather than spending lots of time gathering app components, connecting them together, and testing them.

So, let's tell Rails to generate a new app for us. It only requires us to name the app. Let's name it 'blog'.

$ rails new blog

This creates the directory structure for a web app and fills it with default HTML, CSS, and JS files. It also sets up the HTTP server and Ruby classes that handle HTTP requests. Most importantly, this generates our app's bundle file.

There are many libraries and third-party apps, such as an HTTP server, that compose our app. These dependencies are all collected into a single location, called a 'bundle' file. A tool called 'Bundler' reads this file to download and install these dependencies into our app for it to use.

One of these dependencies is a database solution.


Setting up Databases

Rails uses SQLite as its default database. This is a nice database because it's fast, which makes development more fun. However, because the production environment might require a heavier database, we might want to use two different databases - one for development and one for production. The PostgreSQL database has some really cool features, and Heroku likes this database, so I want to use it in production. Rails supports using multiple databases like this, so let's take a look.

Bundler installs our database software. We can ask Bundler to install SQLite if the environment is called 'development', and install PostgreSQL if it is called 'production'. Let's set up Bundler to do this.

  • Define different development and production databases

    • Open the gemfile file, which is located in the rails app's root directory.
    • Find the gem 'sqlite3' statement
    • Replace this line with the following

      group :production do
        gem "pg"
      end

      group :test do gem "sqlite3" end

Now, when this app is deployed to production and installed, Bundler will run, see that it's on production, and install PostgreSQL instead of SQLite to use. We can run Bundler on our app right now, in test mode, and I believe it will still download PostgreSQL, but not use it.

If we try to install this additional dependency now, it will fail because we haven't installed the PostgreSQL software to which this gem will attach. So let's install PostgreSQL.

  • Install PostgreSQL and header files for libraries

    $ sudo apt-get install postgresql-9.1
    $ sudo apt-get install libpq-dev
    

We can test this by running Bundler on our app again.

  • Install app dependencies with Bundler

    • Navigate to the Rails app's root directory.

      $ bundle install
      

Set up Data Model & Scaffolding

Our blog will be simple - its posts will have only a 'title' and a 'body'.

Adding a new database object to an application traditionally isn't as simple as clicking an 'Add' button. There are a few places to make this addition, namely in the database, in the persistence layer definitions, and Ruby classes to match the new object. These changes can be predictable for most use cases, so Rails can generate this code for us. In Rails, this stack of code for using and persisting an object in this manner is called a 'scaffold'. So, let's have Rails make this scaffold for us.

  • Make a new persistable object in Rails

    • Navigate to your app's root directory
    • Execute the following command to define and implement a new model named 'Post'

      $ rails generate scaffold Post title:string body:text
      

Note: You may have no problem, but I ran into an issue on Ubuntu. The result from running the command above is "Could not find a JavaScript runtime.", which I think is related to auto-compiling CoffeeScript. I really don't like installing Node.js just to allow Rails to auto-compile CoffeeScript, but this was my only way forward. A gem called therubyracer can be placed in the GemFile, which should fix this, but it didn't work for me. Maybe this issue is fixed in Rails 4. I'll check later. For now, let's manually add a JavaScript runtime, we must install Node.js. After installing this, run the command to generate the scaffold again.

  • Install Node.js

    $ sudo apt-get install nodejs
    

When the scaffold script is running, you can see it create some Ruby files, some Ruby HTML templates, and some CSS files. Let's feel lucky we didn't have to write that ourselves.


Customize Model's View Page

In customizing our app, we will spend majority of our time in a few places.

  • app/views/
  • app/controllers/
  • app/models/
  • config/

When a user navigates to our app using a web browser, they will be requesting files from our views directory. Each view will have dynamic data behind it, so a developer will be modifying the respective controller, which are in the controllers directory.

That's all we need to know about this for now.


Changing the Landing Page

The default landing page for out web app is a static page, specifically the public/index.html file.

One way we can customize the landing page is to define a dynamic route matcher. When a user enters a URL, something like mysite.com/posts/12345, the posts/12345 bit is called the route.

Your app may want to listen for these routes and respond when a pattern is matched. You can define such patterns in the config/routes.rb file. Let's add a route matcher for request for our app's root.

  • Add a route match for root

    • Open the config/routes.rb file
    • Add this line near the top

      root :to => "posts#index"
      
    • Save the file

Now, Rails will only use our routes mapping for a root request only if the public/index.html file doesn't exist. So, to activate our root mapping, we have to hide this file. Let's just change its name.

  • Hide the default root file

    • Rename the root file by executing this from the root directory

      $ mv public/index.html public/index.html.bak
      

When we start our app and navigate to the root page, we should see the index page for our posts.


Testing Our App Locally

Most of initializing and starting our app locally involves database preparation. We used Rails' scaffold command to add a Post object to our app. This command also added entries to our database management scripts, which is convenient. All we're left to do is run those scripts. Then, we can start our app server and test it with a web browser.

  • Create the database

    $ rake db:create
    
  • Run database migrations

    $ rake db:migrate
    
  • Start the app

    $ rails server
    

When you navigate to 0.0.0.0:3000 in your web browser, you should see a boring page that says "Listing posts" and has a "New Post" link.

Congrats! We have a working app!


Conclusion

After following the Rails walkthrough as organized by Chris Kemp, it seems like a pretty simple platform on which to create web apps. Do I dare say that it seems to be as simple as making Force.com apps?

Yes, figuring out what you need to start working on a Rails app and setting up your environment is a bit of work, but once prepared, customizing your app seems to be really straight-forward.

I'm curious how web apps manage user authentication and permissions, so I'll be looking into that next. It looks like Rails has good support for two authentication frameworks/libraries, called Devise and OmniAuth. I have no idea how these work, but the RailsApps group seems to have a good tutorial on creating a Rails app which uses Devise and Mongoid, so I'll be looking at this next.

Thanks for reading!

2012 Retrospective

Wednesday, January 2, 2013

Last Year's Accomplishments


One of my priorities in life is to keep improving and growing. So, to see my progress, motivate me, and give me self-confidence, I like to review my accomplishments from the last year, both big and small.

I'll list everything I'm proud of, in no order. Then I will choose a few significant ones to elaborate:

  • Spoke at a national software conference
  • Travelled to Vietnam and Taiwan
  • Fixed a falling garage door opener with my friend
  • Replaced the retaining wall for my home's egress window with my dad
  • Contributed to an open source software project
  • Significantly improved my JavaScript skills, which is still only the first few steps down that road
  • Learned more about my personality and moods
  • Set up a mini home server computer
  • Learned how to host a personal web server
  • Started learning how to use vim to edit text files for blog posts and what not
  • Dramatically improved my Chinese skills since really starting 12 months ago
  • Watched every episode of Star Trek to build my nerd-cred
  • Learned about early and middle history of Vietnam
  • Started learning about early history of China
  • Attained first rank (5-kyuu) in aikido after 6 months of training
  • Built better posture and self-confidence after lifting weights for 6 months
  • Improved straight-blade shaving skills by experimenting with variables of the art
  • Made home-made yogurt and bread. Failed attempt at brewing kombucha, but I learned from it
  • Bought many kinds of loose-leaf tea and became a fan of tea
  • Attended an anime convention with friends, which was an interesting experience
  • Was a member of the wedding party for a best college friend's wedding, which was an honor and humbling
  • Authored a programming article that was published on a major site

Spoke at National Conference


In the middle of summer last year I picked up an open source project that helps build HTML5 mobile apps on Salesforce to learn more about the practice. I believe I was the only one publicly making noise about the project by posting blog posts and tweets about it. The developer relations group in Salesforce announced a Call for Papers for Dreamforce 2012, which is the first year they included heavy support for both developers and the developer community at the huge conference. I thought I was qualified to talk about this open source project at Dreamforce, so I crafted an idea for a talk and an abstract to submit. A few weeks later, my talk was accepted. I was humbled for being chosen, excited for the opportunity, and scared of failure. I spent many hours in the next 2-3 months creating my talk, revising it, practicing it, and revising and practicing it more.

I finally found myself on the airplane to San Francisco. The night before my talk, I found myself in my hotel room practicing and still revising my talk. My talk was at noon on Wednesday, so I arrived at the conference hall an hour early to prepare my room. The conference employees told me that I must be in a room watching Salesforce's CEO give his keynote talk and ushered me into a room to watch it. His keynote talk was more than thirty minutes long, which meant that I was able to get into my room at 11:45am.

This proved to be not enough time since I found that my netbook was not compatible with the laptop presentation system in the room. I had to move my slide deck from my Linux laptop onto the Windows laptop which was provided with the room. I later found that several important images did not survive the file conversion to Windows' file format. I meant to create suspense before showing a slide with an image, but the audience laughed when I switched to blank slide and the suspense fell to the floor.

There was one other major issue with my presentation. My talk was about writing HTML5 applications, which are rendered in a browser. When I demonstrated how to use the software by opening the app in a browser, I was given a blank screen. Where was my app? I decided that the code must be wrong, and rather than debug the app, it would be best to continue. My second code demonstration fell to the same fate. What to do? Luckily, an audience member suggested I try a different browser. After spending a few empty minutes on stage loading my app into a new browser, I found it worked perfectly. Nice! This was hardly my fault, since I was forced to use a different laptop just minutes before starting my talk. An educational experience, to be sure.

In the end, it was a pretty great talk. At least five of the 150+ attendees stepped up after my talk to shake my hand and pay me compliments. One person later said that it was one of the most educational talks he attended at the four-day conference. How nice!

Visited Vietnam and Taiwan


From San Francisco, I skipped the last day of the conference and flew directly to Vietnam to attend a friend's wedding. I arrived on Saturday morning, and fought occasional punches of jet lag all day. The wedding was elaborate and I was humbled to be able to be there. I think is the most international wedding I will ever attend. The bride and grooms classmates from Japan, family from Vietnam and Scotland, and friends from even more countries were present to give their best wishes.

After the wedding, three of us travelled around Vietnam. One friend from Vietnam was an expert tour guide and served as a translator, a near-necessity when travelling to the smaller towns. With my other friend from Taiwan, the three of us saw remnants of the last war, climbed mountains, visiting a historic trading town, and saw dragons dancing for the autumn festival. And the food - the food was incredible. So many vegetables. Loved the variety.

After returning, I saw that my company had a two-day holiday for Thanksgiving, so I had to capitalize on the chance to take another extended vacation by spending a week in Taiwan to visit my friend there. Together, we again had the best vacation ever. We ate interesting food every day, climbed a mountain, saw the sun rise above the clouds, saw various sea creatures on a coral island, visited a town that was the site of the first trading settlement in the country. Awesome variety. We rode bullet trains, normal trains, subways, tour buses, city buses, taxis, and cars, not including the airplane home. My lust for adventure with friends was satisfied again. So awesome.

Build Some Muscle and Learned Some Aikido


I joined a gym and an aikido dojo in July last year, both at about the same time. After spending nearly two years building my software engineering knowledge, I felt a growing desire to build myself physically. I was a thin and kinda awkward guy, so I made a conscious decision to commit to building upper-body muscle and to learn a martial art. I visited a few different martial art dojos a year or two before, and I decided at that time that aikido was the best fit for me.

I'm proud to say that I was successful with both commitments. The first few months were very difficult, mostly because I started a strict diet while lifting heavy weights 4-5 times a week and also spending 4-5 days a week training aikido. I arrived home at 8pm every day completely physically exhausted. After stopping the strict food diet, I learned that the persistant lack of energy I experienced was caused by a lack of proper nutrition. I added fat and more calories into my diet, and my mood and energy quickly returned. It was an educational experience, to be sure.

Several times during this six months I was very close to quitting aikido. However, I chose to obey my commitment and I continued my training. The dojo follows a very traditional Japanese style. In our dojo, this means that there is a deep respect for older students and a deeper respect for dojo rules. This respect manifests in the form of ceremony and behavioral corrections by older students. I felt very restricted by the rules. I wanted to ask questions about how to perform a technique, but I was discouraged from doing so. Instead, I was told that aikido is something that your body learns by doing and explanations will not help. I also felt restricted from learning by experimenting. When I did experiment, I was told "You're doing it wrong. The technique is supposed to go like this". This was frustrating because everyone did the same technique differently and had different opinions, but I couldn't create my own flavor. It was a restrictive environment indeed.

After six months of training, however, I took my first test and attained the first for adults (5-kyuu). The test consisted of only 5 techiques, so I wasn't too worried about it. I practiced the same damned techniques so many times in the previous six months that I think I would go crazy if I was forced to practice them again. Despite my low expectations for satisfaction from the test, I surprised myself by how happy I was to pass. After the test, sensei said, "Alex", and I stood up. He said "Pass!" with the same serious and straight face he always had, and then gave his comments on my test. "That was some good stuff." This was the third time in six months that sensei ever directly addressed me. The last time he did so he asked me how old I was. His only response was a deep, dark laugh and then he moved on to train with another student.

I derived zero fun from my time at the aikido dojo. I actually disliked class. I didn't dislike the ceremony, but rather, it was the zero-explanation behavioral fixes from older students that I grew to dislike. I really didn't like operating in the dojo under the constant fear of breaking "the code". This refers to the proper code of conduct, which only a few older students knew. They grew to understand sensei's true wishes because they trained with him the longest and they have a special relationship with him. It's very much like a religion in which a priest claims he communicates with God. Because the priest is closest to God, you have no choice but to believe and obey what he says. This situation bothered me quite deeply, and I really questioned my long-term compatibility with the dojo.

Having said all this, studying aikido at the dojo was still a very educational experience. I learned a lot about commitment and about situations that don't agree with me. This will be a good point of reference for later in life, to be sure.

Focus for 2013


Having considered my progress in 2012, I would like to create areas of focus for my progress in 2013.

Last year, I made great progress in my career. I wanted to become an expert in my area, and I think I came close to attaining that. Am I satisfied with 2013 completely? No, not completely. One of my problems is that I push people away from me so that I can focus on satisfying my curiousity in software. However, I notice that one thing hasn't changed at all since last year: my friend count. While I have gained new friends in my career path, I haven't made new friends outside of work. Is this ok? I feel like I should diversify. Therefore, one of my areas of focus in 2013 is to spend less time learning about software and spending more time building friendships. This will be very challenging for me. I must recruit a friend to help me with this.

The second area of focus for me next year is to become even better at Chinese. I have made a lot of progress in the last year with my casual Chinese studies. I can recognize words when listening to songs, I can get a rough idea of a casual Chinese sentence on the Internet, I know many basic conversation words, and I have a pretty decent vocabulary about things I do. However, this opinion is all relative to my geographic location, which is Fargo, ND. If I want to get serious about learning Chinese, I would have to move to China. Anyways, I want to focus more on my Chinese studies next year.

This concludes my 2012 retrospective and 2013 goals. I'm all about encouragement in the right direction and setting attainable goals. I believe I've made my goals plenty general. Good luck to me and to you in 2013!