From: "Victor \"Zverok\" Shepelev" Date: 2006-12-06T20:35:35+09:00 Subject: Re: Lisp comprehensions => SQL From: khaines@enigo.com [mailto:khaines@enigo.com] Sent: Wednesday, December 06, 2006 1:15 PM >On Wed, 6 Dec 2006, Victor "Zverok" Shepelev wrote: > >>> Think about the syntax of it, though. >>> >>> From a ruby perspective, you call select(), then sort_by(), then [] >>> >>> Three separate method calls, and there is no way any of them can know >>> which is the last one. So there's no way to assemble the SQL call you >>> would like to see, where a single query is assembled to implement what >is >>> implied by those three separate method calls. >>> >> >> It's a matter of philosophy. > >No, my point is that philosophy doesn't matter there, because without some >additional information, it can't work quite like you have described it. > >If you requires that a query start with a call to select(), but not be >invoked until a second method call, then it would be possible; > >employees.select{|e| (e.name == 'John') & (e.salary > 50)}.sort_by{|e| >e.age}[2..10].run > >You could assemble all of the information that described the query with >the chained method calls; the sentinel that indicates the end of query >construction is the call to run() > >> To the contrary, trying to read this >> >> employees.select{|e| (e.name == 'John') & (e.salary > 50)}.sort_by{|e| >> e.age}[2..10] >> >> is very familiar for any rubyist; but also cause a bunch of questions >from >> SQL perspective (would it be performed in one request or several? How >many >> data would be selected? What's the overhead?) > >That syntax seems very straight forward from a Ruby perspective and a >database interaction perspective. > >1) select all employees from the database where the name is 'John' and the >salary is greater than 50. Return that result set. That's a discrete >method call that invokes a discrete database interaction. > >2) Sort the result set by the age field on the records. > >3) Return a slice from the result set. > >I think your original wish -- that all of those operations magically be >combined into a single query -- would be counterintuitive if it were >possible without some sort of a final sentinel method call like I >illustrated above. > OK, I agree. I've came to proposed version in two stages: 1. was excited about idea on "list comprehension as database request" ideom 2. was translated the "common" list comprehension to Ruby-style one. Hence the controversial result. Idea I ruled by was shown in Links[1] language overview and looks like where (prefix != "") take(10, for (var w <- wordlist) where (w.word ~ /{prefix}.*/) orderby (w.word) [w] ) Which, in turn, looks like "only one" method call. Where ruby's equivalent is several calls. So, for consistency, the idea must look like you've shown: employees.select{|e| (e.name == 'John') & (e.salary > 50)}.sort_by{|e| e.age}[2..10].run or, may be employees.do{ select{|e| (e.name == 'John') & (e.salary > 50)}.sort_by{|e| e.age}[2..10] } Hmm. I see, while I'm writing this, you have already posted the nearly same :) V. 1. http://groups.inf.ed.ac.uk/links/