"..best direction for evolving Java is to encourage a more functional style"
mail.openjdk.java.net
mail.openjdk.java.net
EDIT: Ok, I think I'm starting to understand the issue. If lambdas are objects then they have to be typed by their signature. It would have to be a parameterized type i.e. generic. And because of type erasure, the call signature of lambdas would only be known at compile time. So you can't check, at runtime, that a lambda has a compatible signature. That does seem pretty hairy to me.
And if they aren't objects, I guess their signatures would be tracked with some sort of new parallel type system that could be better tailored for the purpose. Is that it?
Erased generics are a bad idea when your type system is full of holes (easy to bypass) and lots happen at runtime, as is the case in Java.
Haskell still needs to do some stuff at runtime for type classes.
Function0<Int> f = () => 5
f here is a lambda that take no args and returns an Int. It's type is Function0 (0 for no args) and parameterized with the return type.Another example with 2 args:
Function2<String, Float, Int> f = (String name, Float rate) => 5
The Function* types are the generic structural types able to describe lambdas. C# has them, and so does Scala.Java however decided not to have them, because they don't adhere well with Java's history with nominative types (a type has a name that carries sense). They rather came up with the SAM auto conversion, which is a neat idea in itself, but a bit less flexible than structural types, and may (and will lead to a Cambrian explosion in the number of types, e.g. Reducer, Mapper, Folder, Filter, Predicate, etc.)
What's even worse though is erasure: Java generics are erased at compile time, and this fucks up things really bad with overloading, so in a code like this (in the type List for example):
public <S> List<T> stupidOpName(Function1<T, S> f) { ... }
public List<T> stupidOpName(Function1<T, Boolean> f) { ... }
After erasure, we'll end up with : public List stupidOpName(Function1 f) { ... }
public List stupidOpName(Function1 f) { ... }
i.e. 2 methods with the same name and same signature. This is bad. You don't ever want that to happen. And fortunately the java compiler won't let it happen.So, the alternative is I said SAM (Single Abstract Method) types: no structural types, but lambdas can be automatically converted to a SAM if compatible, so you could do this for example:
Runnable r = () => { ... }
The lambda gets converted to the Runnable type.With the slight difference that its generics are reified, so all `Function` generic arities have the same name (it's `Function<T>`, `Function<T1, T2>`, ...), although because there is no `void` or `Unit` type in C# it needs two base function types, to handle functions with a return value (`Function`) and functions with no return value (`Action`).
I believe the Kotlin project fixes this issue by having a first-class `Unit` type, so C#'s `Action` becomes `Func<Unit>` in Kotlin.
If they were all just Func<T> (or aliases for that, or wrappers over that when multicast is really needed), it would be a lot simpler.
Function<Void>
It's a bit shady though as you still have to return a value from the body of the method, and that value has to be null.'bit of an understatement there.
I assume there is some way to specify the SAM type explicitly, for cases where it can't be inferred properly?
As to your second question, yes, you can cast a lambda to explicitly specify it's target SAM type:
obj.method((Runnable)(()=> println("oh hai !")));Using lambdas to parameterize algorithms gives you more power, and if the algorithm can assume that the lambda passed in is stateless, it can do things like memoize (cache) calls to it to further optimize the algorithm. Lambdas as higher order functions help you make more composable libraries, because often the glue needed to join one bit of code to another is just a transformation of the return value of one function to the parameter type of another. That's an ideal application for a lambda.
For example, take sorting a list of objects by a particular attribute. A sort routine can be written that takes in a comparison routine, and that comparison routine can do the work of selecting the attributes and comparing them. But chances are you're comparing things like numbers and strings; you'll have other library code that can do those comparisons. So what you actually want, most of the time, is just the bare minimum: a lambda that, given the object to be sorted, returns the attribute to sort by. That's how the Sort routine works in .NET's LINQ, for example: myList.Sort(x => x.Name) will return a sorted sequence of the contents of myList in the order of x.Name property or field. The lambda here is extremely simple and syntactically light, and that's what makes the pattern work. Above all, the lambda isn't really acting like an object.
1. Make the most popular languages, c# and Java, more complex by adding more features such as functional and dynamic support.
2. Make the "core" languages simple and precise, and encourage the use of other languages for adding more options and features to the platform.
Currently, for example, c# does support functional style programming, but there is also f# which ships with VS2010. At first, it seams as if the designers are not sure which of the two approaches to take. and just go both ways. Java is a little behind, but that's why we have clojure and scala.
If you're coming from an imperative, oop, background then these languages will require more learning because you're not familiar with the concepts.
But a language like Java is huge by comparison with something like Javascript or python. In terms of the size of grammar, the number of semantic rules required for description, etc.
What I was getting at would be more in the lines of "confined to a single paradigm and style". And again, not saying either of the two mentioned are. It is more a question of future orientation and concept.
It may seem like it's more complex if the user doesn't have a functional background; but if the user is equally comfortable with both OOP and Functional paradigms F# is the simpler, smaller, more regular language of the two.
unfortunately you can't build hacks on hacks on hacks...even as engineeringly pleasing as some hacks might be.
imo, java needs to find some way of updating the vm.
It's not that they can't update the VM, it's that they don't want to force a painful migration to reified versions of libraries that aren't backwards compatible. But I don't know why they can't just do what that last comment said: extend the old interfaces for reification without breaking them, using Object as the default type parameter.
it would remain binary compatible tho, so it would seem to be a possible solution.
for java to really advance forward it needs to be done in a manner where the principal is the future, not the past. if this means rendering old code as non-type-stafe then this is a small price for a whole new programming paradigm, or even two.
i've struggled with generics since they were added and the problem is that all the potential they propose is only possible if they're reified. as they stand they are worthless and just move a cast from the value to the class but they allude to far more, which is a rat hole.
java's had full backward compatibility for decades. code is a depreciating asset and worth less with every year since compilation. it's an incumbent now, slowing, even mutating, progress.
if some legacy code is so valuable, it should have earned its scars enough to have type safety turned off.
The advantages of the performance of imperative code that exist with C aren't there, nor is the simple flexibility of Lisp or Python.
I attended a talk by James Gosling and he pretty much summed it up when he said, "Java was an attempt to drag C++ programmers kicking and screaming halfway to Common Lisp."
"Evolving" such a language into a more functional one, and doing it properly, will require much more than an evolution. That would completely change the language.
And you can still take advantage of functional concepts in Java as is. To me it seems like static methods are underused, but if you eliminate most or all of the member variables from your classes, you can code in a very functional style in Java. It's not the prettiest solution, but neither is having little bits of state everywhere at once.
The core of Java is the OO programming model, and "good" Java programming revolves around what works in that model.
Lately I've become a fan of "import static", which imports static functions from another class. "import static java.lang.Math." is good to do if you need to do a lot of math, for instance. "import static com.example.mysystem.MyDSL." sets you up to use an internal DSL.
Faking Lambdas with objects is cumbersome but not difficult, and remember there are many tricks like new ArrayMap<String,String>() {{ put("k1","v1"); put ("k2","v2") }} which let you build structures the way you would in Javascript, Python, PHP, C# or whatever.
"Webcomic".
"Cell phone".
What I meant was that, when Java somehow becomes ‘functional’ (like that transition can happen to an established language) it will be assumed that any program written in this version is ‘functional,’ regardless of whether it really is written in a functional style.
Either way, adding lambdas does not make you into an acceptable functional language. Java is still not a language that Joel Spolsky won’t complain about the teaching of in schools.
I don't think that's the case. Higher-order functions have been part of the OO toolbox since the batch of OO languages has existed, generally under the label "blocks" (indicating non-local returns separating them from the preexisting "lambdas").
And I'd argue that a language without anonymous first-class function can not be "truly" object-oriented, or at least not without significant syntactic overhead.
To me, a core idea of OO is that objects are opaque boxes to which you "give order" (that makes Erlang's processes excellent objects, by the way). But it is very common that you need to customize the exact behavior in some way.
Without first-class functions, the choices are to either extract all relevant data from the object, perform the operation yourself and (optionally) feed the data back, low overhead but a far cry from object orientation; or to create a new type holding all relevant customization information (that's the delegate pattern), very high overhead but remains object oriented.
First-class functions in OO language act as very-low-overhead delegates (you may still need full-blow delegates for complex customization, but single-method delegates aren't needed anymore), and let language users avoid imperative programming.
But I have only used a few languages - Scheme and C are horrible to use (personal experience, yours might defer). Java and JavaScript have been brilliant!
It's not a pure functional language, but it's sure not pure OO either.
(And why the downvote?)
I suspect most people think readability is more affected by style rather than choice of programming language.
I have observed that (may be due to the lack of a review system in academia) the code was much harder to read. With C, the problem was even worse due to extensive use of global variables and poor structuring of code. Java, on the other hand, has two benefits: firstly, it's really strict and verbose. So even if a person is practicing bad coding, it is still harder to make truly unreadable code. Secondly, the IDE are more powerful, makes coding as well as code browsing easier.
My prejudice might be against C and in favor of Java. And i just related it to functional and OO respectively. But I would like to add that modifying objects still somehow seem more intuitive to me - probably because I had a better Java teacher than a C teacher. :)
Functional programming refers to languages (like scheme and Haskell, and also Ruby and Python) where a function is no different than any other object in memory (like int, char, etc.). It can be returned as a value and passed as a parameter. A function can take functions as arguments and return another function as a result, kind of like taking the derivative or integral in math. (Something like this can be done in C with function pointers, but it's ugly.) Moreover, it's possible to define an "anonymous function", or "lambda". This is essentially an expression that evaluates to a function without a name, the same way you can type (x * y * z) and have it evaluate to a number without having to store it in a named variable first.
Also, you ideally want to define "pure functions", which means functions that return the same value for the same inputs no matter when you call them. These are much easier to debug than code that depends on outside conditions.
When you wrap your head around functional programming, it is actually a lot easier and more sensible in many cases than OOP. Of course, OO is still ideal in a lot of situations, which is why many languages (Python, Ruby most notably) combine the two.
(if you've been in academia, Mathematica is an example of a functional language.)
Worth saying: "I like pizza. Its combination of bread, cheese and tomato sauce is unique."
Anyway.
It might be harder to read because you already know Java. Javascript has some horrible warts (IMO), and CoffeeScript fixes.
Also, Javascript is usually targeting the DOM, which is often ugly, especially if you are trying to include compatibility stuff. The DOM is basically a GUI, and GUI code can be rank ugly. Yes, it is hard to read (and learn) HTML, CSS, DOM, HTTP, and Javascript all at once, which is what real Javascript often involves.
BTW, are there any other resources similar to these videos? (Or, to put it differently, is Douglas Crockford the authority for JS?)
Look through your for and foreach loops. I bet a lot of them would be neater, more readable, and better express intent as some combination of map and filter.
Count how many classes you have with only one method and no data in them. Would you really make separate classes for all of those if you had the option to pass them around as functions?
I would also like to see something like the yield and yield! (yield every item in this collection) keywords, because those can give readability improvements in a lot of places too, but one step at a time.
I have never done this, but for the usecase that you have mentioned, would the following work?
class Xyz {
private Type type;
private RetType type1MethodName(params) {
// Do Whatever
}
private RetType type2MethodName(params) {
// Do Whatever
}
public Xyz(type) {
this.type = type;
}
public RetType methodName(params) {
switch(type) {
type1:
return type1MethodName(params);
type2:
return type2MethodName(params);
}
}
public enum Type {
type1;
type2;
}
}
And then when we want to pass methods according to types, we can just instantiate the class with a proper type and pass it. List<int> mapped = new List<int>();
for (int i = 0; i < list.count(); i++)
{
mapped[i] = list[i] + 1;
}
Or: List<int> mapped = list.map((x) => x + 1);
Which do you think is more elegant and readable? For a slightly more extreme example, what if we want the numbers less than 100: List<int>filtered = new List<int>();
for (int i = 0, j = 0; i < list.count(); i++)
{
if (list[i] < 100)
{
filtered[j] = list[i];
j++;
}
}
Or this: List<int> filtered = list.filter((x) => x < 100);http://jaydonnell.com/blog/2011/08/07/is-your-idea-clealry-e...
The code gets nutty when you have to do multiple transforms on collections. There are some libraries in Java which make it more bearable.
http://code.google.com/p/lambdaj/
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());