question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Any reason FuncN is not parametrized on the input type ?

See original GitHub issue

Current FuncN definition is only parametrized on the result type, loosing type information regarding the input of the call method:

public interface FuncN<R> extends Function {
    public R call(Object... args);
}

An implementer will most often cast the parameter in order to process it adequately. Which can be tricky (and ugly) for arrays. For example, when using the varadic overload of CombineLatest, a sequence :: List<Observable<Boolean>> -> Observable<List<Boolean>> looks like this:

Observable<List<Boolean>> sequence (List<Observable<Boolean>> listOfObservableBools) {
return Observable.combineLatest(listOfObservableBools, new FuncN<List<Boolean>> {
   public List<Boolean> call(Object... args) {
     Boolean[] = Arrays.copyOf(args, args.length, Boolean[].class); // Ewww
      return Arrays.asList(booleans);
  }
});
}

It also prevents abstracting over the content type (here Boolean) as erasure disallows something like T[].class. It is thus impossible to implement a generic version of this operator, List<Observable<T>> -> Observable<List<T>>.

The solution IMHO is to add a type parameter to FuncN representing the type of the input parameter:

public interface FuncN<T, R> extends Function {
    public R call(T... args);
}

CombineLatest would go from

public static final <T, R> Observable<R> combineLatest(List<? extends Observable<? extends T>> sources, FuncN<? extends R> combineFunction)

to

public static final <T, R> Observable<R> combineLatest(List<? extends Observable<? extends T>> sources, FuncN<? extends T, ? extends R> combineFunction)

making this (and others usages) possible:

Observable<List<T>> sequence (List<Observable<T>> listOfObservableTs) {
return Observable.combineLatest(listOfObservableTs, new FuncN<T, List<T>> {
   public List<T> call(T... args) {
      return Arrays.asList(args);
  }
});
}

Is there a technical reason for the current state of affair ?

Thanks for your hard work and time !

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
amazaricommented, May 17, 2014

Is there a technical reason for the current state of affair ?

Answering my own question: As far as I can see, having FuncN non-parametrized on the input type was made to permits using combineLatest(List..., FuncN) in the implementations of the multiple parameter versions (combineLatest(Observable<T1>, Observable<T2>, Func2<T1, T2, R>), combineLatest(Observable<T1>, Observable<T2>, Observable<T3>, Func3<T1, T2, T3, R>)… ) through a transformation from Func<2|3|4|..., R> to FuncN<R> looking like this:

    public static <T0, T1, T2, T3, R> FuncN<R> fromFunc(final Func4<? super T0, ? super T1, ? super T2, ? super T3, ? extends R> f) {
        return new FuncN<R>() {
            public R call(Object... args) {
                if (args.length != 4) {
                    throw new RuntimeException("Func4 expecting 4 arguments.");
                }
                return f.call((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3]);
            }

        };
    }

Indeed in that case the parameters types might be heterogeneous and fallback to the lower denominator type Object, before being cast back to their original type.

0reactions
headintheboxcommented, May 20, 2014

I’d favor tuples to List<Object> anyday.

Let’s agree to disagree on this. You are trading a lot of complexity for what, some type safety? In this case that is not worth the trouble. Static types are nice when they work, but they are just a means to an end, not a goal you chase at any cost. Like spice & food.

Read more comments on GitHub >

github_iconTop Results From Across the Web

why do functions dont have parameterized return types, as it ...
Ya, this is a solution. And I was wondering why the language don't have the feature of parametrized return type. Here the Problem...
Read more >
proposal: spec: allow type parameters in methods · Issue ...
According to the Type parameters proposal, it is not allowed to define type parameters in methods. This limitation prevents to define ...
Read more >
Documentation - More on Functions - TypeScript
We've created a type parameter Func that doesn't relate two values. That's always a red flag, because it means callers wanting to specify...
Read more >
Functions :: Eloquent JavaScript
A function can have multiple parameters or no parameters at all. In the following example, makeNoise does not list any parameter names, whereas...
Read more >
JavaScript Function Parameters - W3Schools
Function parameters are the names listed in the function definition. Function arguments are the real values passed to (and received by) the function....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found