John Smith
John Smith

Reputation: 897

Cannot return value from a function: ERROR: LoadError: ArgumentError: `nothing` should not be printed; use `show`, `repr`, or

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

Answers (1)

rafak
rafak

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

Related Questions