> On Sep 22, 2016, at 11:23 AM, Jens Persson <j...@bitcycle.com> wrote:
> 
> Oh, but how can the following (earlier mentioned) example have anything to do 
> with Script-mode top-level locals being treated as globals?
> 
> Create "AnotherFile.swift" containing:
> func f() -> Int { return a }
> let a = f()

In this case, you have a deadlock, since the initialization of `a` depends on 
its own initialization.

-Joe

> Create "main.swift" containing:
> print(a)
> 
> Compile. Run. For ever. At zero % CPU.
> 
> /Jens
> 
> 
> 
> On Thu, Sep 22, 2016 at 8:03 PM, Jens Persson <j...@bitcycle.com> wrote:
> Thank you for the thorough explanation!
> /Jens
> 
> On Thu, Sep 22, 2016 at 7:28 PM, Jordan Rose <jordan_r...@apple.com> wrote:
> Yep, it really is a long-standing bug. Script-mode top-level locals are 
> treated as globals (module-scope bindings) by the compiler, but their initial 
> bindings are evaluated eagerly instead of lazily (as you’d want in a script). 
> Taken together, this means that you can get this completely unsafe behavior.
> 
> So, why is ‘a’ accepted but ‘b’ not in your original example?
> 
>> func foo() -> Int { return b }
>> let a = 1
>> let b = 2
>> print(foo())
> 
> The secret to the current behavior is that script mode is executed 
> interactively, instead of parsing it all up front. To make things a little 
> better, it actually parses any number of declarations until it sees something 
> it actually needs to execute—a statement or a declaration with an initial 
> value expression. This allows for recursive functions while still being 
> “live”.
> 
> The consequence here is that one top-level binding after a series of 
> functions may be visible. This is obviously not optimal.
> 
> To fix this, we should:
> 
> - Distinguish between script-mode top-level locals and module-scope variables 
> that happen to be declared. My personal preference is to treat anything with 
> explicit access control as a normal lazy global and anything without access 
> as a top-level local.
> 
> - Consider parsing everything up front, even if we don’t type-check it, so 
> that we can say “use of ‘b’ before it’s initialized” instead of “undeclared 
> name ‘b’”
> 
> Note that we do need to be conservative here. This code should continue to be 
> rejected, even though ‘f’ doesn’t refer to ‘local’ directly, because calling 
> ‘f' would be dangerous before the initialization of ‘local':
> 
> internal func f() -> Int {
>   return g()
> }
> // more code here
> 
> let local = 42
> private func g() -> Int {
>   return local
> }
> 
> Thanks for bringing this up, if only so I have an opportunity to write out 
> the issue. :-)
> Jordan
> 
> 
>> On Sep 21, 2016, at 23:04, Jens Persson <j...@bitcycle.com> wrote:
>> 
>> Did you see the other code examples that came up in that twitter 
>> conversations?
>> For example:
>> 
>> This worrying little program compiles:
>> func f() -> Int {
>>     return a
>> }
>> let a = f()
>> 
>> 
>> It also compiles if you print(a) at the end, and it will print 0.
>> 
>> If we replace Int with [Int] it will still compile but crash when run.
>> 
>> And also this:
>> 
>> AnotherFile.swift containing:
>> func f() -> Int {
>>     return a
>> }
>> let a = f()
>> 
>> main.swift containing
>> print(a)
>> 
>> Compile, run (for eternity, at 0% CPU).
>> 
>> /Jens
>> 
>> 
>> On Thu, Sep 22, 2016 at 3:13 AM, Joe Groff <jgr...@apple.com> wrote:
>> 
>> > On Sep 21, 2016, at 2:22 PM, Jens Persson via swift-users 
>> > <swift-users@swift.org> wrote:
>> >
>> > // This little Swift program compiles (and runs) fine:
>> >
>> > func foo() -> Int { return a }
>> > let a = 1
>> > let b = 2
>> > print(foo())
>> >
>> > But if `foo()` returns `b` instead of `a`, I get this compile time error:
>> > "Use of unresolved identifier `b`"
>> 
>> This looks like a bug to me (cc-ing Jordan, who's thought about global 
>> scoping issues more than me). In "script mode", it shouldn't be possible to 
>> refer to a variable before its initialization is executed. However, the way 
>> this is currently modeled is…problematic, to say the least, among other 
>> reasons because script globals are still visible to "library" files in the 
>> same module.
>> 
>> -Joe
>> 
> 
> 
> 

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to