# "\`const static\`" function parameters

**URL:** <https://discourse.julialang.org/t/const-static-function-parameters/1803>\
**Category:** General Usage\
**Created:** [January 31, 2017, 4:54pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803 "2017-01-31T16:54:10Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [January 31, 2017, 4:54pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/1 "2017-01-31T16:54:10Z")

</div>

I have a function that uses a constant parameter. The parameter never changes between function calls. For example:

```julia
function radtodeg(x)
    const PI = 3.14159
    return x * 180 / PI
end

```

Here `PI` is a constant that doesn’t change between function calls. Moreover, it is only used by the function (`PI` is a bad example in this regard), so it makes no sense to declare it as a global constant. Also, it makes no sense to have the caller pass the constant variable pre-allocated, because this is a parameter that only makes sense internally in the function.

A more complicated example could use a constant array instead of just a number. I don’t want to have to reallocate this variable every time the function is called.

In C++, you could mark such constant parameters as `const static`. I understand that a proposal for static variables was rejected:

[https://github.com/JuliaLang/julia/issues/12627](https://github.com/JuliaLang/julia/issues/12627)

So what is the proper way to deal with this scenario? Or maybe Julia’s compiler is smart enough to detect this condition, and allocates `PI` only once?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [January 31, 2017, 5:20pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/2 "2017-01-31T17:20:28Z")

</div>

I think Jameson’s suggestion from the end of the thread you linked should just work in your case:

```julia
let 
   const a = pi
   global f
   function f(x)
       x + a
   end
end

```

The `let` block ensures that the constant `a` doesn’t show up at global scope, and the `global f` ensures that the function `f` _does_ show up at global scope.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [January 31, 2017, 5:22pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/3 "2017-01-31T17:22:30Z")

</div>

I saw that. I just think it is too convoluted. Specially compared to just saying `const static` as in C++.  
I was wondering if there was a better and also more readable way.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 31, 2017, 5:35pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/4 "2017-01-31T17:35:20Z")

</div>

> [@rdeits](#):
>
> const a = pi

Also, no const. \<20 chars…\>

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [January 31, 2017, 8:45pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/5 "2017-01-31T20:45:02Z")

</div>

If verbosity is a problem, you can go back to the good ol’ eval at compile time trick, which comes with its own set of restrictions:

```nohighlight
macro static_var(x)
    anon = gensym()
    fun = eval(Main, :(const $anon = $x))
    :(Main.$anon)
end
function test()
    secret = @static_var begin
        println("Var, so static right now")
        "i did it!"
    end
    secret
end
>Var, so static right now # println at definition time

test() # no println no more
> i did it

julia> @code_warntype test()
Variables:
  #self#::#test
  secret::String

Body:
  begin
      secret::String = Main.##270 # line 6:
      return secret::String
  end::String

```

You could come up with quite a variety of macros to do similar things depending on your taste and goals.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [February 7, 2017, 8:54pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/6 "2017-02-07T20:54:40Z")

</div>

@sdanisch This only works with compile-time constants, right? What if my static variable is run-time constant (meaning that the value is set once and for all at run time, but may change between runs)?

Maybe that use-case is too weird and need not be considered…

---

<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:** [February 8, 2017, 7:29pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/7 "2017-02-08T19:29:06Z")

</div>

I don’t think that feature request was rejected so much as deemed “not important enough to work on now”. There are ways of getting what you need and a static variable feature could be added in the future. Using a global constant here seems fine to me since a static variable is just a global constant whose name is only visible to one function.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [February 13, 2017, 2:48pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/8 "2017-02-13T14:48:53Z")

</div>

@StefanKarpinski It would be nice if the variable was visible only inside the function. It would not pollute global scope.

---

<div class="post-metadata">

**Author:** ![jtravs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jtravs/32/2010_2.png) [@jtravs](https://discourse.julialang.org/u/jtravs)\
**Post date:** [February 13, 2017, 3:47pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/9 "2017-02-13T15:47:17Z")

</div>

Can you explain what the problem with just using

```julia
PI = 3.14159

```

is?

AFAIK there are no performance gains to a `const` inside a function in Julia and this will be optimized. What is the problem you are trying to solve?

For example for the code above:

```julia
function radtodeg2=(x)
       PI = 3.14159
       return x * 180 / PI
end

```

Then `code_llvm` returns

```julia
define double @julia_radtodeg_71699(double) #0 { 
top:                                              
  %1 = fmul double %0, 1.800000e+02               
  %2 = fdiv double %1, 3.141590e+00               
  ret double %2                                   
} 

```

i.e the constant is inline.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [February 13, 2017, 4:49pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/10 "2017-02-13T16:49:21Z")

</div>

@jtravs I’m thinking of a constant that takes more space, like an array of coefficients. I don’t think that can be inlined, and I want to make sure it is allocated only once.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 13, 2017, 5:08pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/11 "2017-02-13T17:08:38Z")

</div>

If it’s an array of constants, can’t you write it without the array? Maybe a macro would make it nicer, and then you could use `a1` instead of `a[1]` etc., and it would all inline at compilation.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [February 13, 2017, 5:15pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/12 "2017-02-13T17:15:04Z")

</div>

Sometimes you just want to put a fat array inside a function. The macro posted above is a bit of a hack but it does the job.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [February 13, 2017, 5:19pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/13 "2017-02-13T17:19:14Z")

</div>

@ChrisRackauckas What if it is a constant matrix? You don’t want to expand it into components `a1, ...` because you want to exploit matrix multiplication.

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [February 13, 2017, 5:25pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/14 "2017-02-13T17:25:59Z")

</div>

> [@sdanisch](#):
>
> If verbosity is a problem, you can go back to the good ol’ eval at compile time trick, which comes with its own set of restrictions

FWIW, you can boil this down to:

```julia
macro static(ex)
  eval(ex)
end

```

🙂 (though you might strictly need a quotenode or something if `ex` could be an expression)

> [@e3c6](#):
>
> What if my static variable is run-time constant (meaning that the value is set once and for all at run time, but may change between runs)?

It is indeed pretty weird to want to do this, but just for fun:

```julia
using MacroTools

macro static(ex)
  @capture(ex, name_::T_ = val_) || error("invalid @static")
  ref = Ref{eval(T)}()
  set = Ref(false)
  :($(esc(name)) = if $set[]
      $ref[]
    else
      $ref[] = $(esc(ex))
      $set[] = true
      $ref[]
    end)
end

function test(n)
  @static pi::Float64 = 2n
  return pi
end

test(6) # 12.0
test(3) # also 12.0

```

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [February 13, 2017, 5:33pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/15 "2017-02-13T17:33:09Z")

</div>

@MikeInnes I propose that something like this be included in `Base`. Don’t you think?

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [February 13, 2017, 5:35pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/16 "2017-02-13T17:35:58Z")

</div>

@MikeInnes Why is the llvm code so messy?

```julia
@code_llvm test(6)

```

> define double @julia\_test\_71387(i64) #0 {  
> top:  
> %1 = load i8, i8\* inttoptr (i64 139707517794576 to i8\*), align 16  
> %2 = and i8 %1, 1  
> %3 = icmp eq i8 %2, 0  
> br i1 %3, label %L, label %L1

> L: ; preds = %top  
> %4 = shl i64 %0, 1  
> %5 = sitofp i64 %4 to double  
> store double %5, double\* inttoptr (i64 139707517794560 to double\*), align 256  
> store i8 1, i8\* inttoptr (i64 139707517794576 to i8\*), align 16  
> br label %L1

> L1: ; preds = %top, %L  
> %“#temp#.sroa.0.02” = load double, double\* inttoptr (i64 139707517794560 to double\*), align 256  
> ret double %“#temp#.sroa.0.02”  
> }

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [February 13, 2017, 5:42pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/17 "2017-02-13T17:42:14Z")

</div>

I suspect it’s not widely useful enough to have in base; but the good news is that if it doesn’t require language support, there’s no real downside to having it in a package.

The LLVM code isn’t going to be as clean as the “really static” version because you have to do pointer lookups and branches to initially set the variable. Such is the cost of being dynamic, I’m afraid.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 13, 2017, 9:32pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/18 "2017-02-13T21:32:15Z")

</div>

> [@e3c6](#):
>
> What if it is a constant matrix? You don’t want to expand it into components a1, … because you want to exploit matrix multiplication.

Depends on how big it is. It may be a good idea to skip BLAS if the constant matrix is small enough. But yes, the right approach all depends on the problem, which I do not know. I was just suggesting other approaches.

Another way you might want to handle this without polluting any good names in the global namespace is to use a more specific global name, and alias it in the function. Like

```julia
const GLOBAL_PI = ...

```

and then in the function, just

```julia
pi = GLOBAL_PI

```

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [November 9, 2017, 12:40pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/19 "2017-11-09T12:40:41Z")

</div>

> [@MikeInnes](#):
>
> It is indeed pretty weird to want to do this …

I dont think it’s weird. This is how local `static` variables work in C. I think it would also reduce a lot of the use cases for global variables. IMHO, static local vars would be better than globals.

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [November 9, 2017, 2:40pm UTC](https://discourse.julialang.org/t/const-static-function-parameters/1803/20 "2017-11-09T14:40:45Z")

</div>

> [@MikeInnes](#):
>
> using MacroTools
> 
> macro static(ex)  
> @capture(ex, name\_::T\_ = val\_) || error(“invalid @static”)  
> ref = Ref{eval(T)}()  
> set = Ref(false)  
> :($(esc(name)) = if $set  
> $ref  
> else  
> ref[] = (esc(ex))  
> $set = true  
> $ref  
> end)  
> end
> 
> function test(n)  
> @static pi::Float64 = 2n  
> return pi  
> end

This reminds me of a situation I encounted the other day in which some kind of global variable would be convenient. I had an array of objects that needed a common variable. In some languages, its possible to do something like this:

```julia
mutable myStruct
    global x::Int
    y::Int
end

M = [myStruct() for i in 1:100]

myStruct.x = 1

```

The field x would be the same across all elements in M and could be updated simultaneously. The field y, on the other hand, could be unique for each element in M. Is it possible to achieve this with a variation of your code (it does not appear to work as is)?

[Next page](https://discourse.julialang.org/t/const-static-function-parameters/1803.md?page=2)
