Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[name bikeshed] Is "Context" the right name? #44

Closed
codehag opened this issue Mar 23, 2023 · 19 comments · Fixed by #55
Closed

[name bikeshed] Is "Context" the right name? #44

codehag opened this issue Mar 23, 2023 · 19 comments · Fixed by #55

Comments

@codehag
Copy link
Contributor

codehag commented Mar 23, 2023

I don't have a concrete suggestion here, but context can be so broad that it can be meaningless. At the same time, we now have the decorator context argument, and while i don't think that collisions are imminent it might be worth discussing here.

@ljharb
Copy link
Member

ljharb commented Mar 23, 2023

I think it's acceptable to have both, but if we had to pick one, I'd rather rename the decorator argument :-)

Perhaps it's my React ecosystem bias, but "context" seems like the perfect name for what this proposal does.

@hax
Copy link
Member

hax commented Mar 23, 2023

Maybe AsyncLocal is still a good name?

@ljharb
Copy link
Member

ljharb commented Mar 23, 2023

Just like "global" to me implies top level, "local" implies to me bottom level :-/

@jridgewell
Copy link
Member

I'm really partial to calling these "async contexts", mainly because I absolutely hate the names that Node gave it (AsyncLocalStorage, which is an AsyncLocal-Storage and not an Async-LocalStorage). "storage" is just the wrong name for this concept.

AsyncLocalContext could work with these called "async locals", but I don't have a better word than context.

@andreubotella
Copy link
Member

There's also the fact that "async context" (or "async-local context") seems to refer to the general key-value map (the "snapshot", as we have sometimes called it). An AsyncContext instance represents an entry in that map.

@ljharb
Copy link
Member

ljharb commented Mar 23, 2023

altho to me "context" does imply the map. Maybe AsyncContextEntry or something?

@andreialecu
Copy link

andreialecu commented Mar 24, 2023

I'm really partial to calling these "async contexts", mainly because I absolutely hate the names that Node gave it (AsyncLocalStorage, which is an AsyncLocal-Storage and not an Async-LocalStorage). "storage" is just the wrong name for this concept.

I believe the name AsyncLocalStorage came from the concept in C# called ThreadLocalStorage.

I've also been interested in this concept for a while.

I asked ChatGPT for some other name ideas (I particularly like AsyncScope and AsyncState):

  • AsyncScope: This name suggests the idea of a defined scope or boundary for asynchronous operations. It emphasizes the encapsulation of the context and its management within a specific area.
  • AsyncCarrier: This name implies that the proposal will carry or transport the context information throughout the asynchronous flow, ensuring the context is preserved and accessible when needed.
  • AsyncFlow: This name highlights the flow of asynchronous operations and how the context is maintained and passed along during the execution of those operations.
  • AsyncState: This name emphasizes the state of the context, which might change during the execution of asynchronous operations, and the need to manage that state effectively.
  • AsyncThread: This name draws a parallel between JavaScript's asynchronous operations and threads in other programming languages, emphasizing the need to manage context in a similar way to how threads manage their own context.
  • AsyncLink: This name suggests the idea of linking or connecting the context through various asynchronous operations, ensuring that the context remains consistent and available throughout the entire chain of execution.
  • AsyncChain: This name refers to the chain of asynchronous operations, emphasizing the continuity of context throughout the execution of these operations.
  • AsyncBinder: This name implies that the proposal will bind or tie together the context across asynchronous operations, making sure that the context is accessible and consistent at every stage.
  • AsyncRuntime: This name highlights the runtime environment where asynchronous operations occur, emphasizing the need for context management during the actual execution of the operations.
  • AsyncTrace: This name refers to the idea of tracing the context throughout the asynchronous operations, providing a clear path for the context to follow and ensuring its availability when needed.

@lilactown
Copy link

In Project Loom for the JDK, they introduced ScopedValue which is very similar in both syntax and goals.

final static ScopedValue<...> V = new ScopedValue<>();

// In some method
ScopedValue.where(V, <value>)
           .run(() -> { ... V.get() ... call methods ... });

// In a method called directly or indirectly from the lambda expression
... V.get() ...

In clojure, there is a concept called "dynamic binding" which is used similarly to bind a value in a scope. Many functions which start or run on a thread implement what is called "binding conveyance" which propagates dynamic bindings across async contexts.

(def ^:dynamic *v* 1) ; dynamic values are typically denoted with earmuffs

(binding [*v* 2]
  (future (print *v*)))
;; 2

I think that if consumers end up finding it useful outside of async contexts then it would be worth leaving that part out of the name.

My 2c:

  1. ScopedValue
  2. DynamicBinding
  3. BoundValue

@mhofman
Copy link
Member

mhofman commented Mar 25, 2023

From what I gather, in scheme and its variants, this concept is called a fluid.

Here is my suggestion:
FluidValue

@hax
Copy link
Member

hax commented Mar 25, 2023

I believe the name AsyncLocalStorage came from the concept in C# called ThreadLocalStorage.

C# also have AsyncLocal, and I believe the name is coming from ThreadLocal.

@jridgewell
Copy link
Member

From what I gather, in scheme and its variants, this concept is called a fluid.

I tried looking up fluid scopes when Mark was talking about it in SES, and all I could find were esoteric CS papers and scheme. I'd really like to avoid this naming.

they introduced ScopedValue which is very similar in both syntax and goals

I wouldn't be opposed to ScopedValue, with the mapping of all values being a ScopedContext. Similar for AsyncLocal. I'm not going to call the individual items "storage".

@codehag
Copy link
Contributor Author

codehag commented Mar 30, 2023

after thinking through the motivation, a couple of suggestions for naming:

  • Capture, on it's own or as a prefix (CapturedValue, CapturedBinding, CaptureMap) -- argument here is what we are doing is taking a selection of implicit values and propagating them. This is similar to captured bindings in c++, where an anonymous function by default does not have implicit or explicit values from it's outer scope, you have to pass them in intentionally. The name Capture communicates that we are not saving the entire context, but selecting what information we are passing through. The relationship with c++ may be a problem however, many people feel strongly about the language. This can also be used in combination with Scope or async, such as or ScopeCapture, AsyncCapture.
  • Conveyance which shu mentioned partially in jest also gets the idea of what is happen across. We are crossing the event loop barrier, so to speak, and we want to convey information from one call stack to another. ConveyanceBinding or ConveyanceValue could also work -- the problem here is it is verbose and may be challenging to non-fluent english speakers.
  • SustainedValue -- similar benefits to capture, but without the history. It indicates a value persisted over time.
  • Ancestor along with AncestorValue -- not ... great. But this is bikeshedding so.
  • IncumbentValue -- I don't expect this one to be taken too seriously ;)

I am somewhat against the use of Dynamic because it doesn't help with understanding the concept. Fluid is similarly problematic, it has great aesthetics but doesn't describe what is going on.

I am in support of ScopedValue we are really capturing information from a scope higher up on the call stack, in order for use later. The location where we do the capture is the ancestor scope in question. So, also a good name.

I am also less against context now (i was never in full opposition fwiw), though it still has the problem of possibly meaning anything, and that we are only taking a subset of variables from the context.

@andreialecu
Copy link

I ran the full thread through gpt 4 again 😬 and I'm sharing it here because I think it's insightful, especially for bikeshedding purposes:


After reviewing the thread, it appears that there are a number of different naming suggestions with various pros and cons. My thoughts on the naming options discussed are:

  1. Context: As mentioned, this name can be broad and potentially confusing. It might be best to avoid it to prevent collisions with other concepts.
  2. AsyncLocal: This name has roots in C# and could work, but may not be the most descriptive option.
  3. AsyncContextEntry: This name emphasizes the map-like nature of the concept, but it might be too long and not as intuitive.
  4. AsyncScope, AsyncState, AsyncCarrier, etc.: These names suggested by ChatGPT seem to emphasize different aspects of the proposal, but may not provide a clear winner.
  5. ScopedValue, DynamicBinding, BoundValue: These suggestions from @lilactown could work, but the distinction between implicit and explicit values could be confusing.
  6. FluidValue: This name has historical roots in Scheme, but it may not be as descriptive or intuitive for those unfamiliar with the background.
  7. Capture, Conveyance, SustainedValue, Ancestor, IncumbentValue: These suggestions from @codehag all have various pros and cons, but may not provide a clear favorite.

Given the various trade-offs, I would suggest considering a combination of the names presented so far, such as "AsyncScopedValue" or "AsyncCaptureValue". This would emphasize both the asynchronous nature of the proposal and the capturing of values from the scope. However, it is important to ensure that the chosen name effectively communicates the concept to developers and avoids confusion with other features or concepts in the language.

@irvinebroque
Copy link

When I first heard about AsyncLocalStorage, it wasn't clear what it should be used for. When I heard about the AsyncContext proposal, it immediately made sense and mapped to a problem I'd seen (accessing context down a chain of async operations). Seems like a pretty good name! 😄

@jridgewell
Copy link
Member

Maybe it's enough to distinguish between an individual value and the global mappings? In my initial design AsyncContext was a namespace with a AsyncContext.Value class. So you'd have async context "values", and the overall mappings were the "async context".

@legendecas
Copy link
Member

legendecas commented Mar 31, 2023

I'm supportive of distinguishing an individual instance and the global mappings, regarding #21.

I'd avoid the term "dynamic" or "fluid" as they don't help to understand the concept productively. Async-"LocalStorage" is not a good term for the web platform as it may suggest relations to the LocalStorage API.

A class in the namespace AsyncContext sounds like a good alternative. However, I find Variable or Binding better describes the instance that can be mapped to different values in distinct async control flow, than Value does.

@hax
Copy link
Member

hax commented Apr 4, 2023

Note, Python use the name "contextvars" as module/namespace, and have classes ContextVar, Context (and Token which could be used to reset the var). See https://peps.python.org/pep-0567/ for details.

@littledan
Copy link
Member

I'd consider renaming AsyncContext to AsyncVariable (since an instance stands for a single variable--AsyncLocal or AsyncState or AsyncValue are reasonable alternatives), and using the term AsyncContext for AsyncResource/AsyncContext.Snapshot, as discussed in other issues like #21 .

@jridgewell
Copy link
Member

During today's meeting, we decided to introduce new naming. We'll need to settle the exact names naming, but we're aligned with changing the proposal in a way that should solve this issue.

  1. "Local" (or "Variable", or "Value", etc), which is a individual value
  2. "Context", which is the overall mapping of all individual values

This ties into #21 a bit. We'll be introducing 2 new classes, one to represent a value and one to represent a snapshot of the current context. So we could have a AsyncLocal class, and a AsyncSnapshot class (which is an opaque object representing the current context).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.