Inconsistent behaviour of forward declarations


(Dan Cutting) #1

Hi,

This code builds and runs fine:

func foo() -> Int { return soon + 1 }
let soon = 1

But the following code has a compilation error (“Use of unresolved identifier ‘soon’”):

func foo() -> Int { return soon + 1 }
let wat = true
let soon = 1

Any ideas why? Is this a bug in Swift or intended behaviour?

I might expect either or neither of these to work, but to have one work and one fail is perplexing.

Thanks,
Dan


(Victor Guerra) #2

hi Dan,

Seems to work when using Swift 2.2 Snapshot from 6th of jan:

Welcome to Apple Swift version 2.2-dev (LLVM 3ebdbb2c7e, Clang f66c5bb67b,
Swift 54dcd16759). Type :help for assistance.
  1> func foo() -> Int { return soon + 1 }
  2. let wat = true
  3. let soon = 1
wat: Bool = true
soon: Int = 1
  4> foo()
$R0: Int = 2

I am able to reproduce the bug on a playground though where swift 2.1 is
used I guess.

···

On Sat, Jan 9, 2016 at 10:44 PM Dan Cutting via swift-users < swift-users@swift.org> wrote:

Hi,

This code builds and runs fine:

func foo() -> Int { return soon + 1 }
let soon = 1

But the following code has a compilation error (“Use of unresolved
identifier ‘soon’”):

func foo() -> Int { return soon + 1 }
let wat = true
let soon = 1

Any ideas why? Is this a bug in Swift or intended behaviour?

I might expect either or neither of these to work, but to have one work
and one fail is perplexing.

Thanks,
Dan

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


(Dan Cutting) #3

Thanks Victor.

Actually, that snippet works in the v2.1.1 REPL as well, so I think the REPL environment works differently.

Both v2.1.1 and v2.2-dev fail when running that code as a script.

Thanks,
Dan

···

On 9 Jan 2016, at 10:41 PM, Victor Guerra <vguerra@gmail.com> wrote:

hi Dan,

Seems to work when using Swift 2.2 Snapshot from 6th of jan:

Welcome to Apple Swift version 2.2-dev (LLVM 3ebdbb2c7e, Clang f66c5bb67b, Swift 54dcd16759). Type :help for assistance.
  1> func foo() -> Int { return soon + 1 }
  2. let wat = true
  3. let soon = 1
wat: Bool = true
soon: Int = 1
  4> foo()
$R0: Int = 2

I am able to reproduce the bug on a playground though where swift 2.1 is used I guess.

On Sat, Jan 9, 2016 at 10:44 PM Dan Cutting via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi,

This code builds and runs fine:

func foo() -> Int { return soon + 1 }
let soon = 1

But the following code has a compilation error (“Use of unresolved identifier ‘soon’”):

func foo() -> Int { return soon + 1 }
let wat = true
let soon = 1

Any ideas why? Is this a bug in Swift or intended behaviour?

I might expect either or neither of these to work, but to have one work and one fail is perplexing.

Thanks,
Dan

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


(Victor Guerra) #4

Thanks Victor.

Actually, that snippet works in the v2.1.1 REPL as well, so I think the
REPL environment works differently.

Both v2.1.1 and v2.2-dev fail when running that code as a script.

You are right Dan. I did give it a try previously from the REPL. And yes,
fails if scripted.

···

On Sat, Jan 9, 2016 at 11:56 PM Dan Cutting <dan@cutting.io> wrote:


(Joshua Scott Emmons) #5

You are right Dan. I did give it a try previously from the REPL. And yes, fails if scripted.

I think what you're running into here is the different ways the REPL, Playgrounds, and .swift files are initialized (esp. with respect to globals). There's some interesting talk about this on the (original) Swift blog at Apple: https://developer.apple.com/swift/blog/#article-18

"Most Swift files in your app are order-independent, meaning you can use a type before it is defined, and can even import modules at the bottom of the file (although that is not recommended Swift style.)"

"Code within a playground file is order-dependent, run in top-down lexical order. For example, you can’t use a type before you define it."

"The exception is a special file named “main.swift”, which behaves much like a playground file, but is built with your app’s source code. "

"Given how Swift determines where to start executing an app, how should global variables work? ... In a single-file program, code is executed top-down, similar to the behavior of variables within a function. Pretty simple. The answer for complex apps is less obvious... [Swift] runs the initializer for a global the first time it is referenced, similar to Java ... which is the best of all worlds: it allows custom initializers, startup time in Swift scales cleanly with no global initializers to slow it down, and the order of execution is completely predictable."

This was from back in beta days, but I'm pretty sure it still applies.

···

--
Cheers!
-jemmons


(Zhao Xin) #6

I think the codes should not run in a playground file. But they should run
in a swift file. Both assuming they are outside a class/struct/enum.

Because in playground, codes run from top to bottom; in swift file, all
global variables and functions are known by the compiler before the app
runs.

zhaoxin

···

On Sun, Jan 10, 2016 at 7:08 AM, Victor Guerra via swift-users < swift-users@swift.org> wrote:

On Sat, Jan 9, 2016 at 11:56 PM Dan Cutting <dan@cutting.io> wrote:

Thanks Victor.

Actually, that snippet works in the v2.1.1 REPL as well, so I think the
REPL environment works differently.

Both v2.1.1 and v2.2-dev fail when running that code as a script.

You are right Dan. I did give it a try previously from the REPL. And yes,
fails if scripted.

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

--

Owen Zhao