Functional Java 3.0

71 views
Skip to first unread message

Tony Morris

unread,
Jun 25, 2010, 7:00:21 AM6/25/10
to functio...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Functional Java 3.0 is released.
http://functionaljava.org/

A crucial change has been made to the F interfaces, which are now
abstract classes and containing useful methods. This means some other
methods (fj.Function) are redundant and will be removed in a release
soon (perhaps with a @Deprecated first). There are other minor
additions and bug fixes.

- --
Tony Morris
http://tmorris.net/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkwkjEQACgkQmnpgrYe6r61QPACgqiWu1DzMBGqVNw49FNHKX+jk
ozgAniVCpbAPvdXbjQYxslQpnCFpXpOS
=hsBi
-----END PGP SIGNATURE-----

Ted Neward

unread,
Aug 15, 2010, 5:29:17 AM8/15/10
to functio...@googlegroups.com
Tony, et al--

I'm getting ready to do some presentations on FJ for the NFJS conference
series, and doing so requires some serious research on my part beforehand.
Are there *any* other examples/demos/write-ups/docs/etc floating around the
Internet on FJ that aren't too outdated that I can start from? Secondly, is
the best place to bug you guys about explanations and what-not through the
list here, or through personal email? (Some of my questions--such as
explanations of some terms used in the FJ javadocs--may not go directly to
the FJ library, and thus may not be appropriate to the list, which is why I
ask.)

Ted Neward
Java, .NET, XML Services
Consulting, Teaching, Speaking, Writing
http://www.tedneward.com

> --
> You received this message because you are subscribed to the Google Groups
> "Functional Java" group.
> To post to this group, send email to functio...@googlegroups.com.
> To unsubscribe from this group, send email to
> functionaljav...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/functionaljava?hl=en.

Ted Neward

unread,
Aug 15, 2010, 5:33:09 AM8/15/10
to functio...@googlegroups.com
By the way, forgot to mention--as an inducement to help me get all this
sorted out, I'm writing several articles on FJ as well, which I'll donate
back to here as (hopefully) good "getting started" articles for people
coming to the FJ library for the first time. Knowing me, I'll probably end
up writing four or five articles (instead of the two I owe the NFJS
Journal), to try and cover all of this stuff, but I'd love to have somebody
(or somebodies) from here volunteer to review the technical accuracy of what
I'm saying and writing.

Runar Oli

unread,
Aug 15, 2010, 9:26:47 AM8/15/10
to functio...@googlegroups.com
Ted,


Posting your questions here on the list is perfectly appropriate, even if they don't pertain directly to the library as such.

I would be more than happy to review your articles. Sounds like a great idea, especially if they could become part of the library documentation.


Rúnar

Tom Adams

unread,
Aug 15, 2010, 11:45:31 PM8/15/10
to functio...@googlegroups.com
Hi Ted,

As Rúnar said, please pose here. I'm sure there are several people
here (myself included) that can help with article reviews, history,
etc. I was across the room when Tony started FJ and have used it in
quite a few projects. The scalaz list also has a lot of the same crowd
who may like to help.

Tom

--
tom adams
e:tomjadams<at>gmail.com

Ted Neward

unread,
Aug 16, 2010, 9:50:37 AM8/16/10
to functio...@googlegroups.com
OK, first dumb question--what's a "product-1"? I get that a function
(F<Integer,String>) is a "transformation" from A to B, but I'm not sure what
a product-n (P, P1<A>, P2<A,B>, and so on) is. It seems like a P2 is a pair,
so is a "product-n" essentially a tuple (from F# or Scala)? And if that's
the case, the fj.P type is just a collection of methods/functions for doing
various things with P-n products/tuples, yes?

Second dumb question: fj.data.List doesn't define an equals()? I tried this,
and (surprisingly, to me) it failed:

@Test public void set_map() {
final Set<Integer> a =
Set.empty(Ord.intOrd).
insert(1).insert(2).insert(3).insert(4).insert(5).insert(6);
final Set<Integer> b =
a.map(Ord.intOrd, new F<Integer, Integer>() {
public Integer f(final Integer i) {
return i / 2; // divide each integer by 2
}
});
assertEquals(List.list(3,2,1,0), b.toList());
}

Is there an easy way to test Lists for equivalence, if not through the Java
equals() method?

Third dumb question: Is there any practical reason that the fj.data classes
don't implement the java.util Collection interfaces? Recognizing, of course,
that the Collection classes allow for mutability, I realize that
implementing them might be awkward, but why not do so and just throw
UnsupportedOperationExceptions for the mutable methods? (I think I know the
answer to this one, but I wanted to hear the rationale regardless, if that's
OK.)

Lonnie Princehouse

unread,
Aug 16, 2010, 12:16:35 PM8/16/10
to functio...@googlegroups.com
I've just started using FunctionalJava, but I can take a stab at your first two questions.

1. P1 does seem kind of useless on the surface.  You might think "Why not just use Object"?  But I think it does have some benefits.  It's got the same methods as other P* -- bind, curry, map, etc, so it's consistent.  It also has a type parameter P<T>, so P will give you type safety in situations that Object does not.  The next logical question is "Why not just use a type parameter T instead of P or object?", and the answer to that may be that generics in Java have some inconvenient limitations because of type erasure.  E.g., you can't create an array of type T[].

2. FunctionalJava takes the approach of explicitly specifying what kind of equivalence is being used.  The Equal.listEqual static method is what you're looking for.  It gives you a chance to define the meaning of per-element equality.

Runar Bjarnason

unread,
Aug 16, 2010, 1:41:35 PM8/16/10
to functio...@googlegroups.com
Ted,

Yes, you have it right. A product-n is an n-tuple.
http://en.wikipedia.org/wiki/Product_type

As for list-equality, FJ supplies an Equal type class instead of implementing equals(). By doing this we gain modularity and type safety. There's also a Hash class for obviating hashCode(). You would compare two lists of integers for equality like this:

assert(listEqual(intEqual).eq(list(3,2,1,0), b.toList()))

See here:
http://functionaljava.googlecode.com/svn/artifacts/3.0/javadoc/fj/Equal.html

The fj.data classes have pretty easy conversions to and from java.util collections. For example, if you have an fj.data.List, just call toCollection(). These classes also implement Iterable. A very common use case is to want to get a java.util.List from one of these collections. IterableW helps here. If you have an fj.data.List and you want to treat it as a java.util.List, you must do this:

IterableW.wrap(myList).toStandardList()

This gives you a java.util.List which is implemented by an fj.data.Zipper. It also works for Option, Stream, Zipper (which will give you a list of Zippers), etc.

Keep the questions coming if you have them.


Rúnar

Runar Bjarnason

unread,
Aug 16, 2010, 1:43:15 PM8/16/10
to functio...@googlegroups.com
Also, P1 is potentially lazy. We use it for the implementation of Stream, for example.

Rúnar

Tom Adams

unread,
Aug 16, 2010, 8:03:07 PM8/16/10
to functio...@googlegroups.com
> Also, P1 is potentially lazy. We use it for the implementation of Stream,
> for example.

That's the easy winner in my book for P1, I wrote some Scala yesterday
that does this with a HashMap:

val applications = new HashMap[String, Application]

def application(applicationId: String) =
applications.getOrElseUpdate(applicationId, new
Application(applicationId))


So basically it will return the "application" if its there, or, if
not, create a new one, store it in the map, and return then return it.
That function getOrElseUpdate looks like this:


def getOrElseUpdate(key: A, op: => B): B


Because that function is lazy in the second parameter, it is never
evaluated unless it's needed (in this case, not present in the map).
In Java, you'd need to implement that with a P1, something like (not
sure this is legal syntax):


public B getOrElseUpdate(A key, P<B> creationFunction)


I used to hate doing this stuff in Java with checking maps, is it
there, should I use contains, get() & check for null, etc., I think
this is a really nice use case for one of the uses of P1.

Tom

Ted Neward

unread,
Aug 17, 2010, 5:08:02 AM8/17/10
to functio...@googlegroups.com
I'm still not sure why P1 is lazy, though--this is probably a pretty
fundamental thing, so I want to get it right. Is it just that P<B> (in the
Java example) isn't evaluated until _1() is called, thereby meaning the F<>
hiding inside of it isn't called until then?

Nit: Doesn't the second param in the Scala version require that to be a
closure/function block, then? My Scala is I think a tad rusty, but I thought
that "new" evaluated directly, not lazily. Does Scala transform the "new
Application()" call into a block because the parameter is declared as a
closure/block (whatever the right term is in Scala, I forget)?

Ted Neward
Java, .NET, XML Services
Consulting, Teaching, Speaking, Writing
http://www.tedneward.com

> -----Original Message-----
> From: functio...@googlegroups.com
> [mailto:functio...@googlegroups.com] On Behalf Of Tom Adams
> Sent: Monday, August 16, 2010 5:03 PM
> To: functio...@googlegroups.com
> Subject: Re: [functionaljava] Functional Java 3.0
>

Tom Adams

unread,
Aug 17, 2010, 6:54:36 AM8/17/10
to functio...@googlegroups.com
Let me try to answer, knowing I may be wrong! :)

> I'm still not sure why P1 is lazy, though--this is probably a pretty
> fundamental thing, so I want to get it right. Is it just that P<B> (in the
> Java example) isn't evaluated until _1() is called, thereby meaning the F<>
> hiding inside of it isn't called until then?

I don't have the FJ source handy, but basically yes, you need to
explicitly call the _1() method to compute the value, there's no
automatic help here sorry :)


> Nit: Doesn't the second param in the Scala version require that to be a
> closure/function block, then?

I think the short answer is no. The compiler does it for you in most
cases, and when it can't will tell you if you need to force the
parameter to be an anonymous function, something like (this is bogus
I'm sure):

new Application() _


>My Scala is I think a tad rusty, but I thought
> that "new" evaluated directly, not lazily.

Not sure, I usually do what the compiler tells me! I'm sure someone
who knows can explain, maybe not on the FJ list though :)

>Does Scala transform the "new
> Application()" call into a block because the parameter is declared as a
> closure/block (whatever the right term is in Scala, I forget)?

I think the answer is yes. It works is all I can say :)

Erik van Oosten

unread,
Aug 17, 2010, 8:19:39 AM8/17/10
to functio...@googlegroups.com
This shouldn't be on this list but here it goes anyway:

> Nit: Doesn't the second param in the Scala version require that to be a
> closure/function block, then?

The definition of the scala method is:

> def getOrElseUpdate(key: A, op: => B): B

Note that the type of 'op' is '=> B', without any parameters before the
'=>'.
Any argument (the complete expression, so in this case 'new
Application(applicationId)') is translated to a new anoymous function by
the scala compiler. Each time the body of 'getOrElseUpdate' uses 'op',
and not earlier, the anonymous function is evaluated.

Regards,
Erik.

Op 17-08-10 11:08, Ted Neward schreef:

>> use contains, get()& check for null, etc., I think this is a really nice


>>
> use case
>
>> for one of the uses of P1.
>>
>> Tom
>> --
>> tom adams
>> e:tomjadams<at>gmail.com
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Functional Java" group.
>> To post to this group, send email to functio...@googlegroups.com.
>> To unsubscribe from this group, send email to
>> functionaljav...@googlegroups.com.
>> For more options, visit this group at
>> http://groups.google.com/group/functionaljava?hl=en.
>>
>

--
Sent from my SMTP compliant software
Erik van Oosten
http://day-to-day-stuff.blogspot.com/


Reply all
Reply to author
Forward
0 new messages