> On Thu, May 26, 2011 at 2:40 AM, Edwin Eyan Moragas <e...@yndy.org> wrote:
> > Hi list,
> > after checking the 'select' predicate doc, i can't find any way to
> > limit the number of results of the query.
On Thu, May 26, 2011 at 10:30:13AM +0700, Henrik Sarvell wrote:
> >From http://www.prodevtips.com/2008/04/28/advanced-oodb-in-pico-lisp/ we
> (setq *Query (goal '(@Headline "2008" (db headline +Article @Headline @A))))
> (do 1 (bind (prove *Query) (println (get @A 'headline))))
> Instead of the less than practical second row you could do this:
> (do 10
> (prove *Query) (link @A) ) ) )
Let me add a little background explanation: An explicit limitation is
not needed. Also, this is not just an issue of 'select/3' specifically,
but concerns any Pilog query (as Henriks examples above).
'select/3', 'db/3' etc. just initiate the query, similar to a CURSOR in
SQL. It is up to the application to retrieve the results one after the
other, possibly ad infinitum.
'solve', however, retrieves them _all_, and returns them as a list, so
it is useful only for relatively small result sets.
More often used is 'pilog' (a frontend function to 'prove'), which
handles each result individually. Instead of the 'do' loop in Henrik's
example, you might also use 'pilog' and execute a 'throw' when you don't
want to continue any longer.
I think I usually use the following construct:
(for (Q (goal '((select (@Obj) ..) ..)) (and (some-condition) (prove Q)))
(with (; @ @Obj)
i.e. a 'for' loop with an init-clause and a condition (re-init clause is
omitted). The first argument to 'with' retrieves the object from the
list returned by 'prove'.
This is, BTW, also the mechanism used by 'pilog' itself:
: (pp 'pilog)
(de pilog ("CL" . "Prg")
(for ("Q" (goal "CL") (prove "Q"))
(bind @ (run "Prg")) ) )