5

I'm trying to implement a lazy sequence (meaning that the next item is only calculated when you invoke the step function), and one of the methods it should have is "map" which receives a function that affects all the members.
The most elegant way to do this is to use function composition, and assign the new function to the function variable, but since functions are not first class values in Java I have no idea how to do this.

I thought about having a class that only contains a function, as a sort of "function pointer" wrapper, but I don't see how that can be used for composition.

Edit: question is homework related.
Also, it should be able to handle multiple compositions along the lines of map(map(map(stepFunction()))) ("map" in this case being the function given through the method "map").

2
  • So when you say you want to do map(map(map(stepFunction()))), does that mean you've got a list of lists of lists and you want to call stepFunction on every element of all of the child lists in that hierarchy? I'm still not completely clear on what you're trying to accomplish. Commented Nov 19, 2009 at 21:50
  • No. Basically this is the deal: I only have three things at any given time: the step function, the current value, and the base value. If Seq.map(someFunctionToMapWith) was never applied then current value = base value = stepFunction(previous base value). However, once map is applied to the sequence, each time I invoke seq.tail() to change the current value, I first change the base value and mutate it further using the function I was given: curr = mapFunc(stepFunc(base value)) (base value is also updated). If map was invoked multiple times, it should be map(map(..map(stepFunc(base value))..)). Commented Nov 20, 2009 at 8:04

6 Answers 6

7

Welcome to Java and its pains.

interface Function<T> {
    public T eval(T argument);
}

class Lazy<T> {
    private Iterator<T> source;
    private Function<T> filter;
    Lazy(final Iterator<t> source, final Function<T> filter) {
        this.source = source;
        this.filter = filter;
    }
    public T step() {
        return filter.eval(source.next());
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I don't see how this helps me with the composition. Perhaps I should've mentioned that it should be able to respond to multiple applications of map().The behavior I want to achieve is map(map(map(stepFunction()))) (for example).
Then make Lazy<T> extend Iterator<T>... The idea was to give you a pointer in the right direction, not to write all of your code!
@EpsilonVector consider making it a fluent interface instead, so: stepFunction().map(Functor).map(Functor).take(5) or whatever
5

Google Collections has the Function type, the Functions.compose(Function, Function) method, the Iterables.transform(Iterable, Function) method, and much more.

Not helpful to you if this is for homework (I really wish everyone would disclose when their question is homework-related).

Comments

1

In Java, you always do this with a class protocol. See java.lang.Thread and the run function for the canonical example. There are no 'function pointers' or 'function variables' in Java.

Comments

0

FWIW, the "function pointer" equivalent in Java is an interface with a single method. You implement the interface with some class, which provides an implementation of the method, and then store a reference to that class object.

Changing the reference to another class object, which implements the method differently, is equivalent to changing the function pointer to point to a different function.

Comments

0

Java 8 added the java.util.function package, wich make possible to do what the original question asked (https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html):

Function<Integer, Integer> multiply = (value) -> value * 3;
Function<Integer, Integer> add      = (value) -> value + 2;

Function<Integer, Integer> addThenMultiply = multiply.compose(add);

Integer result1 = addThenMultiply.apply(3);
System.out.println(result1); // 15

Still it's not really super nice, but this is using both composition and laziness as requested in the question...

Comments

-1
public static <T> void apply(final List<T> list, final Function<T> func)
{
    for(final T val : list)
    {
        func.perform(val);
    }
}

interface Function<T>
{
    void apply(T value);
}

class DisplayFunction<T>
    implements Function<T>
{
    public void perform(T value)
    {
        System.out.println(value);
    }
}

the call apply(list, new DisplayFunction());

3 Comments

and the random downmarking with no reason give still happens apparently. If you think something is wrong it is polite to explain why you think so.
It could be because it doesn't answer the question, which asked how to compose two functions, not just map using one. Also, functions don't actually modify their inputs, they return a separate transformed value.
You can change it to public static <T, R> R apply(final List<T> list, final Function<T> func) to have it return a different value (or remove R and use T for the return value if the return value will be the same). Generally I won't answer homework directly... but this answer should be enough to get things started.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.