# Semicolons inside function declaration

**URL:** <https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970>\
**Category:** New to Julia\
**Created:** [July 23, 2023, 5:20pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970 "2023-07-23T17:20:32Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![enderw88](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/enderw88/32/48997_2.png) [@enderw88](https://discourse.julialang.org/u/enderw88)\
**Post date:** [July 23, 2023, 5:20pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/1 "2023-07-23T17:20:32Z")

</div>

I am picking up a stale package that reads a specific type of text file (IGC file if anyone out there flies gliders).

I have seen a few instances of including a semi-colon inside the function declaration, like

```julia
function read(fname::AbstractString, ::Type{IGCDocument}; parsing_mode=ParsingMode.DEFAULT, store_all_records=DEFAULT_STORE_ALL_RECORDS)
    stream = open(fname)
    return parse(IGCDocument, stream, parsing_mode=parsing_mode, store_all_records=store_all_records)
end

```

I can’t find any reason for that documented. The code base is about 4 years old. Is this an obsolete syntax?

---

<div class="post-metadata">

**Author:** ![enderw88](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/enderw88/32/48997_2.png) [@enderw88](https://discourse.julialang.org/u/enderw88)\
**Post date:** [July 23, 2023, 5:51pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/3 "2023-07-23T17:51:10Z")

</div>

I appreciate the help, I tried to separate to independent questions. One question was the “type annotation with no name”, the other was “semi colon in the function declaration”. I am seeing how the first works. Can you clue me in on the semi colon?

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [July 23, 2023, 5:51pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/4 "2023-07-23T17:51:31Z")

</div>

> [@enderw88](#):
>
> Can you clue me in on the semi colon?

This separates positional arguments from keyword arguments

---

<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:** [July 23, 2023, 5:54pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/5 "2023-07-23T17:54:02Z")

</div>

Sorry about that - I think I was biased by the previous one 🙂

@gdalle provided the answer.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [July 23, 2023, 5:54pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/6 "2023-07-23T17:54:41Z")

</div>

```julia
julia> f(a, b) = a + b
f (generic function with 1 method)

julia> g(a; b) = a + b
g (generic function with 1 method)

julia> f(1, 2)
3

julia> g(1, 2)
ERROR: MethodError: no method matching g(::Int64, ::Int64)

Closest candidates are:
  g(::Any; b)
   @ Main REPL[2]:1

Stacktrace:
 [1] top-level scope
   @ REPL[4]:1

julia> g(1; b=2)
3

```

---

<div class="post-metadata">

**Author:** ![enderw88](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/enderw88/32/48997_2.png) [@enderw88](https://discourse.julialang.org/u/enderw88)\
**Post date:** [July 23, 2023, 5:55pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/7 "2023-07-23T17:55:07Z")

</div>

@algunion I appreciate the help, the “Holy Trait” was new to me and didn’t come up in any of the searching I did.

---

<div class="post-metadata">

**Author:** ![enderw88](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/enderw88/32/48997_2.png) [@enderw88](https://discourse.julialang.org/u/enderw88)\
**Post date:** [July 23, 2023, 5:56pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/8 "2023-07-23T17:56:19Z")

</div>

@gdalle Tricky, thank you that explains something else i saw in that code base.

---

<div class="post-metadata">

**Author:** ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)\
**Post date:** [July 23, 2023, 6:02pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/9 "2023-07-23T18:02:05Z")

</div>

You can find documentation for this syntax here: [Functions · The Julia Language](https://docs.julialang.org/en/v1/manual/functions/#Keyword-Arguments)

---

<div class="post-metadata">

**Author:** ![enderw88](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/enderw88/32/48997_2.png) [@enderw88](https://discourse.julialang.org/u/enderw88)\
**Post date:** [July 23, 2023, 6:23pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/10 "2023-07-23T18:23:30Z")

</div>

@dylanxyz. Thank you.

---

<div class="post-metadata">

**Author:** ![Xing\_Shi\_Cai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xing_shi_cai/32/14128_2.png) [@Xing\_Shi\_Cai](https://discourse.julialang.org/u/Xing_Shi_Cai)\
**Post date:** [February 28, 2025, 1:52pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/11 "2025-02-28T13:52:59Z")

</div>

Is there a case when calling a function via `g(1; b=2)` and `g(1, b=2)`, i.e., using or not using semicolon in calling a function, matters?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [February 28, 2025, 2:24pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/13 "2025-02-28T14:24:31Z")

</div>

IMO the best practice is to use `;` explicitly to avoid syntactic ambiguity. Consider this:

```julia-repl
julia> sum(i for i = 1:2, init = 2)
3

julia> sum(i for i = 1:2; init = 2)
5

```

Source:

- [Expression performance when `; init = 0` used in sum · Issue #204 · jump-dev/MutableArithmetics.jl · GitHub](https://github.com/jump-dev/MutableArithmetics.jl/issues/204#issuecomment-1478878764)

---

<div class="post-metadata">

**Author:** ![apo383](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/apo383/32/11272_2.png) [@apo383](https://discourse.julialang.org/u/apo383)\
**Post date:** [February 28, 2025, 8:38pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/14 "2025-02-28T20:38:15Z")

</div>

Can you explain the difference between comma and semi-colon here? In @Xing_Shi_Cai’s question, I would expect `g(1; b=2)` to work the same either way, and the semi-colon seems mostly useful for the human reader.

But in the sum, I don’t understand how it’s parsed. If I use an empty collection the `init` seems to be treated the same both ways:

```julia
julia> sum([]; init=1)
1

julia> sum([]; init=0)
0

```

What is going on with `sum(i for i = 1:2, init = 2)`?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 28, 2025, 9:04pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/15 "2025-02-28T21:04:57Z")

</div>

The whole of `i for i = 1:2, init = 2` is parsed as a comprehension with _two_ loops. You can use a comma there if you separately ensure the comprehension doesn’t gobble it up — it’s effectively a precedence issue:

```julia-repl
julia> sum((i for i = 1:2), init = 2)
5

```

The explicit semicolons are useful to ensure that everything that follows is a kwarg, and they also solve this particular precedence problem. They’re required to separate optional args from kwargs in function definitions. And at call sites they enable the special variable-name-is-kwarg-name syntax:

```julia-repl
julia> init = 2
2

julia> sum(i for i = 1:2; init)
5

```

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [February 28, 2025, 9:09pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/16 "2025-02-28T21:09:32Z")

</div>

In addition to the above reply, it’s possible to visualize the parse tree using JuliaSyntax.jl:

```julia-repl
julia> using JuliaSyntax

julia> parsestmt(SyntaxNode, "sum(i for i = 1:2, init = 2)")
line:col│ tree │ file_name
   1:1 │[call]
   1:1 │ sum
   1:5 │ [generator]
   1:5 │ i
   1:10 │ [cartesian_iterator]
   1:10 │ [=]
   1:11 │ i
   1:14 │ [call-i]
   1:15 │ 1
   1:16 │ :
   1:17 │ 2
   1:19 │ [=]
   1:20 │ init
   1:27 │ 2

```

---

<div class="post-metadata">

**Author:** ![apo383](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/apo383/32/11272_2.png) [@apo383](https://discourse.julialang.org/u/apo383)\
**Post date:** [February 28, 2025, 9:38pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/17 "2025-02-28T21:38:08Z")

</div>

Thanks, I never would have guessed two comprehensions. I can now kind of understand it, since it is kind of like this:

```julia
julia> sum(i for i in 1:2, j in 1:2)
6

```

Part of my discomfort is that `init = 2` looks like a left assignment, just like a statement `x = 2` except it’s not. I don’t expect `init = 2` to somehow affect `i`, because who said so?

Also, this interpretation seems to be particular to `sum` and not to comprehensions in general. For example, this errors: `[i for i in 1:2; init=1]` but it’s fine in `sum`.

I find `BenchmarkTools.@btime` more sensible, with `setup = (i = 2)`. I suppose this is for macros, so I might prefer something like `@sum(i for i in 1:2; setup = (i = 2))`, which I find much clearer. Maybe the `@` is ugly but I think it helps signal that we’re only initializing (EDIT: the dummy variable) ~~`i`~~ within the comprehension but not outside, and that `setup` is merely a keyword/container for that info.

Or maybe there is a better way to think of `init = 2` so it feels more natural.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 28, 2025, 9:53pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/19 "2025-02-28T21:53:43Z")

</div>

Ehhh, that’s still pretty confused. There are three very different concepts happening here:

- You can specify multiple loops in a _single_ generator.

- The `sum` function can take an `init` keyword that is the “initializer” of your sum. t’s not affecting the `i` in your generator **_at all_**. It’s just the thing that the first element from the generator gets added to. (As an aside, it’s actually required to be an additive identity as it may get incorporated more than once with a parallel algorithm.)

- Macros can do whatever magic they want.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [February 28, 2025, 10:13pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/20 "2025-02-28T22:13:57Z")

</div>

> [@apo383](#):
>
> Part of my discomfort is that `init = 2` looks like a left assignment, just like a statement `x = 2` except it’s not.

In case it’s not clear, Julia’s syntax allows `in`, `∈` or `=` to be used interchangeably in `for` loops and generator expressions. As documented here: [Repeated Evaluation: Loops](https://docs.julialang.org/en/v1/manual/control-flow/#man-loops). I agree with you though, seeing `=` used for this purpose makes me uncomfortable, too 😆

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 1, 2025, 6:48pm UTC](https://discourse.julialang.org/t/semicolons-inside-function-declaration/101970/21 "2025-03-01T18:48:20Z")

</div>

I think this is probably disambiguated the wrong way. The parser should prefer the keyword argument interpretation here. Passing a generator with nested loops to a function is weird and if you really meant that you can either parenthesize it or use multiple `for` keywords.
