/*
 *  @author Ranides Atterwim <ranides@gmail.com>
 *  @copyright Ranides Atterwim
 *  @license WTFPL
 *  @url http://ranides.net/projects/assira
 */

package net.ranides.assira.generic;

import java.io.Serializable;
import java.util.concurrent.Callable;

/**
 * Interfejs reprezentujący odwzorowanie {@code S -> T} (funktor, wyrażenie lambda).
 * <p>
 * Może być interpretowany jako uogólnienie interfejsu {@link Runnable}, który
 * reprezentuje funkcję {@code void -> void} (procedurę) albo interfejsu {@link Callable},
 * który reprezentuje funkcję {@code void -> T}.
 * </p>
 * @param <T>
 * @param <S>
 * @author ranides
 */
public interface Function<T,S> extends Serializable {

    // Uwaga - implementacje Function posiadają losowy serialversionuid zasadniczo.
    // W efekcie serializowana klasa nie jest przenośna pomiędzy VM.
    // Żeby się nie męczyć z deklarowaniem svuid dla każdej anonimowej funkcji,
    // napisać subklasę ObjectInputStream, która olewa svuid dla klas, które
    // - są anonimowe
    // - implementują Function
    // - implementują CoFunction

    // @todo (prev # 8) przenośna serializacja Function
    // http://stackoverflow.com/questions/1816559/make-java-runtime-ignore-serialversionuids

    /**
     * Bezstanowa metoda implementująca zachowanie funkcji.
     * <p>
     * Może być interpretowana jako transformacja {@code S -> T}.
     * </p>
     * @see Runnable#run
     * @see Callable#call
     * @param source
     * @return
     */
    T apply(S source);

}
