Stating my opininon

I think that has nothing to do with scope, but with the way that for works in Julia, just iterating over a well-defined collection (which is of finite length). At each step you assign i to the next element in the collection. This is way off topic, but if you want to do something like the c code you could perhaps do something similar to this?

function main(n::Int)
  r = 0
  i = 1
  while (i += 1) < n
    i -= 1
    r += 1
  end
  r
end
3 Likes

Oops, @kristoffer.carlsson beat me to it! He seems to be everywhere all the time. Thanks for all your help in discourse Kristoffer!

3 Likes

We can of course create a macro that simulates the C for loop style

macro cfor(loop_preamble, body)
    init, cond, post = loop_preamble.args
    return quote
        let
            $init
            while $cond
                $body
                $post
            end
        end
    end
end
julia> @cfor (i = 1, i<5, i+=1) begin
           println(i)
       end
1
2
3
4
7 Likes

It is not the same.
Using “for i in 1:n” in Julia, you update i using an iterator, it does not use the previous value, so if you change it inside the block, it does not matter. Using a while the result should be the same than in C.
It has not relationship with the scope of variable i.

Yes, exactly, good point with the iterator. I tried using all sorts of global and local declarations to access the i but yes, inside the loop I was always dealing with a different variable and I didn’t know how Julia implements that.

@kristoffer.carlsson @pablosanjose thanks for the rewrite, very helpful. In terms of time and space complexity the Julia algorithm accurately maps the C implementation. Nice stuff.

1 Like

2 posts were split to a new topic: Allocations in function timing

This has nothing to do with scoping but how a C-loop is defined.

Pretty interesting, this means that for loops in Julia are primitive recursive, no?

Could you elaborate what is interesting?

Remember that for i in iter; #body; end is just syntax for

next = iterate(iter)
while next !== nothing
    (i, state) = next
    # body
    next = iterate(iter, state)
end

and that it is trivial to write an iterator that works just like the C-loop.

1 Like

Its just interesting from a theoretical point of view since it means for loops are really less powerful in Julia than in C. Note that this is a good thing. If one can avoid while loops and recursion it should be possible showing that a given function halts.

A for loop is lowered to a while loop and as I said, any C for loop can be written as a julia for loop with a suitable iterator.

I think a concrete example would solidify your point.

1 Like

The point is that for loops in Julia are not as powerful as while loops (I am talking here from the computability point of view). One can convert a for loop into a while loop but not vice versa. In C they are equally powerful.

I brought this up since @essenciary said

and if for loops are primitive recursive in Julia then this can be formally proven.

(Primitive recursive function - Wikipedia for some background)

You cannot mean the following?

for _ in Iterators.repeated(true)
    cond && break
    body  
end

This answers my question

Pretty interesting, this means that for loops in Julia are primitive recursive, no?

with no, they are μ-recursive (General recursive function - Wikipedia). The power comes from the fact that iterators don’t need to iterate over a finite range. Thanks!

They are equally “powerful” in Julia as well.

1 Like

“Power” is a misleading concept here. Both languages have general constructs for control flow, Julia’s for just does different things (being closely related to the iteration interface, cf similar C++ solutions). Saying that the C/C++ for is more powerful is not unlike arguing that Base.* is more “powerful” than C’s * because in Julia it also works for strings.

The “power” is standard terminology for describing the computability aspects of any programming language (or abstract machines like the Turing machine). Most programming languages that we use are all equally powerful and in particular as powerful as a Turing machine. One essential thing is whether a programming language provides a LOOP-like (LOOP (programming language) - Wikipedia) iteration protocol or a WHILE iteration.

My point was that it makes little sense to talk about the “power” of a particular language construct in isolation.

Languages like LOOP and WHILE have been designed exactly for the purpose of investigating what power a language construct gives to a language. Maybe we just look from different angles on this subject. The term “power” should really not imply anything negative. From a language point of view it would actually be better if things like Iterators.repeated(true) could be prevented. Reasoning about a program where for is only primitive recursive is much easier (and actually computable) instead of a for loop that is μ-recursive.

2 Likes