> The two paradigms are not necessarily in conflict.
Agreed - that's my whole point. It's better to think of object-oriented programming as a construction within FP. Of course, some (badly-designed) OO languages like Java sandbox you and restrict your access to some of the more powerful, higher-order concepts, which is why they seem to be 'in conflict', when in reality, one is just a more abstractly implemented, whereas the other's more specifically implemented.
> Scala is a perfect example of a language which is both.
No, it's not - for example, functions have to exist within an instantiation of a class (a singleton object counts). By providing true first-class objects (unlike Java), you get many of the same benefits as first-class functions, but it's fundamentally not the same thing.
Really, an easy way to create a language which supports both is to start with a very basic language with true first-class functions and closures (like Lisp) and then define a few closures that encapsulate state (objects), and then add a couple of basic macros that turn generic functions into bound methods (ie, automatically provide the implicit parameter instead of calling it explicitly).
...which is why I agree that they're not in conflict - a well-designed OO system can be easily implemented within a well-designed functional system!
(The reverse doesn't work so well because you can easily add an implicit parameter to generic functions, but you can't completely remove an implicit parameter from a bound method, even if you pretend it doesn't exist - ie, treat all methods as static methods).
A "first-class function" is a function that can be passed to a function, returned from a function, assigned to a variable, or stored in a data structure or basically used in any way that you would use any value. In Scala:
object Foo {
def f1(x : Int) : (Int => Int) = {
return { y : Int => x + y }
}
def f2(f : Int => Int) : Int = { return f(5) }
val f3 = f1(1)
val f4 = List(f1(2), f1(3), f1(4))
}
Yes, functions cannot be defined at the toplevel (unless you're in the REPL), but values also cannot be defined at the toplevel; they too must exist within an object or class. In that sense, functions are on equal footing with values.
> In that sense, functions are on equal footing with values.
But function objects are not on equal footing with non-function objects. You can nest function objects or non-function objects inside other function/non-function objects, but at the root, you need an object that isn't a function.
At the end of the day, yes, you can do the same things, but my original point was that this doesn't make Scala functional: it makes Scala object-oriented (Java, by contrast, is not properly object-oriented, because it has four kinds that aren't objects).
Agreed - that's my whole point. It's better to think of object-oriented programming as a construction within FP. Of course, some (badly-designed) OO languages like Java sandbox you and restrict your access to some of the more powerful, higher-order concepts, which is why they seem to be 'in conflict', when in reality, one is just a more abstractly implemented, whereas the other's more specifically implemented.
> Scala is a perfect example of a language which is both.
No, it's not - for example, functions have to exist within an instantiation of a class (a singleton object counts). By providing true first-class objects (unlike Java), you get many of the same benefits as first-class functions, but it's fundamentally not the same thing.
Really, an easy way to create a language which supports both is to start with a very basic language with true first-class functions and closures (like Lisp) and then define a few closures that encapsulate state (objects), and then add a couple of basic macros that turn generic functions into bound methods (ie, automatically provide the implicit parameter instead of calling it explicitly).
...which is why I agree that they're not in conflict - a well-designed OO system can be easily implemented within a well-designed functional system!
(The reverse doesn't work so well because you can easily add an implicit parameter to generic functions, but you can't completely remove an implicit parameter from a bound method, even if you pretend it doesn't exist - ie, treat all methods as static methods).