Re: Java interop
Hi Henrik, nice research! writeup here: http://www.prodevtips.com/2010/05/30/clojure-with-a-picolisp-= database-via-clojure-http-client/ Concerning your worries about using 'eval' in: (println (eval (list 'get (qReq 'link) (qReq 'direction) (qReq 'attr Perhaps I don't fully understand the problem, but wouldn't simply (println (get (any (req 'link)) (any (req 'direction)) (any (req 'attr)) ) ) do it, and 'apply' or 'eval' are not necessary at all? Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: Java interop
Fixed, works, thanks! My own simple testing confused me, since then I would do (get '{x-x} 'to 'uid), I just locked on to that and thought I would need the quotes and all but of course I don't. On Thu, Jun 3, 2010 at 8:23 AM, Alexander Burger a...@software-lab.de wrot= e: Hi Henrik, nice research! writeup here: http://www.prodevtips.com/2010/05/30/clojure-with-a-picoli= sp-=3D database-via-clojure-http-client/ Concerning your worries about using 'eval' in: =A0 (println (eval (list 'get (qReq 'link) (qReq 'direction) (qReq 'attr)= ))) Perhaps I don't fully understand the problem, but wouldn't simply =A0 (println =A0 =A0 =A0(get =A0 =A0 =A0 =A0 (any (req 'link)) =A0 =A0 =A0 =A0 (any (req 'direction)) =A0 =A0 =A0 =A0 (any (req 'attr)) ) ) do it, and 'apply' or 'eval' are not necessary at all? Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=3dunsubscribe -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: Java interop
I tried out communication via HTTP in the weekend, posted a little writeup here: http://www.prodevtips.com/2010/05/30/clojure-with-a-picolisp-= database-via-clojure-http-client/ It worked well enough that I will probably not put any effort into getting up and running with InOut.java On Fri, May 28, 2010 at 10:56 AM, Henrik Sarvell hsarv...@gmail.com wrote= : Thanks for that one, haven't had time to look into it yet, but I have had time to think a bit about the interop problem. An easier way out that would also result in a more general solution would be to simply use the http server in PL and work on the contents of POST variables, using JSON or plain literal lists as the data format. Some people might wonder about the list part since we're talking about Java here but I have no intention of writing my application logic in pure Java, I will use Clojure which is a lisp. If special structures are avoided as elements in a list then a list in Clojure will look exactly like a list in PL. So http-posting it to PL and then having PL simply evaluate it should work while avoiding the overhead of JSON. In this way data can come from may sources, especially if JSON is added as a format that could be handled, API's would be a breeze to launch. The downside is of course that it involves more overhead, but I'm starting to get the feeling that it might be worth it. Any thoughts on this (hopefully more people than Alex will chime in) ? On Thu, May 27, 2010 at 2:05 PM, Alexander Burger a...@software-lab.de w= rote: On Thu, May 27, 2010 at 11:45:57AM +0200, Henrik Sarvell wrote: Now pretend I have a PL database that listens on say port 4040, could it be possible to use the current Java interop code to pass data to that database for storage? This is not directly supported by the existing interfaces, as 'Reflector' is itself a server which expects to be queried by PicoLisp. On the PicoLisp side nothing special needs to be implemented. On the Java side you need library that connects to the PicoLisp server, sends requests, and receives answers via java/InOut.java. This is in fact very similar to what the old Java GUI applets are doing (mainly in java/Pico.java). These applets connect back to the HTML server on a dedicated port (passed via the HTML page as a parameter to the applet), and use the PLIO functions (in java/InOut.java) to send events and receive layout and content informations from the server. Parts of the 'connect' method (line 36 in java/Pico.java) and all the calls to 'IO.somefunction()' might be useful. You could simply send complete PicoLisp statements, packed into Java arrays. They will appear as lists in PicoLisp. But easier is probably sending the data items individually, as you then have better control over the type. For example, with 'prSym()' you can then send internal symbols (typically functions), directly executable on the PicoLisp side (I hope to don't forget about security ;-) For example, to call (collect 'nm '+Cls) on the DB server (not tested): =A0 IO.Out.write(BEG); =A0 =A0 =A0IO.prSym(collect); =A0 =A0 =A0IO.Out.write(BEG); =A0 =A0 =A0 =A0 IO.prSym(quote); =A0 =A0 =A0 =A0 IO.Out.write(DOT); =A0 =A0 =A0 =A0 IO.prSym(nm); =A0 =A0 =A0IO.Out.write(BEG); =A0 =A0 =A0 =A0 IO.prSym(quote); =A0 =A0 =A0 =A0 IO.Out.write(DOT); =A0 =A0 =A0 =A0 IO.prSym(+Cls); =A0 Out.write(END); =A0 IO.flush(); So this is a bit tedious. If the PicoLisp server uses a dedicated port f= or the Java queries, and does not =A0 (while (rd) =A0 =A0 =A0(eval @) ) but instead =A0 (while (rd) =A0 =A0 =A0(apply @ (rd)) ) then you can send the arguments without quoting in a list (array): =A0 Object args[]; =A0 // fill args with 'nm' and '+Cls', and possibly more =A0 IO.prSym(collect); =A0 IO.print(args); =A0 IO.flush(); Hope this works ;-) Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=3dunsubscribe -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: Java interop
Thanks for that one, haven't had time to look into it yet, but I have had time to think a bit about the interop problem. An easier way out that would also result in a more general solution would be to simply use the http server in PL and work on the contents of POST variables, using JSON or plain literal lists as the data format. Some people might wonder about the list part since we're talking about Java here but I have no intention of writing my application logic in pure Java, I will use Clojure which is a lisp. If special structures are avoided as elements in a list then a list in Clojure will look exactly like a list in PL. So http-posting it to PL and then having PL simply evaluate it should work while avoiding the overhead of JSON. In this way data can come from may sources, especially if JSON is added as a format that could be handled, API's would be a breeze to launch. The downside is of course that it involves more overhead, but I'm starting to get the feeling that it might be worth it. Any thoughts on this (hopefully more people than Alex will chime in) ? On Thu, May 27, 2010 at 2:05 PM, Alexander Burger a...@software-lab.de wro= te: On Thu, May 27, 2010 at 11:45:57AM +0200, Henrik Sarvell wrote: Now pretend I have a PL database that listens on say port 4040, could it be possible to use the current Java interop code to pass data to that database for storage? This is not directly supported by the existing interfaces, as 'Reflector' is itself a server which expects to be queried by PicoLisp. On the PicoLisp side nothing special needs to be implemented. On the Java side you need library that connects to the PicoLisp server, sends requests, and receives answers via java/InOut.java. This is in fact very similar to what the old Java GUI applets are doing (mainly in java/Pico.java). These applets connect back to the HTML server on a dedicated port (passed via the HTML page as a parameter to the applet), and use the PLIO functions (in java/InOut.java) to send events and receive layout and content informations from the server. Parts of the 'connect' method (line 36 in java/Pico.java) and all the calls to 'IO.somefunction()' might be useful. You could simply send complete PicoLisp statements, packed into Java arrays. They will appear as lists in PicoLisp. But easier is probably sending the data items individually, as you then have better control over the type. For example, with 'prSym()' you can then send internal symbols (typically functions), directly executable on the PicoLisp side (I hope to don't forget about security ;-) For example, to call (collect 'nm '+Cls) on the DB server (not tested): =A0 IO.Out.write(BEG); =A0 =A0 =A0IO.prSym(collect); =A0 =A0 =A0IO.Out.write(BEG); =A0 =A0 =A0 =A0 IO.prSym(quote); =A0 =A0 =A0 =A0 IO.Out.write(DOT); =A0 =A0 =A0 =A0 IO.prSym(nm); =A0 =A0 =A0IO.Out.write(BEG); =A0 =A0 =A0 =A0 IO.prSym(quote); =A0 =A0 =A0 =A0 IO.Out.write(DOT); =A0 =A0 =A0 =A0 IO.prSym(+Cls); =A0 Out.write(END); =A0 IO.flush(); So this is a bit tedious. If the PicoLisp server uses a dedicated port fo= r the Java queries, and does not =A0 (while (rd) =A0 =A0 =A0(eval @) ) but instead =A0 (while (rd) =A0 =A0 =A0(apply @ (rd)) ) then you can send the arguments without quoting in a list (array): =A0 Object args[]; =A0 // fill args with 'nm' and '+Cls', and possibly more =A0 IO.prSym(collect); =A0 IO.print(args); =A0 IO.flush(); Hope this works ;-) Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=3dunsubscribe -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: Java interop
Hi Henrik, Hi Alex, I just took a look at the old java gui download. ... communicating with a running JVM from PL. The starting point is the class java/Reflector.java, together with the start-up shell script java/vm. 'Reflector' is a kind of Java functionality server. It mediates - as you observed - between the Java and PicoLisp worlds. Also included is a demo Java library java/Util.java, containing some Java functions be callable from PicoLisp. You can start it as $ java/vm java/util.jar Now the Java functionality server is running in the background. The startup script created a named pipe fifo/java where the server is listening at. Now any PicoLisp program can load lib/java.l, and requests the execution of Java functions on that server: : (load lib/java.l) - java : (java 'Util 'md5 This is a string) - 87704939138141002822102625569266896500 : (hex @) - 41FB5B5AE4D57C5EE528ADB00E5E8E74 : *Pid - 15561 If you look now into the fifo/ directory prw-r--r-- 1 abu abu 0 May 27 09:15 java| prw-r--r-- 1 abu abu 0 May 27 09:15 java15561| you see that the PicoLisp process created another fifo with its PID in the name, to receive the answers from the server. The types of requests the Reflector understands is rather limited. It could be - static methods (when the second argument is a symbol or string (like 'md5' above), or - methods invoked on a 'new' object which is created on the fly (when the second argument is NIL or a list) In the second case, NIL causes the creation of a Java object of the given class (in the first argument). I don't remember exactly what a list of classes means (calling getConstructor() with a list of classes), as I never needed that. If you should need it, we must investigate a little more ... fork routine) and then having the Java end use the code in inOut.java to print to and read from this port? As you see from the above examples, the PicoLisp side doesn't need to worry about the communication details (just call 'java'), and the Java side also doesn't need that, as the Java reflection api takes care of that so that you can concentrate on the Java side just on writing proper functions. Btw there are two java folders, java and java2, what is the difference? 'java' should be sufficient here. 'java2' contains only the newer version of the GUI (Swing instead of AWT), and the Z3dField class for the 3D graphics (used in the flight simulator). Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: Java interop
Great, thanks, I haven't tested yet but that answer should be enough to get me up and running with the scenario where PL is using Java in an auxiliary fashion. Now pretend I have a PL database that listens on say port 4040, could it be possible to use the current Java interop code to pass data to that database for storage? Data that might be coming as a HTTP request to a servlet for instance. It doesn't have to be fancy, simply having a Java vector/array (or whatever the simplest sequential Java construct is called) appear as a list in PL would be enough to get me started. On Thu, May 27, 2010 at 10:07 AM, Alexander Burger a...@software-lab.de wr= ote: Hi Henrik, Hi Alex, I just took a look at the old java gui download. ... communicating with a running JVM from PL. The starting point is the class java/Reflector.java, together with the start-up shell script java/vm. 'Reflector' is a kind of Java functionality server. It mediates - as you observed - between the Java and PicoLisp worlds. Also included is a demo Java library java/Util.java, containing some Java functions be callable from PicoLisp. You can start it as =A0 $ java/vm java/util.jar Now the Java functionality server is running in the background. The startup script created a named pipe fifo/java where the server is listening at. Now any PicoLisp program can load lib/java.l, and requests the execution of Java functions on that server: =A0 : (load lib/java.l) =A0 - java =A0 : (java 'Util 'md5 This is a string) =A0 - 87704939138141002822102625569266896500 =A0 : (hex @) =A0 - 41FB5B5AE4D57C5EE528ADB00E5E8E74 =A0 : *Pid =A0 - 15561 If you look now into the fifo/ directory =A0 prw-r--r-- 1 abu abu 0 May 27 09:15 java| =A0 prw-r--r-- 1 abu abu 0 May 27 09:15 java15561| you see that the PicoLisp process created another fifo with its PID in the name, to receive the answers from the server. The types of requests the Reflector understands is rather limited. It could be =A0 - static methods (when the second argument is a symbol or string =A0 =A0 (like 'md5' above), or =A0 - methods invoked on a 'new' object which is created on the fly (when =A0 =A0 the second argument is NIL or a list) In the second case, NIL causes the creation of a Java object of the given class (in the first argument). I don't remember exactly what a list of classes means (calling getConstructor() with a list of classes), as I never needed that. If you should need it, we must investigate a little more ... fork routine) and then having the Java end use the code in inOut.java to print to and read from this port? As you see from the above examples, the PicoLisp side doesn't need to worry about the communication details (just call 'java'), and the Java side also doesn't need that, as the Java reflection api takes care of that so that you can concentrate on the Java side just on writing proper functions. Btw there are two java folders, java and java2, what is the difference? 'java' should be sufficient here. 'java2' contains only the newer version of the GUI (Swing instead of AWT), and the Z3dField class for the 3D graphics (used in the flight simulator). Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=3dunsubscribe -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe
Re: Java interop
On Thu, May 27, 2010 at 11:45:57AM +0200, Henrik Sarvell wrote: Now pretend I have a PL database that listens on say port 4040, could it be possible to use the current Java interop code to pass data to that database for storage? This is not directly supported by the existing interfaces, as 'Reflector' is itself a server which expects to be queried by PicoLisp. On the PicoLisp side nothing special needs to be implemented. On the Java side you need library that connects to the PicoLisp server, sends requests, and receives answers via java/InOut.java. This is in fact very similar to what the old Java GUI applets are doing (mainly in java/Pico.java). These applets connect back to the HTML server on a dedicated port (passed via the HTML page as a parameter to the applet), and use the PLIO functions (in java/InOut.java) to send events and receive layout and content informations from the server. Parts of the 'connect' method (line 36 in java/Pico.java) and all the calls to 'IO.somefunction()' might be useful. You could simply send complete PicoLisp statements, packed into Java arrays. They will appear as lists in PicoLisp. But easier is probably sending the data items individually, as you then have better control over the type. For example, with 'prSym()' you can then send internal symbols (typically functions), directly executable on the PicoLisp side (I hope to don't forget about security ;-) For example, to call (collect 'nm '+Cls) on the DB server (not tested): IO.Out.write(BEG); IO.prSym(collect); IO.Out.write(BEG); IO.prSym(quote); IO.Out.write(DOT); IO.prSym(nm); IO.Out.write(BEG); IO.prSym(quote); IO.Out.write(DOT); IO.prSym(+Cls); Out.write(END); IO.flush(); So this is a bit tedious. If the PicoLisp server uses a dedicated port for the Java queries, and does not (while (rd) (eval @) ) but instead (while (rd) (apply @ (rd)) ) then you can send the arguments without quoting in a list (array): Object args[]; // fill args with 'nm' and '+Cls', and possibly more IO.prSym(collect); IO.print(args); IO.flush(); Hope this works ;-) Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe