# Lock() and do-block syntax

**URL:** https://discourse.julialang.org/t/lock-and-do-block-syntax/100854
**Category:** General Usage
**Tags:** question
**Created:** [June 26, 2023, 6:12pm UTC](https://discourse.julialang.org/t/lock-and-do-block-syntax/100854 "2023-06-26T18:12:48Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)
#### Post date: [June 26, 2023, 6:12pm UTC](https://discourse.julialang.org/t/lock-and-do-block-syntax/100854/1 "2023-06-26T18:12:48Z")

</div>

I recently stumbled upon a combination of `lock` and `do` - similar to `open` and `do`.

```julia
lock(x.lock) do
        # do something unsafe here
end

```

It is unclear that the `do-block` syntax automatically calls unlock after the work inside the block is done (at least, I cannot derive that from the documentation - and it doesn’t feel right to extrapolate the open/close behavior to this). The `lock` and `unlock` matching requirement is pretty clear from the documentation.

Context: I am reading lots of code these days, and I encountered the behavior above in the [LRUCache](https://github.com/JuliaCollections/LRUCache.jl/blob/618677182498ceeaae16dcdd4f49aad29b5c4c0b/src/LRUCache.jl#L201C11-L201C11) package.

Am I missing something? Maybe some more general principle about the `do-block`?

To remove any ambiguity, can I safely use `lock` + `do-block` syntax in my code?

---

<div class="post-metadata">

### Author: ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)
#### Post date: [June 26, 2023, 6:14pm UTC](https://discourse.julialang.org/t/lock-and-do-block-syntax/100854/2 "2023-06-26T18:14:47Z")

</div>

there is nothing particularly special about `do` notation, it is simply a syntax trick to create an anonymous function and pass it as the first argument of the preceding call (for _any_ call, not just `lock`). you can read the docs for `lock(f::Function, lock)` here:

```julia
lock(f::Function, lock)

  Acquire the lock, execute f with the lock held, and release the lock when f
  returns. If the lock is already locked by a different task/thread, wait for
  it to become available.

  When this function returns, the lock has been released, so the caller should
  not attempt to unlock it.

```

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [June 26, 2023, 6:16pm UTC](https://discourse.julialang.org/t/lock-and-do-block-syntax/100854/3 "2023-06-26T18:16:43Z")

</div>

I would disagree: The `do`-syntax is quite special. It creates an anonymous function and passes it as the first argument to the preceding function.

[https://docs.julialang.org/en/v1/manual/functions/#man-anonymous-functions](https://docs.julialang.org/en/v1/manual/functions/#man-anonymous-functions)

---

<div class="post-metadata">

### Author: ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)
#### Post date: [June 26, 2023, 6:17pm UTC](https://discourse.julialang.org/t/lock-and-do-block-syntax/100854/4 "2023-06-26T18:17:16Z")

</div>

Thanks for the instant answer - you are right - I was looking at the wrong signature (I was biased - maybe because in the same codebase, it also uses lock/unlock matching when `do-block` is not used).

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [June 26, 2023, 7:14pm UTC](https://discourse.julialang.org/t/lock-and-do-block-syntax/100854/5 "2023-06-26T19:14:02Z")

</div>

> [@algunion](#):
>
> maybe because in the same codebase, it also uses lock/unlock matching when `do-block` is not used

Just to explain that, I believe manual try-finally blocks are used in that codebase when we want to return from inside that block, e.g. in [https://github.com/JuliaCollections/LRUCache.jl/blob/618677182498ceeaae16dcdd4f49aad29b5c4c0b/src/LRUCache.jl#L81-L88](https://github.com/JuliaCollections/LRUCache.jl/blob/618677182498ceeaae16dcdd4f49aad29b5c4c0b/src/LRUCache.jl#L81-L88). We can’t do that bit with the do-block form, since that would just define the return for the anonymous function, not the outer function.

Later versions of Julia have a macro form `Base.@lock` (which is exported on Julia 1.9). This is nice because it does not need to define an anonymous function (such closures can cause performance issues in some cases, xref [#15276](https://github.com/JuliaLang/julia/issues/15276)), and one can `return` from it.

---

<div class="post-metadata">

### Author: ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)
#### Post date: [June 26, 2023, 7:29pm UTC](https://discourse.julialang.org/t/lock-and-do-block-syntax/100854/6 "2023-06-26T19:29:22Z")

</div>

Thanks - I can see [here](https://github.com/JuliaCollections/LRUCache.jl/blob/618677182498ceeaae16dcdd4f49aad29b5c4c0b/src/LRUCache.jl#L91) the `return` from the anonymous function and also the dedicated `return` from the outer one.

However, this was a lame omission on my part: I wasn’t paying enough attention to the different signatures. The more frequent syntax is `f(x) do y` - however, because the anonymous function has no [argument](https://github.com/JuliaLang/julia/blob/863057689bc3444c363147a101770250b6b8977c/base/lock.jl#L226), it seems that `f(x) do` is also legitimate (I don’t think I encountered that before).

Thanks for the clarifications.
