Idiomatic clojure for decorating graph
Hi all, What is the idiomatic way to decorate a nested graph with multiple decorators? Let me explain: I have a list of graphs: [ { :id 1 propertyA: {:customer 1 :name whatever :date (Date.)} propertyB: {:customer 1 :created (Date.) :someOtherProperty 13} } ] After creating this graph (and only after, not before), I can now retrieve all the customers I need and create map (using group-by) of customerId: customer. I also want to replace all the Dates to millisecondsSinceEpoch. Just for fun I also want to decorate all instances of propertyA (but not propertyB) with an extra property. Some contraints: I cannot decorate each item at the time it is being loaded. For example, I need to load the entire graph to identify which customers are needed, which I can then load in one batch. I can't load all the customers because there are a gazillion of them. What I am currently doing is a wonderfully complex combination of defining each decorator as a separate function and then using nested fors. Something like: (defn transform [graphs] (let [ customers (load-customers-by-id graphs) ] (defn resolve-customer [g] (assoc g :customer ((:customer g) customers) ) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Idiomatic clojure for decorating graph
Oops - clicked wrong button (why doesn't gmail have paredit!) - sorry... (defn transform [graphs] (let [ ;; map of {:id customer} customers (load-customers-by-id graphs) ] (defn resolve-customer [g] (assoc g :customer ((:customer g) customers (defn switch-date-to-ms [g] (assoc :date (.getTime g)) (into [] (for [g graphs] (resolve-customer (switch-date-to-ms g))) ) Now this works except for the fact I have multiple decorators which work on a graph which might be 5 levels deep and looks horrible :). Any advice/guidance? Thanks! Col P.S. Where is the best place to get the clojure 101 type help? I feel this type of request is almost noise for this mailing list On 11 November 2011 10:42, Colin Yates colin.ya...@gmail.com wrote: Hi all, What is the idiomatic way to decorate a nested graph with multiple decorators? Let me explain: I have a list of graphs: [ { :id 1 propertyA: {:customer 1 :name whatever :created (Date.)} propertyB: {:customer 1 :created (Date.) :someOtherProperty 13} } ] After creating this graph (and only after, not before), I can now retrieve all the customers I need and create map (using group-by) of customerId: customer. I also want to replace all the Dates to millisecondsSinceEpoch. Just for fun I also want to decorate all instances of propertyA (but not propertyB) with an extra property. Some contraints: I cannot decorate each item at the time it is being loaded. For example, I need to load the entire graph to identify which customers are needed, which I can then load in one batch. I can't load all the customers because there are a gazillion of them. What I am currently doing is a wonderfully complex combination of defining each decorator as a separate function and then using nested fors. Something like: (defn transform [graphs] (let [ customers (load-customers-by-id graphs) ] (defn resolve-customer [g] (assoc g :customer ((:customer g) customers) ) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: gaidica command??
On Nov 11, 5:29 am, jayvandal s...@ida.net wrote: I tried this command but can't find how to execute it. $ lein run -m gaidica.core What folder do I execute this ? (Vista windows ) Probably simple but it's difficult for me Thanks # gaidica Example Seesaw application. Display weather data from weatherunderground.com ## Usage $ lein deps $ lein run -m gaidica.core lein is the leiningen build tool. many clojure projects need it, since it reduces a lot of the overhead of finding and installing dependencies and setting up java options etc. you can get it at https://github.com/technomancy/leiningen after you've installed leiningen, you can run the above commands in the seesaw/examples/gaidica directory (which is in the seesaw source distribution - clone that from https://github.com/daveray/seesaw ) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
Have you tried clojure.tools.logging to see whether you get the same behavior? On Fri, Nov 11, 2011 at 8:15 AM, finbeu info_pe...@t-online.de wrote: Hello, I'm using log4j and have some a simple wrappers in clojure that work well so far. Actually, I do (def *logger* (Logger/getRootLogger)) Then I set loglevel, appenders, layout and so on. I have a function (defn debug [msg] (.debug *logger* msg) This works nice as long as I do not try to log a lazy sequence. Instead, the string clojure.lang.LazySeq@hdk73gdf9 gets logged instead of the content. How can I enforce logging of a lazy sequence? I tried to wrap it with doall but it has no effect. Thx. Finn -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
Hi, what happens is probable that the logger tries to turn the lazy seq object itself into a string. Try calling pr-str on the seq before passing it to debug: (debug (pr-str your-seq-object)). Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
Hi Sean no, not yet. I stick with my own simple logging ns which works nice so far. Just have to fix this ...) (but I use clojure.java.jdbc with Sybase ASE 15.0.3. I hope I will find some time soon to contribute some testcases.) Finn -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
Yes! That's it. With pr-str it works. Thx!! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
On Fri, Nov 11, 2011 at 8:53 AM, finbeu info_pe...@t-online.de wrote: no, not yet. I stick with my own simple logging ns which works nice so far. Just have to fix this ...) I just wondered whether using a well-maintained standard library might be an easier path than rolling your own... (but I use clojure.java.jdbc with Sybase ASE 15.0.3. I hope I will find some time soon to contribute some testcases.) Thank you! -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
yes, when starting my project, I was looking at the logging library which resides (resided) in clojure.contrib and I didn't like it at that point in time. I think because it was trying to do too many things at once. If my use case can be solved with some small java wrappers, I try to do it on my own. This is of course not the case for jdbc where I appreciate java.jdbc although I have difficulties using c3p0 with sybase. I will follow up on this maybe later). -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: gaidica command??
This is what I get when I run the commands. I have had lleiningen installed and used it somewhat. I get the classpath error and I don't understand ? Thanks for your help Microsoft Windows [Version 6.0.6000] Copyright (c) 2006 Microsoft Corporation. All rights reserved. C:\Users\jim.jim-PCcd\ C:\dir Volume in drive C is HP Volume Serial Number is 28B9-D63A Directory of C:\ 11/04/2011 02:11 AM99,840 $$DeleteMe.$$DeleteMe.$$DeleteMe.$$Delete Me.$$DeleteMe.poqexec.exe.01cc9bfc5aabc8c9.0001.01cc9bfcb851437a..01cc9c6f30 b35c9e..01cc9fce0d0cc616..01cca07571cd84f5. 11/02/2006 01:46 AM71,680 $$DeleteMe.atl.dll.01cc9ae51cdf7a90.0036 11/02/2006 01:46 AM 1,984,512 $$DeleteMe.authui.dll.01cc9ae50dc822f0.00 19 11/02/2006 01:46 AM17,408 $$DeleteMe.CbsMsg.dll.01cc9ae5104ad630.00 2d 11/02/2006 01:46 AM19,456 $$DeleteMe.cfgmgr32.dll.01cc9ae50ff061f0. 0027 11/02/2006 01:46 AM 204,800 $$DeleteMe.dhcpcsvc.dll.01cc9ae50dca8450. 001a 11/02/2006 01:46 AM 120,320 $$DeleteMe.dhcpcsvc6.dll.01cc9ae50dd8cc90 .001b 11/14/2007 02:14 PM 162,816 $$DeleteMe.dnsapi.dll.01cc9ae50d348db0.00 13 11/14/2007 02:14 PM84,480 $$DeleteMe.dnsrslvr.dll.01cc9ae50d36ef10. 0014 11/02/2006 01:46 AM 134,656 $$DeleteMe.dps.dll.01cc9ae51e90b4d0.0044 11/02/2006 01:46 AM 256,512 $$DeleteMe.dpx.dll.01cc9ae50ffeaa30.0028 11/02/2006 01:46 AM 614,400 $$DeleteMe.fastprox.dll.01cc9ae50f2f9290. 0024 11/02/2006 01:46 AM28,672 $$DeleteMe.FwRemoteSvr.dll.01cc9ae51edf42 30.0047 11/02/2006 01:46 AM 296,448 $$DeleteMe.gdi32.dll.01cc9ae51cca0e30.003 5 11/02/2006 01:46 AM30,720 $$DeleteMe.httpapi.dll.01cc9ae50c0d6330.0 008 11/02/2006 01:46 AM 266,752 $$DeleteMe.iertutil.dll.01cc9ae51f4cc170. 0049 11/14/2007 02:19 PM 178,688 $$DeleteMe.iphlpsvc.dll.01cc9ae50ee36690. 0022 11/02/2006 01:46 AM 361,984 $$DeleteMe.IPSECSVC.DLL.01cc9ae51ed81e10. 0046 11/02/2006 01:46 AM 493,056 $$DeleteMe.kerberos.dll.01cc9ae511367e50. 0030 11/02/2006 01:46 AM 874,496 $$DeleteMe.kernel32.dll.01cc9ae50ea582d0. 001f 11/02/2006 01:44 AM38,400 $$DeleteMe.kmddsp.tsp.01cc9ae51e8bf210.00 42 11/02/2006 01:46 AM 694,272 $$DeleteMe.localspl.dll.01cc9ae51182aa50. 0032 11/02/2006 01:46 AM24,064 $$DeleteMe.lpk.dll.01cc9ae51fabf870.004c 11/02/2006 01:46 AM 1,233,408 $$DeleteMe.lsasrv.dll.01cc9ae50ea582d0.00 1e 11/02/2006 01:45 AM 7,680 $$DeleteMe.lsass.exe.01cc9ae50ea0c010.001 d 10/02/2006 06:10 PM 7,815,292 $$DeleteMe.meiryo.ttc.01cc9ae50b79cdf0.00 00 11/02/2006 01:46 AM59,904 $$DeleteMe.msasn1.dll.01cc9ae50c468430.00 0a 11/03/2011 02:22 AM 367,104 $$DeleteMe.mscorjit.dll.01cc9ae50cf1e730. 000e 11/03/2011 02:22 AM 5,815,296 $$DeleteMe.mscorwks.dll.01cc9ae50cf44890. 000f 11/02/2006 01:46 AM 213,504 $$DeleteMe.msv1_0.dll.01cc9ae51138dfb0.00 31 11/02/2006 01:46 AM 1,204,224 $$DeleteMe.msxml3.dll.01cc9ae51dcfe570.00 39 11/02/2006 01:41 AM 2,048 $$DeleteMe.msxml3r.dll.01cc9ae51dcd8410.0 038 11/02/2006 01:46 AM 1,337,344 $$DeleteMe.msxml6.dll.01cc9ae50bfa5830.00 03 11/02/2006 01:41 AM 2,048 $$DeleteMe.msxml6r.dll.01cc9ae50bfa5830.0 002 11/02/2006 01:46 AM 797,696 $$DeleteMe.NaturalLanguage6.dll.01cc9ae51 0dc0a10.002e 11/02/2006 01:44 AM49,664 $$DeleteMe.ndptsp.tsp.01cc9ae51e90b4d0.00 45 11/02/2006 01:46 AM 425,472 $$DeleteMe.netapi32.dll.01cc9ae51c3d9d10. 0033 11/02/2006 01:46 AM 383,488 $$DeleteMe.netcfgx.dll.01cc9ae51e8990b0.0 041 11/02/2006 01:46 AM 558,080 $$DeleteMe.oleaut32.dll.01cc9ae50d3bb1d0. 0015 11/02/2006 01:45 AM99,840 $$DeleteMe.poqexec.exe.01cc9ae50bff1af0.0 004 11/02/2006 04:35 AM 272,384 $$DeleteMe.PortableDeviceApi.dll.01cc9ae5 1e14ed50.0040 11/02/2006 04:35 AM95,232 $$DeleteMe.PortableDeviceClassExtension.d ll.01cc9ae51e128bf0.003f 11/02/2006 04:35 AM 160,768 $$DeleteMe.PortableDeviceTypes.dll.01cc9a e51e102a90.003e 11/02/2006 01:46 AM37,376 $$DeleteMe.printcom.dll.01cc9ae50da20cf0. 0016 11/02/2006 01:46 AM 749,568 $$DeleteMe.qmgr.dll.01cc9ae50bc85b50.0001 11/02/2006 01:46 AM 274,432 $$DeleteMe.raschap.dll.01cc9ae50c03ddb0.0 006 11/02/2006 01:46 AM 232,960 $$DeleteMe.rastls.dll.01cc9ae50c063f10.00 07 11/02/2006 01:46 AM 467,456 $$DeleteMe.riched20.dll.01cc9ae51e8bf210. 0043 11/02/2006 01:46 AM 789,504 $$DeleteMe.rpcrt4.dll.01cc9ae50c1bab70.00 09 11/02/2006 01:46 AM 545,792 $$DeleteMe.rpcss.dll.01cc9ae50f1ee8f0.002 3 11/02/2006 01:46 AM 269,312 $$DeleteMe.schannel.dll.01cc9ae50d23e410. 0012 11/02/2006
Re: Debugging lazy seqs with log4j
On Fri, Nov 11, 2011 at 9:25 AM, finbeu info_pe...@t-online.de wrote: yes, when starting my project, I was looking at the logging library which resides (resided) in clojure.contrib and I didn't like it at that point in time. I think because it was trying to do too many things at once. If my use case can be solved with some small java wrappers, I try to do it on my own. FWIW: (use 'clojure.tools.logging) (info (range 4)) happily logs (0 1 2 3) - with tools.logging 0.2.3 Sorry to seem to be belaboring the point but the standard logging library just works and handles lazy sequences without needing any workarounds (unless I'm missing something here?). The reason I'm pushing on this is that it's entirely possible that a contrib library wasn't suitable back then but things are moving along pretty well with the modular contrib libraries now and it's helpful - for all of us - for folks to use those, for a number of reasons. It avoids reinventing the wheel. It gets more usage of libraries that we want as robust as possible. If folks don't like the modular contrib libraries, we need the feedback in the form of JIRA tickets so that we can improve them - and open discussion on the lists. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
Thanks. I think when I tried it (correct me if I'm wrong) it was not possible to set the debug level dynamic. For instance I usually have a port where I can send messages to (simple UDP datagram packet), the message string is a map which I read-string and eval and upon that event, I reset some internal state like debugging or print the state of some objects or whatever. Maybe I should invent my own simple messaging system based on good old UPD datagram packets :-) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Debugging lazy seqs with log4j
You could consider contributing your improvements to the logging library. On Nov 11, 2011 10:27 AM, finbeu info_pe...@t-online.de wrote: Thanks. I think when I tried it (correct me if I'm wrong) it was not possible to set the debug level dynamic. For instance I usually have a port where I can send messages to (simple UDP datagram packet), the message string is a map which I read-string and eval and upon that event, I reset some internal state like debugging or print the state of some objects or whatever. Maybe I should invent my own simple messaging system based on good old UPD datagram packets :-) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Idiomatic clojure for decorating graph
On Nov 11, 2011, at 4:48 AM, Colin Yates wrote: Now this works except for the fact I have multiple decorators which work on a graph which might be 5 levels deep and looks horrible :). Have you looked into clojure.zip? http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/ - Brian Marick, Artisanal Labrador Now working at http://path11.com Contract programming in Ruby and Clojure Occasional consulting on Agile -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Idiomatic clojure for decorating graph
Thanks Brian - I will look into it. On 11 November 2011 15:40, Brian Marick mar...@exampler.com wrote: On Nov 11, 2011, at 4:48 AM, Colin Yates wrote: Now this works except for the fact I have multiple decorators which work on a graph which might be 5 levels deep and looks horrible :). Have you looked into clojure.zip? http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/ - Brian Marick, Artisanal Labrador Now working at http://path11.com Contract programming in Ruby and Clojure Occasional consulting on Agile -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
How do I store/read data with function references in it?
If I use pprint and read-string to serialize and deserialize data w/o function references it works o.k. This is clojure 1.3. e.g. save something to disk, restart the vm, read it in ok. user= (def foo {:a 1 :b 2 :c [more stuff]}) user= (def output (java.io.FileWriter. foo.clj)) user= (clojure.pprint/pprint foo output) user= (.close output) $ cat foo.clj {:a 1, :b 2, :c [more stuff]} user= (def foo (read-string (slurp foo.clj))) ;;; all good However, if there's a function in that data structure, I cannot read the forms back in. user= (def foo (assoc foo :d clojure.core/+)) user= foo {:d #core$_PLUS_ clojure.core$_PLUS_@1ce00b4, :a 1, :b 2, :c [more stuff]} user= ;; save to file as above... $ cat foo.clj {:d #core$_PLUS_ clojure.core$_PLUS_@1ce00b4, :a 1, :b 2, :c [more stuff]} user= (def foo (read-string (slurp foo.clj))) java.lang.RuntimeException: java.lang.Exception: Unreadable form (NO_SOURCE_FILE:1) As an experiment, I edited the file and changed the object reference to the fully qualified name of the function, I could read the structure in, and it appears to be a function (according to clojure test), but it prints differently, and it does not behave like + anymore, instead I simply get the last argument back. $ cat foo.clj {:d clojure.core/+ :a 1, :b 2, :c [more stuff]} user= (def foo (read-string (slurp foo.clj))) #'user/foo user= (require 'clojure.test) nil user= (clojure.test/function? (foo :d)) true user= + #core$_PLUS_ clojure.core$_PLUS_@1a19458 user= (foo :d) ;;; notice that it prints differently clojure.core/+ user= ((foo :d) 4 5) ;;; what don't I understand about this? 5 user= (def fun (foo :d)) #'user/fun user= (fun 4 5) ;;; didn't expect different... 5 user= (+ 4 5) 9 I'm not sure what I don't undertand about what I had going on in the last example, but that isn't my primary question. My primary question is, how do I serialize and deserialize data with function references in it? Thanks -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: How do I store/read data with function references in it?
It looks like your (:foo d) is a symbol. ((:foo d) 4 5) is trying to look itself up as a key in the map you provided, which is 4. Since that's not a map, the lookup fails and it returns the default value you provided: 5. It's very forgiving that way :) As for your main question, about how to serialize functions, someone else will have to answer - as far as I know, you just can't do that. - Chris -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Doric 0.6.0
I just released a new version of doric (https://github.com/joegallo/doric) -- it's a fun little utility library that you might want to look at if you're using clojure.pprint/print-table, but want a few more features than it provides. This version includes support for generating csv, raw text, and html tables, in addition to the default emacs org-mode tables. New custom table formats can also be created by supplying a namespace that implements 3 functions (see the source for examples). Happy hacking! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Adding a jar to dependencies in lein
I want to interface with the Jericho html-parser available from sourceforge. How do I specify it in project.clj for lein to fetch? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Adding a jar to dependencies in lein
Go to search.maven.org, and type in jericho-html. That'll take you to some results pages that will tell you the versions that are available, and also the correct groupId and artifactId. Then you add into project.clj the following [groupId/artifactId version]. In this case, [net.htmlparser.jericho/jericho-html 3.2] should work. Joe -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
Here is a Python version (http://pastebin.com/reW5eaCy): def valid(a,b,c,d): return set(w*a + x*b + y*c + z*d for w in [-1,0,1] for x in [-1,0,1] for y in [-1,0,1] for z in [-1,0,1]) set(range(1,41)) ws = [(a,b,c,d) for a in range(1,41-1-1-1) for b in range(a,41-a-1-1) for c in range(b,41-a-b-1) for d in range(c,41-a-b-c) if valid(a,b,c,d)] I wonder if you can make the cKanren version just as declarative as this one (cKanren's purpose being declarative). Jules On 1 nov, 04:48, David Nolen dnolen.li...@gmail.com wrote: A blog post explaining the solution step by stephttp://dosync.posterous.com/another-taste-of-ckanren. On Mon, Oct 31, 2011 at 9:36 PM, David Nolen dnolen.li...@gmail.com wrote: Here's a correct version that solves the puzzle in ~12ms, https://gist.github.com/1329580. A bit longer but it fun to combine constraints w/ search. Will try to find some time to write a more detailed explanation. On Sun, Oct 30, 2011 at 9:00 PM, David Nolen dnolen.li...@gmail.comwrote: Heh, as someone pointed out this doesn't actually solve the puzzle since I'm not considering putting stones on either side of the scale. Still I think the idea of what cKanren can do is communicated :) On Sun, Oct 30, 2011 at 8:34 PM, Brent Millare brent.mill...@gmail.comwrote: Looks really cool. Can't wait to see the talk. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: How do I store/read data with function references in it?
So far its looking like I can't. I will just have to work around it then. NBD. Thanks On Nov 11, 12:02 pm, Chris Perkins chrisperkin...@gmail.com wrote: It looks like your (:foo d) is a symbol. ((:foo d) 4 5) is trying to look itself up as a key in the map you provided, which is 4. Since that's not a map, the lookup fails and it returns the default value you provided: 5. It's very forgiving that way :) As for your main question, about how to serialize functions, someone else will have to answer - as far as I know, you just can't do that. - Chris -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: scheme to clojure translation
On Nov 8, 10:08 pm, Aquahappy joshua.ay...@gmail.com wrote: Hi Jim, Thanks so much! Using 'def' instead of 'defn' when defining a function composed of functions was what I was missing. I can't believe I spent an hour trying to figure this out -- it seems very obvious now. Doh! :) Notice that the Scheme (define (f args ...) ...) becomes (defn f [args ...] ...) in Clojure, and (define f ...) becomes (def f ...) Brian -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: All subsets of a vector
On Nov 9, 2:47 pm, Shoeb Bhinderwala shoeb.bhinderw...@gmail.com wrote: ([a] [a b] [a b c] [a b c d]) It should be pointed out that this result -- while it may be what you actually want -- is not all subsets of [a b c d]. For that you might want to use combinatorics/subsets: user= (C/subsets [a b c d]) (() (a) (b) (c) (d) (a b) (a c) (a d) (b c) (b d) (c d) (a b c) (a b d) (a c d) (b c d) (a b c d)) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Getting index of char from end
Hi I'm wondering the best way to express: (position #\a abba :from-end t) Should I use interop? (.lastIndexOf abba (int \a)) Thanks! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
I wonder if you can make the cKanren version just as declarative as this one (cKanren's purpose being declarative). I don't think the Python version could be considered declarative. One of the concepts behind logic programming (and to some extent declarative programming) is that you can simply provide the system with facts, and then the system (as a black box) decides on the correct way to perform the operation. This Python example is really nothing more than syntactic sugar around a imperative brute force approach to the problem. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
In the same way the cKanren version is syntactic sugar around imperative code. Declarative is not a property of a language, it's a property of code that says how close to a mathematical specification the code is. My Python code is much more declarative than the given cKanren code in that regard. Just compare: http://dosync.posterous.com/another-taste-of-ckanren On 11 nov, 23:47, Timothy Baldridge tbaldri...@gmail.com wrote: I wonder if you can make thecKanrenversion just as declarative as this one (cKanren'spurpose being declarative). I don't think the Python version could be considered declarative. One of the concepts behind logic programming (and to some extent declarative programming) is that you can simply provide the system with facts, and then the system (as a black box) decides on the correct way to perform the operation. This Python example is really nothing more than syntactic sugar around a imperative brute force approach to the problem. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
My Python code is much more declarative than the given cKanren code in that regard. Just compare: http://dosync.posterous.com/another-taste-of-ckanren I don't think you understand what declarative programming is at its core. Declarative programming To borrow from the ever-present wikipedia: declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.[1] Many languages applying this style attempt to minimize or eliminate side effects by describing what the program should accomplish, rather than describing how to go about accomplishing it.[2] This is in contrast with imperative programming, which requires an explicitly provided algorithm. (see: Declarative Programming) This is where the cKanren code succeeds where the Python code fails. The Python code is all algorithm, and no facts. While the cKanren code is a direct implementation of the facts about the problem: one stone must be 1lb all stones should equal 40lb, etc. The cKanren code leaves the interpretation of these facts up to the logic engine, while the Python code sets strict guidelines that the compiler must follow. If, for instance, it was faster for a given computer to count down from instead of counting up, the Python code would run much slower, by defining the algorithm (by using range, and for loops), you're restricting the interpreter to your view of how to solve the problem. The cKanren compiler/interpreter/whatever is free to solve the problem in any way it pleases, as long as the requirements (facts) are met. The original problem states find 4 numbers that equal 40 but a combination of any of which can be 1 through 40 it says nothing of range sequences, for loops, etc. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Open source Clojure projects
Those are 2 very good links so far. You can always look at the Clojure Toolbox to get an idea of the landscape. - http://www.clojure-toolbox.com/ But the github link, though, will take you closer to what different people are working on. It is a good idea though, to step back and try to scratch a little itch that you're having, as suggested by 'Ulises'. Good-luck Tim On Wed, Nov 9, 2011 at 2:27 PM, Chris Perkins chrisperkin...@gmail.comwrote: There are lots. You could start browsing from here: https://github.com/languages/Clojure - Chris -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
Are we reading the same cKanren code? I'll give you that the matches definition is declarative, but then read checko and subchecko. They are all about (recursive) control flow. Where does the specification say anything remotely close to the checko and subchecko relations? In contrast to this, the Python set comprehensions have minimal control flow. Yeah, the standard Python implementation has a certain order of executing the comprehensions, but so does the cKanren implementation when executing the predicates. My Python program doesn't depend on this order: it just uses declarative descriptions of sets as set comprehensions. Just being written in cKanren doesn't make a program declarative. If you write a C interpreter in cKanren and then write your actual program in a literal string, that doesn't magically make the program declarative even though it is a cKanren program. Similarly, checko and subchecko don't describe the problem in a declarative way. Compare this with the Python valid() function: the set of possible weights you can make has to be a superset of {1..40}. Again, declarativeness is a property of programs, not languages. Some languages make writing declarative programs easier, of course. cKanren is supposed to be such a language, so it would be neat to see a more declarative cKanren program for this problem. Also, I don't see how one stone should weigh 1lbs is part of the specification. Now, it is true that the answer happens to have one stone equal to 1, but how is that part of or trivially follows from the specification? We might as well hard-code the whole solution. Jules On 12 nov, 00:49, Timothy Baldridge tbaldri...@gmail.com wrote: My Python code is much more declarative than the given cKanren code in that regard. Just compare:http://dosync.posterous.com/another-taste-of-ckanren I don't think you understand what declarative programming is at its core. Declarative programming To borrow from the ever-present wikipedia: declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.[1] Many languages applying this style attempt to minimize or eliminate side effects by describing what the program should accomplish, rather than describing how to go about accomplishing it.[2] This is in contrast with imperative programming, which requires an explicitly provided algorithm. (see: Declarative Programming) This is where the cKanren code succeeds where the Python code fails. The Python code is all algorithm, and no facts. While the cKanren code is a direct implementation of the facts about the problem: one stone must be 1lb all stones should equal 40lb, etc. The cKanren code leaves the interpretation of these facts up to the logic engine, while the Python code sets strict guidelines that the compiler must follow. If, for instance, it was faster for a given computer to count down from instead of counting up, the Python code would run much slower, by defining the algorithm (by using range, and for loops), you're restricting the interpreter to your view of how to solve the problem. The cKanren compiler/interpreter/whatever is free to solve the problem in any way it pleases, as long as the requirements (facts) are met. The original problem states find 4 numbers that equal 40 but a combination of any of which can be 1 through 40 it says nothing of range sequences, for loops, etc. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
Here is a new program. Perhaps you would consider this declarative: def valid(a,b,c,d): weights = set(w*a+x*b+y*c+z*d for (w,x,y,z) in product([-1,0,1],repeat=4)) return weights = set(range(1,41)) ws = [(a,b,c,d) for (a,b,c,d) in product(range(1,41),repeat=4) if a = b = c = d and a+b+c+d == 40 and valid(a,b,c,d)] On 12 nov, 01:48, Jules julesjac...@gmail.com wrote: Are we reading the same cKanren code? I'll give you that the matches definition is declarative, but then read checko and subchecko. They are all about (recursive) control flow. Where does the specification say anything remotely close to the checko and subchecko relations? In contrast to this, the Python set comprehensions have minimal control flow. Yeah, the standard Python implementation has a certain order of executing the comprehensions, but so does the cKanren implementation when executing the predicates. My Python program doesn't depend on this order: it just uses declarative descriptions of sets as set comprehensions. Just being written in cKanren doesn't make a program declarative. If you write a C interpreter in cKanren and then write your actual program in a literal string, that doesn't magically make the program declarative even though it is a cKanren program. Similarly, checko and subchecko don't describe the problem in a declarative way. Compare this with the Python valid() function: the set of possible weights you can make has to be a superset of {1..40}. Again, declarativeness is a property of programs, not languages. Some languages make writing declarative programs easier, of course. cKanren is supposed to be such a language, so it would be neat to see a more declarative cKanren program for this problem. Also, I don't see how one stone should weigh 1lbs is part of the specification. Now, it is true that the answer happens to have one stone equal to 1, but how is that part of or trivially follows from the specification? We might as well hard-code the whole solution. Jules On 12 nov, 00:49, Timothy Baldridge tbaldri...@gmail.com wrote: My Python code is much more declarative than the given cKanren code in that regard. Just compare:http://dosync.posterous.com/another-taste-of-ckanren I don't think you understand what declarative programming is at its core. Declarative programming To borrow from the ever-present wikipedia: declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.[1] Many languages applying this style attempt to minimize or eliminate side effects by describing what the program should accomplish, rather than describing how to go about accomplishing it.[2] This is in contrast with imperative programming, which requires an explicitly provided algorithm. (see: Declarative Programming) This is where the cKanren code succeeds where the Python code fails. The Python code is all algorithm, and no facts. While the cKanren code is a direct implementation of the facts about the problem: one stone must be 1lb all stones should equal 40lb, etc. The cKanren code leaves the interpretation of these facts up to the logic engine, while the Python code sets strict guidelines that the compiler must follow. If, for instance, it was faster for a given computer to count down from instead of counting up, the Python code would run much slower, by defining the algorithm (by using range, and for loops), you're restricting the interpreter to your view of how to solve the problem. The cKanren compiler/interpreter/whatever is free to solve the problem in any way it pleases, as long as the requirements (facts) are met. The original problem states find 4 numbers that equal 40 but a combination of any of which can be 1 through 40 it says nothing of range sequences, for loops, etc. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
need help eliminating ordinary recursion/thinking the Clojure way
I'm having a conceptual problem, thinking functionally, and I was hoping the fine Clojurians could take a peek. Boiled down, I need to do a combination of map and reduce on a collection. My walker needs to look at pairs along the collection, but then sort of inject new values and restart when necessary. Since I don't know of a more general über-HOF that will do what I want, I tried to write my own function. It's not tail recursive, which is a big problem. So I need help. But let me back up, and start where it will make sense. I need to represent, in their most-reduced form, collections of half- closed intervals on Z (integers). So an interval might be [2, 4) which means 2 and 3 are elements, but 1 and 4 are not. Since the collections of intervals must be reduced, I can't have (using chicken lips as vector for clarity): [2, 4) [4, 8) Note that all elements between 2 (inclusive) and 8 (exclusive) satisfy this collection, so the two intervals must be merged. This collection should be: [2, 8) Similarly, all partially or completely overlapping intervals must be merged. See how this could be like a map/reduce function? Sort the collection. Look at the first two elements; if they can merge, merge them and then restart with the newly merged interval at the head. If they can't be merged, release the first into the result, and consider the second and third, etc. So I'm representing spans (ranges) of integers with a map, like so: (defn make-span Makes a non-zero-width span of integer value. ([start end] {:pre [(integer? start) (integer? end) ( start end)]} {:start (min start end) :end (max start end)}) ([singleton] (make-span singleton (inc singleton I can tell if these intervals are in some way overlapping or perfectly adjacent like this: (defn overlap? Are these two spans partially or totally overlapping or perfectly adjacent? [s1 s2] (not (or (pos? (- (:start s2) (:end s1))) (pos? (- (:start s1) (:end s2)) Straightforward so far. Now, given a *sorted* collection of spans, I should be able to reduce the collection to its canonical form by looking at first and second, merging their span if they overlap, and recurring as necessary: (defn merge-spans [spans] (if (empty? spans) spans (let [x (first spans) ys (rest spans)] (if (empty? ys) spans (let [y (first ys) zs (rest ys)] (if (overlap? x y) ; this is the merge (let [xy (make-span (min (:start x) (:start y)) (max (:end x) (:end y)))] (recur (into [xy] zs))) ; this is the recursive problem (into [x] (merge-spans ys Let's try some demo code: (defn safe-merge [] (let [s1 (make-span 1) s2 (make-span 2) s3 (make-span 9) demo-spans (sort-by :start [s2 s3 s1])] ; we sort by :start (merge-spans demo-spans))) (defn unsafe-merge [] (let [bad-spans (sort-by :start (map make-span (range 0 10 2)))] (count (merge-spans bad-spans user= (safe-merge) [{:start 1, :end 3} {:start 9, :end 10}] ; perfect! user= (unsafe-merge) StackOverflowError clojure.lang.PersistentArrayMap.equalKey (PersistentArrayMap.java:201) OK, this is a really long post because of all the code, but thanks for reading this far. Can anyone suggest a way for me to either A) get rid of the ordinary recursion in merge-spans, or B) approach this problem from a different angle I'm not thinking about? Thanks in advance everybody… Mike -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: using sqlite3
On Nov 8, 12:47 pm, loonster tbur...@acm.org wrote: After searching long and hard, there really isn't any good documentation for using sqlite3 with clojure 1.3. Any help connecting to an existing sqlite3 db and performing selects and updates greatly appreciated. Tim Thanks all. In the end, the following works like a charm. I found that clojure/java/jdbc namespace has a conflict with clojure/core, both having resultset-seq function, hence the exclusion: (ns psyN.core (:use [clojure.java.jdbc]) (defproject psyN 0.1.0 :dependencies [[org.clojure/clojure 1.3.0] [org.clojure/java.jdbc 0.1.1] [org.xerial/sqlite-jdbc 3.7.2]]) ;** (ns psyN.core (:use [clojure.java.jdbc]) (:refer-clojure :exclude [resultset-seq])) (def db {:classname org.sqlite.JDBC :subprotocol sqlite :subname /path/to the sqlite file/psyN/db/thx }) ;get count of table.notes records: (def rec-cnt (with-connection db (with-query-results rs [select * from notes] (count rs (def output (with-connection db (with-query-results rs [SELECT * FROM notes WHERE id = ? (+ 1 (rand-int rec-cnt))] (into {} rs -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: need help eliminating ordinary recursion/thinking the Clojure way
Since you're given a sorted list of intervals, you don't actually need to restart the whole merging process from the start after each merge; you can just replace the last interval in your output with the new, merged interval and continue from there. So `reduce' is the perfect tool for the job; my solution is below. I used 2-vectors for ranges since they're easier to type and read. Note that reduce-intervals builds its result in reverse, since seqs like to be manipulated from the head. (defn intervals-intersect? [s1 s2] (not (or ( (s1 0) (s2 1)) ( (s2 0) (s1 1) (defn join-intervals [s1 s2] [(min (s1 0) (s2 0)) (max (s1 1) (s2 1))]) (defn reduce-intervals [reduced s] (let [[s-prev more] reduced] (if (and s-prev (intervals-intersect? s-prev s)) (cons (join-intervals s-prev s) more) (cons s reduced (defn merge-intervals [intervals] (reverse (reduce reduce-intervals [] intervals))) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: need help eliminating ordinary recursion/thinking the Clojure way
Ahhh...excellent, I see why I was blind. =) If you just build your reduction collection in reverse, then the head of the reduction is always the one you want to compare with as you traverse the incoming collection. So you either cons one item or two onto the result, and when you're all done reverse it. Thanks! Makes perfect sense. I'll have to remember this. Mike On Nov 11, 10:33 pm, Michael Gardner gardne...@gmail.com wrote: Since you're given a sorted list of intervals, you don't actually need to restart the whole merging process from the start after each merge; you can just replace the last interval in your output with the new, merged interval and continue from there. So `reduce' is the perfect tool for the job; my solution is below. I used 2-vectors for ranges since they're easier to type and read. Note that reduce-intervals builds its result in reverse, since seqs like to be manipulated from the head. (defn intervals-intersect? [s1 s2] (not (or ( (s1 0) (s2 1)) ( (s2 0) (s1 1) (defn join-intervals [s1 s2] [(min (s1 0) (s2 0)) (max (s1 1) (s2 1))]) (defn reduce-intervals [reduced s] (let [[s-prev more] reduced] (if (and s-prev (intervals-intersect? s-prev s)) (cons (join-intervals s-prev s) more) (cons s reduced (defn merge-intervals [intervals] (reverse (reduce reduce-intervals [] intervals))) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
Can you reorder your statements without changing the meaning of your program? For example you cannot move the placement of the return expression. David On Fri, Nov 11, 2011 at 8:09 PM, Jules julesjac...@gmail.com wrote: Here is a new program. Perhaps you would consider this declarative: def valid(a,b,c,d): weights = set(w*a+x*b+y*c+z*d for (w,x,y,z) in product([-1,0,1],repeat=4)) return weights = set(range(1,41)) ws = [(a,b,c,d) for (a,b,c,d) in product(range(1,41),repeat=4) if a = b = c = d and a+b+c+d == 40 and valid(a,b,c,d)] On 12 nov, 01:48, Jules julesjac...@gmail.com wrote: Are we reading the same cKanren code? I'll give you that the matches definition is declarative, but then read checko and subchecko. They are all about (recursive) control flow. Where does the specification say anything remotely close to the checko and subchecko relations? In contrast to this, the Python set comprehensions have minimal control flow. Yeah, the standard Python implementation has a certain order of executing the comprehensions, but so does the cKanren implementation when executing the predicates. My Python program doesn't depend on this order: it just uses declarative descriptions of sets as set comprehensions. Just being written in cKanren doesn't make a program declarative. If you write a C interpreter in cKanren and then write your actual program in a literal string, that doesn't magically make the program declarative even though it is a cKanren program. Similarly, checko and subchecko don't describe the problem in a declarative way. Compare this with the Python valid() function: the set of possible weights you can make has to be a superset of {1..40}. Again, declarativeness is a property of programs, not languages. Some languages make writing declarative programs easier, of course. cKanren is supposed to be such a language, so it would be neat to see a more declarative cKanren program for this problem. Also, I don't see how one stone should weigh 1lbs is part of the specification. Now, it is true that the answer happens to have one stone equal to 1, but how is that part of or trivially follows from the specification? We might as well hard-code the whole solution. Jules On 12 nov, 00:49, Timothy Baldridge tbaldri...@gmail.com wrote: My Python code is much more declarative than the given cKanren code in that regard. Just compare: http://dosync.posterous.com/another-taste-of-ckanren I don't think you understand what declarative programming is at its core. Declarative programming To borrow from the ever-present wikipedia: declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.[1] Many languages applying this style attempt to minimize or eliminate side effects by describing what the program should accomplish, rather than describing how to go about accomplishing it.[2] This is in contrast with imperative programming, which requires an explicitly provided algorithm. (see: Declarative Programming) This is where the cKanren code succeeds where the Python code fails. The Python code is all algorithm, and no facts. While the cKanren code is a direct implementation of the facts about the problem: one stone must be 1lb all stones should equal 40lb, etc. The cKanren code leaves the interpretation of these facts up to the logic engine, while the Python code sets strict guidelines that the compiler must follow. If, for instance, it was faster for a given computer to count down from instead of counting up, the Python code would run much slower, by defining the algorithm (by using range, and for loops), you're restricting the interpreter to your view of how to solve the problem. The cKanren compiler/interpreter/whatever is free to solve the problem in any way it pleases, as long as the requirements (facts) are met. The original problem states find 4 numbers that equal 40 but a combination of any of which can be 1 through 40 it says nothing of range sequences, for loops, etc. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at
Re: A Taste of cKanren (via a coding challenge)
(define (matches n) (run #f (q) (fresh (a b c d s1 s2) (== q `(,a ,b ,c ,d)) (domfd a b c d s1 s2 (range 1 n)) (all-differentfd `(,a ,b ,c ,d)) (== a 1) (=fd a b) (=fd b c) (=fd c d) (plusfd a b s1) (plusfd s1 c s2) (plusfd s2 d n) (checko `(,a ,b ,c ,d) () () n Note that the return expression here has been moved to the top. It does not change the meaning of the program. In cKanren you do have to be a little bit careful with recursive goals, but the freedom to rearrange expressions is much greater than in Python. In declarative programs, the order of expressions should not influence the result. David On Fri, Nov 11, 2011 at 8:09 PM, Jules julesjac...@gmail.com wrote: Here is a new program. Perhaps you would consider this declarative: def valid(a,b,c,d): weights = set(w*a+x*b+y*c+z*d for (w,x,y,z) in product([-1,0,1],repeat=4)) return weights = set(range(1,41)) ws = [(a,b,c,d) for (a,b,c,d) in product(range(1,41),repeat=4) if a = b = c = d and a+b+c+d == 40 and valid(a,b,c,d)] On 12 nov, 01:48, Jules julesjac...@gmail.com wrote: Are we reading the same cKanren code? I'll give you that the matches definition is declarative, but then read checko and subchecko. They are all about (recursive) control flow. Where does the specification say anything remotely close to the checko and subchecko relations? In contrast to this, the Python set comprehensions have minimal control flow. Yeah, the standard Python implementation has a certain order of executing the comprehensions, but so does the cKanren implementation when executing the predicates. My Python program doesn't depend on this order: it just uses declarative descriptions of sets as set comprehensions. Just being written in cKanren doesn't make a program declarative. If you write a C interpreter in cKanren and then write your actual program in a literal string, that doesn't magically make the program declarative even though it is a cKanren program. Similarly, checko and subchecko don't describe the problem in a declarative way. Compare this with the Python valid() function: the set of possible weights you can make has to be a superset of {1..40}. Again, declarativeness is a property of programs, not languages. Some languages make writing declarative programs easier, of course. cKanren is supposed to be such a language, so it would be neat to see a more declarative cKanren program for this problem. Also, I don't see how one stone should weigh 1lbs is part of the specification. Now, it is true that the answer happens to have one stone equal to 1, but how is that part of or trivially follows from the specification? We might as well hard-code the whole solution. Jules On 12 nov, 00:49, Timothy Baldridge tbaldri...@gmail.com wrote: My Python code is much more declarative than the given cKanren code in that regard. Just compare: http://dosync.posterous.com/another-taste-of-ckanren I don't think you understand what declarative programming is at its core. Declarative programming To borrow from the ever-present wikipedia: declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.[1] Many languages applying this style attempt to minimize or eliminate side effects by describing what the program should accomplish, rather than describing how to go about accomplishing it.[2] This is in contrast with imperative programming, which requires an explicitly provided algorithm. (see: Declarative Programming) This is where the cKanren code succeeds where the Python code fails. The Python code is all algorithm, and no facts. While the cKanren code is a direct implementation of the facts about the problem: one stone must be 1lb all stones should equal 40lb, etc. The cKanren code leaves the interpretation of these facts up to the logic engine, while the Python code sets strict guidelines that the compiler must follow. If, for instance, it was faster for a given computer to count down from instead of counting up, the Python code would run much slower, by defining the algorithm (by using range, and for loops), you're restricting the interpreter to your view of how to solve the problem. The cKanren compiler/interpreter/whatever is free to solve the problem in any way it pleases, as long as the requirements (facts) are met. The original problem states find 4 numbers that equal 40 but a combination of any of which can be 1 through 40 it says nothing of range sequences, for loops, etc. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe
Re: A Taste of cKanren (via a coding challenge)
I assume the cKanren version can run backwards with a little tweak? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
Excellent point Ambrose ;) And here it is: (define (subchecko w sl r o n) (conde ((== sl ()) (fresh (a d) (domfd a (range 1 100)) (conde ((conso a d r) (plusfd a 1 w) (conso w r o)) ((== r '()) (conso w r o) ((fresh (a b c ro0 ro1 nw nsl) (domfd a b c (range 1 100)) (conso a nsl sl) (plusfd a b w) (plusfd a w c) (subchecko b nsl r ro0 n) (subchecko w nsl ro0 ro1 n) (subchecko c nsl ro1 o n) (define (checko ws sl r n) (conde ((== ws '()) (fresh (a) (caro r a) (== a n))) ((fresh (w wr nsl nr) (conso w wr ws) (subchecko w sl r nr n) (conso w sl nsl) (checko wr nsl nr n) (define (matches a b c d n) (fresh (s1 s2) (domfd a b c d n s1 s2 (range 1 100)) (all-differentfd `(,a ,b ,c ,d)) (fd a b) (fd b c) (fd c d) (== a 1) (plusfd a b s1) (plusfd s1 c s2) (plusfd s2 d n) (checko `(,a ,b ,c ,d) () () n))) (run* (q) (matches 1 3 9 27 q)) ;; (40) (run* (q) (fresh (a b c d) (== q `(,a ,b ,c ,d)) (matches a b c d 40))) ;; ((1 3 9 27)) On Sat, Nov 12, 2011 at 12:31 AM, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: I assume the cKanren version can run backwards with a little tweak? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: A Taste of cKanren (via a coding challenge)
Also note that even given all this generality over the Python code - the earlier Python implementation takes ~300ms and this implementation takes 900ms on my machine. Quite a bit slower than ~12ms. Inferring 40 takes even less time of course - ~8ms. But really the execution time is just icing on the declarative cake ;) David On Fri, Nov 11, 2011 at 8:09 PM, Jules julesjac...@gmail.com wrote: Here is a new program. Perhaps you would consider this declarative: def valid(a,b,c,d): weights = set(w*a+x*b+y*c+z*d for (w,x,y,z) in product([-1,0,1],repeat=4)) return weights = set(range(1,41)) ws = [(a,b,c,d) for (a,b,c,d) in product(range(1,41),repeat=4) if a = b = c = d and a+b+c+d == 40 and valid(a,b,c,d)] On 12 nov, 01:48, Jules julesjac...@gmail.com wrote: Are we reading the same cKanren code? I'll give you that the matches definition is declarative, but then read checko and subchecko. They are all about (recursive) control flow. Where does the specification say anything remotely close to the checko and subchecko relations? In contrast to this, the Python set comprehensions have minimal control flow. Yeah, the standard Python implementation has a certain order of executing the comprehensions, but so does the cKanren implementation when executing the predicates. My Python program doesn't depend on this order: it just uses declarative descriptions of sets as set comprehensions. Just being written in cKanren doesn't make a program declarative. If you write a C interpreter in cKanren and then write your actual program in a literal string, that doesn't magically make the program declarative even though it is a cKanren program. Similarly, checko and subchecko don't describe the problem in a declarative way. Compare this with the Python valid() function: the set of possible weights you can make has to be a superset of {1..40}. Again, declarativeness is a property of programs, not languages. Some languages make writing declarative programs easier, of course. cKanren is supposed to be such a language, so it would be neat to see a more declarative cKanren program for this problem. Also, I don't see how one stone should weigh 1lbs is part of the specification. Now, it is true that the answer happens to have one stone equal to 1, but how is that part of or trivially follows from the specification? We might as well hard-code the whole solution. Jules On 12 nov, 00:49, Timothy Baldridge tbaldri...@gmail.com wrote: My Python code is much more declarative than the given cKanren code in that regard. Just compare: http://dosync.posterous.com/another-taste-of-ckanren I don't think you understand what declarative programming is at its core. Declarative programming To borrow from the ever-present wikipedia: declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.[1] Many languages applying this style attempt to minimize or eliminate side effects by describing what the program should accomplish, rather than describing how to go about accomplishing it.[2] This is in contrast with imperative programming, which requires an explicitly provided algorithm. (see: Declarative Programming) This is where the cKanren code succeeds where the Python code fails. The Python code is all algorithm, and no facts. While the cKanren code is a direct implementation of the facts about the problem: one stone must be 1lb all stones should equal 40lb, etc. The cKanren code leaves the interpretation of these facts up to the logic engine, while the Python code sets strict guidelines that the compiler must follow. If, for instance, it was faster for a given computer to count down from instead of counting up, the Python code would run much slower, by defining the algorithm (by using range, and for loops), you're restricting the interpreter to your view of how to solve the problem. The cKanren compiler/interpreter/whatever is free to solve the problem in any way it pleases, as long as the requirements (facts) are met. The original problem states find 4 numbers that equal 40 but a combination of any of which can be 1 through 40 it says nothing of range sequences, for loops, etc. Timothy -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members
classpath on seesaw????
I am trying to run the examples in seesaw.I must not have seeesaw installed correctly. any help please Microsoft Windows [Version 6.0.6000] Copyright (c) 2006 Microsoft Corporation. All rights reserved. C:\cd cljr C:\cljrjava -jar c:/clojure-1.3.0.jar c:/cljr/kitchensink.clj Error: Unable to access jarfile c:/clojure-1.3.0.jar C:\cljrjava -jar c:/clojure-1.3.0/clojure-1.3.0.jar c:/cljr/ kitchensink.clj Exception in thread main java.lang.RuntimeException: java.io.FileNotFoundExcep tion: Could not locate seesaw/core__init.class or seesaw/core.clj on classpath: at clojure.lang.Util.runtimeException(Util.java:165) at clojure.lang.Compiler.eval(Compiler.java:6476) at clojure.lang.Compiler.eval(Compiler.java:6455) at clojure.lang.Compiler.load(Compiler.java:6902) at clojure.lang.Compiler.loadFile(Compiler.java:6863) at clojure.main$load_script.invoke(main.clj:282) at clojure.main$script_opt.invoke(main.clj:342) at clojure.main$main.doInvoke(main.clj:426) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.lang.Var.invoke(Var.java:401) at clojure.lang.AFn.applyToHelper(AFn.java:161) at clojure.lang.Var.applyTo(Var.java:518) at clojure.main.main(main.java:37) Caused by: java.io.FileNotFoundException: Could not locate seesaw/ core__init.cla ss or seesaw/core.clj on classpath: at clojure.lang.RT.load(RT.java:430) at clojure.lang.RT.load(RT.java:398) at clojure.core$load$fn__4610.invoke(core.clj:5386) at clojure.core$load.doInvoke(core.clj:5385) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invoke(core.clj:5200) at clojure.core$load_lib.doInvoke(core.clj:5237) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invoke(core.clj:602) at clojure.core$load_libs.doInvoke(core.clj:5271) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invoke(core.clj:604) at clojure.core$use.doInvoke(core.clj:5363) at clojure.lang.RestFn.invoke(RestFn.java:408) at seesaw.test.examples.kitchensink $eval3$loading__4505__auto4.invok e(kitchensink.clj:11) at seesaw.test.examples.kitchensink $eval3.invoke(kitchensink.clj:11) at clojure.lang.Compiler.eval(Compiler.java:6465) ... 11 more C:\cljr -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Getting index of char from end
I think regex free solution is best for this (defn last-indexof [s c] (- s (filter #(= c %)) count dec) On Nov 12, 3:36 am, jongwon.choi oz.jongwon.c...@gmail.com wrote: Hi I'm wondering the best way to express: (position #\a abba :from-end t) Should I use interop? (.lastIndexOf abba (int \a)) Thanks! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en