On 09/29/2015 12:28 PM, Tim Roberts wrote:
I'm coming to Racket after many decades of programming in other
languages. One of the things that still gives me trouble is being able
to know exactly what type of "thing" I have at any given point.
Let me give you an example, which is actually quire similar to a
question asked last December. I've been playing with the database
module to read through a Mysql database. If I use query-rows, I get a
list of vectors. That's fine -- I know how to enumerate through the
list, and I know how to access the columns in the vector. But if I use
in-query, then I don't know what I'm getting. I get back a stream, but
a stream of what?
Here's an example.
(define rset (query-rows dbc "SELECT id,name,council FROM clubs
LIMIT 2"))
(length rset)
(first rset)
(define rset1 (in-query dbc "SELECT id,name,council FROM clubs LIMIT
2"))
(sequence-length rset1)
(sequence-ref rset1 0)
If I run that, the output is:
2
'#(35 "Salem Swingin' Stars" "Mid-Willamette Council")
2
35
"Salem Swingin' Stars"
"Mid-Willamette Council"
Clearly, the first thing is a vector. Easy-peasy. What's the second
thing? What type of thing prints as 3 separate entities with no
apparent container? It's true that I can iterate through the items by
doing:
(for ([(id name council) rset1]) (...))
but that only works if you know the number of columns beforehand. What
if I want to handle a variable number of columns? I foolishly assumed
that each entry in the sequence would be a vector, but this fails with
an arity mismatch:
(for ([row rset1]) (...))
as does this:
(define row (sequence-ref rset1 0))
Is in-query simply the wrong toy to use in that situation? What IS the
type of (sequence-ref rset1 0) in my example?
It's a multiple-valued sequence [1]; each iteration produces as many
values as the row has fields. Note that in Racket, "multiple values" is
not a first-class object.
You can receive multiple values using define-values (or let-values), if
you know how many to expect:
(define-values (id name council) (sequence-ref rset1 0))
Or you can deal with an arbitrary number of multiple values by using
call-with-values, eg to collect them in a vector:
(call-with-values
;; Thunk that produces multiple values:
(lambda () (sequence-ref rset1 0))
;; Variadic function that receives the values:
(lambda vs (list->vector vs))
(The latter function can be simplified to just `vector`, which takes an
arbitrary number of arguments and forms a vector containing them.)
Ryan
[1]
http://docs.racket-lang.org/guide/for.html#%28part._.Multiple-.Valued_.Sequences%29
--
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.