Ruby arrays and matrices

February 22, 2006

One of the first things you learn when reading a book on Ruby is that “variables” hold references to objects. Consider


a = Foo.new
b = a

Both a and b contain the same instance of the object. Fine. Simple. Java does the same and so does Python. You just know what that means and you know that if you want a copy instead (that is to say b and a should change indipendently) you must dup or clone them.


a = Foo.new
b = a.dup

Now it comes to arrays. Ruby arrays are much like Python list. They are powerful objects. And have something Python lists do not have, some more constructor. From the ruby doc:

Array::new
Array.new(size=0, obj=nil)
Array.new(array)
Array.new(size) {|index| block }

Returns a new array. In the first form, the new array is empty. In the second it is created with size copies of obj (that is, size references to the same obj). The third form creates a copy of the array passed as a parameter (the array is generated by calling to_ary on the parameter). In the last form, an array of the given size is created. Each element in this array is calculated by passing the element’s index to the given block and storing the return value.

We analyze the very first constructor. It makes perfectly sense: consider this:

  l = Array.new(5, "") # ["", "", "", "", ""]
  l[1] ="foo"
  l # ["", "foo", "", "", ""]

Now consider this:

    l = Array.new(5, []) # [[], [], [], [], []]
    els = %w{ el1 el2 el3 el4 el5 }
    l.each_index { | index | l[index].push els[index] }
    #  [
    #    ["el1", "el2", "el3", "el4", "el5"], 
    #    ["el1", "el2", "el3", "el4", "el5"], 
    #    ["el1", "el2", "el3", "el4", "el5"], 
    #    ["el1", "el2", "el3", "el4", "el5"], 
    #    ["el1", "el2", "el3", "el4", "el5"]
    #  ]

This is the correct result. But this probably is not what we wanted to obtain. The “correct way to initialize l” would have been

    l = Array.new(5) { | dummy | Array.new } # [[], [], [], [], []]
    els = %w{ el1 el2 el3 el4 el5 }
    l.each_index {| index | l[index].push els[index] }
    # [["el1"], ["el2"], ["el3"], ["el4"], ["el5"]]

This time for each line we are creating a “new” empty list, not the very same one.

In this case you probably should have been using the Matrix class, anyway.

Advertisements

get_sublist in prolog

February 20, 2006

The hardest thing when programming prolog, is to change your mind. In fact declarative programming (while powerful) is hard to get in touch. I always tend to think imperatively, even if I attended formal logic lessons in the University.

Now just a couple of easy things… I’m a beginner.

get_sublist(Start, Len, List, Sub) :- append(L1, L2, List),
length(L1, Start), append(Sub, _, L2), length(Sub, Len).

This way you get a sublist. The style is declarative. The efficience is …. well we ll’see later.
An “imperative” version is

get_sublist(_, 0, _, []).
get_sublist(Start, Len, List, [H | Acc]) :- nth0(Start, List, H),
succ(Start, NStart), succ(NLen, Len),
get_sublist(NStart, NLen, List, Acc).

It’s not as clean, but should be more efficient. It uses an accumulator variable. In fact this algorithm is not really declarative. We could say that it does the same thing than

def get_sublist(start, len, list, acc)
if len > 0
acc.push list[start]
nstart = start + 1
nlen = len - 1
get_sublist(nstart, nlen, list, acc)
end
end

Incidentally this is ruby code, you can test it with

l = []
get_sublist(2, 3, %w{ a b c d e f g}, l)
l.each { |e| puts e}

And now… lets see if we optimized or not. This is comes from SWIProlog.

5 ?- time(get_sublist(2, 3, [a, b, c, d, e, f], Acc)).
% 22 inferences, 0.00 CPU in 0.00 seconds (0% CPU, Infinite Lips)

Acc = [c, d, e]

Yes
6 ?- time(get_sublist_old(2, 3, [a, b, c, d, e, f], Acc)).
% 37 inferences, 0.00 CPU in 0.00 seconds (0% CPU, Infinite Lips)

Acc = [c, d, e]

Let’s try with bigger numbers…

24 ?- make_list(100000, L), time(get_sublist(2000, 500, L, Acc)).
% 378,001 inferences, 0.33 CPU in 0.42 seconds (78% CPU, 1145458 Lips)

L = [100000, 99999, 99998, 99997, 99996, 99995, 99994, 99993, 99992|...]
Acc = [98000, 97999, 97998, 97997, 97996, 97995, 97994, 97993, 97992|...]

Yes
25 ?- make_list(100000, L), time(get_sublist_old(2000, 500, L, Acc)).
% 15,007 inferences, 0.08 CPU in 0.09 seconds (87% CPU, 187587 Lips)

L = [100000, 99999, 99998, 99997, 99996, 99995, 99994, 99993, 99992|...]
Acc = [98000, 97999, 97998, 97997, 97996, 97995, 97994, 97993, 97992|...]

Yes
26 ?- make_list(100000, L), time(get_sublist_old(2000, 5000, L, Acc)).
% 42,007 inferences, 0.56 CPU in 0.66 seconds (85% CPU, 75013 Lips)

L = [100000, 99999, 99998, 99997, 99996, 99995, 99994, 99993, 99992|...]
Acc = [98000, 97999, 97998, 97997, 97996, 97995, 97994, 97993, 97992|...]

Yes
27 ?- make_list(100000, L), time(get_sublist(2000, 5000, L, Acc)).
% 7,530,001 inferences, 6.88 CPU in 8.82 seconds (78% CPU, 1094477 Lips)

L = [100000, 99999, 99998, 99997, 99996, 99995, 99994, 99993, 99992|...]
Acc = [98000, 97999, 97998, 97997, 97996, 97995, 97994, 97993, 97992|...]

Yes

It looks like we didn’t optimize very much. 😦
I should study more.


Ruby vs. Python? [no, Ruby vs. Ruby ]

February 20, 2006

In fact this is not a Ruby vs. Python list. I know not enought Ruby and I love Python to much :). It’s more a picture of the first impressions I had on Ruby after I seriously began studying it.

This is a quick list of thoughts. I’m probably adding more stuff later. In fact I’m reaaly amazed. Ruby is really hackish, but it’s also neat and clean. It may sound strange… but I’m afraid I’m gonna love ruby more than Python: it addresses many of the things I come to dislike in Python.

Some stuff I like

  • Adding dynamically stuff to classes. The syntax is clean and obvious
    class MyClass
      def aMethod
        puts "Called aMethod"
      end
    end
    
    m = MyClass.new
    
    begin
      m.aMethod2
    rescue NoMethodError => ex
      puts "Failed to call #{ex}"
    end
    
    class MyClass
      def aMethod2
          puts "Called aMethod2"
      end
    end
    
    m.aMethod2

    In Python for example it is not that clean. The ruby code looks more like ObjectiveC categories (even if in fact you don’t specify a category, of course, since ruby does not need categories).

  • private, protected, public modifiers. Being dynamic they do not limit me in any way (if I need I can dynamically change this)
    class MyClass
      protected
      def aMethod
        puts "Called aMethod"
      end
    end
    
    m = MyClass.new
    
    begin
      m.aMethod
    rescue NoMethodError => ex
      puts "Failed to call #{ex}"
    end
    
    class MyClass
      public :aMethod
    end
    
    m.aMethod

    Moreover I can’t think to a cleaner syntax to do this. Of course one can argue that they aren’t really necessary. Of course, but if you want they do give you a little bit of control, but they don’t limit you in any way.

  • Object#freeze: if you suspect that some unknown portion of code is setting a variable to a bogus value, try freezing the variable. The culprit will then be caught during the attempt to modify the variable.
  • I love postfixed control clauses. In fact if used with moderation they can augment code readbility (and of course if abused they make it less readable). However, it is pretty logigal to say do_something if something_else. In fact since ruby has blocks it is ok also to write
    begin
        # some stuff
    end if condition
    

    maybe not everyone agrees

  • Accessors are great. Using attr and similar constructs is great. I also find quite more readable to “assign” with foo= than using more Javesque setFoo(val). In fact properties in Python work in a similar fashion, even if maybe a bit more verbose (however, I think they make it clearer how to document code, but this is a ruby aspect I’ve not yet exploited)
  • Gems: I think python needs something like that. Pimp is not that good, in my opinion, of course.

Stuff I don’t know if I like or not

  • Not having to write parentheses with no-argument methods. I’ve not yet discovered if I like it or not.
  • All the $_… They are used a lot in Perl. I like it, but I’m afraid it can mess things up.

Stuff I dislike

  • I don’t like passing strings to require. In fact it can have advantages, but I prefer the pythonic import foo to require "foo".
  • The try catch semantic of try/catch, makes me think to some kind of disguised goto. I’m sure I’m wrong… but
  • I’d like to have something like Perl use strict;. It’s something I miss in Python (even if with pychecker you can just live without it). Now I’ve got to find some kind of “use strict” or “rubycheck”.
  • Assignment is an expression. This directly leads to code like
    a = true
    b = false
    print b if b=a
    

    and we imagine the programmer wanted to write

    a = true
    b = false
    print b if b==a
    

    However in Ruby almost everything is an expression, and it has quite a lot of advantages. So we have to tolerate the “=” for “==” problem.


Ruby 0.0

February 17, 2006

Today I decided to take some time and have a look at Ruby. I found online a version of Programming Ruby and started reading it. In fact I knew I was going to like Ruby. In fact the first time I took contact with it I quite liked it, even if I didn’t fully exploit its capabilities.

Well… let’s see how it goes. Right at the moment the first thing I wrote is

class Employee
  attr_reader :wage, :name
  attr_writer :wage
  
  def initialize(name, surname, wage)
    @name = name
    @surname = surname
    @wage = wage
  end
  
  def surname
    @surname
  end
  
  def to_s  
    "#{name} #{surname} (#{wage})"
  end
  protected :wage=
  
end

class Manager > Employee
  def initialize(name, surname, wage, employees=[])
    super(name, surname, wage)
    @employees = employees
  end
  
  def setWage(emp, wage)
    emp.wage = wage
    emp
  end
   
  def to_s
    super + @employees.collect{|e| "\n  #{e}"}.join("")
  end
end

mr = Employee.new("Jack", "Bravo", "1000€")
mc = Employee.new("Michael", "Charlie", "300€")
mngr = Manager.new("Angus", "Smith", "10000€", [mr, mc])
mngr.setWage(mc, "700€")
puts mngr

About learning Cocoa

February 12, 2006

I first learnt about ObjectiveC and Open/GNUStep when I was basically a Linux user. That was quite a lot of time ago. I was a WindowMaker fan, and that was the way I learnt about GNUStep. However, I did not learn ObjectiveC nor GNUStep programming. In fact there was plenty of “wonderful” languages out there and I felt no need for another one. The few GUI applications I did were made with GTK1 and C (yes, GTK 2 did not exist yet and wx was not really widespread; the first time I installed Audacity on Slackware 8.1 I had to google for them) or Qt with C++.
I was quite skeptical with interpreted languages too: I knew a bit of Lisp (more for academic reasons than for “real programming” — that is to say I would not be able to write a piece of useful software; well, this isn’t changed, anyway) and quite a lot of Perl (still I did not use to do what I considered “serious work”: a few cgi and some system scripting). But I’m going off topic.

One day one of my friends showed me the Powerbook G4 and MacOS X (it was Jaguar, for those who care). After some time I bought my first Mac with MacOS X. Before being a Linux user I was a big fan of MacOS Classic (and the first machine I installed GNU/Linux on was an iMac), so I was really happy with the “new deal” of Apple. Still I planned to “install GNU/Linux as soon as possible”. In fact this never happened (but one of this days when I have time and airport support is stable enough…).
The first thing I did was to learn Objective C. I took a look at Carbon, but I wasn’t amazed. I read Apple’s guides about the language. They were clear and well done. Still to code GUI applications I needed a more detailed book (I’m kind of a perfectionist) since the Tutorial, although well done, is designed for absolute beginners. Anyway the Apple guide for the language ObjectiveC is here.

I still have no idea why I chose to learn it. In fact I was a “cross-platform gui”. I still thought I would use both systems, so having my own applications on both of them was probably quite desirable. Moreover the QT MacOS port was young (it was released a couple of months after I bought the Mac, IIRC).
In the same period I was learning Python too, and almost everything else (system tools, web sites, cross platform gui applications with awful Tk) was made with it. I found some similarities between the two languages (in fact I think they were more similarities between Python and Smalltalk, and only indirectly between Python and ObjectiveC). Still one thing was different. Python is a very high level language, but does not force you in anyway into some kind of framework.

In fact you can perfectly “translate” command line from C using the same POSIX APIs or, for example, “convert” a Qt + C++ program. The language Objective C in fact has the same properties. In fact I wrote a few command line utilities and found that the Foundation kit was a well designed environment that abstracted some POSIX interfaces. I quite liked it. And quite liked ObjectiveC.

The only thing I truly missed were namespaces (or analogue things). I spend a couple of days understanding the memory model and that was everything. I bought two books, “Cocoa in a Nutshell” (today I would not buy this) and “Cocoa Programming” by Anguish Buck and Yacktman. They were both good books. I do not use the Nutshell because Apple documentation is more recent today, not because it’s not well done.
Cocoa Programming” is a “big” book. There are lots of infos. Some of them are advanced topics (for example there are Chapters about optimizations — you know, optimization hinders evolutions, but we want to run our software on something more portable than a mainframe).

The book focuses on how Cocoa was thought with Design Patterns (expecially those from the famous book), even if they change their name (and Anguish/Buck/Yacktman show which Cocoa pattern corresponds to a GOF pattern). I was already acquainted with DP, I read the “Design Patterns: EORSD” some time ago (and recently I bought the book and I’m reading it again). In fact Cocoa developing needs understanding of design patterns, but you can have a less theoretical approach to Cocoa.

I recently read Hillegass’s “Cocoa Programming for MacOS X” and that is what I mean. It’s more like a tutorial, but not as elementar as Apple one. It shows you some “real life” small applications that use key tecnologies. It shows Cocoa structure, main “patterns” (for example how to deal with a NSTableView — and introduces the concept of delegation).
While “Cocoa Programming” shows how much Cocoa can be powerful, Hillegass shows how much Cocoa is easy. There are many things that are not explained in the latter (even if it covers some topics I didn’t find in the other book).

You may need (you probably need) a book like Anguish/Buck/Yacktman’s “Cocoa Programming“, but I strongly advise to start with “Cocoa Programming for MacOS X“. It’s not recent, but it’s well done and complete. You can build a whole lot of applications reading it, and for example explains the Document Based Applications in a very simple yet complete way (for example in “Cocoa Programming” the authors implement classes that act quite like the NSDocument and friends to show you in details how it works, still I was not really able to understand how easy it is programming Doc-based apps with Cocoa; in fact I thought it was hard, since many explanation about how the “true” class works are embedded in the explanation of how to rewrite a subset of it.
Another reason for reading “Cocoa Programming for MacOS X” is its length. Much shorter than the other one, you can read it in less than a week, and dive into programming with more skills. Some useful subjects in “Cocoa Programming” are not at the beginning and you must already know you have to skip chapters and go and read them.
In fact I find the two books complement each other well. I’ve got a third book (well a fourth), but I’m not gonna speak about it this time.

  1. Cocoa Programming” – Anguish/Buck/Yacktman
  2. Cocoa Programming” for MacOS X” – Hillegass

Apple PyObjC tutorial (Cocoa programming with Python)

February 12, 2006

This is Apple’s tutorial about programming Cocoa with Python. It’s an easy one, but read it if you want to start programming Cocoa with Python. It is quite well done.

Here PyObjC website.


MacOS X Intel & Rosetta: application compatibility

February 10, 2006

This site keeps an updated list of software that works with Rosetta and how they work. For example some applications do work, but with serious performance issues. If you have to use them professionaly (or often) you should consider not to go with Intel Macs and stay with old Macs.

With some other applications however Intel performances are quite impressive.