What are the main differences between Scala and Frege (in programming paradigms)?
Asked Answered
F

3

33

Scala and Frege are both typed functional languages that target JVM.

Frege is closer to Haskell, Scala has a more independent history.

But if we don't look at syntactic differences, what are the differences in the allowed programming techniques, styles, concepts between the two?

Firebrick answered 28/7, 2013 at 5:33 Comment(6)
Frege is a non-strict, pure functional programming language in the spirit of Haskell. Scala is a strict language. Scala does not enforce purity. And scala is not an attempt to port Haskell to the JVM, not even close to it. You should look for Scala vs. Haskell questions, for instance: What are the differences and similarities of Scala and Haskell type systems?.Ascarid
Ankur: a functional language is a language that allows writing programs with pure, referentially transparent functions. You can write very complex programs in scala without ever using side effects. So scala does not just look like a functional language, it is one.Nunuance
@RüdigerKlaehn By your definition, every almost language is functional. Even C--because it is certainly possible to avoid side effects in C, and use function pointers to simulate HOFs. Yet, not many people would call C a functional language. (And likewise, almost every language can be said to be object-oriented.)Mammy
@Mammy Scala offers enough constructs and straight forward suggestions that put it in a very different category than C w.r.t. functional programming. No trolling, please.Receiver
@RüdigerKlaehn Purity isn't really a requirement of functional languages. Being able to accept functions as arguments, return functions as results, and create new functions at runtime (i.e. have a syntax for anonymous functions a.k.a. lambdas) are the requirements of a functional language. Haskell and Frege are pure, which means that side effects are isolated. Scala is certainly functional AND object-oriented. but it is not pure, largely due to practical concerns of running on the JVM and interacting with Java.Modernity
According to the definition on wikipedia, "In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data". Scala does not enforce purity, but it has a sufficiently powerful "pure subset" to write very complex programs. Languages like ruby on the other hand, where even basic data types like strings are mutable, can never claim to be functional even if they have mechanisms for higher order "functions".Nunuance
S
41

IMHO both are really good languages but with respect to paradigms, Scala does OO better than Frege but Frege does functional better than Scala. With respect to differences, it comes down to mostly Haskell vs Scala since Frege is (or almost, see differences between Haskell and Frege here) Haskell for the JVM.

  1. Frege's type inference is global so we don't have to annotate types as often as we do in Scala (local inference).

  2. In Frege, modules are just namespaces for types and functions whereas Scala has better module system. http://2013.flatmap.no/spiewak.html

  3. In Frege, functions are curried by default so there is no need for additional constructs for partial function application. Same goes for partial type constructor application.

  4. In Frege, there is no def vs val and everything is function. Hence functions are more first-class than Scala.

  5. Frege has no sub-typing but the type system figures out the sub typing on native calls. For example, you can pass an ArrayList to a function which requires a Java List.

    Since there is no subtyping, in Frege we cannot extend a Java class or implement an interface as of now (might be supported in future) so we need to have a Java class which would extend/implement but the method implementations would be passed from Frege as functions.

  6. From Scala, it is easy to call Java but in Frege, a Java class/method must be declared (Just the type and purity annotations) before use. For example, to use Java's LinkedList,

    data LinkedList a = native java.util.LinkedList where
        native add :: Mutable s (LinkedList a) -> a -> ST s Bool
        native get :: Mutable s (LinkedList a) -> Int -> ST s (Maybe a) throws
           IndexOutOfBoundsException
        native new :: () -> STMutable s (LinkedList a)
    

    Here since the functions mutate the object, they must be in ST monad. Also note that here Frege also handles null returned from the get method since it is annotated with Maybe type. The only way null can get through to your Frege program is through native interface since Frege doesn't have a notion of null.

    Another example: pure native floor Math.floor :: Double -> Double

    which states that the function is pure and hence the signature directly reflects the original Java signature without IO or ST.

  7. Frege has no variables as in Scala's var and the side effects are more explicit through types. (Just no null, no var and explicit side effects make Frege more interesting, atleast for me. In a sense, Frege, just as Haskell, is a "fine imperative programming language", for the JVM!)

  8. Being a Haskell dialect, Frege is more natural towards Functors, Applicatives, Monads and other functional "patterns" and has those in it's standard library whereas in Scala, you might need Scalaz.

  9. Frege is lazy by default but strictness can be enabled where necessary through ! whereas Scala is strict by default but has lazy keyword for lazy evaluation.

Nevertheless, being JVM languages, one language can benefit from other. I once ported an Akka example to Frege. In the end, it comes down to strictness, purity, functional, OO and type inference and how much they matter to you.

Sufferance answered 28/7, 2013 at 19:29 Comment(3)
Great, very detailed post. Though I would prefer Frege is a substitute for Haskell on the JVM, the more so as many identify Haskell with GHC, and it is not realistic (to say the least) to assume that Frege could ever remotely support all the cool GHC features.Ubiquitous
With respect to language constructs, evaluation model and the similarities between the libraries, it is almost close to Haskell for the JVM (In the ideal case, with little exaggeration :), we can run Haskell code as it is on the JVM with Frege). But as you said, it may not come close to what GHC offers. I have edited that part and added the link to Haskell-Frege differences on the project page.Sufferance
Frege is lazy by default but strictness can be enabled where necessary through ! whereas Scala is strict by default but has lazy keyword for lazy evaluation. I have edited the post with this point as well.Sufferance
U
17

Apart from syntactical issues, the biggest difference is in the type system and the execution model.

As @senia already pointed out, scala is strict and not pure, which does not mean that you can't write pure functions (you can do that in C, too), just that the compiler won't enforce it.

Frege, OTOH is lazy and pure, which means that all impure effects are forced to live in the ST or IO monad. The type system is essential that of Haskell 2010, with type classes and additional higher rank function types. Type inference works program wide, the only exception are functions with higher rank types, where at least the polymorphic argument must be annotated. Here is an example:

both f xs ys = (f xs, f ys)

For this function, the compiler infers the type:

both :: (α->β) -> α -> α -> (β, β)

Note that both xsand ysget the same type, because of the application of f. But now lets say we want use a polymorphic list function that we can use with differently typed xs and ys. For example, we want to write:

both reverse [1,2,3] ['a' .. 'z']

As it stands, this application would be in error, because the two lists have different element types and hence different types. So the compiler would refuse the character list.

Fortunately, we can tell the compiler more precisly what we want with a type annotation:

both :: (forall e.[e] -> [e]) -> [a] -> [b] -> ([a], [b])

This tells the following: we will pass to both a function that does some list transformation but doesn't care about the list element type. Then we pass 2 lists with possibly different element types. And we get a tuple with our transformed lists back. Note that the code of both needs not to be changed.

Another way to achieve the same would be to write:

both (f :: forall e.[e]->[e]) xs ys = (f xs, f ys)

and the type checker infers the rest, namely that xs and ys must be lists, but can have different element types.

Scalas type system fully (to my knowledge) supports OO. While Frege supports it only partially with regard to types imported for Java, but does not support definition of own OO-like types.

Hence, both languages support functional programming in a JVM environment, although in completly different niches. A third niche is the dynamically typed one, where Clojure is king in the JVM world.

Ubiquitous answered 28/7, 2013 at 8:53 Comment(2)
Nice answer! Minor nitpick: Effect system for Scala, available as a plugin: github.com/lrytz/efftpEclecticism
@Eclecticism Thanks for the link. Nevertheless I think that the claim that Scala-the-unmodified-language does not help you isolate effects is still justified.Ubiquitous
M
3

Maybe it's off topic, but Scala can be used to develop Android applications (*), but Frege hasn't been successfully used for that, yet.(**) IIRC, it's because interop with existing Java libraries is much easier in Scala than in Frege, among other issues.

(*) Caveat emptor. I've only done small, example programs myself.

(**) Frege/Java mixes have been used for Android applications, but Frege-only applications are still not available, AFAIK.

Modernity answered 8/8, 2013 at 14:47 Comment(2)
Whether "successfull" or not, but there is at least a proof of concept Android App in a Java/Frege mix. It must be remembered in this context that Scalas followers count in the 10 thousands, while Frege, being not that long around and not very well known yet even among knowledgeable FP people, has maybe 200 that know of its existence.Ubiquitous
Scala-only Android apps are possible. In Frege, you have to mix in some Java so you can subclass in the right places, IIRC. That wasn't clear in my answer though. The Java/Frege mix is quite suitable to Android development. I'll add a note to clarify.Modernity

© 2022 - 2024 — McMap. All rights reserved.