functionaljava / functionaljava Goto Github PK
View Code? Open in Web Editor NEWFunctional programming in Java
Home Page: www.functionaljava.org
Functional programming in Java
Home Page: www.functionaljava.org
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
No one should be able to mistake it for the current repo
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));
}
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).
Added new function F1Functions.f
, which could be confused with F.f
P1Functions.f(f, a) == P1Functions.lazy(f).f(a)
many times I ended up in writing following combinators, I think it would add some value if library has it :
isn't
]additionally we could add:
nand, nor, xor
We can also implement Predicate2<A, B>, Predicate3<A, B, C> and so on.
thoughts?
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?
Seem to conflict in particular in earlier Java 8 (1.8.0_05) where calls to foreach(F<P2<K, V>, Unit>)
and foreach(Effect1<P2<K, V>>)
are ambiguous and compilation to a call fails.
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)
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.
List.list(1,2,3,4,5).init() returns <1,1,1,1> which should be <1,2,3,4>
current work around
List.list(1,2,3,4,5).reverse().tail().reverse();
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))));
}
};
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
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.
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)
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
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.
See the comment by @zot at #106 (comment).
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 :)
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.
This would take advantage of type inference to avoid having to specify the type like:
new Equal<ComplexType>(...)
Many of the show instances have a poor string representation. This can be improved.
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.
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);
How will I go about building a fj.List from a java array?
I don't have a minimal test case or anything, but I think this bug is pretty clear:
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.
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.
Add equals, hashCode and toString to Stream, NonEmptyList, Tree, etc. as per issue #14 and PR #15 (which added them for fj.data.List). The discussion for this topic is at https://groups.google.com/forum/?fromgroups#!topic/functionaljava/qc5fUHOg0AU.
Hey,
I would like to see :
partition :: (a -> Bool) -> [a] -> ([a], [a])
safeHead :: [a] -> Maybe a
on the List type, thoughts?
It looks like Set.member can only return false after traversing the entire tree :((
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);
}
});
}
});
}
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;
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:
These collections can be implemented using hash tries (like in Scala)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.