receiver.myMethod(arg1);
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
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.
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.
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:
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:
Position.ticker position -- "getter"
position.ticker
And there are more options for setting or updating "fields":
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.
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
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 | |
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" |