[plt-scheme] Errors from Snooze Quick Start

From: Dave Gurnell (d.j.gurnell at gmail.com)
Date: Tue Jan 6 20:36:47 EST 2009

Henk Boom wrote:
> I actually meant without the parentheses. I've never tried this, but
> I'm under the impression that this can be done with
> make-set!-transformer.

That's what I'm using in this new code. It definitely sounds like  
we're thinking along the same lines.

> Dave Gurnell wrote::
>> [...] if you use person with parentheses, you get what is  
>> effectively an alias for use in queries:
>>   (person)               ; ==> table-alias
>>   (person name)          ; ==> column-alias
>>   (sql (select #:from (person)))
> That could work, but why not allow the use of the accessors  
> directly? [...]
> rather than using person-name as an accessor and (person name) as an  
> alias,
> you allow the use of person-name as both a structure accessor and as  
> an sql
> column alias. I think that would be much clearer to use.

Ah yes... I get you. That's a neat way of doing it. There are a lot of  
factors in play here, though, and I can see arguments that run both  

One thing to consider is that there are two query languages in Snooze.  
There's the syntax query language, which is terse and neat:

   (sql (select #:from (inner person employer (= person-employer-id  

and there's a procedural version that's a little more flexible in that  
you can use things like "apply":

   (sql:select #:from (sql:inner person employer (apply sql:= (list  
person-employer-id employer-id))))

(The latter is provided from snooze.ss but is pretty poorly covered in  
the docs.)

I find that the procedural language is an infrequent but definite  
necessity in Untyped applications: there are a few queries that just  
can't be constructed without it. Ideally we need a consistent way of  
referring to aliases that works in both situations.

The unparenthesised approach is fine in the syntax language because we  
can design the language to interpret identifiers in whatever way is  
appropriate. The procedural language is tricker, though, because it is  
just regular Scheme.

The identifier "person" is already used at expansion time (struct type  
identifier) and run time (entity metadata). We need a way of referring  
to the alias (instead of these other things) when we're in a query.

The parenthesised approach works for this because a parenthesised use  
of the identifier can always be resolved to an alias:

   (sql:select #:what (list (person name)) #:from (sql:inner  
(person) ...))

However, the unparenthesised approach requires further thought. One  
approach would be to store a default alias in the entity metadata and  
lift entities and accessor procedures at run-time (neat but slower):

   (sql:select #:what (list person-name) #:from (sql:inner person ...)))

Another approach would be to require the programmer to wrap the  
identifiers in (sql ...) blocks so the identifiers can be interpretted  
at expansion time (faster but much messier):

   (sql:select #:what (list (sql person-name)) #:from (sql:inner (sql  
person) ...)))

And now it's after midnight. I'm probably not making much sense so  
I'll stop. This is definitely worth further discussion, though. I'll  
give it some solid thought, chat to the other Untypers, and post again  
when the ideas are more solidly formed in my head.

Thank you for the injection of fresh ideas!


-- Dave

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20090107/ebfc1ee5/attachment.html>

Posted on the users mailing list.