Edgar Klerks
Edgar Klerks

Reputation: 1537

Polymorphic functions and subtypes in julia

I am learning Julia and for that purpose I am building a simulation of a scheduler for some non specified task. For this I want to create an abstract type, which represents the idea of state. A task could be in any state Accepted, Unfulfilled, Running, Finished:

abstract RequestState 

Then I add some concrete states, which have RequestState as superstate:

immutable StateAccepted <: RequestState 
       name :: String 
end 

And because each state is immutable anyway and it doesn't have an interesting structure, all instances are the same, so I instantiate an instance of the above type to use:

const Accepted = StateAccepted("Accepted")

I generate this with a macro, perhaps it is relevant.

Now comes the problem. I want to write a function, which checks valid transitions. I only have a skeleton at this point:

function checkTransition{T <: RequestState, Q <: RequestState}(t :: T, q :: Q) :: Bool 
  return true 
end      

I assumed I should read the expression:

 T <: RequestState 

As something like forall T which is a subtype of RequestState, but I think this is wrong.

I would expect that this code compiles. The problem is that I don't understand the error and also can't find anything in the documentation. Note that this could be, because I am unfamiliar with the language. The relevant error is:

 Error During Test
  Expression evaluated to non-Boolean
   Expression: checkTransition(Accepted,Running)
   Value: ResourceScheduler.StateRunning("Running")
 ERROR: LoadError: There was an error during testing
   in record(::Base.Test.FallbackTestSet, ::Base.Test.Error) at      ./test.jl:397
    in do_test(::Base.Test.Returned, ::Expr) at ./test.jl:281
    in include_from_node1(::String) at ./loading.jl:488
    in process_options(::Base.JLOptions) at ./client.jl:262
    in _start() at ./client.jl:318
    while loading /home/eklerks/.julia/v0.5/ResourceScheduler/test/runtests.jl

How would I make a generic function accepting only arguments of subtypes of RequestState?

EDIT:

As requested the offending test:

@test checkTransition(Accepted, Running) 

But this didn't work out, because I forgot to update and install my package after I changed it. Before that change it read:

function checkTransition{T <: RequestState, Q <: RequestState}(t :: T, q :: Q) :: Q 
    return q 
end 

Which was the source of the error. Type Q is indeed not a Boolean. I was experimenting with the type system at that moment.

Upvotes: 0

Views: 310

Answers (1)

Fengyang Wang
Fengyang Wang

Reputation: 12051

While your code should work, typically one writes

checkTransition(t::RequestState, q::RequestState) = true

instead of using the unnecessary T <: RequestState parameterization. Note that f{T <: X}(::T) should not be read as "for all T subtype of X", but rather "there exists T subtype of X", as this is an existential type and not a universal type.

The error you're getting is due to checkTransition(Accepted,Running) returning a non-boolean, which must be due to a mistake unrelated to the code that you've posted.

Upvotes: 4

Related Questions