Duck typing alows true polymorfisim

lets say you want a generic numerical algorithom like sum

Ruby

def sum lst
lst.inject(0){|total,current| total*current}
end

Java // i dont know if there is a numeric super class for numbers

class Sum{
public static int sum(int[] lst){
int total = 0;
for(int current : lst){
total+=current;
}
return total;
}
// repeat for all other number types
}

[email protected] wrote:

Java // i dont know if there is a numeric super class for numbers

It is, confusingly enough, Number. And this is a silly example for Java,
since the language lacks an abstract numerical tower, which is a very
concrete deficiency of the language, and doesn’t say anything about
polymorphism being limited with static typing.

You could probably do that algorithm as elegantly in OcaML (splitting
between integral and real number types, since those aren’t unified in
the language), or better Haskell which treats all numbers uniformly.
Both are very, very strictly statically typed languages.

Your example doesn’t prove anything about latent typing at all.

David V.

On 8/25/06, [email protected] [email protected] wrote:

The title of this thread was almost like a post I made a year or so ago:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/145049

What you wrote still isn’t as generic as it could be. This can handle
more
than just numerics:

def sum enum
enum.inject{ |total,current| total+current }
end

enum can be anything that responds to inject (likely an Enumerable) with
a
block that takes 2 arguments where the first responds to +. If enum is
an
Enumerable, this means the first element responds to + which returns
something that also continues to respond to +.

Now you can do this:

three = sum([1,2])
hello_world = sum([“hello”,“world”])
concatenated_lines = sum(anIO)

The simpler you can make the description of the duck-typing of a method,
the
more generic and flexible it will be. By adding a 0 argument to inject,
you
made the duck-typing a little more complex and stiffled it by only
allowing
elments that can be added to 0.

[email protected] wrote in message
news:[email protected]

lets say you want a generic numerical algorithom like sum

Ruby

def sum lst
lst.inject(0){|total,current| total*current}
end

Java // i dont know if there is a numeric super class for numbers

[snip- int only example]

There is, and it is interesting because it hilights the
real difference: Java uses C style numerics, where
you select the model of arithmetic you want using
the type system. Here’s a ‘generic sum’ for Java:

public static double sum(Iterable<? extends Number> list)
{
double total=0;
for(Number n : list)
double+=n.doubleValue();
return total;
}

If I got it right (I’m a bit rusty with Java) that will sum
any collection containing any kind of number.

But you have to specify that you want double arithmetic,
as you see; had I chosen int, it would produce different
answers.

In some languages- like Ruby I think- you cannot make
this choice. Your language chooses for you. Most languages
that do this prefer accuracy to speed, so everything gets
promoted to larger types on demand, and things like
rounding and overflow are avoided.

However, even if you agree with this choice, you can
still get into trouble. Promoting to ‘double’ or ‘float’
imposes different errors that you’d get with ints, but
they still exist. Sometimes a ratio type is better; other
times you would prefer a decimal type.

The greatest advantage of static type systems is to
expose design decisions like these in a way the
compiler can see.

[email protected] wrote:

lets say you want a generic numerical algorithom like sum

Hmmm, I thought you were going to announce that you were the first born
son of Xah Lee. Actually you did!

[email protected] wrote:

class Sum{
public static int sum(int[] lst){
int total = 0;
for(int current : lst){
total+=current;
}
return total;
}
// repeat for all other number types
}

Any more to add? Your question is not exactly clear. Are you asking how
to do higher order procedures in Python? Here’s sum as a higher-order
procedure… It sums the numbers from a to b (or any thing that can be
compared and added with “<” and “+”).

def Sum(term, next, a, b):
if(a > b):
return 0
else:
return (term(a) + (Sum(term, next, next(a), b)

This function takes two functions (term and next) and two objects (in
our case numbers) representing the range to sum across. Now let’s say
you want to add the numbers 1 through 10. The term for the summation
would just be the number, so the term function would simply be a
function called identity, and could be defined as

def identity(x):
return x

To get the next term, we are just adding one each time (i.e. 1, 2, 3,
4, …). So our next function is

def increment(x):
return x += 1

Then we call Sum(identity, increment, 1, 10), and we get 1 + 2 + 3 + 4

  • and so on.

Now what if you wanted the sum of the CUBES of 1 through 10? Easy, we
replace the term function with a function cube(x) that returns xxx.

Sum(cube,increment,1,10)

Hence each term in our summation is the cube, but we are still
incrementing by one each time, so we get (1^3 + 2^3 + 3^3 + 4^3 + …)

Similarly we can change the next function to skip certain number, meet
certain requirement, do some tranformation, whatever. The fact that
python accept and uses functions as parameters to other functions is
awesome in terms of power, but it can get a little mind boggling
sometimes.

What was i thinkinng repace * with + i was’nt thinking i origanaly
thaught of sum of squares so i put a * insted of a +

In comp.lang.java.advocacy, [email protected]
[email protected]
wrote
on 25 Aug 2006 12:05:21 -0700
[email protected]:

class Sum{
public static int sum(int[] lst){
int total = 0;
for(int current : lst){
total+=current;
}
return total;
}
// repeat for all other number types
}

There isn’t; Java makes the distinction between an int and
an Integer, a double and a Double. Java 5 did introduce
autoboxing, which makes things like

Number[] numbers = new Number[]{1, 2.3, 4, 5.6};

possible, and Number is a baseclass for both Integer and
Double (but not int and double).

Therefore, one could write:

public class Sum {
public static double sum(int[] lst)
{
Number[] nlst = new Number[lst.length];
for(int i = 0; i < nlst.length; i++) nlst[i] = new Integer(lst[i]);
return sum(Arrays.asList(nlst));
}
public static double sum(double[] lst)
{
Number[] nlst = new Number[lst.length];
for(int i = 0; i < nlst.length; i++) nlst[i] = new Double(lst[i]);
return sum(Arrays.asList(nlst));
}
public static double sum(float[] lst)
{
Number[] nlst = new Number[lst.length];
for(int i = 0; i < nlst.length; i++) nlst[i] = new Double(lst[i]);
return sum(Arrays.asList(nlst));
}
public static double sum(Number[] lst)
{
return sum(Arrays.asList(lst));
}
public static double sum(Collection lst)
{
double sum = 0;
for(Iterator i = lst.iterator(); i.hasNext())
sum += i.next().doubleValue();
return sum;
}

}

A rather ugly but possibly useful duckling.

[email protected] wrote:

What was i thinkinng repace * with + i was’nt thinking i origanaly
thaught of sum of squares so i put a * insted of a +

But again, what’s your question?

[email protected] wrote:

class Sum{
public static int sum(int[] lst){
int total = 0;
for(int current : lst){
total+=current;
}
return total;
}
// repeat for all other number types
}

What’s your question? (Or, if no question, point?) :slight_smile:

Totally off topic (and indeed “off-list”…) is that really how ruby
sums a list? How does that work? Doesn’t the ‘*’ mean multiply? and
what are the pipe symbols for? (Feel free to ignore these questions. I
should really go look it up myself if I’m so curious…)

Peace,
~Simon

“Simon Forman” [email protected] writes:

[email protected] wrote:

What’s your question? (Or, if no question, point?) :slight_smile:

This is atbusbook. He doesn’t have a point - he does bizarre stuff
like this. Seriously - google his email address sometime, especially
on google groups.

I’m not going to attempt to understand him, and have concluded after
his “the perens in lisp dilects is there for a reson… macros” post
from August fifth that the best thing to do is ignore him until he
decides to start being coherent.

Daniel M. wrote:

This is atbusbook. He doesn’t have a point - he does bizarre stuff
like this. Seriously - google his email address sometime, especially
on google groups.

I’m not going to attempt to understand him, and have concluded after
his “the perens in lisp dilects is there for a reson… macros” post
from August fifth that the best thing to do is ignore him until he
decides to start being coherent.

Wooer. Troll fight over Ruby? (Spot the book reference and win…
NOTHING at all!)

David V.