beam icon indicating copy to clipboard operation
beam copied to clipboard

A variant of select that doesn't require QBaseScope

Open enobayram opened this issue 3 years ago • 2 comments

Wouldn't it be completely safe to have a variant of the select function with the following signature:

select' :: forall s be db res. 
  (BeamSqlBackend be, HasQBuilder be, Projectible be res) => 
  Q be db s res -> 
  SqlSelect be (QExprToIdentity res)

I.e. one that doesn't insist on having QBaseScope. I know this is an odd thing to want, but I find myself writing higher order beam utilities that involve passing query fragments around, and they play better with type inference when the types are as monomorphic as possible and sometimes that requires me to select a Q be db (QNested something) res. If I understand the purpose of QNested correctly, it's not safe to cast a Q be db (QNested QBaseScope) res to a Q be db QBaseScope res in general, but it should be safe to select a Q be db (QNested QBaseScope) res, right? If my assumption is correct, having that select variant would enable some advanced use cases for me.

I know I could just copy-paste the implementation of select and give it the type I want, but I want to confirm here that it is indeed a safe thing to do.

enobayram avatar Dec 16 '22 09:12 enobayram

QBaseScope et al were put in place because of limitations of the Haskell type system at the time. It's likely we can get rid of this. In fact, we should probably rethink the entire scoping system in light of new GHC features, and be willing to break compatibility.

tathougies avatar Feb 22 '23 04:02 tathougies

That sounds terrific. IME, the s parameter is the biggest friction to higher order programming with beam. Still doable, but it requires careful thought.So I'd say removing that friction is definitely worth a major version.

If my understanding is correct, the purpose of the s parameter is to make sure that bindings from one scope can't be used in a nested scope where, due to the underlying SQL semantics, those bindings shouldn't be visible. So, I'm curious, what are other ways you can enforce these boundaries without the s parameter?

enobayram avatar Feb 22 '23 05:02 enobayram