armature icon indicating copy to clipboard operation
armature copied to clipboard

Multiple arg types is kinda messed up

Open xendk opened this issue 3 months ago • 6 comments

Trying to use the new multiple arg methods, I'm running into problems that might kill the multiple args idea. Take this:

      route context do |r, response, session|
        r.on "snapshot", String do |_, snapshot_id|
          snapshot = @project.snapshots[snapshot_id]

Which results in Error: expected argument #1 to 'Appocular::Storage::YAML(Appocular::Snapshot)#[]' to be String, not (Bool | String).

A bit of testing shows that the type of the block parameters is actually the union of the types returned by the called #match? methods (but only the ones that's actually called). Turns out that Tuple#map is just a macro that constructs a new tuple by inlining the block code. But the return type of self#[] would be the union of the types of the union, which in turn makes the return type of our block in on to the union of the return types of the match? methods.

Of course one can do as(Whatever) in one's on blocks, but I think it kinda ruins the DSL.

One solution that might work is making the multiple arg #is/#on into macros that unroll into nested single argument calls. That ought to make the compiler capable of pinpointing the exact type at each level, but I don't know if such a macro is possible.

What's your thoughts?

xendk avatar May 08 '24 19:05 xendk