F # packing statements in the do block
I have a question regarding the conventions for using do blocks in F #. This primarily occurs when working with .NET library classes and other .NET code.
Let me give you an example.
1.With a do block wrapped around statements:
let drawHelloName (width:int, height:int) name =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
use gr = Graphics.FromImage(bmp)
do
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
bmp
2. Without the do block:
let drawHelloName (width:int, height:int) name =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
use gr = Graphics.FromImage(bmp)
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
bmp
Now, in my opinion, I think example 1 is clearer and more in line with the point and style of F #. Since it's not really "natural" to work with statements in functional programming, we explicitly wrap statements in the do block to show that they are side effects. But I'm wondering what is a convention?
source to share
Since it is not entirely "natural" to work with statements in functional programming, we explicitly wrap statements in the do block to show that they are side effects.
I agree with you. However, if you look at F # code in the wild, they are generally free on the subject. There is no strict agreement, just follow what you think is right for you.
Another point is that blocks block the creation of new ranges for values ββthat we would like to explicitly control their lifetime. For example, if you want to use earlier gr
and continue to use fnt
, your first function could be written to:
let drawHelloName (width:int, height:int) name =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
do
use gr = Graphics.FromImage(bmp)
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
(* Continue to do something with 'fnt' *)
bmp
Another place where you should use blocks do
is inside implicit constructors, for example.
type T(width, height) =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
use gr = Graphics.FromImage(bmp)
do
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
source to share