>  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`. Alternatively, you could just use 
`define-namespace-anchor` and `namespace-anchor->namespace`.

Thanks! That both explains and resolves the issue.

In my original example, if I replace the beginning part with:

#lang racket

(require db)
(require sql)

(define sql-namespace (make-base-empty-namespace))
(define src-namespace (current-namespace))
(parameterize ([current-namespace sql-namespace])
  (namespace-attach-module src-namespace 'sql)
  (namespace-require 'sql))

Then everything works as expected, and now I know why.

> But, as others have said, you really don't want to use `eval`. (If you 
aren't already familiar with the issues, see [...]

Point taken. At the time I just wanted the variable-columns thing working 
and I hadn't figured out how to make it work with a list. Additionally, 
escaping column names isn't going to be an issue, because most likely in 
the actual use case the user's required column list will pass through a 
whitelist. That part's solved, one way or another.

> 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.

That did occur to me, and was my other idea compared to eval, up until I'd 
figured out the INJECT thing, but I didn't do it as then there would be a 
huge amount of select statements. The idea was to basically take the column 
list, sort it, string-join, and then get the relevant select from a hash 
table. But there'd be way too many.

As to why I would like to do this, well, basically at my workplace we sort 
of make web applications, generally split into a separate server side 
application that's basically an HTTP API, that different browser and mobile 
applications talk to. I've previously always written the server side part 
in python. "Sort of" because have to work offline too.

One of the problems we face is of moving too much data around. Mobile 
applications that have to mainly work offline and periodically sync, they 
have to move around lots of data on horrible connections. (We do gzip and 
all. Choosing a data format that's not json is an option I'll evaluate in 
the future.)

So selecting a list of fields when getting data for different entites is 
something we provide in our APIs. In the beginning we did in fact return 
all of an entity's data. as writing different column sets for different 
clients, while do-able, is sort of bad in the sense that then when somebody 
asks for adding a column in a table in the mobile app, it required changes 
in two places, and needlessly adds code. The idea being that when we only 
write a different column set (and call it a different entity) on the same 
enttiy when it's a non trivial thing to do.

So anyway while most of this is solved for the current few projects we 
have, we're moving away from python. Racket's an experiment, partly chosen 
because we agree with the "many languages" approach. Things like python's 
django, sqlalchemy and javascript's vue aren't libraries, they're #langs. 
So now I have to write solutions/languages in Racket to make sure we're at 
least on par with what we have at the moment. Like in python we have our 
little filters language, which piggybacks on django ORM's column and 
relation lookup syntax, but we restrict some operations and add some 
others, nest them in and/or/not operators, and generically handle edge 
cases that django doesn't (like ensuring that joins don't increase row 
count). And no, writing SQL in the client application is not (yet) an 
option as we need to evaluate certain things first. Evaluated graphQL, a 
bit, tentatively, and alone, it doesn't to fit the use case. A hybrid 
approach seems do-able in the short term but a bad idea in the long term.

Anyway, thanks for the help. and I suppose I should mark this thread as 
solved (I don't know what that really does). I don't mind people asking 
things, but I suppose littering the list with specifics would be frowned 
upon.

-- 
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