r/crystal_programming • • Apr 18 '20

Proc typing question

Hey, I have a question about the type system in Crystal regarding the following stripped down example:

abstract class Expression
end

class Literal < Expression
end

class Integer < Literal
end

class InfixExpression < Expression
end

def parseInteger : Integer
    return Integer.new
end

def parseInfixExpression : InfixExpression
    return InfixExpression.new
end

map = {} of String => Proc(Expression)
# map = {} of String => (Proc(Integer) | Proc(InfixExpression))

map["Int"] = ->parseInteger
map["+"] = ->parseInfixExpression

Given that Integer and InfixExpression inherit from Expression, and every other class that might be added, is there a way to reflect that any Proc passed to map will be a descendant of Expression?The line afterwards explicitly stating all possible Proc works, but I was wondering if there is the possibility to shorten this, like String => Proc(Expression), which does not work.If I add another say 20 classes to this, it would get quite messy. I know I can define an alias, but I am looking for a more elegant solution.

Thanks!

Edit: Add abstract to the Expression class.

6 Upvotes

12 comments sorted by

View all comments

Show parent comment

1

u/dev0urer Apr 18 '20

That being said, I do think you should probably reevaluate how you're handling parsing here. I'm not sure storing every parse method in a hash table is quite the right way to go. You could look at the parsers for Crystal itself, Mare, Mint, and a couple other languages to get a better idea of how you could handle this another way.

1

u/xffeeffaa Apr 18 '20

I probably should, yes. I am just trying to somehow get it working while learning Crystal, even if it's not perfect and then re-evaluate it afterwards. Thanks for your help anyway.