Understand the "get" function in queries

Hello there,

I have a handy query that get me some blocks of different kind.

{ :title "All stories"
  :query [
  :find (pull ?b [*])
  :where
    [?b :block/properties ?prop]
    [(get ?prop :kind) ?kind]
    [(contains? #{"movie", "show", "anime", "book", "manga", "game"} ?kind)]
  ]
}

I want to exclude the blocks that are templates.
I know I can use the “missing?” function to achieve that.
What I try to do is to improve my understanding of the language.

{ :title "All stories"
  :query [
  :find (pull ?b [*])
  :where
    [?b :block/properties ?prop]
    [(get ?prop :kind) ?kind]
    [(contains? #{"movie", "show", "anime", "book", "manga", "game"} ?kind)]
    [(get ?prop :template) ?template]
    [(not (nil? ?template))]
  ]
}

Why doesn’t this query return anything ?
?template should be nil if the key was not present in props, according to the documentation.

It seems that the [(get ?prop :template) ?template] line filters out blocks without this tag, but I don’t understand why, I just want to affect the ?template variable.

Thanks for your time.

  • Prefer this syntax: (not [(nil? ?template)])
  • The line [(get ?prop :template) ?template]
    • already filters out blocks without this tag, because every clause is checked for missing return value
      • If missing, the respective entry is dropped.
    • would have the same effect as simply [(get ?prop :template)]

I get the others points, but I’ll need more information on that bit. Can you elaborate on the difference in syntax ? Thanks.

For instance, I don’t get why [(nil? ?template)] should be surrounded in brackets while not doesn’t.

  • [] is a rule
  • [()] is a predicate inside a rule
    • e.g. (nil? ...) is a predicate
    • predicates go inside rules
  • [() ?var] is a function-call inside a rule
    • e.g. (get ...) is a function-call
    • functions go inside rules
  • ([]) is a rule inside a clause
    • e.g. (not ...) is a clause
    • clauses can be nested, in contrast to the previous cases
3 Likes