40

What are the key differences between the approaches taken by Scala and F# to unify OO and FP paradigms?

EDIT

What are the relative merits and demerits of each approach? If, in spite of the support for subtyping, F# can infer the types of function arguments then why can't Scala?

Nikit Batale
  • 1,790
  • 2
  • 15
  • 20

7 Answers7

43

I have looked at F#, doing low level tutorials, so my knowledge of it is very limited. However, it was apparent to me that its style was essentially functional, with OO being more like an add on -- much more of an ADT + module system than true OO. The feeling I get can be best described as if all methods in it were static (as in Java static).

See, for instance, any code using the pipe operator (|>). Take this snippet from the wikipedia entry on F#:

[1 .. 10]
|> List.map     fib

(* equivalent without the pipe operator *)
List.map fib [1 .. 10]

The function map is not a method of the list instance. Instead, it works like a static method on a List module which takes a list instance as one of its parameters.

Scala, on the other hand, is fully OO. Let's start, first, with the Scala equivalent of that code:

List(1 to 10) map fib

// Without operator notation or implicits:
List.apply(Predef.intWrapper(1).to(10)).map(fib)

Here, map is a method on the instance of List. Static-like methods, such as intWrapper on Predef or apply on List, are much more uncommon. Then there are functions, such as fib above. Here, fib is not a method on int, but neither it is a static method. Instead, it is an object -- the second main difference I see between F# and Scala.

Let's consider the F# implementation from the Wikipedia, and an equivalent Scala implementation:

// F#, from the wiki
let rec fib n =
    match n with
    | 0 | 1 -> n
    | _ -> fib (n - 1) + fib (n - 2)

// Scala equivalent
def fib(n: Int): Int = n match {
  case 0 | 1 => n
  case _ => fib(n - 1) + fib(n - 2)
}

The above Scala implementation is a method, but Scala converts that into a function to be able to pass it to map. I'll modify it below so that it becomes a method that returns a function instead, to show how functions work in Scala.

// F#, returning a lambda, as suggested in the comments
let rec fib = function 
    | 0 | 1 as n -> n 
    | n -> fib (n - 1) + fib (n - 2)

// Scala method returning a function
def fib: Int => Int = {
  case n @ (0 | 1) => n
  case n => fib(n - 1) + fib(n - 2)
}

// Same thing without syntactic sugar:
def fib = new Function1[Int, Int] {
  def apply(param0: Int): Int = param0 match {
    case n @ (0 | 1) => n
    case n => fib.apply(n - 1) + fib.apply(n - 2)
  }
}

So, in Scala, all functions are objects implementing the trait FunctionX, which defines a method called apply. As shown here and in the list creation above, .apply can be omitted, which makes function calls look just like method calls.

In the end, everything in Scala is an object -- and instance of a class -- and every such object does belong to a class, and all code belong to a method, which gets executed somehow. Even match in the example above used to be a method, but has been converted into a keyword to avoid some problems quite a while ago.

So, how about the functional part of it? F# belongs to one of the most traditional families of functional languages. While it doesn't have some features some people think are important for functional languages, the fact is that F# is function by default, so to speak.

Scala, on the other hand, was created with the intent of unifying functional and OO models, instead of just providing them as separate parts of the language. The extent to which it was succesful depends on what you deem to be functional programming. Here are some of the things that were focused on by Martin Odersky:

  • Functions are values. They are objects too -- because all values are objects in Scala -- but the concept that a function is a value that can be manipulated is an important one, with its roots all the way back to the original Lisp implementation.

  • Strong support for immutable data types. Functional programming has always been concerned with decreasing the side effects on a program, that functions can be analysed as true mathematical functions. So Scala made it easy to make things immutable, but it did not do two things which FP purists criticize it for:

    • It did not make mutability harder.
    • It does not provide an effect system, by which mutability can be statically tracked.
  • Support for Algebraic Data Types. Algebraic data types (called ADT, which confusingly also stands for Abstract Data Type, a different thing) are very common in functional programming, and are most useful in situations where one commonly use the visitor pattern in OO languages.

    As with everything else, ADTs in Scala are implemented as classes and methods, with some syntactic sugars to make them painless to use. However, Scala is much more verbose than F# (or other functional languages, for that matter) in supporting them. For example, instead of F#'s | for case statements, it uses case.

  • Support for non-strictness. Non-strictness means only computing stuff on demand. It is an essential aspect of Haskell, where it is tightly integrated with the side effect system. In Scala, however, non-strictness support is quite timid and incipient. It is available and used, but in a restricted manner.

    For instance, Scala's non-strict list, the Stream, does not support a truly non-strict foldRight, such as Haskell does. Furthermore, some benefits of non-strictness are only gained when it is the default in the language, instead of an option.

  • Support for list comprehension. Actually, Scala calls it for-comprehension, as the way it is implemented is completely divorced from lists. In its simplest terms, list comprehensions can be thought of as the map function/method shown in the example, though nesting of map statements (supports with flatMap in Scala) as well as filtering (filter or withFilter in Scala, depending on strictness requirements) are usually expected.

    This is a very common operation in functional languages, and often light in syntax -- like in Python's in operator. Again, Scala is somewhat more verbose than usual.

In my opinion, Scala is unparalled in combining FP and OO. It comes from the OO side of the spectrum towards the FP side, which is unusual. Mostly, I see FP languages with OO tackled on it -- and it feels tackled on it to me. I guess FP on Scala probably feels the same way for functional languages programmers.

EDIT

Reading some other answers I realized there was another important topic: type inference. Lisp was a dynamically typed language, and that pretty much set the expectations for functional languages. The modern statically typed functional languages all have strong type inference systems, most often the Hindley-Milner1 algorithm, which makes type declarations essentially optional.

Scala can't use the Hindley-Milner algorithm because of Scala's support for inheritance2. So Scala has to adopt a much less powerful type inference algorithm -- in fact, type inference in Scala is intentionally undefined in the specification, and subject of on-going improvements (it's improvement is one of the biggest features of the upcoming 2.8 version of Scala, for instance).

In the end, however, Scala requires all parameters to have their types declared when defining methods. In some situations, such as recursion, return types for methods also have to be declared.

Functions in Scala can often have their types inferred instead of declared, though. For instance, no type declaration is necessary here: List(1, 2, 3) reduceLeft (_ + _), where _ + _ is actually an anonymous function of type Function2[Int, Int, Int].

Likewise, type declaration of variables is often unnecessary, but inheritance may require it. For instance, Some(2) and None have a common superclass Option, but actually belong to different subclases. So one would usually declare var o: Option[Int] = None to make sure the correct type is assigned.

This limited form of type inference is much better than statically typed OO languages usually offer, which gives Scala a sense of lightness, and much worse than statically typed FP languages usually offer, which gives Scala a sense of heavyness. :-)

Notes:

  1. Actually, the algorithm originates from Damas and Milner, who called it "Algorithm W", according to the wikipedia.

  2. Martin Odersky mentioned in a comment here that:

    The reason Scala does not have Hindley/Milner type inference is that it is very difficult to combine with features such as overloading (the ad-hoc variant, not type classes), record selection, and subtyping

    He goes on to state that it may not be actually impossible, and it came down to a trade-off. Please do go to that link for more information, and, if you do come up with a clearer statement or, better yet, some paper one way or another, I'd be grateful for the reference.

    Let me thank Jon Harrop for looking this up, as I was assuming it was impossible. Well, maybe it is, and I couldn't find a proper link. Note, however, that it is not inheritance alone causing the problem.

Community
  • 1
  • 1
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • 5
    F# also has a syntax sugar version. `let rec fib = function | 0 -> 0 | 1 -> 1 | n -> fib (n - 1) + fib (n - 2)` – gradbot May 25 '10 at 23:47
  • 1
    @gradbot is that truly syntactic sugar, or is it multiple dispatch? When I said syntactic sugar, I meant that the two implementations were exactly equal. Well, the first one extends `AbstractFunction1`, which implements `Function1`, but I left that out to keep it simple. The code you produced is clearly not the same, as it returns 0 for 0 and 1 for 1, whereas the original returned n for 0 or 1. The _result_ is the same, but not the implementation. – Daniel C. Sobral May 26 '10 at 04:18
  • 3
    @Damiel, As @grandbot said it's just a syntactic sugar. See section 6.6.5 of F# spec (http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.pdf). – missingfaktor May 26 '10 at 08:47
  • That definition of `fib` is not the normal way to write it in Scala. The normal prototype would be `def fib(x:Int):Int = x match{...}`, and this isn't syntactic sugar for anything. (You would get a free function from this using `fib(_)`. – Ken Bloom May 26 '10 at 13:40
  • I see your point. Perhaps this code is closer to the Scala example. `let rec fib = function | n when n = 0 || n = 1 -> n | n -> fib (n - 1) + fib (n - 2)` – gradbot May 26 '10 at 15:08
  • @Ken Yeah, but that would be just a method, not a function. And though one can easily get a closure calling that method, choosing a method would not server to show and explain what functions in Scala are. Besides, this is shorter, and I do use it on occasion when I'm not interested in naming my arguments. – Daniel C. Sobral May 26 '10 at 15:21
  • 3
    @Daniel, I think the point you're trying to make is **close** to being false. Yes, all Scala functions are objects, but methods aren't their own objects by default, and the terminology difference is subtle. (I'm tempted to take my own editor pen to that section of the post to clarifly.) – Ken Bloom May 26 '10 at 15:46
  • 2
    @Daniel, if you're going to do it that way, then you should make `fib` a val. Doing it as a `def` creates a new function object for each recursive call. That's a lot of garbage. – Ken Bloom May 26 '10 at 15:47
  • 1
    @Ken Well, I was _trying_ to make a clear distinction between methods, as in `map`, and functions. That's why I opted to have `fib` be a function instead of a method that gets closured in first place. By all means, go ahead and clarify it. As for `def` and `val`, that's completely irrelevant to this discussion. For recursive stuff like this, `val` is definitely better. Where I use this pattern, though, a `val` would add to the size of the objects that really matter, and there's no recursion to be concerned about. I think introducing a `val` in the answer would be counter-productive. – Daniel C. Sobral May 26 '10 at 16:11
  • 2
    "Scala can't use the Hindley-Milner algorithm because of Scala's support for inheritance". Can you elaborate on this in light of the fact that OCaml and F# both have inheritance and use HM? Also, it is the Hindley-Milner type system and the Damas-Milner type inference algorithm. – J D Nov 25 '10 at 21:54
  • @Jon Harrop: _I_ can't. I'll quote and link some references. As for the H-M, it is common usage to refer to the algorithm as Hindley-Milner (http://en.wikipedia.org/wiki/Type_inference#Hindley.E2.80.93Milner_type_inference_algorithm), but correctness is good, so I'll fix the text. – Daniel C. Sobral Nov 25 '10 at 22:28
  • 2
    I can't for the life of me find one of the five points that is not supported by F#. While I do agree with the first part of the answer, I can't see the points focused on by Odersky making any difference at all between Scala and F#. What am I missing? – Muhammad Alkarouri Oct 11 '11 at 20:34
14

F# is functional - It allows OO pretty well, but the design and philosophy is functional nevertheless. Examples:

  • Haskell-style functions
  • Automatic currying
  • Automatic generics
  • Type inference for arguments

It feels relatively clumsy to use F# in a mainly object-oriented way, so one could describe the main goal as to integrate OO into functional programming.

Scala is multi-paradigm with focus on flexibility. You can choose between authentic FP, OOP and procedural style depending on what currently fits best. It's really about unifying OO and functional programming.

Dario
  • 48,658
  • 8
  • 97
  • 130
  • 3
    F# is not a functional language, it's a true multi paradigm language which supports procedural, functional and OO (although I agree on the clumsyness on the OO side). – Patrik Hägne May 25 '10 at 16:40
  • 2
    It theoretically multi-paradigm but de-facto only useful when used primarily functional. – Dario May 25 '10 at 17:01
  • 7
    That's totally very untrue, it's very useful as a scripting language. – Patrik Hägne May 25 '10 at 19:14
  • 4
    Who said functional languages can't be used as scripting languages? That's no contradiction, in fact most useful scripting languages show heavy functional or declarative characteristics. Or do you write huge classes and inheritance trees in your F# scripts? – Dario May 25 '10 at 19:28
  • 4
    Personally, I don't find using OO in F# any more painful than in C#, and there are some OO features of F# which I really wish C# had (e.g. object expressions). I agree, though, that OO is even cleaner in Scala. – kvb May 25 '10 at 20:26
  • 3
    I like F#'s OO when it's not written to be consumed by another C# project. It has a very light feel to it. If you do some JavaScript OO without using the prototype keyword it will give you a different perspective on Functional/OO mixed code. – gradbot May 25 '10 at 23:44
  • 8
    -1: F#'s OOP is far stronger than Scala's FP (e.g. inadequate TCO) so calling Scala multiparadigm but F# not is absurd. – J D May 29 '10 at 14:15
  • Methods aren't even first-class functions in Scala. – J D Nov 25 '10 at 21:55
13

There are quite a few points that you can use for comparing the two (or three). First, here are some notable points that I can think of:

  • Syntax
    Syntactically, F# and OCaml are based on the functional programming tradition (space separated and more lightweight), while Scala is based on the object-oriented style (although Scala makes it more lightweight).

  • Integrating OO and FP
    Both F# and Scala very smoothly integrate OO with FP (because there is no contradiction between these two!!) You can declare classes to hold immutable data (functional aspect) and provide members related to working with the data, you can also use interfaces for abstraction (object-oriented aspects). I'm not as familiar with OCaml, but I would think that it puts more emphasis on the OO side (compared to F#)

  • Programming style in F#
    I think that the usual programming style used in F# (if you don't need to write .NET library and don't have other limitations) is probably more functional and you'd use OO features only when you need to. This means that you group functionality using functions, modules and algebraic data types.

  • Programming style in Scala
    In Scala, the default programming style is more object-oriented (in the organization), however you still (probably) write functional programs, because the "standard" approach is to write code that avoids mutation.

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • Functions are not first-class in Scala and it doesn't do TCO properly. – J D May 29 '10 at 14:42
  • 1
    @Jon: As far as I know, functions _are_ objects in Scala and objects are (not surprisingly) first-class. – Tomas Petricek May 29 '10 at 15:12
  • 1
    As far as I know, members should also be functions but they are not first-class in Scala (as they are in F#, for example). – J D May 29 '10 at 20:50
  • Regarding OCaml, I would actually say that it puts less emphasis on OOP because OCaml's object system was literally added as an afterthough. However, the main difference is that OCaml's object system works a *lot* better with type inference than either F# or Scala. – J D Nov 25 '10 at 21:59
13

What are the key differences between the approaches taken by Scala and F# to unify OO and FP paradigms?

The key difference is that Scala tries to blend the paradigms by making sacrifices (usually on the FP side) whereas F# (and OCaml) generally draw a line between the paradigms and let the programmer choose between them for each task.

Scala had to make sacrifices in order to unify the paradigms. For example:

  • First-class functions are an essential feature of any functional language (ML, Scheme and Haskell). All functions are first-class in F#. Member functions are second-class in Scala.

  • Overloading and subtypes impede type inference. F# provides a large sublanguage that sacrifices these OO features in order to provide powerful type inference when these features are not used (requiring type annotations when they are used). Scala pushes these features everywhere in order to maintain consistent OO at the cost of poor type inference everywhere.

Another consequence of this is that F# is based upon tried and tested ideas whereas Scala is pioneering in this respect. This is ideal for the motivations behind the projects: F# is a commercial product and Scala is programming language research.

As an aside, Scala also sacrificed other core features of FP such as tail-call optimization for pragmatic reasons due to limitations of their VM of choice (the JVM). This also makes Scala much more OOP than FP. Note that there is a project to bring Scala to .NET that will use the CLR to do genuine TCO.

What are the relative merits and demerits of each approach? If, in spite of the support for subtyping, F# can infer the types of function arguments then why can't Scala?

Type inference is at odds with OO-centric features like overloading and subtypes. F# chose type inference over consistency with respect to overloading. Scala chose ubiquitous overloading and subtypes over type inference. This makes F# more like OCaml and Scala more like C#. In particular, Scala is no more a functional programming language than C# is.

Which is better is entirely subjective, of course, but I personally much prefer the tremendous brevity and clarity that comes from powerful type inference in the general case. OCaml is a wonderful language but one pain point was the lack of operator overloading that required programmers to use + for ints, +. for floats, +/ for rationals and so on. Once again, F# chooses pragmatism over obsession by sacrificing type inference for overloading specifically in the context of numerics, not only on arithmetic operators but also on arithmetic functions such as sin. Every corner of the F# language is the result of carefully chosen pragmatic trade-offs like this. Despite the resulting inconsistencies, I believe this makes F# far more useful.

J D
  • 48,105
  • 13
  • 171
  • 274
  • I wish I could up vote *and* down vote this. I like how you summarized the trade-offs between OOP vs Functional, but don't agree that Scala is not a commercial product (I'd say in *addition* to being "programming language research"). Why run on the JVM, which you acknowledge necessitated more sacrifices, if not for commercial appeal? I also don't agree that Scala is no more a functional programming language than C#. Scala has better support for immutability, pattern matching, and stronger type inference than C#. – Tim Goodman Apr 02 '14 at 06:52
  • @TimGoodman: Scala was not yet commercial when I wrote that (2010) but it is today. The JVM is a huge benefit for people implementing non-commercial languages because it provides high-quality garbage collectors that support multithreading. Standalone languages like OCaml and Python struggle with multithreading. Pattern matching and type inference are orthogonal to functional programming (e.g. Lisp has neither). Immutability is trivial in C#, just don't mutate! Lack of TCO so, for example, standard functional idioms like CPS are completely broken is a major flaw IMO. – J D Apr 05 '14 at 18:17
  • Yeah, you make a good point about the garbage collection and multithreading benefits of the JVM. I just re-read some interviews with Martin Odersky on the origins of Scala (like this one: https://www.artima.com/scalazine/articles/origins_of_scala.html ) and it sounds like that was a consideration in choosing the JVM. Also, it seems it's fair to characterize Scala as starting as a research project and then becoming commercial. So I withdraw that criticism. – Tim Goodman Apr 05 '14 at 18:47
  • Regarding whether C# is as functional as Scala, everyone seems to have their own definition of "functional programming", but it's worth noting that Mads Torgensen, who supervises C# language design, has characterized pattern matching, type inference, and immutability as typical functional programming features that C# either lacks or doesn't support to the same degree. See here: http://blogs.msdn.com/b/madst/archive/2007/01/23/is-c-becoming-a-functional-language.aspx That blog post is a bit old, but I don't think much has changed with respect to these features. – Tim Goodman Apr 05 '14 at 18:53
  • Regarding pattern matching and type inference, I would say that they are common features of most *statically-typed* functional programming languages. So while not strictly *required* for a language to be functional, the fact that one statically typed language has them and another (largely) doesn't is relevant to the question "which is more of a functional programming language?" (For some definitions of "functional programming", anyway.) – Tim Goodman Apr 05 '14 at 19:07
7

From this article on Programming Languages:

Scala is a rugged, expressive, strictly superior replacement for Java. Scala is the programming language I would use for a task like writing a web server or an IRC client. In contrast to OCaml [or F#], which was a functional language with an object-oriented system grafted to it, Scala feels more like an true hybrid of object-oriented and functional programming. (That is, object-oriented programmers should be able to start using Scala immediately, picking up the functional parts only as they choose to.)

I first learned about Scala at POPL 2006 when Martin Odersky gave an invited talk on it. At the time I saw functional programming as strictly superior to object-oriented programming, so I didn't see a need for a language that fused functional and object-oriented programming. (That was probably because all I wrote back then were compilers, interpreters and static analyzers.)

The need for Scala didn't become apparent to me until I wrote a concurrent HTTPD from scratch to support long-polled AJAX for yaplet. In order to get good multicore support, I wrote the first version in Java. As a language, I don't think Java is all that bad, and I can enjoy well-done object-oriented programming. As a functional programmer, however, the lack of (or needlessly verbose) support of functional programming features (like higher-order functions) grates on me when I program in Java. So, I gave Scala a chance.

Scala runs on the JVM, so I could gradually port my existing project into Scala. It also means that Scala, in addition to its own rather large library, has access to the entire Java library as well. This means you can get real work done in Scala.

As I started using Scala, I became impressed by how cleverly the functional and object-oriented worlds blended together. In particular, Scala has a powerful case class/pattern-matching system that addressed pet peeves lingering from my experiences with Standard ML, OCaml and Haskell: the programmer can decide which fields of an object should be matchable (as opposed to being forced to match on all of them), and variable-arity arguments are permitted. In fact, Scala even allows programmer-defined patterns. I write a lot of functions that operate on abstract syntax nodes, and it's nice to be able to match on only the syntactic children, but still have fields for things such as annotations or lines in the original program. The case class system lets one split the definition of an algebraic data type across multiple files or across multiple parts of the same file, which is remarkably handy.

Scala also supports well-defined multiple inheritance through class-like devices called traits.

Scala also allows a considerable degree of overloading; even function application and array update can be overloaded. In my experience, this tends to make my Scala programs more intuitive and concise.

One feature that turns out to save a lot of code, in the same way that type classes save code in Haskell, is implicits. You can imagine implicits as an API for the error-recovery phase of the type-checker. In short, when the type checker needs an X but got a Y, it will check to see if there's an implicit function in scope that converts Y into X; if it finds one, it "casts" using the implicit. This makes it possible to look like you're extending just about any type in Scala, and it allows for tighter embeddings of DSLs.

From the above excerpt it is clear that Scala's approach to unify OO and FP paradigms is far more superior to that of OCaml or F#.

HTH.

Regards,
Eric.

missingfaktor
  • 90,905
  • 62
  • 285
  • 365
  • 13
    "it is clear that Scala's approach to unify OO and FP paradigms is superior to that of OCaml or F#." I'm afraid that in order to support that statement, you'll have to provide evidence that OO with FP grafted on is superior to FP with OO grafted on. – Joel Mueller May 26 '10 at 18:11
  • 4
    I'm not even sure it is fair to regard F# as FP with OO grafted on when its target was always CIL which is entirely OO. – J D Nov 25 '10 at 22:00
5

The syntax of F# was taken from OCaml but the object model of F# was taken from .NET. This gives F# a light and terse syntax that is characteristic of functional programming languages and at the same time allows F# to interoperate with the existing .NET languages and .NET libraries very smoothly through its object model.

Scala does a similar job on the JVM that F# does on the CLR. However Scala has chosen to adopt a more Java-like syntax. This may assist in its adoption by object-oriented programmers but to a functional programmer it can feel a bit heavy. Its object model is similar to Java's allowing for seamless interoperation with Java but has some interesting differences such as support for traits.

simon cousins
  • 101
  • 1
  • 3
  • 6
  • 2
    *Scala does a similar job on the JVM that F# does on the CLR* - well, only in a box-ticking sense. Scala really is a better thought-out marriage of functional- and OO-style that Ocaml/F#. – Charles Stewart May 26 '10 at 07:08
  • 5
    @Charles: If that were true Scala would do real TCO but it doesn't so any real functional code written in Scala just stack overflows. Hardly "better thought out"... – J D May 29 '10 at 14:39
  • 2
    @Jon: This is a good point, given that some say that you haven't really got functional programming without full TCO. In defence of Scala, they have the problem because they are on the JVM and want full, robust interaction with native Java code, and they do optimise tail calls when they can. Note that Scala on .NET does support full tail calls. – Charles Stewart May 30 '10 at 08:11
  • @Charles: Yes, Scala sacrificed TCO for Java interop. Scala also has second-class functions in the form of members, which is also very dysfunctional. If you believe Scala is a "better thought-out marriage of functional- and OO-style" then you must have some strong grievances with OO in F#. How is OO in OCaml or F# much worse than Java, C# or C++, for example? – J D May 31 '10 at 00:28
  • @Charles: "Note that Scala on .NET does support full tail calls". AFAIK, Scala has not run on .NET for many years (since Scala 1.4). Microsoft may be about to fund work to update the .NET port but it is early days yet. In the mean time, Scala.NET is abandonware. – J D May 31 '10 at 00:29
  • @Jon: "Scala.NET is abandonware" - no, it's not. Scala.net is not where the action is, but it is maintained, and there are plans to extend it, independent of MS's plans. "Scala also has second-class functions in the form of members" - I've no idea what you mean by this. – Charles Stewart May 31 '10 at 07:26
  • @Charles: Are you sure about Scala.NET? I tried to get it running just a couple of weeks ago and found that it was uselessly out of date (see here http://www.scala-lang.org/node/168), e.g. it doesn't even support generics from .NET 2.0 (from 2006). First-class functions are another critically-important feature for FP and not all functions are first class in Scala. See here: http://jim-mcbeath.blogspot.com/2009/05/scala-functions-vs-methods.html – J D May 31 '10 at 08:02
  • Miguel Garcia has been working on the .NET backend, and has plans to tackle generics, see http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/. Wrt. methods: yes, I see where you are coming from. I don't see this as anything like as serious an issue as lack of TCO. : I guess to argue this goes beyond what these comment threads can support, but at least note that Scala does have first-class functions, the point is that not everything that might be a function is one. – Charles Stewart May 31 '10 at 11:10
  • @Charles: Thanks for the info on Scala.NET. I hope it comes to something. The point about second-class functions is that Scala has this inconsistency but F# does not. I'm still curious why you described Scala as a "better thought-out marriage of functional- and OO-style". What's wrong with OO in F#? – J D May 31 '10 at 14:54
  • 4
    @Jon: "What's wrong with OO in F#?" Nothing, really: you can pretty much do C# in it, and since Don Syme is working on mixins, I won't make anything of that. Rather, the problem is that FP works with values, and OO works with classes: you have a distinction, say, between string list and list in F# (and no generics at all in OCaml, so you can't even cast string list to an object). Meanwhile in Scala, all types are classes; the type system derives from the Abadi-Cardelli Theory of Objects, as extended by Odersky, which is the foundation which Scala's FP is built on. – Charles Stewart Jun 01 '10 at 07:54
  • 2
    @Charles: I do not understand: `string list` vs `list` is purely syntactic, OCaml obviously has generics (its family of languages invented generics!). All types are not classes in OCaml but I think they are in F#, aren't they? For example, you can do `(1).GetHashCode()` and `[1;2;3].GetHashCode()` in F#. – J D Jun 01 '10 at 09:31
  • 1
    @Jon: F#-style generics might be coming to OCaml, but they've not made it to the manual yet. I think you may be confusing ML-style polymorphism with Ada-style generics. As I understand it, F# has both, and uses a clever system of casts to try to move between them, so that List and 'a list use different forms of polymorphism. But I'm feeling out of my depth here: the only one of these three languages I've done substantial programming in is OCaml. – Charles Stewart Jun 01 '10 at 11:39
  • 2
    @Charles: `list` and `'a list` are merely different syntaxes for the same thing (a generic list). They are semantically identical. The language feature you are referring to in F#, Ada and OCaml is the same feature: parametric polymorphism. Perhaps you are confusing it with subtype polymorphism from OOP? F# and OCaml both have subtype polymorphism as well, of course, as OOP languages. – J D Jun 01 '10 at 16:09
  • @Jon: I wonder what Simon is making of our discussion! Parametric polymorphism isn't a particular feature, it is a family of formalisms, and Ada generics are more like Haskell's type classes than they are to H-M polymorphism. In particular, H-M polymorphism can't do constraints: it can't look into type parameters at all. – Charles Stewart Jun 02 '10 at 08:30
  • @Jon: Sure but none of these languages are using plain HM anyway. Both OCaml and F# support subtypes and, therefore, constraints over type variables. – J D Jun 02 '10 at 22:09
3

If functional programming means programming with functions, then Scala bends that a bit. In Scala, if I understand correctly, you're programming with methods instead of functions.

When the class (and the object of that class) behind the method don't matter, Scala will let you pretend it's just a function. Perhaps a Scala language lawyer can elaborate on this distinction (if it even is a distinction), and any consequences.