# What is direct parameter assignment useful for?

**URL:** <https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047>\
**Category:** Questions & Answers\
**Created:** [June 2, 2022, 1:28am UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047 "2022-06-02T01:28:19Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![notjack](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@notjack](https://racket.discourse.group/u/notjack)\
**Post date:** [June 2, 2022, 1:28am UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/1 "2022-06-02T01:28:19Z")

</div>

Parameters can be either [parameterized](https://docs.racket-lang.org/reference/parameters.html#%28form._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._parameterize%29%29) or directly assigned to. The latter mutates a thread cell, while the former attaches a continuation mark.

When is it useful to actually assign a parameter instead of using `parameterize`? The two use cases I can think of are:

- When you want `(require somelib)` to trigger configuration of a parameter
- When you don't feel like indenting your code to the right more

These use cases don't seem super compelling on their own. I think the former could be replaced by parameterizing the body of client modules instead. Are there other reasons to directly assign parameters?

For context, I've been thinking about making something like async-await for Racket, and I want it to cooperate with parameters and continuation marks. So I'm doing a lot of research into the evaluation model for continuations and threads.

---

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [June 2, 2022, 3:55pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/2 "2022-06-02T15:55:36Z")

</div>

> [@notjack](#):
>
> When is it useful to actually assign a parameter instead of using `parameterize`?

When you want to run into very subtle bugs that take ages to figure out. :\>

For more, see here: [Running a procedure from 'delay' does not capture modified parameters](https://racket.discourse.group/t/running-a-procedure-from-delay-does-not-capture-modified-parameters/936)

---

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [June 2, 2022, 5:25pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/3 "2022-06-02T17:25:33Z")

</div>

I have some html rendering code that uses a mix of parameters with parameterize as well as regular variables. I use parameterize when I can to hold the current style when the renderer descends into a new element. For other cases it wasn't convenient to use parameterize, so I used a standard variable with assignment instead. I can imagine someone choosing a slightly different path and using a mix of parameterize and assignment to parameters.

---

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [June 2, 2022, 7:32pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/4 "2022-06-02T19:32:01Z")

</div>

Assigning a parameter is useful when you want to provide some interface for updating its value.

Contrived example:

```nohighlight
#lang racket/base

(provide current-addresses add-address)

(define _current-addresses (make-parameter (hasheq))

(define (add-address id val)
  (_current-addresses (hash-set (_current-addresses) id val))

(define (current-addresses) (_current-addresses))

```

There may be better ways to do this kind of thing? but I know it’s something I’ve done.

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [June 2, 2022, 8:55pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/5 "2022-06-02T20:55:06Z")

</div>

In that particular case, wouldn't a mutable hash and `hash-set!` be better? Or is there some reason to prefer a private parameter?

---

<div class="post-metadata">

**Author:** ![countvajhula](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/countvajhula/32/65_2.png) [@countvajhula](https://racket.discourse.group/u/countvajhula)\
**Post date:** [June 2, 2022, 9:26pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/6 "2022-06-02T21:26:56Z")

</div>

The [docs on command line parsing](https://docs.racket-lang.org/reference/Command-Line_Parsing.html#%28form._%28%28lib._racket%2Fcmdline..rkt%29._command-line%29%29) use parameters to hold the flag values. So maybe a good question is, why do the docs use parameters here (without parameterize)?

Incidentally, I adopted this pattern in the [cli library](https://docs.racket-lang.org/cli/index.html) as well, so that flags correspond to parameters, but I don't recall now whether I considered using mutable (lexically-scoped / global) hashes.

Another place I've personally used parameters is in the probe debugger for Qi. [This comment](https://github.com/countvajhula/qi/blob/ecfecb11e5015fd43ff8059c609d1842f22bf320/qi-probe/probe.rkt#L27-L56) explains how parameters are used. Would parameterize work for this usecase? I'll plan to take a closer look at this at some point.

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [June 2, 2022, 9:59pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/7 "2022-06-02T21:59:30Z")

</div>

I'm being sort of devil's-advocate-ish here, but:

- "Avoiding indent" seems easy to dismiss, but given the amount of effort that's gone into internal `define` as an alternative to `let`, I wonder if a "post-mortem" discussion of that effort might be relevant for this?

- Given that parameters are thread-local, the ability to set that thread-local default --- the value to be used in a thread if no one `parameterize`s it --- seems useful? It seems to enable expressing, "If no one has some better idea, here's what I think the value should be". Maybe as you say all such uses could be replaced by a parameterization introduced in the expansion of the module... but I wonder if that option is always available or practical?

---

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [June 2, 2022, 10:15pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/8 "2022-06-02T22:15:55Z")

</div>

> [@greghendershott](#):
>
> If no one has some better idea, here's what I think the value should be".

Wouldn't that case be dealt with by simply giving the parameter an initial value?

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [June 2, 2022, 10:51pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/9 "2022-06-02T22:51:52Z")

</div>

> > If no one has some better idea, here's what I think the value should be".
> 
> Wouldn't that case be dealt with by simply giving the parameter an initial value?

Yes, for a library that defines a parameter: "Here is the default value for all threads created by every other library or applications that uses me."

But for an application using that library, it might want to set its own default?

---

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [June 2, 2022, 10:52pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/10 "2022-06-02T22:52:19Z")

</div>

> [@benknoble](#):
>
> In that particular case, wouldn't a mutable hash and `hash-set!` be better? Or is there some reason to prefer a private parameter?

Because parameters are thread-safe?

---

<div class="post-metadata">

**Author:** ![notjack](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@notjack](https://racket.discourse.group/u/notjack)\
**Post date:** [June 2, 2022, 10:58pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/11 "2022-06-02T22:58:00Z")

</div>

The thread safety doesn't extend to mutable objects _contained_ by parameters. You're still concurrently updating a hash table.

---

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [June 3, 2022, 6:19pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/12 "2022-06-03T18:19:47Z")

</div>

In the contrived example I gave above, the value contained by the parameter is immutable. I am definitely not a Racket expert so maybe my mental model is wrong. But if I “update” an immutable hash table contained in a parameter by doing this:

```nohighlight
(current-param (hash-set (current-param) 'newkey "newval"))

```

…then I’m not mutating a value held in the parameter, I’m rather changing the current thread’s copy of the parameter to point to a completely new hash table, right? Or no?

In other words, it’s still thread safe, because if I had spawned another thread before doing that update, that thread’s `current-param` parameter would still be hanging onto the original hash table. Using a parameter in this way prevents me from stomping on another thread’s data, where `hash-set!` definitely would not give me that assurance. [edit to add:] For sure it makes sense to me that it doesn’t make much sense to try and clothe a mutable value in a parameter, at least in any context I can think of.

---

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [June 3, 2022, 6:33pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/13 "2022-06-03T18:33:06Z")

</div>

I’ve run into this issue directly with Pollen projects. Pollen holds metadata about the current document (if there is one) in an immutable hash table served by a `current-metas` parameter, because it’s useful to be able to get at that data from everywhere. But it’s also useful to be able to add to or update those values from functions called within the document itself.

You don’t want the scope of those changes to be limited to that one function call, you want them to be visible to all later code evaluated in the Pollen program/document.

You also need to consider that multiple Pollen programs/documents may be running concurrently.

So you need a) an immutable hash-table contained in b) a parameter, and c) a way to update it in a way that “sticks” outside the current lexical scope (direct assignment).

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [June 4, 2022, 10:46am UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/14 "2022-06-04T10:46:23Z")

</div>

> [@countvajhula](#):
>
> The [docs on command line parsing](https://docs.racket-lang.org/reference/Command-Line_Parsing.html#%28form._%28%28lib._racket%2Fcmdline..rkt%29._command-line%29%29) use parameters to hold the flag values. So maybe a good question is, why do the docs use parameters here (without parameterize)?

I've asked myself the same question. One possibility is that you can `parameterize` the setting in other places in the code, but that could be very brittle depending on how the parameter or even values derived from it are used in the code.

Another possibility could be that it's easier to write  
`(my-argument new-value)`  
than  
`(set! my-argument new-value)`.

On the other hand,  
`(define my-argument initial-value)`  
is easier to write than  
`(define my-argument (make-parameter initial-value))`

I guess the actual answer has to come from the person who wrote the `command-line` example. 🙂

---

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [June 7, 2022, 1:52pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/15 "2022-06-07T13:52:33Z")

</div>

> [@countvajhula](#):
>
> The [docs on command line parsing](https://docs.racket-lang.org/reference/Command-Line_Parsing.html#%28form._%28%28lib._racket%2Fcmdline..rkt%29._command-line%29%29) use parameters to hold the flag values. So maybe a good question is, why do the docs use parameters here (without parameterize)?

I think a more illuminating question is, what advantage would any other form have over direct parameter assignment for that example?

---

<div class="post-metadata">

**Author:** ![notjack](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@notjack](https://racket.discourse.group/u/notjack)\
**Post date:** [June 8, 2022, 4:05am UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/16 "2022-06-08T04:05:06Z")

</div>

Direct variable assignment with `set!` would be simpler, and uses of the variables wouldn't require parens.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [June 8, 2022, 7:58am UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/17 "2022-06-08T07:58:37Z")

</div>

> [@joeld](#):
>
> what advantage would any other form have over direct parameter assignment for that example?

For one, just using straightforward `define` and `set!` would avoid wondering about why the author of the code used parameters. 🙂 For that reason, I think using `define` and `set!` is clearer.

---

<div class="post-metadata">

**Author:** ![alexh](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/alexh/32/315_2.png) [@alexh](https://racket.discourse.group/u/alexh)\
**Post date:** [June 8, 2022, 10:55am UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/18 "2022-06-08T10:55:02Z")

</div>

> [@sschwarzer](#):
>
> For one, just using straightforward `define` and `set!` would avoid wondering about why the author of the code used parameters. 🙂 For that reason, I think using `define` and `set!` is clearer.

Initially, one can simply follow the example and use the parameters, than, once their program grows to multiple files, they can move each parameter to the most appropriate file in their project and things will continue to work.

If you use `define` and `set!`, you'll be in for a surprise when you refactor your code.

There are, of course, several ways to solve the multi-file project problem, but I am not sure if any alternative would be clearer or simpler.

Alex.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [June 8, 2022, 2:34pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/19 "2022-06-08T14:34:02Z")

</div>

Usually, I try to avoid global state (including parameters) for command line arguments. I use one module that parses the command line data and returns it as a struct.

An example is [here](https://git.sr.ht/~sschwarzer/todo-txt/tree/main/item/file/todoreport/private/cli.rkt). I use `define` and `set!` only locally in the function [`make-command-line-data`](https://git.sr.ht/~sschwarzer/todo-txt/tree/main/item/file/todoreport/private/cli.rkt#L288). The main program in [`todoreport.rkt`](https://git.sr.ht/~sschwarzer/todo-txt/tree/main/item/file/todoreport.rkt) gets the command line arguments with `make-command-line-data` and calls the actual functionality in other modules. No code accesses global state with command line data.

I try _not_ to pass the command line struct to code that's unrelated to command line processing. Called functions are supposed to only get the data they need.

Of course, the above approach may not work or not work so easily for some other programs. That said, if in doubt I would start with a relatively simple design and refactor later if the simpler design is no longer enough ([YAGNI](https://en.wikipedia.org/wiki/YAGNI)). (You could argue that just using parameters would be simpler, but not depending on global state was so important to me that I didn't use this design. 🙂 )

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [June 8, 2022, 3:23pm UTC](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047/20 "2022-06-08T15:23:13Z")

</div>

FWIW [`current-command-line-arguments`](https://docs.racket-lang.org/reference/runtime.html#%28def._%28%28quote._~23~25kernel%29._current-command-line-arguments%29%29) is a parameter. 😉

EDIT for p.s.: I apologize for being a smarty-pants. I realize that the fact that Racket originally provides this information as a parameter, doesn't really have any bearing on how you use it and treat it thereafter in your program.

[Next page](https://racket.discourse.group/t/what-is-direct-parameter-assignment-useful-for/1047.md?page=2)
