# We need \`#fileName\`

**URL:** <https://forums.swift.org/t/we-need-filename/19781>\
**Category:** Pitches\
**Created:** [January 24, 2019, 11:48pm UTC](https://forums.swift.org/t/we-need-filename/19781 "2019-01-24T23:48:46Z")\
**Posts on this page:** 18\
**Page:** 2

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [February 13, 2019, 8:08pm UTC](https://forums.swift.org/t/we-need-filename/19781/22 "2019-02-13T20:08:47Z")

</div>

Yes. With `#sourceRoot` too, all the use cases I can think of would still be possible. I like that idea much better than the status quo.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 14, 2019, 7:42am UTC](https://forums.swift.org/t/we-need-filename/19781/23 "2019-02-14T07:42:51Z")

</div>

Without derailing from the main topic, with all these new keywords being pitched I think the context is growing too fast. Would it make sense to generalize that into a special `StaticContext<T>` type where the generic parameter allows the users to specify the subset of all `#keywords`, so that the context value isn't exploding in size where not appropriate? This will also reduce the number of parameters a function must have to obtain such static context compared to current status quo.

There was a similar topic, but instead of smashing everything inside one type it would be far better if we could specify a subset of static information we want to obtain:

> [@Supplement #file, #line, and #function with #context](https://forums.swift.org/t/supplement-file-line-and-function-with-context/9505):
>
> I'd like to see a #context keyword for the compiler that expands in to a compiler generated struct: struct Context { let file: StaticString let line: UInt let column: UInt let function: StaticString let dsohandle: UnsafeRawPointer } This would make it much easier to capture the context in which some code is executed rather than having to put file: StaticString = #file, line: UInt = #line parameters everywhere. A context: Context = #context would be much easier.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [February 14, 2019, 4:30pm UTC](https://forums.swift.org/t/we-need-filename/19781/24 "2019-02-14T16:30:23Z")

</div>

I agree, that would be a good idea, especially since people are in fact relying on the current behavior of `#file` and we don't want to disrupt them, so that suggests to me introducing new context values would be preferable to breaking the existing ones.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 14, 2019, 4:38pm UTC](https://forums.swift.org/t/we-need-filename/19781/25 "2019-02-14T16:38:05Z")

</div>

I really like the idea of `StaticContext`. It's much more usable than an ad-hoc collection of parameters that all have to be forwarded individually.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 14, 2019, 4:42pm UTC](https://forums.swift.org/t/we-need-filename/19781/26 "2019-02-14T16:42:38Z")

</div>

Aside the pitch from @davedelong, I tried to create my own type to accumulate the context but I failed because the current static capturing behavior isn't that trivial as I initially thought.

> [@Is this correct StaticString capturing behavior?](https://forums.swift.org/t/is-this-correct-staticstring-capturing-behavior/19258):
>
> I wonder why the obtain function captures test while it's not really executed inside the scope of the test function. func obtain(\_ s: StaticString = #function) -\> StaticString { return s } func test( \_ s1: StaticString = #function, \_ s2: StaticString = obtain(), \_ s3: StaticString = obtain(#function) ) { print(s1, s2, s3, #function) } func foo() { test() } foo() // prints "foo() test test test"

So it definitely requires a formal proposal and some compiler help to create such a type.

---

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [February 14, 2019, 4:43pm UTC](https://forums.swift.org/t/we-need-filename/19781/27 "2019-02-14T16:43:44Z")

</div>

IIRC @beccadax has also taken a stab at implementing `#context`; I do not know how far he's gotten.

---

<div class="post-metadata">

**Author:** ![NSProgrammer](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nsprogrammer/32/7254_2.png) [@NSProgrammer](https://forums.swift.org/u/NSProgrammer)\
**Post date:** [September 11, 2019, 10:25pm UTC](https://forums.swift.org/t/we-need-filename/19781/28 "2019-09-11T22:25:16Z")

</div>

Now that ` __FILE_NAME__ ` exists in clang for C family languages, it seems like a no brainer to add `#fileName` for Swift -- same behavior available for all languages.

---

<div class="post-metadata">

**Author:** ![AlexanderM](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alexanderm/32/9781_2.png) [@AlexanderM](https://forums.swift.org/u/AlexanderM)\
**Post date:** [September 11, 2019, 11:03pm UTC](https://forums.swift.org/t/we-need-filename/19781/29 "2019-09-11T23:03:25Z")

</div>

Which "size" are you concerned about, in particular? The memory of a `Context` object, or the "mental" size of a large Context API with many properties?

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [September 11, 2019, 11:17pm UTC](https://forums.swift.org/t/we-need-filename/19781/30 "2019-09-11T23:17:52Z")

</div>

At least in the former case, we should implement `#context` in such a way that values can be emitted as static global data.

---

<div class="post-metadata">

**Author:** ![AlexanderM](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alexanderm/32/9781_2.png) [@AlexanderM](https://forums.swift.org/u/AlexanderM)\
**Post date:** [September 12, 2019, 1:08am UTC](https://forums.swift.org/t/we-need-filename/19781/31 "2019-09-12T01:08:38Z")

</div>

That's what I would have thought.

It would be an issue if all properties were stored, for all uses of #context, even if only a properties are every accessed.

Could there be an optimization to only populate that data which will actually be referenced? Though I imagine an optimization like that would be defeated as soon as someone passes a `Context` object across a module boundary, or dumps/prints the entire object.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [September 12, 2019, 1:10am UTC](https://forums.swift.org/t/we-need-filename/19781/32 "2019-09-12T01:10:57Z")

</div>

It would be easy to make it so that if you did something like `func foo(x: String = #context.file)`, we only instantiate the `file` string. Passing around whole context values might be trickier, though in most cases they would probably be passed around as read-only, so if the type is large enough that we pass it indirectly we would just pass the global pointer around.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [September 12, 2019, 1:18am UTC](https://forums.swift.org/t/we-need-filename/19781/33 "2019-09-12T01:18:34Z")

</div>

> [@Joe\_Groff](#):
>
> if the type is large enough that we pass it indirectly we would just pass the global pointer around

It would be pretty cool to have a really cheap context like this, especially if it could support `Hashable` by just comparing / hashing the pointer value.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [September 12, 2019, 3:53pm UTC](https://forums.swift.org/t/we-need-filename/19781/34 "2019-09-12T15:53:53Z")

</div>

If it's acceptable to say that context values are only ever compiler-generated, then the type representation could be a plain pointer to the global compiler-generated value. That might cut off possibilities for manipulating context values when forwarding them through different logging APIs, though.

---

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [September 12, 2019, 4:36pm UTC](https://forums.swift.org/t/we-need-filename/19781/35 "2019-09-12T16:36:13Z")

</div>

Could that be mitigated by making `Context` be a reference type? Then compiler generates references would be a pointer to the static information, but as a developer I’d still be able to lash up my own composite/altered contexts.

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [September 13, 2019, 2:17am UTC](https://forums.swift.org/t/we-need-filename/19781/36 "2019-09-13T02:17:55Z")

</div>

I'd very much love to be able to carry around source location information as some form of thing "together" very cheaply -- a pointer to a static, compiler generated, immutable "location context" would be quite great. We currently pass around #file and #line, though sometimes I think to myself "#function might have been nice to carry here as well" but we don't since it's too much hassle at some point (debate-able, maybe worth it to carry around, maybe not).

Usage patterns we have for these things are usually:

- carry around the location info always
- very rarely actually access it -- only when things went wrong, then in asynchronous programs one can say "the thing that originated at line ... failed"
- this isn't a replacement for full on tracing, but a simpler lightweight source location focused helper

Introducing anything reference type for this hurts the first point, as it'd have to be refcounted I guess; and I can't really afford risking those refcounts in hot code paths (where the carrying is used).

So an immutable compiler generated + direct pointer to it sounds quite great to me -- carrying it around would be cheap, just a pointer after all, and no refcount since the source location info is "immortal" \<3

* * *

> [@Joe\_Groff](#):
>
> If it's acceptable to say that context values are only ever compiler-generated, then the type representation could be a plain pointer to the global compiler-generated value.

I think this is acceptable for source location; more advanced things I'd expect to go full on tracing (open tracing / dapper / pivot tracing style), and those are runtime generated and kind of expected to "weight" a bit.

---

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [September 13, 2019, 7:19am UTC](https://forums.swift.org/t/we-need-filename/19781/37 "2019-09-13T07:19:56Z")

</div>

> [@ktoso](#):
>
> So an immutable compiler generated + direct pointer to it sounds quite great to me

Don't value types that are bigger than a certain threshold (~40 bytes I think but not declared as it's implementation detail) behave like that under the hood?

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [September 13, 2019, 8:57am UTC](https://forums.swift.org/t/we-need-filename/19781/38 "2019-09-13T08:57:22Z")

</div>

> [@ktoso](#):
>
> Introducing anything reference type for this hurts the first point, as it'd have to be refcounted I guess; and I can't really afford risking those refcounts in hot code paths (where the carrying is used).

I'm sure we could get around that. If there was something like a `SourceContext` type in the standard library (which only the compiler could construct), the compiler could also know that those objects are always singletons/immortal and omit reference counting.

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [September 15, 2019, 12:13pm UTC](https://forums.swift.org/t/we-need-filename/19781/39 "2019-09-15T12:13:34Z")

</div>

True my bad actually about the worry about the reference types for this. As long as we know it’s immortal it’s fine indeed.

[Previous page](https://forums.swift.org/t/we-need-filename/19781.md?page=1)
