<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: rustyoctopus</title>
    <description>The latest articles on DEV Community by rustyoctopus (@rustyoctopus).</description>
    <link>https://dev.to/rustyoctopus</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F419049%2Ff551af35-3871-4a41-90fd-8aed3bc3060d.jpg</url>
      <title>DEV Community: rustyoctopus</title>
      <link>https://dev.to/rustyoctopus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rustyoctopus"/>
    <language>en</language>
    <item>
      <title>Generating static arrays during compile time in Rust</title>
      <dc:creator>rustyoctopus</dc:creator>
      <pubDate>Tue, 01 Sep 2020 20:20:50 +0000</pubDate>
      <link>https://dev.to/rustyoctopus/generating-static-arrays-during-compile-time-in-rust-10d8</link>
      <guid>https://dev.to/rustyoctopus/generating-static-arrays-during-compile-time-in-rust-10d8</guid>
      <description>&lt;h1&gt;
  
  
  Generate static arrays during build time
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Update 2022-09-27
&lt;/h2&gt;

&lt;p&gt;It's more than two years since I've published this article and Rust and its ecosystem has improved a lot. Unfortunately I will not update or correct this article in the near to mid future, maybe never. However I believe that most of the things I wrote are still correct. However due to the improvements in Rust and its ecosystems, some of the limitations I identified two years ago have improved as well. The following items have caught my attention in the last two years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A lot more &lt;code&gt;const fn&lt;/code&gt; in the standard and core library. This could improve the &lt;code&gt;const fn&lt;/code&gt; option.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;[env]&lt;/code&gt; attribute that can be defined in &lt;code&gt;Cargo.toml&lt;/code&gt;, find more information about this &lt;a href="https://doc.rust-lang.org/cargo/reference/config.html?highlight=%5Benv%5D#env" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This could improve the &lt;code&gt;build.rs&lt;/code&gt; solution if the necessary environment variables could be fixed (if fixable) in a downstream dependency of the crate that requires these environment variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I haven't checked these options in more detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Memory usage and management is crucial in embedded systems software. Dynamic memory is often not available or avoided to reduce the risk of runtime errors (e.g. out-of-memory errors). Therefore the to-be-used memory is often defined and allocated during compile time. For example, one could define and allocate a buffer used to temporarily store a received message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;MESSAGE_BUFFER&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Such a buffer would be reserved in volatile memory, in order to be modifiable during runtime (in the end it is mutable).&lt;br&gt;
Data that is constant during runtime can be defined as &lt;code&gt;const&lt;/code&gt; (when its small) or &lt;code&gt;static&lt;/code&gt; (when its larger) in Rust. This gives the compiler the opportunity to reserve space for this data at a specific memory location, see the &lt;a href="https://doc.rust-lang.org/reference/items/static-items.html" rel="noopener noreferrer"&gt;Rust language reference, chapter 6.10, Static Items&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A static item is similar to a constant, except that it represents a precise memory location in the program.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each constant is usually inlined by the compiler according to the &lt;a href="https://doc.rust-lang.org/reference/items/constant-items.html" rel="noopener noreferrer"&gt;Rust language reference, chapter 6.9, Constant Items&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Constants are essentially inlined wherever they are used, meaning that they are copied directly into the relevant context when used&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means, when a large array is needed as constant, it makes sense to define it as &lt;code&gt;static&lt;/code&gt; instead of &lt;code&gt;const&lt;/code&gt;. For example,&lt;br&gt;
you don't want to inline a byte array with 64000 bytes each and anytime you use it in your source code. This would unnecessary bloat your binary code.&lt;/p&gt;

&lt;p&gt;Oftentimes embedded software, that requires non-trivial but constant data during runtime, this data is generated as source code and compiled together with rest of the source code. For this, more or less sophisticated tools are used to define the code and generate it. This is, for certain use cases, unavoidable. For example if the data required is to be define by the user of the software to fulfill a project-specific use case. However, what if the data can be generated during compile, since there is an algorithm to do this that requires little input by the user?&lt;/p&gt;

&lt;p&gt;For my use case (described below), I did explore this idea: Generate an array (potentially thousands of &lt;code&gt;f64&lt;/code&gt;) during compile time with the size of the array as a constant literal input (by this, I mean something like &lt;code&gt;1206&lt;/code&gt; in your source code).&lt;br&gt;
However, I want to hide this generation step as much as possible for the users of a potential library, for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The array I generate is only used internally, users do not need to know this, nor should they be bothered to generate the array themselves (however, the runtime impact, this means the static memory size used, should be communicated openly)&lt;/li&gt;
&lt;li&gt;I want an interface, so that a user can configure a cargo feature in order to decide which specific implementation they want, without changing their source code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this a tried to solve my problem by exploring four different options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constant functions and constant generics&lt;/li&gt;
&lt;li&gt;Macro rules macros&lt;/li&gt;
&lt;li&gt;Build scripts&lt;/li&gt;
&lt;li&gt;Procedural macros&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article will shortly introduce and skim-through these options to identify if they can solve my specific problem, their advantages and disadvantages from my point of view. All of these options are much more complex as I can describe them in this already long article, but I added as much references for more in-depth introduction as I did find.&lt;/p&gt;

&lt;p&gt;Short disclaimer about the source code that is in this article: It usually lacks proper error handling (yeah, I know) and is more often than not un-idiomatic Rust (sorry). The source code is intended to explain the specific solution but is not written perfectly. Do not copy and paste it for your projects. I do appreciate everyone who can point me to a better, more idiomatic solution.&lt;/p&gt;
&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Constant functions &amp;amp; constant generics (with Rust 1.46), procedural macros (ideally with 1.45) and build scripts do work but all have drawbacks. Macro rules macros may work but are complex.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The use case
&lt;/h2&gt;

&lt;p&gt;I'll be honest with you, my use case is not a traditional embedded use case. It is rather a challenge for myself to solve a problem with &lt;code&gt;#[no_std]&lt;/code&gt; that perfectly can be solved using dynamic memory. So the idea is: I want to generate so called quasi-random numbers. The name is misleading, since quasi-random numbers have a clear structure and are not really random. That's why they are more correctly termed as &lt;a href="https://en.wikipedia.org/wiki/Low-discrepancy_sequence" rel="noopener noreferrer"&gt;low discrepancy sequences&lt;/a&gt;.&lt;br&gt;
But what's the difference between pseudo random numbers and a quasi random numbers? (As an aside: a &lt;a href="https://en.wikipedia.org/wiki/Pseudorandom_number_generator" rel="noopener noreferrer"&gt;pseudo random number generator&lt;/a&gt; generates random numbers with an algorithm this means deterministically. Hence the name &lt;em&gt;pseudo&lt;/em&gt;.)&lt;br&gt;
See below pseudo random numbers (as 2D points) generated with the &lt;a href="https://crates.io/crates/randomize" rel="noopener noreferrer"&gt;&lt;code&gt;randomize&lt;/code&gt;crate&lt;/a&gt; and plotted with the &lt;a href="https://crates.io/crates/plotlib" rel="noopener noreferrer"&gt;&lt;code&gt;plotlib&lt;/code&gt; crate&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmaj1y153u78j8zdzsu5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmaj1y153u78j8zdzsu5l.png" title="Pseudo random numbers" alt="Pseudo random numbers" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the points seem to distributed pretty randomly. They are clustered at certain spots while other areas in the plot are rather empty.&lt;/p&gt;

&lt;p&gt;Below a plot of a quasi-random sequence:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw60ysuk4i4kqcmb6bmns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw60ysuk4i4kqcmb6bmns.png" title="Quasi random numbers" alt="Quasi random numbers" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The points are pretty evenly distributed in the complete area. There are no clusters. There seems to be a real structure. I would not call this random at all. The quasi random numbers were generated by my own crate, which I hopefully will publish in the future. Plotted again with the &lt;a href="https://crates.io/crates/plotlib" rel="noopener noreferrer"&gt;&lt;code&gt;plotlib&lt;/code&gt; crate&lt;/a&gt; crate. The sequence that was generated was the R2 sequence which is brilliantly introduced in this article:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/" rel="noopener noreferrer"&gt;The Unreasonable Effectiveness of Quasi random Sequences&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So for what is this useful? For example for &lt;a href="https://en.wikipedia.org/wiki/Monte_Carlo_method" rel="noopener noreferrer"&gt;Monte Carlo Simulations&lt;/a&gt;. This is a numerical integration technique which uses random numbers. For some integrations, especially in multi-dimensions, it is beneficial to use quasi random numbers over pseudo random numbers since then the Monte Carlo simulation converges faster or simplified said, you need less program runtime to get your result. There are obviously bounds that prove this mathematically (see &lt;a href="https://en.wikipedia.org/wiki/Quasi-Monte_Carlo_method" rel="noopener noreferrer"&gt;Quasi Monte Carlo method&lt;/a&gt; as a starter) but there is also my layman's explanation: When you want to integrate a function in a space, you want to sample the space as uniformly as possible to evaluate your function in every part of the space evenly. With clusters you may shift the average value of your function evaluations towards these clusters, hence your average value is somehow "biassed" towards these &lt;em&gt;random&lt;/em&gt; clusters. This can be overcome by using more samples so that clusters lose their importance. Or you use a random sequence that is so non-random that it fills the space up more evenly: quasi random numbers.&lt;/p&gt;

&lt;p&gt;What does this have to do with generating static arrays? There are two sequences I am focusing on at the moment. The Rd sequence, which is a generalization of the R2 sequence mentioned above, but with &lt;code&gt;d&lt;/code&gt; dimensions. And the &lt;a href="https://en.wikipedia.org/wiki/Sobol_sequence" rel="noopener noreferrer"&gt;Sobol sequence&lt;/a&gt;. Both have in common, that the sequence is constructed by one or more constants per dimension. For the Rd sequence, there is one &lt;code&gt;f64&lt;/code&gt; value per dimension (can be &lt;code&gt;u64&lt;/code&gt; as well, as an aside). These can be called alphas or alpha values. For Sobol there are 32 &lt;code&gt;u32&lt;/code&gt; per dimension which are called direction numbers. As mentioned above, these numbers are constant and can be arranged into an array (at least it makes sense to do so). Since I want to implement this &lt;code&gt;#[no_std]&lt;/code&gt; I cannot allocate these during runtime without providing an allocator. Therefore it makes sense to generate this array during compile time since usually the dimension is constant as well.&lt;br&gt;
If the dimension is large (&amp;gt;1000) these arrays should be &lt;code&gt;static&lt;/code&gt; as I mentioned above.&lt;br&gt;
Additionally I want to put both sequences behind one interface (i.e. a trait):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the user of my library can choose the sequence with by selecting a &lt;a href="https://doc.rust-lang.org/cargo/reference/features.html" rel="noopener noreferrer"&gt;cargo feature&lt;/a&gt; (either "rd" or "sobol") and the dimension at compile time and gets the sequence without needing to know too much implementation details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// defined and implemented in my crate&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// usage&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;qrand_core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means, if there is a need to change the sequence (e.g. from Rd to Sobol), then the source code needs not to be changed: the implementation details of the sequence is hidden from the user. This is my perfect world. However there are these aforementioned arrays and they differ significantly between these two sequences. Therefore I want to hide them as much as possible from the user as possible. This may not be necessary, however I find this problem interesting and so I went out to try to solve it.&lt;/p&gt;

&lt;p&gt;Before I go through the options I evaluated I want to shortly introduce what needs to be calculated on compile time.&lt;/p&gt;

&lt;p&gt;For the Rd low discrepancy sequence, we need alpha values, one for each dimension we plan to use. This means, we hold an array that contains these alpha values. Each of the alpha value is calculated from one start value, called phi. This phi is specific for a dimension and can be calculated as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_phi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// power is always 1 / (dimension + 1)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.recip&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
       &lt;span class="c1"&gt;// phi is approximated, I loop 25 times to get a reasonable approximation on my machine&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="nf"&gt;.powf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;phi&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this article it is not so much important what and how this is calculated but it is important that I need a loop to calculate phi (see the aforementioned article &lt;a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/" rel="noopener noreferrer"&gt;The Unreasonable Effectiveness of Quasi random Sequences&lt;/a&gt; and its references for more details on why and how to calculate phi).&lt;/p&gt;

&lt;p&gt;The alphas can then be calculated like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;alphas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_capacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculate_phi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;inv_g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="nf"&gt;.recip&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;alphas&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inv_g&lt;/span&gt;&lt;span class="nf"&gt;.powf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.fract&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;alphas&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, it is not that much important how, but that I need to loop through the dimensions. I use a vector here since it is not possible to return an array with the size given as a parameter. For example the following code does not compile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// does not compile&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get error &lt;a href="https://doc.rust-lang.org/error-index.html#E0435" rel="noopener noreferrer"&gt;E0435&lt;/a&gt; saying that you tried to use a non-constant value in a constant. There is a way to do this, which will be explained in the constant function section below.&lt;/p&gt;

&lt;p&gt;I do not present how the direction numbers for the Sobol Sequence, since it would be worth an own article. I may write this article, but for the moment, the alphas of the Rd sequence suffice to explain the use case.&lt;/p&gt;

&lt;p&gt;Finally, as I mentioned above, there are two reasons, why this is not a good embedded use case. The first reason is, that for large dimensions a large amount of (constant) memory is required. For example, if we use the Rd sequence for 1000 dimension we need 8000 bytes of memory for the array. For the Sobol sequence this is 64000 bytes. Although it is part of the program memory, since compiled into the binary, it still makes a huge binary, at least for embedded systems. The other reason is even more important: I don't have a good use case for quasi random numbers (or Monte-Carlo simulation) required in an embedded device (maybe someone can add some in the comments). Still, as mentioned above, I did like the challenge to solve this problem with &lt;code&gt;#[no_std]&lt;/code&gt; and did learn a lot trying it. And my idea was to share some of the key points I learned with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1: constant functions
&lt;/h2&gt;

&lt;p&gt;Using constant evaluations looks like a promising idea for my use case of generating large, static arrays during compile time. But there are several problems. I will get into these step-by-step. However, before I do so, I will shortly introduce constant evaluations and constant functions.&lt;/p&gt;

&lt;p&gt;A constant evaluation is ...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;... the process of computing the result of expressions during compilation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(see &lt;a href="https://doc.rust-lang.org/reference/const_eval.html" rel="noopener noreferrer"&gt;The Rust Reference - Constant evaluation&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This means, a result is computed during compilation. This can be a simple expression or the initialization of a constant value, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But also the execution of constant functions. The relevant part I am interested in, is stated at &lt;a href="https://doc.rust-lang.org/reference/items/functions.html#const-functions" rel="noopener noreferrer"&gt;The Rust Reference - Functions - Const Functions&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When called from a const context, the function is interpreted by the compiler at compile time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A simple example of a constant function could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;divide_by_two&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CONSTANT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;divide_by_two&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice to know as well: A const function can also be called outside of a constant context. But this also means, the constant function will be part of your final binary.&lt;/p&gt;

&lt;p&gt;But there a limitations what a constant function can do, in the &lt;a href="https://doc.rust-lang.org/reference/items/functions.html#const-functions" rel="noopener noreferrer"&gt;The Rust Reference - Functions - Const Functions&lt;/a&gt; there is a list of permitted structures in const functions, which is even more restrictive than what you can do in regular constants. And this was one of the reasons why constant functions did not solve my problem, at least until Rust 1.46. With Rust 1.46, constant functions were improved, by adding, beyond other improvements, the possibility to use &lt;code&gt;while&lt;/code&gt; and &lt;code&gt;loop&lt;/code&gt; loops (see &lt;a href="https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#const-fn-improvements" rel="noopener noreferrer"&gt;The Rust Blog - Announcing Rust 1.46.0 - &lt;code&gt;const fn&lt;/code&gt; improvements&lt;/a&gt;). Unfortunately &lt;code&gt;for&lt;/code&gt; loops are not supported.&lt;/p&gt;

&lt;p&gt;However &lt;code&gt;while&lt;/code&gt; and &lt;code&gt;loop&lt;/code&gt; are already pretty powerful so that the following code does work with 1.46:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// constant functions is an unstable feature, I needs to be activated to use it&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(const_fn)]&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;sum&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I want to point out, that I need to enable constant functions as feature, otherwise it won't compile. That is why I added the &lt;code&gt;#![feature(const_fn)]&lt;/code&gt; and will do so for every constant function I present.&lt;/p&gt;

&lt;p&gt;I presented above code that calculated phi using a &lt;code&gt;for&lt;/code&gt; loop, As mentioned above, this code does not compile if defined as &lt;code&gt;const&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// constant functions is an unstable feature, I needs to be activated to use it&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(const_fn)]&lt;/span&gt;

&lt;span class="c1"&gt;// does not compile&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_phi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// power is always 1 / (dimension + 1)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.recip&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
       &lt;span class="c1"&gt;// phi is approximated, I loop 25 times to get a reasonable approximation on my machine&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="nf"&gt;.powf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;phi&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust compiler rejects this code with error &lt;a href="https://doc.rust-lang.org/error-index.html#E0744" rel="noopener noreferrer"&gt;E0744&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error[E0744]: &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; is not allowed &lt;span class="k"&gt;in &lt;/span&gt;a &lt;span class="sb"&gt;`&lt;/span&gt;const fn&lt;span class="sb"&gt;`&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; const_rd_alphas/src/lib.rs:7:5
   |
   | /     &lt;span class="k"&gt;for &lt;/span&gt;_ &lt;span class="k"&gt;in &lt;/span&gt;0..25 &lt;span class="o"&gt;{&lt;/span&gt;
   | |         phi +&lt;span class="o"&gt;=&lt;/span&gt; 1.0&lt;span class="p"&gt;;&lt;/span&gt;
   | |         phi &lt;span class="o"&gt;=&lt;/span&gt; phi.powf&lt;span class="o"&gt;(&lt;/span&gt;power&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   | |     &lt;span class="o"&gt;}&lt;/span&gt;
   | |_____^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, instead of using a &lt;code&gt;for&lt;/code&gt; loop, I can now use a &lt;code&gt;while&lt;/code&gt; loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// constant functions is an unstable feature, I needs to be activated to use it&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(const_fn)]&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_phi_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// power is always 1 / (dimension + 1)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.recip&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// phi is approximated, I loop 25 times to get a reasonable approximation on my machine&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="nf"&gt;.powf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;phi&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But here I get several &lt;a href="https://doc.rust-lang.org/error-index.html#E0015" rel="noopener noreferrer"&gt;E0015&lt;/a&gt; errors, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error[E0015]: calls &lt;span class="k"&gt;in &lt;/span&gt;constant functions are limited to constant functions, tuple structs and tuple variants
  &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; const_rd_alphas/src/lib.rs:42:15
   |
42 |         phi &lt;span class="o"&gt;=&lt;/span&gt; phi.powf&lt;span class="o"&gt;(&lt;/span&gt;power&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   |               ^^^^^^^^^^^^^^^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which means I can only call other constant functions from a constant function, which makes totally sense. If you want to use constant function &lt;code&gt;a&lt;/code&gt; in a constant context and this function uses function &lt;code&gt;b&lt;/code&gt; then &lt;code&gt;b&lt;/code&gt; must also be constant. However, this means I need to implement all the non-constant standard library functions I need to use. This would be the functions &lt;code&gt;powf&lt;/code&gt; and &lt;code&gt;recip&lt;/code&gt; for floating point values (&lt;code&gt;f64&lt;/code&gt;). And instead of using &lt;code&gt;f64::from&lt;/code&gt; I can cast with the &lt;code&gt;as&lt;/code&gt; keyword. Then the &lt;code&gt;calculate_phi&lt;/code&gt; code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// constant functions is an unstable feature, I needs to be activated to use it&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(const_fn)]&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_phi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// power is always 1 / (dimension + 1)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recip&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// phi is approximated, I loop 25 times to get a reasonable approximation on my machine&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;powf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;phi&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But let's pause for one moment: &lt;code&gt;recip&lt;/code&gt; is trivial to implement (it's basically &lt;code&gt;f(x)=1/x&lt;/code&gt; but I guess it makes sense to implement it carefully, robust and efficient). But it is a different story for &lt;code&gt;powf&lt;/code&gt;: This is not that trivial since you need to implement &lt;code&gt;f(x,y)=x^y&lt;/code&gt; with y being a floating point number (it is easier with an unsigned integer exponent, though). If I want to implement this in software, I need approximate the value numerically and this needs to be well enough. It is possible to do so (maybe even worth another article how to do it) but I did not do it for this article since it is not important for this article how this is done, but that I would have to do it, if I want to use constant functions for my use case. I find that the necessity to implement these functions is inconvenient at best, although I assume that more and more functions of the standard library will be implemented as &lt;code&gt;const&lt;/code&gt; so this should be a temporary temporary issue.&lt;/p&gt;

&lt;p&gt;But let's go on with constant functions and assume, my &lt;code&gt;calculate_phi&lt;/code&gt; and all the other functions are correctly implement as constant functions. I still need to create an array instead of a vector (as I did above). For this I need to use the &lt;a href="https://github.com/rust-lang/rust/issues/44580" rel="noopener noreferrer"&gt;constant generic feature&lt;/a&gt;. Constant generics are a way to define a generic parameter that is constant and has a "trait bound". For example, the &lt;code&gt;create_array&lt;/code&gt; method mentioned above can be defined like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![feature(const_fn)]&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(const_generics)]&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;create_array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, constant generics are not only an unstable feature but it is incomplete. This means you need the &lt;code&gt;nightly&lt;/code&gt; compiler. So you need to install the &lt;em&gt;nightly&lt;/em&gt; compiler with &lt;code&gt;rustup&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup &lt;span class="nb"&gt;install &lt;/span&gt;nightly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And build with &lt;code&gt;+nightly&lt;/code&gt; flag using cargo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo +nightly build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(There are more options to use the nightly compiler, I just presented my favorite.)&lt;/p&gt;

&lt;p&gt;Back to creating the alphas. The code for this could look like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![feature(const_fn)]&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(const_generics)]&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;create_alphas&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculate_phi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;inv_g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;powu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inv_g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;array&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also added a &lt;code&gt;powu&lt;/code&gt; function, a power function with unsigned exponent (which is a lot easier then &lt;code&gt;powf&lt;/code&gt;) and also a &lt;code&gt;fract&lt;/code&gt; implementation, which returns the fractional part of a floating point number.&lt;br&gt;
THis means I can finally implement my &lt;code&gt;create_sequence&lt;/code&gt; function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![feature(const_fn)]&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(const_generics)]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;const_rd_alphas&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;low_discrepancy_sequence&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;create_sequence&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not so fast, there are two more problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Constant functions cannot refer to static parameters&lt;/li&gt;
&lt;li&gt;Usage of the outer constant generic parameter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is not allowed to refer to a static from a constant function. This is compile error &lt;a href="https://doc.rust-lang.org/error-index.html#E0013" rel="noopener noreferrer"&gt;E0013&lt;/a&gt;. We can change it to a constant instead of a static, but remember, constant may be inlined (as I already mentioned above). This means if the constant is used at several locations, it may be copied at each of these positions and then be may lead to code bloat.&lt;/p&gt;

&lt;p&gt;As to the second problem: I cannot use the &lt;code&gt;DIM&lt;/code&gt; constant generic from my &lt;code&gt;create_sequence&lt;/code&gt; function in the &lt;code&gt;create_alphas&lt;/code&gt; function. This means I use the generic parameter from my outer function (here &lt;code&gt;create_sequence&lt;/code&gt;) in my inner function (here &lt;code&gt;create_alphas&lt;/code&gt;) which is not allowed. This is error &lt;a href="https://doc.rust-lang.org/error-index.html#E0401" rel="noopener noreferrer"&gt;E0401&lt;/a&gt;.&lt;br&gt;
I could split up the creation of the alphas and the creation of the sequence into two methods. But then I am not hiding the implementation details anymore, and switching from Rd to Sobol sequence would at least mean changing the internal data types from &lt;code&gt;f64&lt;/code&gt; to &lt;code&gt;u32&lt;/code&gt;. And users of my library need to call two methods in the right order to generate the quasi random numbers. This means the code could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// qrand_core/src/lib.rs&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;create_sequence_data&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;DIM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="cm"&gt;/* would be an u32 array in case of Sobol */&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// user_application/src/main.rs&lt;/span&gt;
&lt;span class="c1"&gt;// usage&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;sequence_data&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_sequence_data&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sequence_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, I can hide this behind a &lt;code&gt;macro_rules&lt;/code&gt; macro (below is more information on how to do this). In some of the other options, it is also required to call two functions in correct order (and hiding this detail in a &lt;code&gt;macro_rules&lt;/code&gt; macro). But it solves the first problem (referring to a static in a constant function, &lt;a href="https://doc.rust-lang.org/error-index.html#E0013" rel="noopener noreferrer"&gt;E0013&lt;/a&gt;). And it also means that using constant functions and constant generics do work to generate large arrays during compile time, with some "small print".&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion using constant functions
&lt;/h3&gt;

&lt;p&gt;Using constant functions and constant generics enable creating large arrays during compile time. However there are some drawbacks: All non &lt;code&gt;const&lt;/code&gt; functions I use from the standard library need to be implemented by either myself or I wait for the standard library to support them as constant functions. Implementing these functions myself may be challenging and error-prone in some cases (that's why I am usually pretty happy, for the functions already implemented in the standard library). Another drawback is using the nightly compiler to enable constant generics. No showstopper but I like to stick on stable and I guess it makes sense especially for embedded use cases. The last drawback I see, is that constant functions are part of the final binary, since they can be used during runtime and not only during compile time. This results in a larger binary which can be critical for an embedded use case. Especially if I already generate large arrays into the binary. Finally I still leak some implementation detail, since a user must call &lt;code&gt;create_sequence_data&lt;/code&gt; and then &lt;code&gt;create_sequence&lt;/code&gt; before using the sequence. This can be hidden in a &lt;code&gt;macro_rules&lt;/code&gt; macro (see below) but still is not ideal, from my point of view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: &lt;code&gt;macro_rules&lt;/code&gt; macros
&lt;/h2&gt;

&lt;p&gt;Another option I looked into are macro_rules macros. These macros match expressions and expand to code during runtime. The below example can be used to hide the necessity of calling the two functions above (&lt;code&gt;create_sequence_data&lt;/code&gt; &amp;amp; &lt;code&gt;create_sequence&lt;/code&gt;) in correct order by packing them into such a macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[macro_export]&lt;/span&gt;
&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;create_seq&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$dimension:expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;constant_function&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_sequence_data&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$dimension&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;create_sequence_data&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;$dimension&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;sequence&lt;/span&gt;
    &lt;span class="p"&gt;}};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The macro is called &lt;code&gt;create_seq&lt;/code&gt; and works like a function like macro. It can be called like a function but an exclamation mark &lt;code&gt;!&lt;/code&gt; must be added to its name. Here is an example usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;create_seq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="nf"&gt;.element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As "argument" one can give an expression to the &lt;code&gt;create_seq&lt;/code&gt; macro. In Rust, expressions can be several things, in &lt;a href="https://doc.rust-lang.org/reference/expressions.html" rel="noopener noreferrer"&gt;The Rust Reference - Expressions&lt;/a&gt; you can find a much better explanation what expressions can be. In my case, I use the expression called &lt;code&gt;$dimension&lt;/code&gt; as an constant usize value, for example to create the &lt;code&gt;ALPHAS&lt;/code&gt; array. This means, it works with a literal that can be a constant usize like &lt;code&gt;2&lt;/code&gt; or &lt;code&gt;const dim:usize = 2;&lt;/code&gt; but does not work for something like &lt;code&gt;const dim:&amp;amp;str = "2";&lt;/code&gt; obviously.&lt;/p&gt;

&lt;p&gt;As mentioned above, macros first match the given argument or arguments and expand the code. The match part is everything before the arrow &lt;code&gt;=&amp;gt;&lt;/code&gt; while the expanding part is everything behind the arrow. You can define several branches in your match. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[macro_export]&lt;/span&gt;
&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;create_seq&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$dimension:expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;constant_function&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_sequence_data&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$dimension&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;create_sequence_data&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;$dimension&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;sequence&lt;/span&gt;
    &lt;span class="p"&gt;}};&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="nd"&gt;create_seq!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the macro from above, but its second branch is used whenever the macro &lt;code&gt;create_seq&lt;/code&gt; is called without any argument at all. It then calls the macro again with the argument &lt;code&gt;1&lt;/code&gt; instead. This means, one can create a sequence like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;create_seq!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="nf"&gt;.element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I want to come to the expansion part of the macro. The very helpful tool &lt;a href="https://crates.io/crates/cargo-expand" rel="noopener noreferrer"&gt;cargo-expand&lt;/a&gt; helps to expand macros, to help debugging etc.. For example the following call to the macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;create_seq!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;expands to the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;constant_function&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_sequence_data&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;create_sequence_data&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;sequence&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;macro_rules&lt;/code&gt; macros are very powerful and can do a lot of more than what I showed above. Better and more complex examples for &lt;code&gt;macro_rules&lt;/code&gt; macros can be found at &lt;a href="https://danielkeep.github.io/tlborm/book/" rel="noopener noreferrer"&gt;The Little Book of Rust Macros&lt;/a&gt; and &lt;a href="http://adventures.michaelfbryan.com/posts/non-trivial-macros/" rel="noopener noreferrer"&gt;Non-trivial macros&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have only developed a basic idea how I could create the array I need with a &lt;code&gt;macro_rules&lt;/code&gt; macro but did not implement it. The reason is that it's too complex, for me at least. However, if someone is more familiar with &lt;code&gt;macro_rules&lt;/code&gt; macros I can recommend writing an article about the process to get to the solution. I would be very happy to reference it here.&lt;/p&gt;

&lt;p&gt;From my point of view there are two relevant patterns of macros that can be used to generate the array during compile time. The first one is incremental TT munching, brilliantly described at &lt;a href="https://danielkeep.github.io/tlborm/book/pat-incremental-tt-munchers.html" rel="noopener noreferrer"&gt;The Little Book of Rust Macros - Incremental TT munchers&lt;/a&gt;. Here the input is processed incrementally and recursively. The second pattern is push-down accumulation, see again &lt;a href="https://danielkeep.github.io/tlborm/book/pat-push-down-accumulation.html" rel="noopener noreferrer"&gt;The Little Book of Rust Macros - Push-down Accumulation&lt;/a&gt; for more details. Here a token sequence can be build up incrementally from incomplete constructs.&lt;/p&gt;

&lt;p&gt;So if the &lt;code&gt;macro_rules&lt;/code&gt; macro would basically look and be used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;create_sequence_data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// here the magic happens ;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// usage&lt;/span&gt;
&lt;span class="nf"&gt;create_sequence_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// which expands to something like this&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.7548776662466927&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5698402909980532&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The macro implementation needs to calculate the &lt;code&gt;phi&lt;/code&gt; value required for the given dimension value literal. Then the macro would somehow deconstruct the given &lt;code&gt;usize&lt;/code&gt; literal dimension value into a sequence or recursion of the &lt;code&gt;usize&lt;/code&gt; values &lt;code&gt;0..dimension&lt;/code&gt;. For each of the dimensions, the alpha values would be calculated using the before calculated &lt;code&gt;phi&lt;/code&gt; value and combines these values together into the final array. Obviously it makes sense to split up the macro into  "smaller" macros, called by the &lt;code&gt;create_sequence_data&lt;/code&gt; macro, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One calculates &lt;code&gt;phi&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;One deconstructs the given &lt;code&gt;dimension&lt;/code&gt; value&lt;/li&gt;
&lt;li&gt;One calculate an alpha value given &lt;code&gt;phi&lt;/code&gt; and an usize value of the range &lt;code&gt;0..dimension&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;One combines the alpha values into the array&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion using &lt;code&gt;macro_rules&lt;/code&gt; macros
&lt;/h3&gt;

&lt;p&gt;Besides the fact, that I only presented an idea using &lt;code&gt;macro_rules&lt;/code&gt; macros there are two more issues with this option, why I would not use it. The first is these quotes from &lt;a href="https://danielkeep.github.io/tlborm/book/blk-counting.html" rel="noopener noreferrer"&gt;The Little Book of Rust Macros - Counting&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a fine option for smallish numbers, but will likely crash the compiler with inputs of around 500 or so tokens [...]&lt;br&gt;
The compiler must parse this into an AST, which will produce what is effectively a perfectly unbalanced binary tree 500+ levels deep. [...]&lt;br&gt;
This particular formulation will work up to ~1,200 tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From my understanding the counting use case described above is similar to my use case, this means it could be possible that generating a larger array may lead to a compiler crash. This is very unlucky.&lt;/p&gt;

&lt;p&gt;The other issue I have is with the complexity. I am obviously still learning Rust but I find complex &lt;code&gt;macro_rules&lt;/code&gt; macros hard to read and write. They are hard to debug and hard to modify. They are also hard to test. This is from my perspective not an ideal solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 3: Build scripts
&lt;/h2&gt;

&lt;p&gt;The next option I (successfully) tried is using build scripts (see &lt;a href="https://doc.rust-lang.org/cargo/reference/build-scripts.html" rel="noopener noreferrer"&gt;The Rust Reference - Build Scripts&lt;/a&gt;). This enables executing a more or less complex program during compiling the crate. This means I can create the array I need during the build step, simply as another &lt;code&gt;rs&lt;/code&gt; file and use this module in another module of my crate. This means the array, its content etc. is completely hidden for the user. For example, my build script &lt;code&gt;build.rs&lt;/code&gt; could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// qrand_core/build.rs&lt;/span&gt;

&lt;span class="c1"&gt;// used to generate the alpha values&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd_alphas&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// primarily used for writing the file&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// I need a way to get the dimension during compile time.&lt;/span&gt;
    &lt;span class="c1"&gt;// Here, for simplicity reasons, I hard-coded it to be 2.&lt;/span&gt;
    &lt;span class="c1"&gt;// See below, how to get the dimension during compile time.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// creating a string with the alpha values&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;array_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"static ALPHAS:[f64; "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"] = [&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// a little bit of formatting is happening as well&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u{20}\u{20}\u{20}\u{20}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;",&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"];&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// write the string to a file. OUT_DIR environment variable is defined by cargo&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;out_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OUT_DIR"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dest_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;out_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alphas.rs"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dest_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;build.rs&lt;/code&gt; file is usually placed at the top level of a crate (this means parallel to &lt;code&gt;Cargo.toml&lt;/code&gt;, &lt;code&gt;src&lt;/code&gt;, etc.). One can also add build specific dependencies, which is great. These dependencies are only used during build time and do not end up in the final binary. For example, I added my own crate &lt;code&gt;rd_alphas&lt;/code&gt; as build dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build-dependencies]&lt;/span&gt;
&lt;span class="py"&gt;rd_alphas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"../rd_alphas"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't need the code to create alphas during runtime, one of the reasons I want to create large static arrays during compile time. So this is great.&lt;/p&gt;

&lt;p&gt;But how do I access this generated file in my library source code? The answer are the &lt;a href="https://doc.rust-lang.org/core/macro.include.html" rel="noopener noreferrer"&gt;&lt;code&gt;include&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://doc.rust-lang.org/core/macro.concat.html" rel="noopener noreferrer"&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/core/macro.env.html" rel="noopener noreferrer"&gt;&lt;code&gt;env&lt;/code&gt;&lt;/a&gt; macros. &lt;code&gt;include&lt;/code&gt; parses a file as an expression or an item. In our case our file contains: &lt;code&gt;static ALPHAS:[f64;2] = [0.7548776662466927, 0.5698402909980532];&lt;/code&gt; which will then be added as expression in our library source code. &lt;code&gt;concat&lt;/code&gt; concatenates literals into a string slice. This will help us to create the path to our generated &lt;code&gt;alpha.rs&lt;/code&gt; file. &lt;code&gt;env&lt;/code&gt; will finally inspect an environment variable during compile time and expand it to a &lt;code&gt;&amp;amp;'static str&lt;/code&gt;. This means, to include our generated &lt;code&gt;alpha.rs&lt;/code&gt; file we need to add the following line to our library source code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;include!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;concat!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OUT_DIR"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"/alphas.rs"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will include the content of &lt;code&gt;alpha.rs&lt;/code&gt; during compile time as an expression (&lt;code&gt;static ALPHAS:[f64;2] = [0.7548776662466927, 0.5698402909980532];&lt;/code&gt;) to our source code from the path given by the environment variable &lt;code&gt;OUT_DIR&lt;/code&gt; and my file name for my alpha values (&lt;code&gt;alphas.rs&lt;/code&gt;). &lt;code&gt;OUT_DIR&lt;/code&gt; is an environment variable set and used by &lt;code&gt;cargo&lt;/code&gt; and it defines the directory in which all output is created. This is where the &lt;code&gt;alphas.rs&lt;/code&gt; file is written to. This means it is part of the target folder. It is written before the library is compiled and therefore found during compile time of the library. The included &lt;code&gt;alphas.rs&lt;/code&gt; enables me to use the static variable &lt;code&gt;ALPHAS&lt;/code&gt; just like I added it to the source code. However its contents are generated during compile time. So my interface (&lt;code&gt;create_sequence&lt;/code&gt;) can be implemented in the following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// qrand_core/src/lib.rs&lt;/span&gt;

&lt;span class="c1"&gt;// the crate which defines the interface for LowDiscrepancySequences&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;low_discrepancy_sequence&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// my internal, non-public module for the Rd sequence&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// including the generated alphas.rs&lt;/span&gt;
&lt;span class="nd"&gt;include!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;concat!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OUT_DIR"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"/alphas.rs"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// my public interface which hides all the details about the alphas&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can even omit the dimension argument, since this argument would not be used anyways. The dimension is defined by the size of the &lt;code&gt;ALPHAS&lt;/code&gt; static variable which is created in the build script.&lt;/p&gt;

&lt;p&gt;In the above example build script the dimension was hard coded to 2, which is not exactly what I want. I want that the user can set an arbitrary dimension during build time, but how? The solution I came up with, is using an environment variable. This means, when my library is build, the user sets the &lt;code&gt;DIMENSION&lt;/code&gt; environment variable before calling &lt;code&gt;cargo build&lt;/code&gt;, for example like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DIMENSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1000 cargo build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then my build script can use this environment variable to generate the array in the given size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/main.rs&lt;/span&gt;

&lt;span class="c1"&gt;// used to generate the alpha values&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd_alphas&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// primarily used for writing the file&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// get the DIMENSION environment variable or panic&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str_radix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DIMENSION"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// creating a string with the alpha values&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;array_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"static ALPHAS:[f64; "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"] = [&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// a little bit of formatting is happening as well&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u{20}\u{20}\u{20}\u{20}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;",&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"];&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// write the string to a file. OUT_DIR environment variable is defined by cargo&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;out_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OUT_DIR"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dest_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;out_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alphas.rs"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dest_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// set reasons to rebuild&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cargo:rerun-if-env-changed=DIMENSION"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is one further important detail in the last line of the main function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cargo:rerun-if-env-changed=DIMENSION"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;println&lt;/code&gt; instructs &lt;code&gt;cargo&lt;/code&gt; to re-execute the build script whenever the &lt;code&gt;DIMENSION&lt;/code&gt; environment variable has changed. This means when the variable is changed, the build script is called again with the new value. This is called change detection, which makes sense to only let &lt;code&gt;cargo&lt;/code&gt; execute the build script if necessary. The possibilities to define rerun can be found at &lt;a href="https://doc.rust-lang.org/cargo/reference/build-scripts.html#change-detection" rel="noopener noreferrer"&gt;The Cargo Book - Build Scripts - Change Detection&lt;/a&gt;. Without this, the build script would not be re-executed even when the &lt;code&gt;DIMENSION&lt;/code&gt; environment variable would change. So if a user defines this variable to be 1000, but later finds out that the dimension should be 2000, the build script would not have created the array with dimension 2000. But with the instruction &lt;code&gt;cargo:rerun-if-env-changed=DIMENSION&lt;/code&gt;. This means, using build scripts does work, enabling the creation of arbitrarily large arrays during compile time and a clear abstraction of this fact from the user.&lt;/p&gt;

&lt;p&gt;However, what I don't like about this solution is, that every user of my library must compile its own application with the environment variable set (for example as shown above or using other ways). This is not a showstopper but it is definitely not very common. Unfortunately I did not find a better option than using the environment variables, but there are only two options for inputs to the build script, see &lt;a href="https://doc.rust-lang.org/cargo/reference/build-scripts.html#inputs-to-the-build-script" rel="noopener noreferrer"&gt;The Cargo Reference - Build Scripts - Inputs to Build Script&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When the build script is run, there are a number of inputs to the build script, all passed in the form of environment variables.&lt;/p&gt;

&lt;p&gt;In addition to environment variables, the build script’s current directory is the source directory of the build script’s package.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the first option is using environment variables, which I find uncommon and therefore suboptimal. The second option is to access files in the directory of the build scripts. This is a great solution for an application where this file can be changed. I don't see it possible to be used in a crate to change files in the directory of a crate that is used as a dependency (nor should it be possible if one thinks about it).&lt;/p&gt;

&lt;p&gt;I originally thought, that a user of my library could use a build script to emit an environment variable (analog to &lt;code&gt;DIMENSION&lt;/code&gt;) which is then used by my build script to generate the array with the defined dimension. This idea is similar to the idea of the &lt;a href="https://crates.io/crates/openssl-sys" rel="noopener noreferrer"&gt;&lt;code&gt;openssl-sys&lt;/code&gt; crate&lt;/a&gt; which is described at &lt;a href="https://doc.rust-lang.org/cargo/reference/build-script-examples.html#conditional-compilation" rel="noopener noreferrer"&gt;The Cargo Reference - Build Scripts Examples - Conditional Compilation&lt;/a&gt;. The build script of this crate identifies the installed OpenSSL version and "communicates" it to the &lt;a href="https://crates.io/crates/openssl" rel="noopener noreferrer"&gt;&lt;code&gt;rust-openssl&lt;/code&gt; crate&lt;/a&gt; which uses it for conditional compilation. However this only works for a dependency to its dependent(s). And this makes sense: A dependency is usually build before its dependents and hence its build scripts are executed before the build scripts of the dependents. But this means, this idea (a build script in the dependent application or crate) does not work, at least at the moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion build scripts
&lt;/h3&gt;

&lt;p&gt;I like this solution a lot. The array is clearly generated during build time. The code to generate the array is not part of the binary since it is called during the build. The array is very much "hidden" from the user: It is an implementation detail. But as mentioned above, the usage of an environment variable to build a library is a drawback for me. I am also not so sure if I really appreciate the fact that no dimension argument is needed to create the sequence, at least from a user standpoint. For me it feels a little bit like magic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 4: procedural macros
&lt;/h2&gt;

&lt;p&gt;The last option I tried out (successfully) were procedural macros. Procedural macros come in three different kinds: function-like macros, derive macros and attribute macros (see &lt;a href="https://doc.rust-lang.org/reference/procedural-macros.html" rel="noopener noreferrer"&gt;The Rust Reference - Procedural Macros&lt;/a&gt;). Function-like macros are the kind of macro relevant for my use case. They are, from a conceptional standpoint, pretty similar to the &lt;code&gt;macro_rules&lt;/code&gt; macros option: There is a macro, which is called like a function, and this macro generates the array and expands it into the source code during compile time. However, procedural macros are implemented differently then &lt;code&gt;macro_rules&lt;/code&gt; macros. The first difference is, that procedural macros are created in their own crate. This is indicated in the procedural macro crates &lt;code&gt;Cargo.toml&lt;/code&gt; file in this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cargo.toml&lt;/span&gt;
&lt;span class="nn"&gt;[package]&lt;/span&gt;
&lt;span class="c"&gt;# ...&lt;/span&gt;

&lt;span class="nn"&gt;[lib]&lt;/span&gt;
&lt;span class="py"&gt;proc-macro&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="c"&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A function like macro is then implemented like a normal public function, but with a &lt;code&gt;#[proc_macro]&lt;/code&gt; attribute. This function has a &lt;code&gt;TokenStream&lt;/code&gt; input and output. A &lt;code&gt;TokenStream&lt;/code&gt; is a representation of&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;an abstract stream of tokens, or, more specifically, a sequence of token trees.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(See &lt;a href="https://doc.rust-lang.org/proc_macro/struct.TokenStream.html" rel="noopener noreferrer"&gt;Rust API documentation - TokenStream&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Simplified said, a &lt;code&gt;TokenStream&lt;/code&gt; represents the Rust source code that is passed to the macro function during compile time. A simple example can be a Derive attribute (see &lt;a href="https://doc.rust-lang.org/reference/attributes/derive.html" rel="noopener noreferrer"&gt;The Rust Reference - Derive&lt;/a&gt;). A &lt;code&gt;#[derive(Debug)]&lt;/code&gt; on a &lt;code&gt;struct&lt;/code&gt; will enable debug information through the &lt;code&gt;?&lt;/code&gt; formatting (see also &lt;a href="https://doc.rust-lang.org/std/fmt/trait.Debug.html" rel="noopener noreferrer"&gt;Rust API Documentation - Debug&lt;/a&gt;). The &lt;code&gt;TokenStream&lt;/code&gt; which is passed to the derive macro function is the representation of the &lt;code&gt;struct&lt;/code&gt;. The output &lt;code&gt;TokenStream&lt;/code&gt; then also contains a representation of Rust source code. This means for the &lt;code&gt;#[derive(Debug)]&lt;/code&gt; example, that the implementations of all functions required by the &lt;code&gt;Debug&lt;/code&gt; trait. Parsing the input &lt;code&gt;TokenStream&lt;/code&gt; and creating the output &lt;code&gt;TokenStream&lt;/code&gt; is obviously not trivial. If you have complex &lt;code&gt;TokenStream&lt;/code&gt; input, then the&lt;a href="https://crates.io/crates/syn" rel="noopener noreferrer"&gt;&lt;code&gt;syn&lt;/code&gt; crate&lt;/a&gt; is ideal to help parsing it. Its congenial partner is the &lt;a href="https://crates.io/crates/quote" rel="noopener noreferrer"&gt;&lt;code&gt;quote&lt;/code&gt; crate&lt;/a&gt; which simplifies generating the output &lt;code&gt;TokenStream&lt;/code&gt;.&lt;br&gt;
Fortunately, parsing and generating the source code is trivial for my use case, especially the &lt;code&gt;parse&lt;/code&gt; function from &lt;code&gt;str&lt;/code&gt; is of help (see &lt;a href="https://doc.rust-lang.org/std/primitive.str.html#method.parse" rel="noopener noreferrer"&gt;Rust API documentation - str - parse&lt;/a&gt;. It can parse a string into a &lt;code&gt;TokenStream&lt;/code&gt;. Additionally my macro can only accept literals of unsigned values (like &lt;code&gt;2&lt;/code&gt; or &lt;code&gt;1000&lt;/code&gt;). Since the input to a procedural function like macro is a &lt;code&gt;TokenStream&lt;/code&gt;, this &lt;code&gt;TokenStream&lt;/code&gt; can only represent what is given as argument. Assume you defined a constant (like &lt;code&gt;const dim:usize = 1000;&lt;/code&gt;) and then called the macro (&lt;code&gt;create_sequence(dim)&lt;/code&gt;), then the &lt;code&gt;TokenStream&lt;/code&gt; is actually, and rightfully so, just &lt;code&gt;dim&lt;/code&gt; with no option (at least to my knowing) to extract the value of &lt;code&gt;dim&lt;/code&gt; from the &lt;code&gt;TokenStream&lt;/code&gt; (here &lt;code&gt;1000&lt;/code&gt;). Therefore my macro is pretty straight-forward (especially since I omitted better error handling):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// rd_proc_macro/src/lib.rs&lt;/span&gt;

&lt;span class="c1"&gt;// I need the TokenStream, since it is required by&lt;/span&gt;
&lt;span class="c1"&gt;// the definitions of the procedural macro.&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;proc_macro&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// I created another crate which creates the alphas for me.&lt;/span&gt;
&lt;span class="c1"&gt;// I plan to re-use this crate for other use cases.&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd_alphas&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Convert the dimension TokenStream to a string and then parse this into an usize&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;parse_dimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// parse the token stream as usize literal or panic&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dim_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;dim_string&lt;/span&gt;&lt;span class="py"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// create the static alphas array as Rust source code string&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_rd_alphas_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// create a string from the alpha values&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;array_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"static ALPHAS:[f64; "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"] = [&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// a little bit of formatting here.&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u{20}\u{20}\u{20}\u{20}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;",&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"];&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[proc_macro]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_rd_alphas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_dimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;array_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_rd_alphas_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// create the TokenStream output&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I can use this macro by, for example, calling &lt;code&gt;create_rd_alphas!(2)&lt;/code&gt;, to create a static, two dimensional array during compile time. For example, one of my integration tests could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;integration_tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd_proc_macro&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_rd_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[test]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_proc_macro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;create_rd_alphas!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.7548776662466927&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5698402909980532&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important to note is, that the above code does only work with Rust 1.45, since before that, procedural function like macros could not be used as a statement. Fortunately this changed, see &lt;a href="https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#stabilizing-function-like-procedural-macros-in-expressions-patterns-and-statements" rel="noopener noreferrer"&gt;The Rust Blog - Rust-1.45.0 - Stabilizing function like procedural macros in expressions patterns and statements&lt;/a&gt;. This is a great improvement because otherwise a user of my library would first needed to call the macro (&lt;code&gt;create_rd_alphas&lt;/code&gt;) in an item position and then create the sequence with another macro. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// application_using_qrand_core/main.rs&lt;/span&gt;

&lt;span class="c1"&gt;// This can be done with a re-export.&lt;/span&gt;
&lt;span class="c1"&gt;// I will demonstrate re-exports below a little bit more&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;qrand_core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_rd_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// the create sequence macro, which "knows" that there is a static array named "ALPHAS"&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;qrand_core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// The trait which is the public interface of my sequence&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;qrand_core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// alphas are created in an item position&lt;/span&gt;
&lt;span class="nf"&gt;create_rd_alphas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// I could also re-export and change the name to something less specific like create_sequence_data&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;create_sequence!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// sequence is used ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is error-prone, although errors would be caught by the compiler. And I would leak more implementation detail that I want to, mainly that I need to create these alphas first (or at least create some kind of sequence data if I rename the re-export from the procedural macro crate). Fortunately Rust 1.45 enables using procedural macros as statements, but currently I only have a procedural macro which helps creating the alphas and I still want to hide this as an implementation detail. I can do this with re-exports in my library which has the procedural macro as dependency. I then have two options. The first option is to use a macro_rules macro, to create the array with the procedural macro and then the sequence. This would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// qrand_core/src/lib.rs&lt;/span&gt;
&lt;span class="c1"&gt;// I need to re-export the LowDiscrepancySequence so that its functions can be used&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;low_discrepancy_sequence&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The procedural macro must also be re-exported&lt;/span&gt;
&lt;span class="c1"&gt;// so that it can be used in the macro_rules macro&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd_proc_macro&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_rd_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// my internal, non-public module for the Rd sequence&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The public interface that wraps the actual implementation of the Rd sequence.&lt;/span&gt;
&lt;span class="c1"&gt;// This is also needed in the macro.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// the macro_rules macro&lt;/span&gt;
&lt;span class="nd"&gt;#[macro_export]&lt;/span&gt;
&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;create_sequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$dimension:expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="c1"&gt;// usage of the re-exported procedural macro&lt;/span&gt;
        &lt;span class="nv"&gt;$crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;create_rd_alphas!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$dimension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// creation of the sequence&lt;/span&gt;
        &lt;span class="nv"&gt;$crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ALPHAS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}};&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;create_sequence!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, I need to re-export the &lt;code&gt;create_rd_alphas&lt;/code&gt; macro and need to set the &lt;code&gt;create_seq&lt;/code&gt; function public, which does expose, that we need a static reference to a slice of &lt;code&gt;f64&lt;/code&gt;. Although the usage of the &lt;code&gt;create_sequence&lt;/code&gt; macro does then hide all details, I still need to expose these two interfaces and therefore my intention to hide these details is only partially fulfilled. Someone could use these interfaces directly instead of the macro. In the worst case, this someone uses them incorrectly.&lt;/p&gt;

&lt;p&gt;However, there is a second option, that is slightly better regarding exposing these interfaces. I could change my procedural macro library, so that there is a macro which does already create the sequence. This could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// rd_proc_macro/src/lib.rs&lt;/span&gt;

&lt;span class="c1"&gt;// I need the TokenStream, since it is required by&lt;/span&gt;
&lt;span class="c1"&gt;// the definitions of the procedural macro.&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;proc_macro&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// I created another crate which creates the alphas for me.&lt;/span&gt;
&lt;span class="c1"&gt;// I plan to re-use this crate for other use cases.&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd_alphas&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Convert the dimension TokenStream to a string and then parse this into an usize&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;parse_dimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// parse the token stream as usize literal or panic&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dim_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;dim_string&lt;/span&gt;&lt;span class="py"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// create the static alphas array as Rust source code string&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_rd_alphas_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// create a string from the alpha values&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;array_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"static ALPHAS:[f64; "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"] = [&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_alphas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// A little bit of formatting&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u{20}\u{20}\u{20}\u{20}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;",&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"];&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;array_string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[proc_macro]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TokenStream&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_dimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// I want to return the sequence and therefore I need a { block&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// the array is created inside the block&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;create_rd_alphas_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// I then create sequence and it is returned&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rd_proc_macro_user_lib::create_seq(&amp;amp;ALPHAS)"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// end of the block&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"}&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// This means the block looks like this for dimension=2:&lt;/span&gt;
    &lt;span class="c1"&gt;// {&lt;/span&gt;
    &lt;span class="c1"&gt;// static alphas:[f64;2] = [0.7548776662466927, 0.5698402909980532];&lt;/span&gt;
    &lt;span class="c1"&gt;// rd_proc_macro_user_lib::create_seq(&amp;amp;ALPHAS) // this returns an impl LowDiscrepancySequence&lt;/span&gt;
    &lt;span class="c1"&gt;// }&lt;/span&gt;

    &lt;span class="c1"&gt;// create the TokenStream output&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My library then re-exports the macro as well which could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// qrand_core/src/lib.rs&lt;/span&gt;

&lt;span class="c1"&gt;// I need to re-export the LowDiscrepancySequence so that its functions can be used&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;low_discrepancy_sequence&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The re-export of the macro&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd_proc_macro&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_sequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// my internal, non-public module for the Rd sequence&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rd&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The public interface that wraps the actual implementation of the Rd sequence.&lt;/span&gt;
&lt;span class="c1"&gt;// This is also needed in the macro.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;LowDiscrepancySequence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;new_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alphas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means, the macro &lt;code&gt;create_sequence&lt;/code&gt; is now re-exported and needed and the only implementation detail leaked is the public interface &lt;code&gt;create_seq&lt;/code&gt; which requires a static reference to &lt;code&gt;f64&lt;/code&gt; slice. This is better from a implementation hiding point of view. But I have another problem with this solution: The procedural macro crate &lt;code&gt;rd_proc_macro&lt;/code&gt; is indirectly dependent on its dependent crate &lt;code&gt;qrand_core&lt;/code&gt;, since the &lt;code&gt;create_seq&lt;/code&gt; function is used (as a string literal) inside the macro. This is not a catastrophe, but it means that the crate can only be used in conjunction with its dependent crate &lt;code&gt;qrand_core&lt;/code&gt; and this feels limiting and strange. Therefore I would prefer the first option, where more implementation details are leaked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion using procedural macros
&lt;/h3&gt;

&lt;p&gt;This option works. The macros are pretty straightforward to write in comparison to using &lt;code&gt;macro_rules&lt;/code&gt; macros. They are more straightforward to use then requiring an environment variable to be set when compiling. However some implementation details are leaked, since the macro needs access to the functions that actually create the sequence. It's not a huge problem but it may be confusing or someone may use these public interface in a wrong way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I introduced and skimmed through 4 options I tried out, for generating large arrays during compile time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using const functions and const generics do require using the nightly compiler and I need to implement some of the standard library functions myself. The need to use the nightly compiler is the reason I wouldn't use this option, at least for now. And I don't like, that the constant functions are part of the final binary, since I don't use them during runtime.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;macro_rules&lt;/code&gt; macros may work, but I could only outline how they may work. At least for me this option is too complicated and may crash the compiler if an array is too large.&lt;/li&gt;
&lt;li&gt;Build scripts do work but require, at least for the moment, the usage of environment variables during compile time.&lt;/li&gt;
&lt;li&gt;Procedural function like macros do also work, but leak a little bit more implementation detail as I prefer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So there are obviously only two options left for my use case: build scripts or procedural macros. I like that build scripts do hide the array completely from the user as an implementation detail. I don't like that a user must set an environment variable to compile my library. Procedural macros are very close to the ideal solution, especially since, with 1.45, they can be used in statements and expressions. However, I don't like that some functions need to be made public that leak implementation detail. These may not be used by the user and a good documentation may fix most of the issues I have, but still it's sub-optimal.&lt;/p&gt;

&lt;p&gt;So for me, there is no clear-cut winner here. At the moment I prefer using build scripts, mainly due to their better hiding of the array as an implementation detail.&lt;/p&gt;

&lt;p&gt;Let me know what you think in the comments below. Also I appreciate comments, critique, correction of errors I made. I will try to update the article appropriately. Thank you for reading.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>embedded</category>
      <category>nostd</category>
      <category>memory</category>
    </item>
  </channel>
</rss>
