Idiomatic clojure for decorating graph

2011-11-11 Thread Colin Yates
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

2011-11-11 Thread Colin Yates
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??

2011-11-11 Thread Joost


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

2011-11-11 Thread Sean Corfield
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

2011-11-11 Thread Meikel Brandmeyer (kotarak)
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

2011-11-11 Thread finbeu
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

2011-11-11 Thread finbeu
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

2011-11-11 Thread Sean Corfield
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

2011-11-11 Thread finbeu
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??

2011-11-11 Thread sixs
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

2011-11-11 Thread Sean Corfield
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

2011-11-11 Thread finbeu
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

2011-11-11 Thread Alex Baranosky
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

2011-11-11 Thread Brian Marick

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

2011-11-11 Thread Colin Yates
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?

2011-11-11 Thread Bill Robertson
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?

2011-11-11 Thread Chris Perkins
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

2011-11-11 Thread joegallo
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

2011-11-11 Thread myriam abramson
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

2011-11-11 Thread joegallo
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)

2011-11-11 Thread Jules
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?

2011-11-11 Thread Bill Robertson
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

2011-11-11 Thread Brian Goslinga
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

2011-11-11 Thread neveu
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

2011-11-11 Thread jongwon.choi
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)

2011-11-11 Thread Timothy Baldridge
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)

2011-11-11 Thread Jules
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)

2011-11-11 Thread Timothy Baldridge
 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

2011-11-11 Thread Timothy Washington
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)

2011-11-11 Thread Jules
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)

2011-11-11 Thread Jules
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

2011-11-11 Thread Mike
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

2011-11-11 Thread loonster


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

2011-11-11 Thread Michael Gardner
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

2011-11-11 Thread Mike
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)

2011-11-11 Thread David Nolen
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)

2011-11-11 Thread David Nolen
(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)

2011-11-11 Thread Ambrose Bonnaire-Sergeant
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)

2011-11-11 Thread David Nolen
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)

2011-11-11 Thread David Nolen
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????

2011-11-11 Thread jayvandal
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

2011-11-11 Thread Jestan Nirojan
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