GithubHelp home page GithubHelp logo

functionaljava / functionaljava Goto Github PK

View Code? Open in Web Editor NEW
1.6K 84.0 252.0 3.66 MB

Functional programming in Java

Home Page: www.functionaljava.org

Java 96.86% Scala 3.14%
algebra algebraic-data-types effects functional-programming java monad monoid optics persistent-data-structure property-based-testing

functionaljava's Issues

Provide equals/hashCode/toString for fj.List<A>

fj.List should provide a default implementation of equals, hashCode and toString that uses the .equals(), .hashCode() and .toString() implementations of its members. For instance, this equality check on the same list contents currently fails:

public class TestList { 
    public static void main( String[] args ) { 
        final java.util.List<Integer> myList = Arrays.asList( 1, 2, 3 ); 
        boolean equal = iterableList( myList ).equals( iterableList( myList ) ); 
        System.out.println( "equal = " + equal );//prints false 
    } 
} `

Discussion of this topic was provided here:
https://groups.google.com/forum/?fromgroups#!topic/functionaljava/qc5fUHOg0AU

Equals.shallowEqualsO may be wrong for non-final class

and thus all Object.equals() implementation that use it in classes that allow subclassing. Pull request to fix this is on the way.
The following test fails:

  @Test
  public void equals() throws Exception {
    P1<Integer> p1a = new P1<Integer>() {

      @Override
      public Integer _1() {
        return 1;
      }
    };
    P1<Integer> p1b = new P1<Integer>() {

      @Override
      public Integer _1() {
        return 1;
      }
    };

    org.junit.Assert.assertTrue(p1a + " and " + p1b + " should be equal by Object.equals", p1a.equals(p1b));
  }

Add toString for P2 to P8

Use the Show.pxShow methods to add toString methods to the classes P2 to P8. P1 is an interface, so toString will have to be added to P1Functions (unfortunately this limits it's usefulness).

Implement Predicate<T>

many times I ended up in writing following combinators, I think it would add some value if library has it :

  1. F<A, Bool> and(F<A, Bool> pred1, F<A, Bool> pred2)
  2. F<A, Bool> or(F<A, Bool> pred1, F<A, Bool> pred2)
  3. F < B, Bool > comap(F<B, A>, F<A, Bool>)
  4. F<B, Bool> notFor(F<B, A>, F<A, Bool>) [a la Haskell's Data.Function.Predicate's isn't]
  5. F<A, Bool> inverse(F<A, Bool>)

additionally we could add:
nand, nor, xor
We can also implement Predicate2<A, B>, Predicate3<A, B, C> and so on.
thoughts?

List.group assumes an already sorted list?

Hi,

Is it normal that List.group assumes that the list is sorted?

System.out.println(List.list("a", "b", "a").group(Equal.stringEqual))

gives

      <<a>,<b>,<a>>

I would have thought it should give

      <<a,a,>,<b>>

Or am I mistaken on the role of the function? If yes, could the documentation be updated then?

Some.toString causes stackoverflow on Android

Option.some("").toString() results in StackOverflowException.

This means assertEquals can't be used in JUnit tests with Options because attempts by that framework to generate an assert failure message result in stack overflow.

java.lang.StackOverflowError
at fj.data.LazyString.toString(LazyString.java:111)
at java.lang.StringBuilder.<init>(StringBuilder.java:81)
....
at fj.data.LazyString.toString(LazyString.java:111)
at java.lang.StringBuilder.<init>(StringBuilder.java:81)
at fj.data.Stream.asString(Stream.java:1049)
at fj.Show.showS(Show.java:83)
at fj.data.Option.toString(Option.java:51)

Collections name conflict with standard library

Actually it is quite frustrating, that common collections names confilct with standard java collections names, e.g. List, HashMap - so you have to use fully qualified names when using both. Isn't it a good idea to give them a prefix for example ListF, HashMapF? (like it is in bolts library - https://bitbucket.org/stepancheg/bolts/src/c91e8b36dc22c92021a055ad183c96c9f734b884/src/main/java/ru/yandex/bolts/collection/?at=trunk)

I understand that these changes are not backward-compatible, but it is not so difficult to refactor though.

Support for higher order type polymorphism

Does @functionaljava rules out any support for higher order type polymorphism?
(ie, like how it is done in https://github.com/DanielGronau/highj/wiki)
If yes, what about about a safer, closed-world implementation via GADT, something like:

/**
 * A 'GADT' for "lifting" a type constructors to type parameter level in order to allow the simulation of higher order type
 * polymorphism.
 */
public abstract class h<X, T> {

  private h() {
  }

  private static abstract class Types<R, X, T> {
    R option(final Option<T> option) {
      throw Bottom.undefined();
    }

    R p1(final P1<T> p1) {
      throw Bottom.undefined();
    }

    // ... all generic types we care about
  }

  abstract <R> R match(Types<R, X, T> types);

  public static <T> h<Option<?>, T> option(final Option<T> option) {
    return new h<Option<?>, T>() {
      @Override
      <R> R match(final Types<R, Option<?>, T> types) {
        return types.option(option);
      }
    };
  }

  public static <T> Option<T> narrow(final h<Option<?>, T> hOption) {
    return hOption.match(new Types<Option<T>, Option<?>, T>() {
      @Override
      Option<T> option(final Option<T> option) {
        return option;
      }
    });
  }

}
public abstract class Monad<X> {

  public abstract <A> h<X, A> pure(A a);

  public abstract <A, B> h<X, B> bind(h<X, A> ha, F<A, h<X, B>> f);

}

  public static final Monad<Option<?>> monad = new Monad<Option<?>>() {

    @Override
    public <A> h<Option<?>, A> pure(final A a) {
      return h.option(some(a));
    }

    @Override
    public <A, B> h<Option<?>, B> bind(final h<Option<?>, A> ha, final F<A, h<Option<?>, B>> f) {
      return h.option(h.narrow(ha).bind(a -> h.narrow(f.f(a))));
    }
  };

TreeZipper.findChild => Error: head on empty stream

Hi,

There seems to be a bug in the inner function 'split' declared in 'TreeZipper.findChild'. Indeed, the sub condition 'xs.isNotEmpty()' does not prevent a recursive call to f with an empty stream as the second argument : in this very case, the first call to 'xs.head()' explodes.

Hope that helps,

G.N

fj.data.LazyString.toString cause infinite recursion on Android

Context : Android (tested on 5.0.1) with FJ 4.2

Trying to print an Option with :
System.out.println(Option.some(45));

cause an infinite recursion in LazyString.toString :

ERR: stack=java.lang.StackOverflowError: stack size 8MB
            at java.lang.StringBuilder.<init>(StringBuilder.java:81)
            at fj.data.LazyString.toString(LazyString.java:111)
...

it seems the StringBuilder constructor call .toString on CharSequence instead of iterating on the characters, leading to a recursion loop.

A falsified test with a null parameter causes a NullPointerException

Test case:

    @Test
    public void testShowNullParameters() {
Arbitrary.arbInteger.gen))), (Integer i) -> {
        Property p = property(arbitrary(Gen.<Integer>value(null)), (Integer i) -> {
                return prop(i != null);
        });
        CheckResult.summary.println(p.check());
    }

Exception stack:

java.lang.NullPointerException
    at fj.Show$3.f(Show.java:183)
    at fj.Show$3.f(Show.java:180)
    at fj.Show.show(Show.java:63)
    at fj.Show.showS(Show.java:83)
    at fj.test.Arg$1.f(Arg.java:57)
    at fj.test.Arg$1.f(Arg.java:55)
    at fj.Show$2.f(Show.java:169)
    at fj.Show$2.f(Show.java:167)
    at fj.Show.show(Show.java:63)
    at fj.Show.showS(Show.java:83)
    at fj.test.CheckResult$1.arguments(CheckResult.java:236)
    at fj.test.CheckResult$1.f(CheckResult.java:247)
    at fj.test.CheckResult$1.f(CheckResult.java:229)
    at fj.Show$2.f(Show.java:169)
    at fj.Show$2.f(Show.java:167)
    at fj.Show.show(Show.java:63)
    at fj.Show.print(Show.java:129)
    at fj.Show.println(Show.java:115)
    at fj.data.test.TestNull.testShowNullParameters(TestNull.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Fails to compile under version 8 updates 20 and 25

Compilation in Java 1.8.0_20 and 25 triggers a JDK compiler bug as per below.

:demo:compileJava
An exception has occurred in the compiler (1.8.0_25). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.NullPointerException
at com.sun.tools.javac.code.Types.isConvertible(Types.java:290)
at com.sun.tools.javac.comp.Check.assertConvertible(Check.java:922)
at com.sun.tools.javac.comp.Check.checkMethod(Check.java:876)
at com.sun.tools.javac.comp.Attr.checkMethod(Attr.java:3838)
at com.sun.tools.javac.comp.Attr.checkIdInternal(Attr.java:3615)
at com.sun.tools.javac.comp.Attr.checkMethodIdInternal(Attr.java:3522)
at com.sun.tools.javac.comp.Attr.checkMethodId(Attr.java:3501)
at com.sun.tools.javac.comp.Attr.checkId(Attr.java:3488)
at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3370)
at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1897)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1843)
at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:649)
at com.sun.tools.javac.comp.Attr.visitVarDef(Attr.java:1093)
at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:852)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:692)
at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1142)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1035)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4342)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4252)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4181)
at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4156)
at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:45)
at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:38)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:96)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:49)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:35)
at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:29)
at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:20)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:33)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:24)
at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:87)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:65)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:235)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:222)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:296)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:86)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:148)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:105)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:85)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:81)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:39)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:29)
at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:50)
at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
at org.gradle.launcher.Main.doAction(Main.java:33)
at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:127)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:55)
:demo:compileJava FAILED

fj.data.Java#EnumSet_List throws ClassCastException

Test code

import fj.Show;
import fj.data.Java;
import fj.data.List;

import java.util.EnumSet;

import static fj.Show.listShow;

public class Test {
  public static void main(final String[] args) {
    final List<Colors> colors = Java.<Colors>EnumSet_List().f(EnumSet.allOf(Colors.class));
    listShow(Show.<Colors>anyShow()).print(colors);
  }

  enum Colors {
    red, green, blue
  }
}

Output

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Enum;
    at fj.data.Java$77.f(Java.java:1781)
    at fj.data.Java$77.f(Java.java:1778)
    at fj.demo.Test.main(Test.java:13)

The problematic part is this: (A[]) new Object[as.size()]

Many more functions in fj.data.Java use this idiom.

Bug in PX.memo()?

Hi,

I'm not exactly sure but I think I found a bug with memo in the PX classes.
Or maybe I'm using it wrongly... I hope not, but if yes, then I don't see how the use case I have should be done with functional java.

When running this code:

public static void main(String[] args) {

    final int i = 5;

    final P3<Integer, Double, String> p = new P3<Integer, Double, String>() {
        @Override
        public Integer _1() {
            return i;
        }

        @Override
        public Double _2() {
            return i*0.2;
        }

        @Override
        public String _3() {
            return "i: "+i;
        }
    };

    p.memo()._3();
}

I get a StackOverflowError:

at fj.F$10$1._1(F.java:203)
at fj.P1$10._1(P1.java:210)
at fj.P3$4._3(P3.java:143)
at fj.P3$7.f(P3.java:182)
at fj.P3$7.f(P3.java:180)
at fj.F$10$1._1(F.java:203)
at fj.P1$10._1(P1.java:210)
at fj.P3$4._3(P3.java:143)
at fj.P3$7.f(P3.java:182)
at fj.P3$7.f(P3.java:180)
at fj.F$10$1._1(F.java:203)
at fj.P1$10._1(P1.java:210)
at fj.P3$4._3(P3.java:143)
at a.Test.main(Test.java:58)

Thanks!

Edit: I simplified the example :)

Why not use git tags?

It would be great if this project adopted the practice of pushing a (git tag)[http://learn.github.com/p/tagging.html] for each released version -- it makes it super easy to go to the source version that corresponds to a released version.

It's such a simple step, and it would be a great help to us users of the library.

Does not compile in eclipse

It seems like functionaljava is a great test case for the Java 8 compiler. I filed a bug with eclipse, and I thought I would put a link to there from here in case someone else runs into the same issues, basically marking this as a known issue with functionaljava in eclipse.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=461004

Note that if you are just using the functionaljava jar files this is not an issue.

P1.memo() sometimes returns null when accessed concurrently

Paweł Krupiński reported an issue in the group as per below (https://groups.google.com/forum/#!topic/functionaljava/nSPIBAvAWVY):

Hi.
We started noticing NullPointerExceptions in our code that accessed fj.data.Stream instances concurrently.

I was able to trace it down to P1.memo() creating a P1 that sometimes returns null from ._1() call when accessed concurrently.
Here's how to reproduce it (sometimes you need to run it multiple times) on Java 8 and functionaljava 4.2:

final P1<String> p1 = P.p("Bla").memo();
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
    executorService.submit(() -> {
        if (p1._1() == null) {
            System.out.println("Null");
        }
    });
}

executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.DAYS);

`Property.check` doesn't propagate exceptions from `Gen`s

I don't have a minimal test case or anything, but I think this bug is pretty clear:

https://github.com/functionaljava/functionaljava/blob/master/core/src/main/java/fj/test/Property.java#L187

public CheckResult check(final Rand r,
                           final int minSuccessful,
                           final int maxDiscarded,
                           final int minSize,
                           final int maxSize) {
    int s = 0;
    int d = 0;
    float sz = minSize;
    CheckResult res;

    while (true) {
      final float size = s == 0 && d == 0 ? minSize : sz + (maxSize - sz) / (minSuccessful - s);
      try {
        final Result x = f.f(round(size)).f(r);
        if (x.isNoResult())
          if (d + 1 >= maxDiscarded) {
            res = exhausted(s, d + 1);
            break;
          } else {
            sz = size;
            d++;
          }
        else if (x.isProven()) {
          res = proven(x.args().some(), s + 1, d);
          break;
        } else if (x.isUnfalsified())
          if (s + 1 >= minSuccessful) {
            res = passed(s + 1, d);
            break;
          } else {
            sz = size;
            s++;
          }
        else if (x.isFalsified()) {
          res = falsified(x.args().some(), s, d);
          break;
        } else if (x.isException()) {
          res = propException(x.args().some(), x.exception().some(), s, d);
          break;
        }
      } catch (final Throwable t) {
        genException(t, s, d); // <= result is discarded
      }
    }

    return res;
  }

if a throwable is caught, it is swallowed silently and the while loop continues on.

TreeMap#split appears broken

I wrote the following test for TreeMap#split and got some unexpected behavior: https://gist.github.com/996438.

It appears the "lesser" and "greater" value sets are being reduced to singleton sets. I looked at the implementation

public P3<Set<V>, Option<V>, Set<V>> split(final K k) {
    final F<Set<P2<K, Option<V>>>, Set<V>> getSome = Option.<V>fromSome().o(P2.<K, Option<V>>__2())
        .mapSet(tree.ord().comap(P.<K, Option<V>>p2().f(k).<V>o(Option.<V>some_())));
    return tree.split(p(k, Option.<V>none())).map1(getSome).map3(getSome)        
        .map2(Option.<V>join().o(P2.<K, Option<V>>__2().mapOption()));
}

and I'm pretty sure the problem is in extrapolating an Ord for values (which may not be comparable at all) from the Ord provided for the keys using a comap. What the current implementation does is map each value v to (k, some(v)), where k is the split key. Unfortunately, the original Ord only considers the first part of the tuple, which is now the constant k for all values. So this comapping effectively makes all values in the set equal, and thus no value inserts after the first one.

Tony on #functionaljava mentioned that TreeMap might have taken some strong implementation cues from Haskell's Data.Map. Here's the signatures for the splits of that structure:

split :: Ord k => k -> Map k a -> (Map k a, Map k a)
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

I'm happier with this implementation, because we're not returning back sets of values, but rather submaps, so we don't have to deal with having an Ord for values at all.

If you guys are in agreement of how to resolve this, I can put together a pull request with the fix and necessary tests.

Parser.StreamParser.satisfyOpt

I wrote this. Seems useful. Is this something y'all want in the library?

    public static <I, O, E> Parser<Stream<I>, O, E> satisfyOpt(final P1<E> missing, final F<I, E> sat,
                                                               final F<I, Option<O>> f) {
        return Parser.StreamParser.<I, E>element(missing).bind(new F<I, Parser<Stream<I>, O, E>>() {
            @Override
            public Parser<Stream<I>, O, E> f(final I i) {
                return f.f(i).option(Parser.<Stream<I>, O, E>fail(sat.f(i)), new F<O, Parser<Stream<I>, O, E>>() {
                    @Override
                    public Parser<Stream<I>, O, E> f(final O o) {
                        return value(o);
                    }
                });
            }
        });
    }

Wrong samples imports

In some samples appear imports like this:

import static fj.pre.Show.intShow;
import static fj.pre.Show.listShow;

I think that right imports should be like this:

import static fj.Show.intShow;
import static fj.Show.listShow;

Implement immutable Vector, HashMap and HashSet backed by hash tries

While red-black trees are suitable for ordered elements, we also need data structures which can hold elements with no notion of ordering.
We should implement 3 types of immutable collections:

  • Vector - sequence of elements
  • HashSet - set of elements (no repetitions)
  • HashMap - map

These collections can be implemented using hash tries (like in Scala)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.