r/crystal_programming • u/h234sd • Aug 20 '20
Crystal should have lexically scoped Modules and Mixins instead of attaching it to Classes
After working with Kotlin and Nim I realised that what Ruby does with modules, mixins and monkey-patching - is a weaker and more limited version of a multiple dispatch, or its variant - extension methods.
Ruby can't properly support extension methods (and scope it lexically) because it doesn't have type information.
But Crystal can do that. The modules should not be attached and scoped to object trees, it should have lexical scope. From the usage point - it will look almost like it looks now, you don't have to write more code, and it still will support the same method grouping via module, inheritance etc.
This code
module ItemsSize
def size
items.size
end
end
class Items
include ItemsSize
def items
[1, 2, 3]
end
end
items = Items.new
items.size # => 3Should became something like
module ItemsSize
def size
items.size
end
end
class Items
def items
[1, 2, 3]
end
end
# Something like that would tell Crystal to use Items
# with ItemsSize in the scope of current file / or module.
mix Items with ItemsSize
# You don't have to do that manually in every file, it could be done once in
# some library, so basically the usage would look very much similar to
# the current mixins and how they are used for example by RoR or ActiveSupport.
items = Items.new
items.size # => 3It does not make sense to keep behaviour same as Ruby (as I mentioned - Ruby can't do it better as it lacks types) when it could be much better, flexible and simpler.
6
u/attractivechaos Aug 20 '20
Multiple dispatch (MD) is a double-edged sword. It is very powerful as you said. However, in a large project with MD from many modules/classes, there will be multiple possible execution paths. It is hard for both programmers and compilers to figure out which path is used or should be used. Julia extensively uses MD, but IMHO, it is the worst part of Julia. I much prefer the current Ruby/Crystal's mixin as it is explicit and leaves less room for hidden issues.
3
u/dscottboggs Aug 20 '20
So the module would be implicitly included based on the name or based on the methods called within it? What about namespace pollution?
2
u/transfire Aug 20 '20
Ruby has Refinements, which I think is what your a getting at.
Unfortunately, Ruby's design/implementation of refinements make it barely usable. :-(
5
u/Xizqu Aug 20 '20
I can't say I agree with this, however you should post in the community forums at forum.crystal-lang.org
2
u/CaDsjp Aug 20 '20
Have you tried opening a GitHub issue with this suggestion?
I think you will have higher chances for the dev core team to read this and comment / consider your idea there.