Compiler complains about "unexpected end"

Compiler complains about “unexpected end” on line 22, but if I remove it I get this error:
syntax: incomplete: “function” at In[35]:1 requires end

Stacktrace:
[1] top-level scope at In[35]:1
[2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091

the code should factor numbers return a Dict and print it.

function crack(n)
dd=Dict(1=>n)
d=2
p=0
while n>=d && n%d==0
n/=d
p+=1
end
if p>0
dd[d]=p
end
d=1
while n>=d
p=0
d+=2
while n>=d
if n%d!=0
break
end /// this end
n/=d
p++
end
if p>0
dd[d]=p
end
end
return dd
end

dd=crack(24)

for (d,p) in dd
println(d,“=>”,p)
end

I don’t get it. Every control statement has its own end statement - Jupyter even indented them properly.

Can you write your code between triple backticks so that it is formatted?

Also the line that says end /// this end is not valid julia syntax. Did you try to write a comment? In julia comments are indicated with #.

Also p++ is not correct julia syntax, it should be p = p + 1 (I think this is your actual error).

Did you copy this from code in another language?

function crack(n)
    dd=Dict(1=>n)
    d=2
    p=0
    while n>=d && n%d==0
        n/=d
        p+=1
    end
    if p>0
        dd[d]=p
    end
    d=1
    while n>=d
        p=0
        d+=2
        while n>=d 
            if n%d!=0
                break
            end
            n/=d
            p++
         
        if p>0
            dd[d]=p
        end
    end
    return dd
end
        
        
dd=crack(24)

for (d,p) in dd
    println(d,"=>",p)
end
    




No that was not a comment, just a marker to show you where the compiler marked the complaint.
If I delete the end it;s an error- missing end tag.
If I keep the end tag the compiler barfs.
I believe I correctly assume that all controls need their own end tags.

This is the python code for the same factoring


from sys import argv


def crack(N):
	ff={}
	n=int(N)
	ff[0]=n;
	d=2
	p=0
	while n>=d and not n%d:
		n/=d
		p+=1
	if p>0:
		ff[d]=p
	
	d=1
	while (n>=d):
		d+=2
		p=0
		while n>=d and not n%d:
			n/=d
			p+=1
		if p>0:
			ff[d]=p
	return ff

def stringy(ff):
	dd=[d for d in ff.keys() ]
	x=dd.index(0)
	n=ff[0];
	if n in ff:
		dd.pop(ff[n])
	print(ff)
	print(f'x={x} dd={dd}')
	dd.pop(x)
	print(f'pop dd={dd}')
	
	s=f'{ff[0]} ='
	if len(dd) == 0: 
		return s+"PRIME"
	for d in dd:
		s+=f'{d}^{ff[d]} * '

	return s[0:-2]
	



if __name__=='__main__':
	
	n=1
	for a in argv[1:]:
		ff=crack(a)
		print(f'cracking {a}')
		print(f'{n}) {stringy(ff)}')
		n+=1
		print()
``
    while n>=d
        p=0
        d+=2
        while n>=d 
            if n%d!=0
                break
            end
            n/=d
            p++ # what is p++?
        # no end here?
        if p>0
            dd[d]=p
        end
    end

Proper formatting already highlights the issue.

Yes you are correct in that everything needs an end. As explained in my previous response the problem is that p++ is not correct julia code, that is confusing the compiler. This works:

function crack(n)
    dd=Dict(1=>n)
    d=2
    p=0
    while n>=d && n%d==0
        n/=d
        p+=1
    end
    if p>0
        dd[d]=p
    end
    d=1
    while n>=d
        p=0
        d+=2
        while n>=d 
            if n%d!=0
                break
            end
            n/=d
            p = p + 1
        end
        if p>0
            dd[d]=p
        end
    end
    return dd
end
        
        
dd=crack(24)

Actually, the error isn’t p++ in and of itself; the error is that ++ is parsed as an infix operator (that is undefined by default but can be defined by the user), but p++ (or p ++) only provides one argument (p) to the function call, whereas two arguments are expected (something like p ++ a). Thus, when the parser encounters p++ followed by end, the end is unexpected because the parser expected another argument to the ++ function call. You would get the same error if instead of p++ you had p+.

But I agree that it seems like there should be a way to make the error message more informative of the actual error (a missing argument to an infix operation). It probably also would make sense to make a special error message for p++ to point out that p++ is not the same as p += 1.


I was curious, and it looks like the same error occurs if you replace p++ with ++(p, (i.e., an incomplete function call, which is what p++ is). I would think the error message could be more informative in this case, too.

Of course, I have no experience with Julia’s parser, so I have no idea how easy it would actually be to improve these error messages.


Also, a lot of smart people with little time work on Julia (I’m not one of them), so if you could kindly refrain from derogatory comments towards people’s hard work that would be appreciated. It is sufficient to point out what can be improved.

11 Likes

I opened a couple of issues:

Thanks Steven. Also thanks for clarifying that the syntax is allowed. That explains the message.