The while cycle doesn't work

I wrote a simple program, literally to test how the while cycle works, but it gives the same error, even though I wrote it identically to the one in the training material.
x=0
while x<10
x+=1
println(x)
end

and the error:
r Warning: Assignment to ‘x’ in soft scope is ambiguous because a global variable by the same name exists: ‘x’ will be treated as a new local. Disamb
iguate by using ‘local x’ to suopress this warning ar “global x° to assign to the existing global variable.
@

ERROR: Unuefvartrror: “x” not detined in local scope
Suggestion: check for an assignment to a local variable that shadows a global of the same name.

Missing an end

julia> while x<100
           x+=1
           if x%2==0
               println(x)
           end
       end
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
52
54
56
58
60
62
64
66
68
70
72
74
76
78
80
82
84
86
88
90
92
94
96
98
100

Consider using a comprehension as an alternative

[println(x) for x in 1:100 if x % 2 == 0]

This is an issue of scope, and I recommend reading more about it here: Scope of Variables · The Julia Language

In short, you’ve created x as a global variable and then created a new “soft” scope within the while loop. The while loop doesn’t “know” whether you intend to reference the global variable or whether you’ve made a mistake and haven’t declared a local value for x.

(Julia’s soft scopes differ in their behaviour depending on whether they are executed in the REPL or from a file (e.g. julia myscript.jl). In my opinion, this difference probably wasn’t a great idea but I think the motivation was to make the REPL easier to work with.)

In any case, the solution here is to tell Julia that you want to use the global variable x inside the while loop, which you can do using the global keyword:

x = 0
while x < 10
  global x
  x += 1
  println(x)
end

Having said this, it’s usually not a good idea to mutate global state since this can lead to spaghetti code. So an easier way to do this is make x local to the scope, either by putting the code in a let block or in a function:

let
  x = 0
  while x < 10
    x += 1
    println(x)
  end
end

Or:

function print_to_ten()
  x = 0
  while x < 10
    x += 1
    println(x)
  end
end

print_to_ten()
6 Likes

There is a tip called A Common Confusion at the top of the Scope section of the manual going over this exact case.

You don’t need to read all of the scoping rules to get a working knowledge of the scope behavior.

  1. Global scope (top level) is special. You generally want to pass global variables as function arguments to make them accessible to inner scopes.
  2. Variables defined in a local scope will be available to inner scopes and not available to outer scopes. If you write all your code inside functions, then you will get better performance and more consistent scoping behavior.
2 Likes