Blogged by Ujihisa. Standard methods of programming and thoughts including Clojure, Vim, LLVM, Haskell, Ruby and Mathematics written by a Japanese programmer. github/ujihisa

Friday, July 31, 2009

Abnormal Weather in Vancouver

http://www.theglobeandmail.com/news/national/record-setting-heat-wave-cooks-the-coast/article1237198/

In Vancouver, where the definition of a hot summer day is 24 degrees, the temperature topped out Wednesday afternoon at 33.8 degrees, which was the hottest day in the city's history, at least until yesterday.

I certainly said the following on the last day of RubyKaigi2009 in Japan. "It is too hot in Japan, so I will escape from here tomorrow" Unfortunately I seem to fail to escape.

In many ways, the scorching days and nights are harder on Vancouverites, where heat waves are as rare as mosquitoes. Few have air conditioning, so people have been flocking to malls and movie theatres. Apartment buildings - especially high rises - have become ovens. Health officials have urged people to check on elderly neighbours and relatives.

Yes, few have air conditioning, and I'm one of them. My room is exactly an oven.

Haskell Platform Instead of MacPorts

Someone hospitably suggested me in this comment to use Haskell Platform instead of MacPorts to install ghc or other haskell libraries.

As most Mac users know, it takes 12+ hours to build ghc. Once you typed sudo port install ghc, you would have to go to bed and sleep for half a day.

The Haskell Platform is a binary package, so now we don't have to

Installing pandoc via Haskell Platform cabal

cabal update
cabal install pandoc

then

Resolving dependencies...
[1 of 1] Compiling Main             ( /var/folders/Dz/Dz5WpFSZGUaFLA8jp8kT5E+++TM/-Tmp-/pandoc-1.2.12656/pandoc-1.2.1/Setup.hs, /var/folders/Dz/Dz5WpFSZGUaFLA8jp8kT5E+++TM/-Tmp-/pandoc-1.2.12656/pandoc-1.2.1/dist/setup/Main.o )
Linking /var/folders/Dz/Dz5WpFSZGUaFLA8jp8kT5E+++TM/-Tmp-/pandoc-1.2.12656/pandoc-1.2.1/dist/setup/setup ...
Configuring pandoc-1.2.1...
Preprocessing library pandoc-1.2.1...
Preprocessing executables for pandoc-1.2.1...
Building pandoc-1.2.1...

src/Text/Pandoc/Shared.hs:118:7:
    Could not find module `Network.URI':
      There are files missing in the `network-2.2.1.4' package,
      try running 'ghc-pkg check'.
      Use -v to see a list of the files searched for.
cabal: Error: some packages failed to install:
pandoc-1.2.1 failed during the building phase. The exception was:
exit: ExitFailure 1
~/.cabal
$ pandoc install network
pandoc: install: openBinaryFile: does not exist (No such file or directory)
$ ghc-pkg check |& grep network-
There are problems in package network-2.2.1.4:
  import-dirs: /Users/ujihisa/.cabal/lib/network-2.2.1.4/ghc-6.10.3 doesn't exist or isn't a directory
  library-dirs: /Users/ujihisa/.cabal/lib/network-2.2.1.4/ghc-6.10.3 doesn't exist or isn't a directory
  include-dirs: /Users/ujihisa/.cabal/lib/network-2.2.1.4/ghc-6.10.3/include doesn't exist or isn't a directory
  cannot find libHSnetwork-2.2.1.4.a on library path
network-2.2.1.4
network-2.2.1
network-2.2.1.1

hmm...

Wednesday, July 29, 2009

Incremental Operator in Ruby

Today I succeeded to add a new syntax "Pre Incremental Operator" like C's ++i into Ruby. The following code can run as you expect.

irb192

There are two possible ways what does ++i mean.

  1. Call succ and assign the result

    i = i.succ
    
  2. Call + with 1 and assign the result

    i = i.+(1)
    

I chose the former this time.

Patch

http://gist.github.com/158449

diff --git a/parse.y b/parse.y
index 10ac878..e02a1b1 100644
--- a/parse.y
+++ b/parse.y
@@ -685,6 +685,7 @@ static void token_info_pop(struct parser_params*, const char *token);
 %type <val> program reswords then do dot_or_colon
 %*/
 %token tUPLUS      /* unary+ */
+%token tINCR       /* ++var */
 %token tUMINUS     /* unary- */
 %token tPOW        /* ** */
 %token tCMP        /* <=> */
@@ -1783,6 +1784,7 @@ op        : '|'       { ifndef_ripper($$ = '|'); }
 '!'       { ifndef_ripper($$ = '!'); }
 '~'       { ifndef_ripper($$ = '~'); }
 tUPLUS    { ifndef_ripper($$ = tUPLUS); }
+       | tINCR     { ifndef_ripper($$ = tINCR); }
 tUMINUS   { ifndef_ripper($$ = tUMINUS); }
 tAREF     { ifndef_ripper($$ = tAREF); }
 tASET     { ifndef_ripper($$ = tASET); }
@@ -4130,6 +4132,15 @@ var_ref      : variable
      $$ = dispatch1(var_ref, $1);
        %*/
        }
+       | tINCR variable
+           {
+           /*%%%*/
+           $$ = assignable($2, 0);
+           $$->nd_value = NEW_CALL(gettable($$->nd_vid), rb_intern("succ"), 0);
+           /*%
+           $$ = dispatch2(unary, ripper_intern("++@"), $2);
+           %*/
+           }
    ;

 var_lhs        : variable
@@ -6773,6 +6784,9 @@ parser_yylex(struct parser_params *parser)

       case '+':
  c = nextc();
+   if (c == '+') {
+       return tINCR;
+   }
  if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
      lex_state = EXPR_ARG;
      if (c == '@') {
@@ -8277,6 +8291,7 @@ void_expr_gen(struct parser_params *parser, NODE *node)
    case '%':
    case tPOW:
    case tUPLUS:
+     case tINCR:
    case tUMINUS:
    case '|':
    case '^':
@@ -9111,6 +9126,7 @@ static const struct {
     {'-',  "-(binary)"},
     {tPOW, "**"},
     {tUPLUS,   "+@"},
+    {tINCR,    "++@"},
     {tUMINUS,  "-@"},
     {tCMP, "<=>"},
     {tGEQ, ">="},

Post Incremental Operator

I tried to add post incremental operator like C's i++, but I found that I couldn't.

There are two possible ways what does i++ mean.

  1. Store the original value, assign the result of succ, and return the original value

    tmp = i; i = i.succ; tmp
    
  2. Assign the result of + with 1, and return the result of - with 1

    (i = i.+(1)) - 1
    

The latter is easier to implement, because there's no storing a value.

Sunday, July 26, 2009

Parsers around Ruby

I'll show some parsers for ruby or parsers on ruby include parse_tree, ruby_parser, treetop and ripper.

Within this entry, there are only two definitions of ruby's syntax. The one is parser.y which is in MRI, and ruby_parser.y which is only in the ruby_parser library.

parse_tree

A parser which converts code in Ruby to S-expression. It is written in Ruby with C extension.

parse_tree uses ruby standard library racc. ([Added on July 28]: It was wrong: parse_tree doesn't use racc.)

require 'rubygems'
require 'parse_tree'

a = ParseTree.translate '1+1'
p a.class #=> Array
p a #=> [:call, [:lit, 1], :+, [:array, [:lit, 1]]]

or simply

$ echo "1+1" | parse_tree_show -f
s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1)))

While parse_tree is a gem library for some ruby implementations, it is a standard library in Rubinius.

parse_tree uses C function rb_compile_string which is defined in MRI's parse.c.

Note that parse_tree cannot accept a string represented code instead of a method or a class. ([Added on July 28]: It was wrong: parse_tree can accept both.)

ruby_parser

Exactly same as parse_tree except that it is written in pure Ruby.

require 'rubygems'
require 'ruby_parser'

a = RubyParser.new.parse '1+1'
p a.class #=> Sexp
p a #=> s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1)))

or

$ ruby_parse a.rb # Unfortunately ruby_parse command handles only actual files.

ruby_parser has own yacc file ruby_parser.y which has 1789 lines. It will be processed by racc.

Rubinius uses ruby_parser as its ruby parser.

Note that ruby_parser cannot accept a method or a class instead of a string represented code.

treetop

Treetop is a packrat parser written in pure Ruby. Treetop has an original syntax.

c.f.

Ripper

The ruby parser written in C. It is a ruby 1.9 standard library. It uses parse.y as ruby itself does.

const RUBY_ENGINE

p RUBY_ENGINE

ruby 1.8: (The constant RUBY_ENGINE is not defined)

ruby 1.9: "ruby"

jruby: "jruby"

rubinius: "rbx"

Saturday, July 18, 2009

My RubyKaigi2009 Talk

Today, the second day of RubyKaigi2009 in Japan, I had a 30 minutes talk.

Slide

(My talk slide will be uploaded here)

I used Vim-like presentation tool powered by Opera, Ruby and Vim.

Video

Description

Originally I had tried to talk about software development environments for ruby in a general way. But unfortunately my slide became something bored. I thought my talk would be bad. Last night, I finally decided to change the topic of my talk.

My old title was "Working Effectively with Ruby for Average Programmers", and the new title was "Vim for Rubyists". I talked about Vim there.

Note

  • In my demonstration, I missed the implementation of FizzBuzz problem on purpose. I wanted someone to mention it at the time, but unfortunately nobody did.
  • (add more...)

Friday, July 17, 2009

Now I'm talking at RubyKaigi2009

I'm very nervous now.

My talk is about

  • quickrun.vim
  • blogger.vim

yay

Wednesday, July 15, 2009

RubyKaigi2009 is Comming

I'll attend a three-days conference RubyKaigi2009 starting tomorrow.

As a speaker

image

I have a talk on July 18 Saturday. I'll talk about development environments.

http://rubykaigi.org/2009/en/talks/18S02

Working Effectively with Ruby for Average Programmers

For software development with the Ruby programming language, this presentation will introduce the study of general productive programming methodology which is primary for ordinary programmers who usually write code simply based on empirical or academical knowledge. This presentation focuses on an environment supports a development particularly. This also shows the advantages powered by Vim by a live coding. Keywords: IDE, Opportunistic Programming, Functional Languages, Grass, Live Coding

If you are an ordinary programmer, and want to improve your coding speed, and if possible you are a vim user, I recommend you to come to my talk! Unfortunately my talk is in Japanese. My slides are both in Japanese and in English.

As a participant

If you find me, feel free to talk me! I can understand slow English and can speak in awkward English. I'll have a speaker nameplate with the name "ujihisa" at the conference room.

Sunday, July 12, 2009

LiveCoding#6 was Successfully Hosted by Me

I'm proud of the exciting event which was held on yesterday.

LiveCoding#6 http://ujihisa.github.com/livecoding6 (in Japanese and English)

There were 9 LiveCoders and about 40 audiences in a traditional Japanese style urbane house.

0

02

Some LiveCoders could complete their products in each 20 minutes while others couldn't.

1

It is hard and oppressive for LiveCoders to code within a time limit, meanwhile it is amusing and interesting for audiences to watch the coders.

2

The contents of this LiveCoding is:

  • Pretty More Useful Twitter with hitode909
  • JavaScript on Scala on GAE with cho45
    • A GAE app in Scala with JS(rhino)
    • Powered by Scala, Java (is abbr of JavaScript), Vim, Rake and MacBook
  • Something with Ruby/SDL with 大林(ohai)
    • Something like a shooting game
    • Powered by Ruby, Emacs, Ion, Debian/GNU Linux, and ThinkPad
  • Something with Vimperator with hotchpotch
    • An unuseful vimperator plugin
    • Powered by Firefox 3.5, Vim, Rascut, Windows7(7100) + Debian/GNU Linux and ThinkPad X61Tablet
  • Something with Android with naoya_t
    • Produce something as an Android app (and then will continue developing it at the Android Hackathon)
    • Powered by Emacs, Eclipse, Android SDK/NDK, Java, gcc, Mac OS X, MacBook Pro and HKK Lite Shiro
  • Google App Engine on Sinatra with ujihisa
    • The ultimate web application platform Sinatra/Google App Engine for Java/JRuby
    • Powered by Vim, Ruby, Mac OS X and MacBook Air
  • Wanted: The Answer of my Assignment with Kimoto
    • There are few hours to submit my report. Does it make on time while I've never got going. Get a unit or repeat the course.
    • Powered by Vim, C, Windows XP Pro and Let's note
  • Wiki on PHP with imos
    • An irresponsible notation wiki
    • Powered by mi, php, Mac OS X and MacBook Pro

3

Actually my turn, "Google App Engine on Sinatra", was just a cheat. I didn't do anything difficult like what other LiveCoders did.

I made and deployed an app here. The app cho466666 can calculate addition and fibonacci sequence like

The core source code is below.

require 'rubygems'
require 'sinatra'

get '/' do
  RUBY_VERSION
end


get '/add/:x/:y' do
  x, y = params[:x].to_i, params[:y].to_i
  "#{x} + #{y} = #{x + y}"
end

get '/fib/:n' do
  n = params[:n].to_i
  "fib#{n} = #{fib(n)}"
end

def fib(n, x = n < 2 ? n : fib(n-2) + fib(n-1))
  x
end

4

After the LiveCoding, we did a Android Hackathon and a Vim Hackathon until the next morning.

drink

hackathon

Other LiveCoding#6 photos are here. Thanks hitode909!

Sunday, July 5, 2009

ANN: LiveCoding#6 Will be Held on the Next Saturday

http://ujihisa.github.com/livecoding6/

LiveCoding is a new boom that programmers show their programming techniques live with communication and develop a new software. It is amusing that we watch a super technique of a great hacker rowdy.

The site is updated very often. I recommend people who are going to attend the event to subscribe the RSS.

It was very exciting.

It Is Difficult For Me oo Know How to Generate RSS Feed Which Items Have a Description Which Has CDATA by Ruby's Standard Library RSS/Maker

so I've decided to stop using rss/maker.

Thursday, July 2, 2009

How to Make an Android Application on Mac OS X

INSTALLATION

I had Vim and NetBeans as IDEs, but I didn't have Eclipse. Unfortunately Android SDK needs Eclipse IDE.

http://www.eclipse.org/downloads/

There are a lot of variations of Eclipse. Download "Eclipse IDE for Java Developers (91 MB)".

A Java or RCP version of Eclipse is recommended.

-- http://developer.android.com/sdk/1.5_r2/installing.html

The RCP version of Eclipse is also OK, but its size is twice as the Java one.

After the installation of Eclipse IDE, install the Android SDK.

Download from here: http://developer.android.com/

And install them somewhere on your machine. For example, now I'll install it on ~/android-sdk-mac_x86-1.5_r2.

Write it on your ~/.zshrc:

export PATH=$PATH:~/android-sdk-mac_x86-1.5_r2/tools/

And then install the ADT: Android Development Tools plugin for Eclipse.

Help > Install New Software...

(I don't know why the plugin adding dialog is located in "Help" menu. I wonder what did the Eclipse developper thing about it.)

And input it: https://dl-ssl.google.com/android/eclipse/

1

Now you have Android plugin. Before you would create a new Android app, you have to set a setting on your Eclipse Preferences.

2

Input the SDK Location and Apply it.

Hello, World with Eclipse

$ android create avd --target 2 --name my_avd # Initial setting

And then make a new Project with your Eclipse.

3

4

5

And run it.

6

OK. Now let's try to show "Hello, world" on the Android emulator window.

The initial src/com.example.hw/hw.java is:

package com.example.hw;

import android.app.Activity;
import android.os.Bundle;

public class hw extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Fix it like below:

package com.example.hw;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class hw extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        tv.setText("Hello, Android");
        setContentView(tv);
    }
}

And then run the Android Application by Eclipse.

a

It took very long time to show the result. After you clicked the run botton, you should drink a cup of coffee.

Hello, World without Eclipse

It is very difficult for us to use Eclipse every time. Now I'll show how to build and run an Android application without using Eclipse.

$ mkdir hw-vim && cd hw-vim
$ android create project --package com.example.hwvim --activity HW --target 2 --path .
(...fix src/(snip)/HW.java like the previous code...)
$ ant debug
$ emulator -avd my_avd
$ adb -s emulator-5554 install bin/HW-debug.apk

It did:

  1. Create a new Android Application Project
  2. Build
  3. Boot the Android emulator
  4. Install the application into the emulator

You may see the following error:

error: device not found

Unfortunately this error is undocumented here. The solution how to avoid it is to restart adb server.

$ ps aux | grep adb
$ kill -HUP {the process id}

Now you must be able to see the new app:

HW there

I don't know why, but I cannot boot the application. An error occurred.

error

;-(

Followers