Recursive Max

Recursive Max
During my initial stages of learning Perl, I tried to write a function that returns the maximum number of a given list of numbers.
In C, we need to pass the address of the array and its size.
In Java, we need to pass the reference of the array object.
In Perl, we can simply pass the list of numbers (or an array).
I feel that this is more flexible than what is in C/Java.
Now, let us see the Perl version.

sub max {
    return undef if @_ == 0;
    return shift if @_ == 1;
    my $n1 = shift;
    my $n2 = &max;             # arguments passed implicitly; please refer perlsub
    $n1 > $n2 ? $n1 : $n2;
}

We can call this function in following ways

my $max1    = max(1, 2, 3, 4, 5);           # a list of args

my @arr     = (1, 2, 3, 4, 5, 6, 7, 8, 9);
my $max2    = max @arr;                     # an array

my $arr_ref = [1, 2, 3, 4, 5];
my $max3    = max @$arr_ref;                # a dereferenced array ref

print "$max1 $max2 $max3", "\n";

The iterative version of the max function would be

sub max {
    return undef if @_ == 0;
    return shift if @_ == 1;
    my $max = shift;
    for my $n (@_) {
        $max = $n if $n > $max;
    }
    return $max;
}

I have to admit that the Java also supports varargs with version 1.5 and above.
Internally, the compiler passes the list of arguments as an array of elements.

public class max {
	public static int max (int... numbers) {
		int no_of_items = numbers.length;
		//if(no_of_items == 0)            // commented because
		//	return null;                  // "null" is not of an "int" datatype
		if(no_of_items == 1)
			return numbers[0];
		int max = numbers[0];
		for(int i = 1; i < no_of_items; ++i) {
			if(max < numbers[i])
				max = numbers[i];	
		}
		return max;
	}
	public static void main(String args[]) {
		int max1 = max(1, 2, 3, 4, 5);
		System.out.printf("Max is %d\n", max1);

		int max_arr[] = new int[] { 10, 20, 3, 42, 5 };
		int max2 = max(max_arr);
		System.out.printf("Max is %d\n", max2);

		int max3 = max(new int[] {50, 6, 5, 1, 0});
		System.out.printf("Max is %d\n", max3);
	}
}

The Java code contains a lot of boiler-plates and hence looks more verbose than Perl code.
Recursive version of max in Java, again, would be more verbose.

Let us see how we can write such a function in Erlang.
Erlang does not support loop constructs. So, writing a recursive function is not a choice but the only option.
And also, it does not allow us passing the arbitrary number of arguments; but allows us to pass a list instead.
Instead of writing if statements to check on the argument length, we give separate function definition for the different arguments.
Erlang decides on which function definition to call based on the pattern matching.

-module(max).
-export([max/1]).

max([])    -> [];
max([N])   -> N;
max([H|T]) ->
   N = max(T),
   if N > H -> N;
      true  -> H
   end.

We can learn Erlang at LYSE and the documentation.

$ erl
Erlang R15B01 (erts-5.9.1)  [smp:4:4] [async-threads:0] [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1> max:max([]).
[]
2> max:max([5]).
5
3> max:max([10, 20, 3, 42, 5]).
42
4> max:max(1, 2).
** exception error: undefined function max:max/2
5> max:max(1).
** exception error: no function clause matching max:max(1) (max.erl, line 4)
6> q().
ok
7> 

As the exception says, we have to pass the arguments surrounded by the square brackets.

All languages have their own way of manipulating the list of arguments.
But learning those different ways would help us in thinking differently.

Happy Programming!