Reputation: 897
I've been solving the problem sets from Harvard's CS50 with Julia. This script is meant to be my solution of [plurality elections.]1
println("How many contenders do we have?")
const max_candidates = parse(Int, readline()) # a maximal number of candidates
# Let us define a composite type for the candidates in our elections
mutable struct Candidate
name::String
votes::Int64
end
function vote(name)
for i in 1:max_candidates
if candidates[i].name == name
candidates[i].votes = candidates[i].votes + 1
end
end
end
function print_winner()
max_votes = 0
for i in 1:max_candidates
if candidates[i].votes > max_votes
max_votes = candidates[i].votes
end
end
for i in 1:max_candidates
if candidates[i].votes == max_votes
candidates[i].name
end
end
end
candidates = Vector{Candidate}(undef, max_candidates)
for i in 1:max_candidates -1
println("Name of the candidate: ?")
name = readline()
votes = 0
candidates[i] = Candidate(name, votes)
println("Thank you, let us move to the next candidate.")
end
#The last candidate i registered outside of the loop because I do no want
#the line println("Thank you, let us move to the next candidate.") to be executed after them.
println("Name of the last candidate: ?")
name = readline()
votes = 0
candidates[max_candidates] = Candidate(name, votes)
println("How many voters do we have?")
voter_count = parse(Int, readline())
for i in 1:voter_count
println("Who are you voting for?")
name = readline()
vote(name)
end
winner = print_winner()
println(winner)
When I run this script I get the following error
ERROR: LoadError: ArgumentError: `nothing` should not be printed; use `show`, `repr`, or custom output instead.
Stacktrace:
[1] print(::Base.TTY, ::Nothing) at ./show.jl:566
[2] print(::Base.TTY, ::Nothing, ::Char) at ./strings/io.jl:42
[3] println(::Base.TTY, ::Nothing) at ./strings/io.jl:69
[4] println(::Nothing) at ./coreio.jl:4
[5] top-level scope at none:0
[6] include at ./boot.jl:317 [inlined]
[7] include_relative(::Module, ::String) at ./loading.jl:1044
[8] include(::Module, ::String) at ./sysimg.jl:29
[9] exec_options(::Base.JLOptions) at ./client.jl:266
[10] _start() at ./client.jl:425
in expression starting at /home/jerzy/C.../plurality.jl:65
The expression referred in the error message as "expression starting at /home/jerzy/C.../plurality.jl:65" is the last name of the script.
I do not understand what is this nothing
?
Nevertheless, following the suggestions of the error message I modified the last line of my code, changing it from:
println(winner)
to
show(winner)
and got the following output:
nothing
I did a some research here and there, yet being a newbie, I don't understand why can't I return a value from my function print_winner. From what I read, return statements are not obligatory.
In the definition of print_winner, when I substitute
candidates[i].name
with
println(candidates[i].name)
and then when the last line is
winner = print_winner()
then I am able to finally get the name of the winner. But it is not the way I want it. I want to return a value and assign it to a variable, and then do something with this variable. I would be able to do this in PHP or Racket, why cannot I in Julia?
Upvotes: 2
Views: 369
Reputation: 5551
The function print_winner
doesn't return anything, in which case the object nothing
is actually returned. So winner
gets the value nothing
(from winner = print_winner()
), and println(winner)
is equivalent to println(nothing)
, which leads to the error.
I want to return a value and assign it to a variable
Then just do that: return a value from print_winner
. Julia can't know what you would want this function to return, so you have to be explicit about it. By default, Julia returns the value of the function expression, which in this case is the result of the last expression, which is here a for
loop. The expression-value of a for
-loop is nothing
in Julia.
Upvotes: 5