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?

+3


source to share


1 answer


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))

      

+7


source







All Articles