The Power of the Dot

When being asked what feature of Object-Oriented languages he would like to see in Haskell, Simon Peyton Jones likes to mention "the power of the dot". In languages like Java and Groovy there is very convenient IDE support for finding the right method when they are called in the form of

receiver.myMethod(arg1);

That is because the IDE knows the type of receiver, can look up the available methods, and can present them to the programmer for selection right after he entered the dot.

The situation is less convenient in most functional programming languages since one typically enters the function name first and the IDE has little useful context to suggest alternatives.

myFunction receiver arg1

Luckily, Frege has a nice dot notation that combines the power of both approaches and can be used by IDEs for providing great support.

receiver.myFunction arg1

The basis for Frege’s dot notation are the module system, type declarations, and typeclasses. Let’s see how that works.

The module system

Frege uses the notion of modules to provide namespaces. A module can be seen as a Java class with only static methods and fields.

A module can export data types (type constructors and value constructors), typeclasses, and functions.

For using a module, one needs an import statement (with an optional qualification) and after that one can use the imported types and functions with a prefix.

A simple module import and module namespace usage
import fregefx.javafx.scene.control.TextArea
-- later
TextArea.getCaretPosition inputArea

Here, we see a first usage of the dot: the getCaretPosition function comes from the TextArea module and Frege uses the dot to locate and disambiguate the function.

The function takes one argument (the inputArea), which is of type TextArea. Now, it is often the case that Frege already knows that type because it is declared or can be inferred. In that case, the dot notation allows us to write inputArea.getCaretPosition. Below is an example from the source code of the Frege JavaFX REPL.

Very close to OO notation
insert :: TextArea -> String -> IO ()
insert inputArea text = do
    pos <- inputArea.getCaretPosition
    inputArea.insertText pos text

This not only reads nicely and familiar, it also opens the door for great IDE support.

And there is more.

Data types

In a former post, we had used the data type Position with the record syntax like so:

Note the use of 'position.ticker'
data Ticker = GOOG | MSFT | APPL | CANO | NOOB

data Position = Position  { soMany :: Int, ticker :: Ticker }

-- later:

value position = calculate $ lookup position.ticker prices where
    -- more here...

With the record syntax, ticker looks like a field (and is sometimes called so) but it is actually a function: the accessor function to the ticker value, analogous to a Java getter method.

We can refer to this function in two equivalent ways:

Two equivalent notations
Position.ticker position  -- "getter"
position.ticker

And there are more options for setting or updating "fields":

Setting and updating equivalents with dot notation
Position.{soMany = } position 1  -- "setter"
position.{soMany = } 1

Position.{soMany <-} position (+1) -- update
position.{soMany <-} (+1)

Again, the notation is very object-like and IDE friendly.

It goes without saying that setter and update are not changing the value in place but - as always - return a new immutable value.

Typeclasses

The story proceeds when typeclasses come into play. Below we introduce a class of types that can somehow duplicate its value and we make String an instance of that class.

Dot notation for instances of a typeclass
class Doubleable a where
    twice :: a -> a

instance Doubleable String where
    twice s = s ++ s

main args = do
    println $ Doubleable.twice "a"
    println   "a".twice
Extending closed types

For the object-oriented programmer it is interesting to see how even the type String (which is a final Java String) can be extended with a new function like twice - in a 100% typesafe manner.

Summary

Frege provides many options for IDEs to support the programmer with code completion through its many usages of the dot notation. These options still wait to be exploited in most IDEs. Please cast your vote!

Dot notation is also a feature that should make it easier for OO programmers to feel at home in the purely functional world since it reads very familiar.

If "the power of the dot" is the most compelling feature that Haskell would like to borrow from OO languages, then Frege has found a nice solution to give you both, the benefits of purely functional programming and the convenience of object notation at the same time.

References

Vote IDE support

https://youtrack.jetbrains.com/issue/IDEABKL-7108

Simon Peyton Jones

https://www.youtube.com/watch?v=dI6kWwZTOKM , ff to Conclusions at the end

Marimuthu on record syntax

http://mmhelloworld.github.io/blog/2014/03/15/frege-record-accessors-and-mutators/

Frege Language Reference

http://www.frege-lang.org/doc/Language.pdf , section 3.2 "Primary Expression"

results matching ""

    No results matching ""