On the original question: Racket's struct types are generative (except for
#:prefab structs), meaning that each time you evaluate a `struct` form (or,
at a lower level, each time you call `make-struct-type`), the you create a
fresh type distinct from all other types. That can be a bit confusing to
just think about in the abstract, so here's a little illustration that
doesn't involve namespaces or modules:
#lang racket
(require rackunit)
(define (generate)
  (struct thing ())
  (values (thing) thing?))
(define-values (a-thing1 thing1?)
  (generate))
(define-values (a-thing2 thing2?)
  (generate))
(check-false (thing2? a-thing1))
(check-false (thing1? a-thing2))

The issue you're encountering with namespaces is analogous, because each
namespace gets its own instances of modules. This is a feature! Imagine,
for example, that you are trying to run students' programs in a sandbox. If
namespaces shared module instances, a malicious or buggy student program
could alter mutable state and affect other students' programs or your
outside-the-sandbox program. But this means that two different namespaces
will have two distinct instances of the `sql` module that export two
distinct `sql-statement?` predicates, each recognizing only its own version
of the sql-statement struct type: this is effectively the same situation as
calling `thing1?` on `a-thing2` in my example.

For times when you really do want to share a module instance, Racket
provides `namespace-attach-module
<https://docs.racket-lang.org/reference/Namespaces.html?#(def._((quote._~23~25kernel)._namespace-attach-module))>`.
Alternatively, you could just use `define-namespace-anchor
<https://docs.racket-lang.org/reference/Namespaces.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define-namespace-anchor%29%29>`
and `namespace-anchor->namespace
<https://docs.racket-lang.org/reference/Namespaces.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._namespace-anchor-~3enamespace%29%29>
`.

But, as others have said, you really don't want to use `eval`. (If you
aren't already familiar with the issues, see
https://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html)
The only part of what you want that (AFAIK) you can't already do with the
`sql` library's dynamic facilities is selecting a dynamically-determined
number of columns. I think your work-around using `ScalarExpr:INJECT` is
reasonable, with the caveat that you need to be sure to understand the
quoting/case-folding rules for the specific database(s) you're targeting.

More broadly, it might help to know why you want to select a number of
columns to be determined dynamically at run-time. I can't immediately think
of a time when I've ever wanted to do that. If you can say a bit more,
there may be a solution to your ultimate problem that doesn't need this
functionality. For example, if you want to select a few different sets of
columns from the same base query, you could write the base query as one
select expression that selects all the columns, then re-use that as the
`#:from` table expression through dynamic composition in more select
statements that return only the particular sets of columns you're
interested in. As long as you at least know the schema you're working with,
you could even generate select statements for all possible sets of columns
at compile time, and then just choose the right statement dynamically with
a runtime function.

If it turns out that you really do need to determine the number of columns
dynamically, you certainly could make a feature request. (Ryan has been
kind enough to accept a few of my pull requests to add some features I've
needed, including additional dynamic statement composition hooks.) The main
thing would probably be to figure out a principled way to structure the
feature.

-Philip


On Fri, Feb 1, 2019 at 11:02 PM hashim muqtadir <hashim.muqta...@gmail.com>
wrote:

> > Good news, limit and distinct are in scope for v0.2 - I'm working on it
> now :)
>
> That's good to hear, thanks! I'll be sure to check it out, and let you
> know if I have any ideas/requirements for features or if I can contribute.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to