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.
-
Frege’s type inference is global so we don’t have to annotate types as often as we do in Scala (local inference).
-
In Frege, modules are just namespaces for types and functions whereas Scala has better module system. http://2013.flatmap.no/spiewak.html
-
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.
-
In Frege, there is no
def
vsval
and everything is function. Hence functions are more first-class than Scala. -
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 JavaList
.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.
-
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 handlesnull
returned from theget
method since it is annotated withMaybe
type. The only waynull
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
orST
. -
Frege has no variables as in Scala’s
var
and the side effects
are more explicit through types. (Just nonull
, novar
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!) -
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.
-
Frege is lazy by default but strictness can be enabled where necessary through
!
whereas Scala is strict by default but haslazy
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.