Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta-Reduce Trivial Conditionals #1692

Open
deusaquilus opened this issue Nov 3, 2019 · 1 comment · May be fixed by #1693
Open

Beta-Reduce Trivial Conditionals #1692

deusaquilus opened this issue Nov 3, 2019 · 1 comment · May be fixed by #1693

Comments

@deusaquilus
Copy link
Collaborator

deusaquilus commented Nov 3, 2019

Version: (e.g. 3.4.8)
Module: (e.g. quill-core)
Database: (e.g. ALL)

As is well known, using a conditional to select a query based on a runtime variable does not work for compile-time queries.

val q = if (cond) quote(query[Person].filter(_.name == "Joe")) else quote(query[Person]) 
q: Quoted[EntityQuery[Person]]{def ast: io.getquill.ast.Query with Product with Serializable} = querySchema("Person").filter(x1 => x1.name == "Joe")

run(q) 
cmd9.sc:1: Dynamic query
val res9 = run(q)

One way to solve this issue however would be to introduce a beta-reduction that would select the then or else clause of a If AST if it sees that the value of condition is trivially true e.g. if it's Constant("foo") == Constant("foo"). That way it would be possible to use conditionals to choose one Query versus another inside of a quotation.

val q = quote { 
  (cond:String) => 
    if (cond=="foo") 
      query[Person].filter(_.name == "Joe") 
    else 
      query[Person] 
} 

// doing q("foo") reduces the AST to: query[Person].filter(_.name == "Joe")
run(q("foo"))
// SELECT p.name, p.age FROM Person p where p.name = 'Joe'

@getquill/maintainers

@deusaquilus deusaquilus linked a pull request Nov 4, 2019 that will close this issue
5 tasks
@deusaquilus
Copy link
Collaborator Author

Now keep in mind that you still wouldn't be able to use runtime variables in these reductions for instance:

val v = "foo"
run(q(lift(v)))

What you would be able to do however, is to use compile-time values to make a choice as to what kind of query to select:

val v = "foo"
if (v == "foo") run(q("foo")) else run(q("bar"))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant