Re: Factor

Factor: the language, the theory, and the practice.

Concatenative Thinking

Tuesday, July 12, 2011

#language

I’ve written about the conciseness of Factor before. Yesterday, I noticed a link to a functional programming tutorial called “Functional Thinking” that was posted two months ago.

The tutorial develops a program for classifying numbers based on the sum of its factors into perfect, abundant, or deficient numbers. The program goes through three improvements, ending up at this “best” solution in Java (using the Functional Java library):

public class FNumberClassifier {

    public boolean isFactor(int number, int potential_factor) {
        return number % potential_factor == 0;
    }

    public List<Integer> factors(final int number) {
        return range(1, number+1).filter(new F<Integer, Boolean>() {
            public Boolean f(final Integer i) {
                return number % i == 0;
            }
        });
    }

    public int sum(List<Integer> factors) {
        return factors.foldLeft(fj.function.Integers.add, 0);
    }

    public boolean isPerfect(int number) {
        return sum(factors(number)) - number == number;
    }

    public boolean isAbundant(int number) {
        return sum(factors(number)) - number > number;
    }

    public boolean isDeficient(int number) {
        return sum(factors(number)) - number < number;
    }
}

While the proffered solution is much (much) better than the original “imperative” solution, I thought I would show what it could look like in Factor:

: factor? ( m n -- ? )
    mod zero? ;

: factors ( n -- seq )
    dup [1..b] [ factor? ] with filter ;

: perfect? ( n -- ? )
    [ factors sum ] [ - ] [ = ] tri ;

: abundant? ( n -- ? )
    [ factors sum ] [ - ] [ > ] tri ;

: deficient? ( n -- ? )
    [ factors sum ] [ - ] [ < ] tri ;

What do you think?