Feature Request: autocasting NamedTuples and Tuples to types

This feature request can fall into the “too clever for its own good” category, so I wanted to solicit opinions here on what others would think.

I like using Tuples and NamedTuples when the structure of my input data is known in compile time, and I like using structs / classes for their methods. I’d like to propose support for autocasting from a Tuple or NamedTuple to a specific type when the type has an initialize method that has the correct positional or named parameters and types.

The below example I hope better illustrates my thoughts:

# Some simple class or struct, has a `def intialize(bar : String)...` method
record Foo, bar : String do
  def baz; puts baz; end

def method(foo : Foo)
  puts foo.bar
  puts foo.baz

# This is currently the only supported approach

# These are currently compiler errors
method({"bar"}) # => Could be inferred to Foo.new(*{"bar"})
method({bar: "bar"}) # => Could be inferred to Foo.new(**{bar: "bar"})

I’m curious what others would think if this inference logic. Too clever? Some edge case that would throw this out? Thoughts welcome!

1 Like

Being explicit is always better than implicit. For such uses cases its better to have developer implement such helper or overloaded methods which can convert Tuple/NamedTuple to specific object(s) and other way around.

IMO it doesn’t make good sense to have some black magic implemented in the language to cater for edge cases.

For your cited use cases (which IMO isn’t a well known use case, neither its something which is required too often or repetitive and require compiler or language to support that) it can be achieved by implementing overloaded constructor(s) and helper methods, so what benefit it brings to the language if compiler do this trick for you?

My 2cents.


Eh, one of the things I love about crystal is how it’s able to imply the type of so many things through inference logic, without needing to be explicit about everything. There are situations where being explicit is better, but I disagree that all situations are always better by being explicit (this might be a reaction on my part to years of java development and being subjected to the sheer amount of verbosity caused by being “explicit”).

The rest of your post makes sense, it is somewhat edge casey :) I appreciate your thoughts @naqvis, thanks.

Would you be willing to expand on your description “black magic” for this feature? Is it ambiguous or unclear on what would be going on? Or put another way, if this feature already existed in the crystal programming language, is there anything that exists today that would break or become hazardous in some way?

Being explicit was referring to the context where you are working on. If you are dealing with Crystal, then that means its better to be clear than being ambiguous. And I had no intention to suggest that one should stay away from the auto inference and other benefits Crystal brings to the table.

black magic was used to refer to the situations where one need to burn mind to understand what such call will be doing? will it be invoking method with variadic params? will it be invoking method with keyword arguments? or will it be doing some magic of converting parms to some object of some type, which this object is expecting.

Current behavior of language is very clear and straight-forward, you know what kind of methods will be invoked by looking at the call site, but if you add some extra functionality and expect compiler to do some processing in the backend for things to work, that’s what to me is a black magic, as one doesn’t know for sure what will happen without looking at the code of the object on which method is being invoked.