Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!zaphod.mps.ohio-state.edu!sdd.hp.com!hplabs!otter.hpl.hp.com!otter!sfk From: sfk@otter.hpl.hp.com (Steve Knight) Newsgroups: comp.lang.lisp Subject: Re: Poplog (was: Re: Is this the end of the lisp wave? (core + penumbra)) Message-ID: <1350034@otter.hpl.hp.com> Date: 21 Jan 91 15:03:51 GMT References: <5538@idunno.Princeton.EDU> Organization: Hewlett-Packard Laboratories, Bristol, UK. Lines: 102 > I keep hearing about Poplog from our friends in the UK, but I'm still > unclear as to what exactly it means "to have CL, ML and Prolog" in this > language. Could some poplogger post an example that shows how these > three languages might be intertwined in a poplog program? The Poplog system includes compilers for four "intrinsic" languages. Each language has extensions for accessing the other compilers. (The compilers are incremental and interactive and play the role of interpreters.) It's normal to organise a multi-language program so that the usages of the different languages are isolated in different files. The example I give below puts the program all in one file, which is less usual. What makes inter-language working feasible in Poplog is that the four intrinsic languages share the same underlying datatypes. For example, Prolog's numbers, atoms, and lists are identical to those of Common Lisp. Structures which are special to Common Lisp (such as vectors) are treated as atoms by Prolog. Common Lisp is supplied with a number of functions for manipulating Prolog terms. For example, from inside Prolog you can call out to Lisp using lisp_apply(Func, Arglist, Result) or, for multiple values, lisp_mv_apply(Func, Arglist, Resultlist) There are many other ways to access Lisp entities from Prolog, of course. The Lisp/Prolog interface utilises the following read macros: {functor arg1 arg2 ... argN} notates a goal in prefix form $word notates a prolog atom ?var notates a prolog atom To illustrate: {$append ?x ?y '(a b c d e)} This creates a Prolog 'goal', a data structure comprising a Prolog term and an association list mapping Lisp symbols to Prolog variables. Note that the forms inside the {} brackets are evaluated as normal Lisp forms (hence the use of $ to notate the functor). Prolog goals can be invoked as boolean functions, by using: (PLOG-GOAL-CALL goal) There's a special-form DO-PLOG that can be used to iterate over all the solutions to a Prolog goal. e.g. (do-plog {$append ?x ?y '(a b c)} (x y) (pprint x) (pprint y) (terpri)) NIL (A B C) (A) (B C) (A B) (C) Finally, here's a tiny example showing Prolog interworking with Pop11 to write a predicate 'shuffles' that creates random permutations of a list. I'd do it in Commn Lisp, but I write Common Lisp so rarely I'd be bound to make a mistake! /* Note that the RHS of an 'is' call call Pop11 functions -- exploiting the syntactic similarity of Pop11 expressions and Prolog terms in order to look natural. */ shuffles( L, S ) :- repeat, S is shuffle( L ). /* Drop into Pop11 to define the shuffle function. It's easier to write shuffle in Pop11. */ :- prolog_language( 'pop11' ). define shuffle( L ); lvars L; ;;; copies the list L to a simple vector v lvars v = L.destlist.consvector; ;;; iterate over decreasing segments of v, swapping the ith element ;;; for any item in the segment. lvars i; for i from v.datalength by -1 to 2 do lvars r = random( i ); ;;; this expression exploits the open stack ( v( r ), v( i ) ) -> ( v( i ), v( r ) ); endfor; ;;; returns v copied back to a list v.destvector.conslist; enddefine; /* Switch back to prolog */ :- prolog_language( 'prolog' ). I hope these small examples give you a feel for what Poplog folks are talking about. It's only a tiny glimpse, of course, but it may enable you to relate it to previous work. You should also bear in mind that the implementations of Common Lisp, Prolog, and ML in Poplog do not currently perform as well as standalone implementations of the same languages -- perhaps half the performance, sometimes much worse, sometimes much better. This is a consequence of the underlying compiler backend, which is optimised for speed of compilation rather than speed of execution of final code. (Compilation speed is excellent, though. There's no need for an interpreter.) Steve