Thursday May 08, 2008

Which Programming Language J. Gosling Would Use Now, Except Java?

>>> Updated later
Maybe we can get completeness of J. Gosling's opinions about Java/Scaka/JVM from here
===

According to Adam Bien's blog from JavaOne

During a meeting in the Community Corner (java.net booth) with James Gosling, a participant asked an interesting question: "Which Programming Language would you use *now* on top of JVM, except Java?". The answer was surprisingly fast and very clear: - Scala.

I think Fortress will also be a very good future choice when it gets mature.

Wednesday Mar 07, 2007

Some Tips for Upgrading to Rails 1.2.x

Bellow are some issues that I met when upgraded from rails 1.1.6 to 1.2.x:

1.About enrivonment.rb
Make sure your application configuration behind:

Rails::Initializer.run do |config|
  ...
end

I met this issue when I put following code:

require 'environments/localization_environment'
require 'localization'
Localization::load_localized_strings
require 'environments/user_environment'

before that closure, which works under 1.1.6, but don't under 1.2.x

2.About ActionMailer::Base.server_settings
If you get errors like:

uninitialized constant ActiveSupport::Deprecation::RAILS_DEFAULT_LOGGER (NameError)

try to change your ActionMailer::Base.server_settings to ActionMailer::Base.smtp_settings

3.Put all "include" statements inside class definitions
You must put include statements inside class/module definitions instead of outside a class/module definition in Rails 1.2.x. Otherwise, you'll get:

Error calling Dispatcher.dispatch #<NameError: cannot remove Object::COPYRIGHT>

Wednesday Feb 07, 2007

Functinal Style Ruby

After playing with Ruby for weeks, I found Ruby is yet interesting. I try to write my code a bit in the likeness of Erlang, where symbol vs atom, array vs list. And the most important syntax that I like are:

  • everything return a value
  • may return multiple values
  • begin-end clause is lambda that may be directly applied
  • parallel assignment

Now, let's write some code before and after (functional):

Example1:

Before

   1. cond = {}  
   2. if par[:id]  
   3.   feed = Feed.find(par[:id])  
   4.   if feed  
   5.     cond[:feed] = feed.id  
   6.   end  
   7. end  
   8. if par[:m]
   9.   limit = par[:m].to_i  
  10. else  
  11.   limit = 20  
  12. end  
  13. if limit >= 4096  
  14.   limit = 4096  
  15. end  
  16. cond[:limit] = limit  
  17. if par[:d]  
  18.   days = par[:d].to_f  
  19.   if days <= 0 || days >= 365  
  20.     days = 365  
  21.   end  
  22.   cond[:time] = Time.now - days*86400  
  23. end  
After
   1. cond = {  
   2.   :feed   => if par[:id]  
   3.                feed = Feed.find(par[:id])  
   4.                feed ? feed.id : nil  
   5.              end,  
   6.   :limit  => begin  
   7.                 limit = par[:m] ? par[:m].to_i : 20  
   8.                 limit >= 4096 ? 4096 : limit  
   9.              end,  
  10.   :time   => if par[:d]  
  11.                days = par[:d].to_f  
  12.                days = days <= 0 || days >= 365 ? 365 : days  
  13.                Time.now - days * 86400  
  14.              end,  
  15. }.delete_if { |k, v| v.nil? } # delete all nil elements of cond  

Example2:

Before

   1.  if f[:mode] == "rss"  
   2.   rss = f[:feed]  
   3.   params[:feed][:channel] = rss.channel.title  
   4.   params[:feed][:description] = rss.channel.description  
   5.   params[:feed][:link] = rss.channel.link  
   6.   params[:feed][:copyright] = rss.channel.copyright  
   7. else  
   8.   atom = f[:feed]  
   9.   params[:feed][:channel] = atom.title  
  10.   params[:feed][:description] = atom.subtitle  
  11.   params[:feed][:link] = atom.links.join  
  12.   params[:feed][:copyright] = atom.rights  
  13. end  
After
   1. params[:feed][:channel],    
   2. params[:feed][:description],    
   3. params[:feed][:link],    
   4. params[:feed][:copyright] = if f[:mode] == "rss"    
   5.                               rss = f[:feed]   
   6.   
   7.                               [rss.channel.title,    
   8.                                rss.channel.description,    
   9.                                rss.channel.link,    
  10.                                rss.channel.copyright]  
  11.                             else    
  12.                               atom = f[:feed]  
  13.     
  14.                               [atom.title,    
  15.                                atom.subtitle,    
  16.                                atom.links.join,    
  17.                                atom.rights]    
  18.                             end    

Example3

   1. # grp_str: p -> public(0) , u -> user(1), f -> friends(2)   
   2. def privilege_cond(user, grp_str)  
   3.   grp_str ||= 'puf'  
   4.   cond = {:pre => "", :sub => []}  
   5.   cond = if loggedin?(user)  
   6.            frds = grp_str.include?('f') ? user.friends.find(:all) : []  
   7.            frd_ids = frds.collect { |frd| frd.friend_id.to_i }  
   8.              
   9.            cond = if grp_str.include?('u')  
  10.                     {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") +   
  11.                              " user_id  = ? ",  
  12.                      :sub => cond[:sub] + [user.id]}  
  13.                   else  
  14.                     cond  
  15.                   end  
  16.       
  17.            cond = if grp_str.include?('f') && !frd_ids.empty?  
  18.                     {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") +   
  19.                              " user_id in (?) AND privilege in (?) ",  
  20.                      :sub => cond[:sub] + [frd_ids, [0, 2]]}  
  21.                   else  
  22.                     cond  
  23.                   end  
  24.       
  25.            cond = if grp_str.include?('p')  
  26.                     {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") +   
  27.                              " user_id != ? AND privilege  = ? ",  
  28.                      :sub => cond[:sub] + [user.id, 0]}  
  29.                   else  
  30.                      cond  
  31.                   end  
  32.          else  
  33.            {:pre => "privilege = ?",  
  34.             :sub => [0]}  
  35.          end  
  36. end  

Monday Jan 29, 2007

Java + Ruby + Erlang = JRE (Just Running Environment)

I'm recently doing a project under Ruby on Rail. It seems to be a reasonable programmer today, one should take at least > 3 languages.

Personally,

I like Erlang: lightweight process + message passing + functional programming + dynamic. It exactly matches my philosophy of looking the real world, and I think it's what functional programming should be.

Are there really Objects exist? I'm not sure. Instead, talking about OO, Object Oriented may be more sense. That is, an Object makes sense only when you orient it. All states look like being "in" an object, are with meaning only when you measure them. But, doesn't "measure" mean applying a "Function" on it? So, the states should always be carried only by functions rather than 'object', and the states are time streaming, they will be transfered from one function to another function, another function ..., so you catch the meaning of them when you track the functions chain, the meaning is based on the functions rather than the name of a Class as a member of. When you want to take a snapshot on them, you save them some where, such as showing on screen, stored in database, printed on paper what ever.

I like Java: tons of APIs + open source code base + Swing + NetBeans. So far, it has the best cross-platform UI tool kit to my eye. I like Swing, I can change or extend it easily to whatever I want. But things go easy because so many people have taken extremely efforts on it. It's bound too Objected, people split world to objects, then try to composite them or inherit something called super to make them together again. I feel pain when doing this, I have to split them, composite them in a way, then things change (or, the real world is still there), I split them, composite them in another way, again and again, it's called re-factor, but people may never catch the real Factor of the real world.

I, have to learn Ruby. Ruby and Rails are very good. For developers term, you should always know things are not so philosophy as yours, you will have guys thinking in different ways, of the real world. So Ruby is there, everyone can think the real world according to his understanding, yeah, in different ways, and, to make them not going too far away, you need rails.

So, I have to learn Java, as a tool make me doing many things interesting and painful; I have to learn Ruby, as a tool make my guys doing many things interesting and on rails; And I'll keep Erlang (Lisp/Scheme) as a tool make me not only doing but also thinking with interesting.

Friday Dec 08, 2006

No Static Method in Interface, So I Write Code As ...

Java does not support static method in interface. But sometimes, I just want a static method to say: PersistenceManager.getDefault(), where PersistenceManager is going to be an interface. I don't like to add one more class named PersistenceManagerFactory, with a method:

public static PersistenceManager PersistenceManagerFactory.getDefault()

So I write code like:

public class PersistenceManager {
    private static I i;

    public static I getDefault() {
        return i == null ? i = ServiceLoader.load(I.class).iterator().next() : i;
    }
    
    /** The interface I, which is actually the PersistenceManager should be: */
    public static interface I {
        
        void saveQuotes(String symbol, Frequency freq, List quotes);
        List restoreQuotes(String symbol, Frequency freq);
        void deleteQuotes(String symbol, Frequency freq, long fromTime);
        void dropAllQuoteTables(String symbol);
        
        void shutdown();
        
        QuotePool getQuotePool();
        TickerPool getTickerPool();
    }
    
}

Then implement the PersistenceManager.I in another package, like:

public class NetBeansPersistenceManager implements PersistenceManager.I {
   ...
}

And declare it under the META-INF as:

core/src/META-INF/services/org.aiotrade.math.PersistenceManager$I

which contains one line:

org.aiotrade.platform.core.netbeans.NetBeansPersistenceManager

I can call PersistenceManager.getDefault().showdown() now.

Sunday Sep 24, 2006

A Regress Bug in java.awt.geom.Path2D (JDK 6.0 beta 2)

I tested AIOTrade on newly downloaded JDK 6.0 beta 2, and got an exception instantly:

java.lang.ArrayIndexOutOfBoundsException: 0
    at java.awt.geom.Path2D$Float.moveTo(Path2D.java:322)
    at java.awt.geom.Path2D$Float.append(Path2D.java:643)
    at java.awt.geom.Path2D.append(Path2D.java:1780)

The code run good in JDK 5.0, so will it be a regress bug in JDK 6.0?

I then checked the source code: 6.0 vs 5.0, and found there were likely a bit of code omited wrongly. That is, in method body of void needRoom(boolean needMove, int newCoords), should add

                if (grow < 1) {
                    grow = 1;
                }
at the next of:
            int size = pointTypes.length;
            if (numTypes >= size) {
                int grow = size;
                if (grow > EXPAND_MAX) {
                    grow = EXPAND_MAX;
                }

The following is the proper code I've tested OK:

        void needRoom(boolean needMove, int newCoords) {
            if (needMove && numTypes == 0) {
                throw new IllegalPathStateException("missing initial moveto "+
                        "in path definition");
            }
            int size = pointTypes.length;
            if (numTypes >= size) {
                int grow = size;
                if (grow > EXPAND_MAX) {
                    grow = EXPAND_MAX;
                }
                /** fix bug:
                 * java.lang.ArrayIndexOutOfBoundsException: 0
                 *     at java.awt.geom.Path2D$Float.moveTo(Path2D.java:322)
                 *     at java.awt.geom.Path2D$Float.append(Path2D.java:643)
                 *     at java.awt.geom.Path2D.append(Path2D.java:1780)
                 */
                if (grow < 1) {
                    grow = 1;
                }
                pointTypes = Arrays.copyOf(pointTypes, size+grow);
            }
            size = floatCoords.length;
            if (numCoords + newCoords > size) {
                int grow = size;
                if (grow > EXPAND_MAX * 2) {
                    grow = EXPAND_MAX * 2;
                }
                if (grow < newCoords) {
                    grow = newCoords;
                }
                floatCoords = Arrays.copyOf(floatCoords, size+grow);
            }
        }

As I can not wait for it be fixed in JDK, so I wrote another org.aiotrade.util.awt.geom.Path2D and org.aiotrade.util.awt.geom.GeneralPath, and replaced the java.awt.geom.GeneralPath in my source tree. you can get the code at:

GeneralPath.java
Path2D.java

Tuesday May 23, 2006

Install XWiki on Glassfish and Derby

I've upgraded blogtrade.org to glassfish b48, with XWiki and javadb (Apache Derby) integrated. Here is a short guide I posted:

http://blogtrader.org/wiki/bin/view/KnowledgeBase/XWikiGlassfishDerby

Thursday Mar 30, 2006

Based on Glassfish b42

The blogtrader.org and blogtrader.net are now based on the newest Glassfish Application Server b42. As Glassfish is also the default bundled J2EE server of NetBeans IDE, with a database: javadb, it's an ideal environment for the developing of BlogTrader Project. I hope to provide stock symbols updating service via a web site to BlogTrader Platform, thus I can add the information of each market, such as local time, open, close hours ect. and you'll need not to input symbol for each stock.

And, the modules updating centre could also be set.