Re: CLR questions

2010-09-23 Thread tsuraan
 First of all, MonoDevelop should be able to load the .sln

Ok, I'll have a look at that.  I currently know nothing of .NET or
mono, so it's all news to me :)

 As far as XNA...last I heard XNA did not have any support for emit,
 and as such is incapable of running any sort of jit code. Basically
 all .NET code has to be ahead-of-time compiled to run a XBOX via XNA.
 It's the same limitation that IronPython has
 (http://ironpython.codeplex.com/wikipage?title=FAQ).

Ok, so for XBox stuff, ScalaCLR or F# would probably be more
practical.  That's unfortunate, but I'm not way too surprised.  Thanks
for the info!

-- 
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: CLR questions

2010-09-23 Thread tsuraan
 As far as XNA...last I heard XNA did not have any support for emit,
 and as such is incapable of running any sort of jit code. Basically
 all .NET code has to be ahead-of-time compiled to run a XBOX via XNA.
 It's the same limitation that IronPython has
 (http://ironpython.codeplex.com/wikipage?title=FAQ).

 Ok, so for XBox stuff, ScalaCLR or F# would probably be more
 practical.  That's unfortunate, but I'm not way too surprised.  Thanks
 for the info!

And, as a lovely self-reply, replace that last practical with
possible.  I think that's more accurate.

-- 
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


CLR questions

2010-09-22 Thread tsuraan
I have two (apparently unrelated) questions about ClojureCLR.

First, does Clojure 1.2 build under mono?  The clojure-clr tree only
appears to have a .sln file; is there some sane way to convert that to
a Makefile or a shell script that can be used under *nix?

Secondly, has anybody tried deploying a clojure-based app under XNA
(the XBox API)?  I've seen some basic howtos for F#-based XNA
development; I'd be interested in hearing about anybody's experience
doing this with Clojure.

Thanks for any input.

-- 
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: Game development in Clojure

2010-09-01 Thread tsuraan
 How would that have helped? The problem lay in the fact that there
 could be many subclasses of Document, but only one specific subclass,
 Attachment, could go into the attachments[] field. So if we had to
 split the code into two files, we'd have

 class Attachment(Document) # -- attachment.py needs to import from 
 document.py
  ...

 and

 class Document
  def create_attachment
    self.attachments += Attachment.new() # -- document.py needs to
 import from attachment.py

What python allows to break the circular dependency is function-level imports:

attachment.py:
from document import Document
class Attachment(Document):
 pass

document.py:
class Document(object):
 def create_attachment(self):
   from attachment import Attachment
   self.attachments += Attachment.new()

I don't think clojure has anything like this; it looks like imports
are at the file-level, rather than the function level as in python.
Perhaps there is a way though?

-- 
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: Help speed up an inner loop?

2010-08-31 Thread tsuraan
 (defn countnl-lite
  [#^bytes buf]
  (areduce buf idx count (int 0)
           (if (= (clojure.lang.RT/aget buf idx) 10)
             (unchecked-add count 1)
             count)))

 Key points are initializing count to a primitive integer and directly
 calling clojure's aget to avoid an unnecessary integer cast.

Are you using clojure 1.2?  If I try to set count to be (int 0) rather
than 0, I get this error:

Exception in thread main java.lang.RuntimeException:
java.lang.IllegalArgumentException: recur arg for primitive local:
count must be matching primitive

Even if I replace inc with the unchecked-add, or cast the result
of the inc to be int (replace (inc count) with (int (inc count)) )
it gives me that error.  Sort of strange...

-- 
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: Help speed up an inner loop?

2010-08-31 Thread tsuraan
 Replace also  (unchecked-add count 1) with  (unchecked-add count (int 1))

 (this should get easier in 1.3)

That didn't change anything for my tests, but this code:

(defn countnl
  [#^bytes buf]
  (areduce buf idx count (int 0)
   (if (= (aget buf idx) 10)
 (unchecked-add count 1)
 count)))

does 34ms runs (the .java code does 20ms runs on the same machine).
The biggest things that make a difference are replacing (inc count)
with (unchecked-add count 1), initializing count to (int 0) rather
than 0, and getting rid of the (let [nl (byte 0)]...).  I was a bit
disappointed that the let statement was so expensive, since I really
prefer seeing a variable to a magic number.  Has somebody written a
macro that can be used to rewrite code replacing variable references
with their constant values?  It would be of limited use (constants
only), but it would make the code prettier :)  For posterity, here are
some variations on countnl and their timings on my machine:

all runs are invoked with this command: java -server -cp clojure.jar
clojure.main iterate.clj; clojure.jar is from the clojure-1.2.zip
distribution


(defn countnl
  [#^bytes buf]
  (let [nl (byte 10)]
(areduce buf idx count 0
 (if (= (aget buf idx) nl)
   (inc count)
   count

Wanted 16777216 got 16777216 bytes
Elapsed time: 184.172834 msecs
Got 65875 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 193.546018 msecs
Got 64995 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 142.546453 msecs
Got 65677 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 135.843933 msecs
Got 66117 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 134.882156 msecs
Got 65449 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 134.864881 msecs
Got 65393 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 134.854118 msecs
Got 65065 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 134.82848 msecs
Got 65346 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 134.803702 msecs
Got 65783 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 134.832489 msecs
Got 65566 nls

(defn countnl
  [#^bytes buf]
  (let [nl (byte 10)]
(areduce buf idx count (int 0)
 (if (= (aget buf idx) nl)
   (inc count)
   count

Wanted 16777216 got 16777216 bytes
Elapsed time: 238.409697 msecs
Got 65698 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 208.872818 msecs
Got 65381 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.786986 msecs
Got 65358 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.76816 msecs
Got 65686 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.899431 msecs
Got 65683 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.783275 msecs
Got 65491 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.735416 msecs
Got 65749 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.762987 msecs
Got 65837 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.749591 msecs
Got 65759 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 88.72971 msecs
Got 65366 nls

(defn countnl
  [#^bytes buf]
  (areduce buf idx count (int 0)
   (if (= (aget buf idx) 10)
 (inc count)
 count)))

Wanted 16777216 got 16777216 bytes
Elapsed time: 185.465613 msecs
Got 65344 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 186.856418 msecs
Got 65529 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.778183 msecs
Got 65662 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.675509 msecs
Got 65034 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.674777 msecs
Got 65459 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.630553 msecs
Got 65172 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.668685 msecs
Got 64939 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.74801 msecs
Got 65462 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.699187 msecs
Got 65602 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 73.611555 msecs
Got 64937 nls

(defn countnl
  [#^bytes buf]
  (areduce buf idx count (int 0)
   (if (= (aget buf idx) 10)
 (unchecked-add count 1)
 count)))

Wanted 16777216 got 16777216 bytes
Elapsed time: 82.865761 msecs
Got 65266 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 34.228646 msecs
Got 65522 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.989741 msecs
Got 65537 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.947045 msecs
Got 65688 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.941481 msecs
Got 65395 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.952149 msecs
Got 65822 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.972258 msecs
Got 65495 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.903989 msecs
Got 65244 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.927276 msecs
Got 65331 nls
Wanted 16777216 got 16777216 bytes
Elapsed time: 33.917789 msecs
Got 65470 nls

(defn 

Re: Help speed up an inner loop?

2010-08-31 Thread tsuraan
 This one is quite good for me.
 (defn countnl
  [#^bytes buf]
  (let [nl (int 10)]
   (areduce buf idx count (int 0)
            (if (== (int (aget buf idx)) nl)
              (unchecked-inc count)
              count


 It appears that == is not resolved for bytes. So converting to int works fine.

aha, converting to int works for me as well.  With bytes it triggers
the reflection warning and takes minutes to run.  with the int
conversion, it runs in an average of 28ms (just a little over java).
Here's something really strange: I de-inlined the newline int, so my
function looks like this:

(defn countnl
  [#^bytes buf]
  (let [nl (int 10)]
(areduce buf idx count (int 0)
 (if (== (int (aget buf idx)) nl)
   (unchecked-add count (int 1))
   count

On my machine, this is running in 19.6ms (after the warmup it's really
constant).  That's the exact speed as the java code, which is really
cool.  it actually works the same way if you just replace the inlined
10 with (int 10), and it makes it just as fast as the explicit
looping code below.  Somehow on my earlier tests the let binding was
really slowing things down, but in this latest function it seems to
have no effect.  weird...

 In this situation, inlining (int 10) does not buy much.

interesting; for me replacing the 10 with (int 10) brings my times
from 28.7ms to 19.6ms.

 This one, though, is even faster and should be not far from the java
 one, if you want to try it.

 (defn countnl
  [#^bytes buf]
  (let [nl (int 10)
        n (int (alength buf))]
   (loop [idx (int n) count (int 0)]
         (if (zero? idx)
             count
             (let [idx (unchecked-dec idx)]
               (if (== (int (aget buf idx)) nl)
                 (recur  idx (unchecked-inc count))
                 (recur  idx count)))

 It would be interesting to know why it is nearly twice as fast as the
 areduce version on my computer.

That runs in 21.3ms for me, which actually makes it a tiny bit slower
than the code above (and slightly slower than the java code).

-- 
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


Help speed up an inner loop?

2010-08-30 Thread tsuraan
Just to try to see if clojure is a practical language for doing
byte-level work (parsing files, network streams, etc), I wrote a
trivial function to iterate through a buffer of bytes and count all
the newlines that it sees.  For my testing, I've written a C version,
a Java version, and a Clojure version.  I'm running each routine 10
times over a 16MB buffer read from /dev/urandom (the buffer is
refreshed between each call to the newline counting function).  With
gcc -O0, I get about 80ms per 16MB buffer.  With gcc -O3, I get ~14ms
per buffer.  With javac (and java -server) I get 20ms per 16MB buffer.
 With clojure, I get 105ms per buffer (after the jvm warms up).  I'm
guessing that the huge boost that java and gcc -O3 get is from
converting per-byte operations to per-int ops; at least that ~4x boost
looks like it would come from something like that.  Is that an
optimization that is unavailable to clojure?  The java_interop doc
makes it sound like java and clojure get the exact same bytecode when
using areduce correctly, so maybe there's something I could be doing
better.  Here are my small programs; if somebody could suggest
improvements, I'd appreciate them.

iterate.clj:

(set! *warn-on-reflection* true)
(import java.io.FileInputStream)

(def *numbytes* (* 16 1024 1024))

(defn countnl
  [#^bytes buf]
  (let [nl (byte 10)]
(areduce buf idx count 0
 (if (= (aget buf idx) nl)
   (inc count)
   count

(let [ifs (FileInputStream. /dev/urandom)
  buf (make-array Byte/TYPE *numbytes*)]
  (dotimes [_ 10]
(let [sz (.read ifs buf)]
  (println Wanted *numbytes* got sz bytes)
  (let [count (time (countnl buf))]
(println Got count nls)


Iterate.java:

import java.io.FileInputStream;

class Iterate
{
  static final int NUMBYTES = 16*1024*1024;

  static int countnl(byte[] buf)
  {
int count = 0;
for(int i = 0; i  buf.length; i++) {
  if(buf[i] == '\n') {
count++;
  }
}
return count;
  }

  public static final void main(String[] args)
throws Throwable
  {
FileInputStream input = new FileInputStream(/dev/urandom);
byte[] buf = new byte[NUMBYTES];
int sz;
long start, end;

for(int i = 0; i  10; i++) {
  sz = input.read(buf);
  System.out.println(Wanted  + NUMBYTES +  got  + sz +  bytes);
  start = System.currentTimeMillis();
  int count = countnl(buf);
  end = System.currentTimeMillis();
  System.out.println(counted  + count +  nls in  +
  (end-start) +  msec);
}

input.close();
  }
}

iterate.c:

#includesys/types.h
#includesys/stat.h
#includesys/time.h
#includestdlib.h
#includeunistd.h
#includestdio.h
#includefcntl.h

int countnl(char *buf, int sz)
{
  int i;
  int count = 0;
  for(i = 0; i  sz; i++) {
if(buf[i] == '\n') {
  count++;
}
  }
  return count;
}

int main()
{
  int fd = open(/dev/urandom, O_RDONLY);
  const int NUMBYTES = 16*1024*1024;
  char *buf = (char*)malloc(NUMBYTES);

  int sz;
  struct timeval start, end;

  int i;
  for(i = 0; i  10; i++) {
sz = read(fd, buf, NUMBYTES);
printf(Wanted %d bytes, got %d bytes\n, NUMBYTES, sz);
gettimeofday(start, 0);
int count = countnl(buf, sz);
gettimeofday(end, 0);
printf(counted %d nls in %f msec\n, count,
(float)(end.tv_sec-start.tv_sec)*1e3 + (end.tv_usec-start.tv_usec)/1e3);
  }

  free(buf);
  close(fd);
  return 0;
}

-- 
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 to get Clojure.Contrib in my Classpath?

2010-02-01 Thread tsuraan
 java -classpath C:\Program Files\Clojure\clojure.jar;C:\Program
 Files\Clojure\clojure-contrib-1.1.0.jar clojure.main

 This starts the repl without a problem, but still, any attempt to use
 a class or function from the contrib library fails, for example,
 running this at the repl...

I'm not sure about windows, but under *NIX the classpath is colon
separated.  Maybe using a colon between the two jars instead of a
semicolon would help.

-- 
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 to get Clojure.Contrib in my Classpath?

2010-02-01 Thread tsuraan
 I had already tried using a colon as the separator, but it gave an
 error. I've also noticed that if neither path resolves to a file, it
 also errors, so it's finding clojure-contrib-1.1.0.jar.

Can you use it with

(use 'clojure.contrib.duck-streams) ?

Both ways work for me, but it's the only other thought I have.

-- 
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: Parallel activities

2010-01-22 Thread tsuraan
 When you send-off an action to an agent, that agent gets is
 allocated a thread for at least the duration of that action.  So
 using send-off on long-running actions to two agents will result
 in those actions being run in parallel.

Ok, I re-read the docs on agents, and it looks like they don't do what
I was thinking they do.  One thread acts on an agent at once; I
somehow missed that.  I was thinking that multiple sends could run on
one agent at once, which just isn't the case.

 And finally, there's really nothing wrong with using (.start
 (Thread. myfn)), if that accomplishes exactly what you need.

I'm guessing that's what I'll wind up doing.  I know it's not
clojure's style, but it just seems like there should be some core
macro (dothread ...) that puts the body into a (.start (Thread. ...))
call.  I guess I'll write one :)

 --Chouser
 http://joyofclojure.com/

Reading through it right now.  Very nice book so far, but I'm really
looking forward to chapters 9 and 10 :)

-- 
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


Parallel activities

2010-01-21 Thread tsuraan
What is the clojure idiom for running multiple (in this case IO bound)
functions simultaneously?  My use case is the parallel activities are
coordinated, basically running in lockstep.  I've been using (.start
(Thread. myfn)).  It works, but I'm wondering if there's a better way.
 The data shared between the threads is stored in an agent, which sort
of suggests send-off to me, but I can't find any reason to think that
send-off runs everything in parallel.  Any thoughts would be welcome.

-- 
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


QCon video download

2009-12-16 Thread tsuraan
Does anybody have a download link for the QCon talk that is linked
from the clojure front page?  I tend to use platforms where Flash
support is even worse than normal, whereas mplayer tends to be very
good at playing videos on every machine I use.

-- 
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: QCon video download

2009-12-16 Thread tsuraan
 If you watch the http traffic, e.g. in firebug, you'll see it makes a
 request to:

 http://flv.thruhere.net/presentations/09-mar-persistentdatastructures.flv

 You'll have to find the slides on the qcon homepage if you want to
 follow.

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: Augmenting the defn attr-map

2009-08-17 Thread tsuraan

 The official docs for this are at: http://clojure.org/
 special_forms#let .

That's a great link.  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: Augmenting the defn attr-map

2009-08-16 Thread tsuraan

 (defh a
[b:String [c:Double :as list:java.util.List] {d:java.util.Random :d}]
(.toCharArray b)
(.size list)
(.floatValue c)
(.nextInt d))

What's that :as in the [ c:Double :as list:java.util.List ] vector?

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Augmenting the defn attr-map

2009-08-12 Thread tsuraan

I'd like to add a :signature entry to the attr-map of defn, that
provides a haskell-style type signature to functions of the
single-arglist-body form.  I find the the normal way of providing
hints to a function:

(defn [ #^Class1 var1 #^Class2 var2 #^Class3 var3] ... )

is way too noisy, and the variables get lost between the types.  What
I'd like instead is to be able to specify the signature in the
function metadata:

(defn {:signature [ Class1 Class2 Class3 ReturnType ]}
  [ var1 var2 var3 ]
  ...)

I've written a little patch to defn that annotates the arguments
correctly (I think).  I'm not sure where the metadata for marking up a
function's return type goes (Is it on the (cons `fn fdecl) part?), but
it probably wouldn't be hard if I knew what I was doing :)

Anyhow, a revised defn (I've called it defn+ to avoid clashes) is as follows:

(defn zip [ a b ] (map vector a b))
(def

 #^{:doc Same as (def name (fn [params* ] exprs*)) or (def
name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
to the var metadata
:arglists '([name doc-string? attr-map? [params*] body]
[name doc-string? attr-map? ([params*] body)+ attr-map?])}
 defn+ (fn defn+ [name  fdecl]
(let [m (if (string? (first fdecl))
  {:doc (first fdecl)}
  {})
  fdecl (if (string? (first fdecl))
  (next fdecl)
  fdecl)
  m (if (map? (first fdecl))
  (conj m (first fdecl))
  m)
  fdecl (if (map? (first fdecl))
  (next fdecl)
  fdecl)
  fdecl (if (vector? (first fdecl))
  (if (:signature m)
; we'll apply the types in the signature vector as the
; :tag metadata for each argument
(list
  (cons
(apply vector
  (for [[ tag var ]
(zip (:signature m) (first fdecl))]
(with-meta var {:tag tag})))
(rest fdecl)))
(list fdecl))
  fdecl)
  m (if (map? (last fdecl))
  (conj m (last fdecl))
  m)
  fdecl (if (map? (last fdecl))
  (butlast fdecl)
  fdecl)
  m (conj {:arglists (list 'quote (sigs fdecl))} m)]
  (list 'def (with-meta name (conj (if (meta name) (meta name) {}) m))
(cons `fn fdecl)

(. (var defn+) (setMacro))

Is this something that people would think is worthwhile?  I really
prefer haskell's type signatures to clojure's inline hints, but maybe
it's just something that people get used to.  Anyhow, my first attempt
at macro hacking, so kind criticism would also be welcome w.r.t.
style, correctness, etc.

--~--~-~--~~~---~--~~
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: Augmenting the defn attr-map

2009-08-12 Thread tsuraan

 - There's already a lot of moving parts to type hinting, so adding
 this optional approach into defn seems like it'd lead to unintended
 consequences.  That said, there's absolutely nothing wrong with an
 alternative def form (defh? as in 'define hinted fn') -- there's
 plenty of them throughout contrib and elsewhere.

Yeah, I tried to slip my change into a place in defn that probably
wouldn't hurt anything, but I'm still not sure what the full
consequences of my change are.  I'm far from a clojure expert :)

 - Remember destructuring, and along with that, one of the nice thing
 about in-place hints, as opposed to a separate definition of expected
 types, is that the definitions can be sparse, e.g.:

 (defn foo [{blah :foo #^MyType mt-obj :bar} a b c] ...)

 It doesn't look like your macro supports hinting destructured args
 (understandably enough, doing so given the :signatures approach would
 likely be very difficult).

I didn't put it in yet, but I was thinking of just having nil in the
type vector for unhinted variables, so you could have

(defn foo {:signature [ String String nil ]} [ a b c ] ...)

and then c wouldn't be hinted.  I hadn't thought of destructuring at
all; I'm guessing that it could be done with

(defn foo {:signature [{:bar Mytype} nil nil nil]} [{blah :foo mt-obj
:bar} a b c] ...)

but that's getting pretty ugly on its own.  I'm not sure if it would
be a win to try to do anything fancy like that.  I'm also not sure
what the destructuring assignment syntax is for maps right now, so
what I wrote might be total nonsense, syntactically.  I hope the idea
is clear, anyhow.

 - The thing I don't like about the current type hints is (IMO) the
 distracting quality of '#^'.  What about something like:

 (defh foo [String:s unhinted-arg {int:a :a}] ...) or
 (defh foo [s:String unhinted-arg {a:int :a}] ...)

 That's far more visually-appealing to me, and has the nice advantages
 of being inline in the case of destructuring and supporting sparse
 hinting easily.  I'll bet the macro would end up being pretty simple,
 as well.

I'd hate to see somebody do it, but it's currently valid to define
variables with colons in them, so there could be code out in the wild
with those definition forms already.  Other than that, I like the
looks of it.  I think the macro would be easy as well, so long as
you're comfortable munging variable names :)

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



zipping together two lists

2009-08-07 Thread tsuraan

Most languages I've used define a zip method, where you can take two
lists and get a list of the pairs of elements in those lists.  So,
(zip '(1 2 3) '(4 5 6)) would give ([1 4] [2 5] [3 6]).  Does clojure
have a core function like that?  I've been poking around, but all I'm
finding is zipmap, which is close but it builds a map instead of a
list of pairs.  Writing my own isn't a big deal, but it seems like
something that has to be in the core somewhere.

--~--~-~--~~~---~--~~
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: zipping together two lists

2009-08-07 Thread tsuraan

 map can do this.

 user (map vector '(1 2 3) '(4 5 6))
 ([1 4] [2 5] [3 6])

Yeah, that works pretty well.  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: Why is this using reflection?

2009-06-08 Thread tsuraan

 I thought it might be fun to try out the new repl-utils expression-info fn
 on
 this.

Is this just in source control, or is it in a release?  I'm using
1.0.0, and I don't seem to have that function.

 So first I had to recreate your 'import' line (you might consider including
 this
 kind of detail next time you post a question):

Yeah, sorry about that.  I'll remember next time.

 Well, that seems to have done it.  Using that style in the original
 expression,
 we get:

   (defn searcher-path [#^IndexSearcher searcher]
 (let [#^FSDirectory fsdir (.. searcher getIndexReader directory)
   #^String  path  (.. fsdir getFile getPath)]
   path))

 That compiles without reflection warnings.

I thought I had tried this and gotten an error for it; I must have
made a typo and assumed it was an invalid thing to do.  It's certainly
working now :)  Where can I get more info on the expression-info call?
 A google search for expression-info and clojure gives a pdf on
multiple dispatch and nothing else.

 Note also that hinting 'path' as 'String' doesn't really do any good when
 all we
 do is return it:

That's really strange.  The clojure compiler doesn't put types on
functions when the only value returned from a function has an explicit
type?

   user= (expression-info '(searcher-path nil))
   nil

 If you want to promise that 'searcher-path' will always return a String so
 that
 the compiler can make further type deductions based on that, you need to
 hint
 the function itself:

   (defn #^String searcher-path [#^IndexSearcher searcher]
 (let [#^FSDirectory fsdir (.. searcher getIndexReader directory)]
   (.. fsdir getFile getPath)))

   user= (expression-info '(searcher-path nil))
   {:class java.lang.String, :primitive? false}

In the type hinting page, it says type hits can be applied to function
parameters, let-bound names, var names and expressions.  Is the
#^String here being applied to a var name (searcher-path)?  It wasn't
obvious to me that one could do that, although I guess functions names
are variables just like any other names in the system.

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Why is this using reflection?

2009-06-05 Thread tsuraan

I have a function to get the path out of a lucene searcher
(documentation at
http://lucene.apache.org/java/2_3_2/api/core/org/apache/lucene/search/IndexSearcher.html).
 The searcher has a Reader, which has a Directory.  The Directory is
abstract, but in my case I know that it's a FSDirectory, so I declare
fsdir, and then use its getFile and getPath.  The actual code I'm
using is:

(defn searcher-path [ #^IndexSearcher searcher ]
  (let [fsdir #^FSDirectory (.. searcher getIndexReader directory)
path  #^String (.. fsdir getFile getPath) ]
path))

When I compile this with warn-on-reflection, I get that getField and
getPath cannot be resolved.  Am I doing the hinting wrong somehow?  I
do have imports in my file for IndexSearcher and FSDirectory, so I'm
not sure what I'm missing.

I've also tried this with nested lets, but that didn't help either (as
expected).

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Using generics

2009-05-28 Thread tsuraan

I have a java class whose constructor expects (among other things) a
BlockingQueueLong.  It's easy to create a BlockingQueue in clojure
(obviously), but I can't figure out the syntax to specialize it to the
Long type.  Is this possible, or does it even make sense?  I seem to
recall that generics are just hints for the java compiler and not
actually enforced by the runtime, which would imply that clojure has
no need to support them.  Is that the case?

--~--~-~--~~~---~--~~
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
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 generics

2009-05-28 Thread tsuraan

   user= (show Class)
   ===  public final java.lang.Class  ===
   [ 0] static forName : Class (String)
   [ 1] static forName : Class (String,boolean,ClassLoader)
   [ 2] asSubclass : Class (Class)
   [...]
   nil
   user= (show Class 2)
   #Method public java.lang.Class
 java.lang.Class.asSubclass(java.lang.Class)

 This shows that the entry point is at some level really expecting a
 Class and returning a Class.

Yeah, that makes sense.  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
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: ns :use with :rename

2009-05-27 Thread tsuraan

 Here's the correct syntax:

 (ns namespace
(:use [other-namespace :rename {existing newname}]))

aha, brackets.  Is there a plan to flesh out the API page to have more
examples of things like that?  As it stands, I think the API page is
probably great for somebody who needs a reminder, but for a newbie, it
could probably be a little more friendly.

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



ns :use with :rename

2009-05-26 Thread tsuraan

Is there an example of using :rename in a :use in the ns macro?  I'm
trying to get it to work, but the best I can come up with is:

(ns namespace
  (:use other-namespace :rename { :existing :newname }))

and when compiling, I get ClassCastException: java.lang.Boolean
cannot be cast to clojure.lang.IFn.  I'm not sure what's being turned
into a boolean or what should be an IFn, but if I get rid of
everything between :rename and ), it compiles.

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



compilation and classpath

2009-05-22 Thread tsuraan

I'm having some trouble getting clojure to generate .class files.  I
have a directory layout like this:

test/
main.clj

where main.clj is the same file as from
http://clojure.org/compilation, but with the 'clojure.examples.hello
replaced with 'test.main .  I've tried running clojure a few different
ways:

from the parent dir of the test dir, as java -cp
~/src/clojure/clojure.jar:`pwd`/ clojure.main
from within the test dir, as java -cp ~/src/clojure/clojure.jar:`pwd`/..

In both cases, I can successfully (use 'test.main) and call (-main
foo), and it works, but when I try to call (compile 'test.main) I
get java.io.IOException: No such file or directory (main.clj:1).  What
do I need to do to get compilation to work?

--~--~-~--~~~---~--~~
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
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: compilation and classpath

2009-05-22 Thread tsuraan

 You probably need to set (and create!) the correct compilation
 (output) directory. This defaults to a classes directory as a
 subdirectory of your current working directory. So if you had:

And this worked!  Now that I'm looking for the *compile-path*
variable, I see that it's mentioned in the compilation page.  I guess
I skimmed a little too lightly :)

Thanks a ton!

--~--~-~--~~~---~--~~
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
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: String.getBytes does not translate to byte[]?

2009-05-13 Thread tsuraan
 Well, under the covers the str function applies the java toString
 method to any passed in object and hence the result could for some
 reason be different to the original String object passed in. I think
 this could occur if the object subclasses String, but has a different
 representation (i.e a different toString method).

 Are you able to post what s contains when this happens?
 You could try printing s in your calling function and then also in the
 defmethod, e.g;

 (defmethod t-str String [s] (prn cls: (class s) s: s chars: (vec s

 Maybe that'll shed some light?

I thought I sent this to the list, but I think I just sent it to a
single person, so I'm trying again...

 Ok, here's a stripped down set of code that has the problem.  It does
 require that erlang be installed with java support.  I couldn't figure
 out a way to duplicate the problem without it, unfortunately.

 To test this out, first start erlang like this:

 erl -setcookie cookie -sname e...@localhost

 Then, run the attached demo.clj.  Once that's started (it won't print
 anything, so just give it a sec to get running), run the following
 from the erlang REPL:

 { echo, e...@localhost } ! { self(), hi there }.

 and then, after the demo.clj has exited,

 (fun() - receive X - X after 0 - nil end end)().

 As the code is submitted, you will get a reply that looks like

 172,237,0,5,117,114,0,2,91,66,172,243,23,248,6,8,84,224,
  2,0,0,120,112,0,0,0,8,104,105,...

 If you replace the (let [ inside s ...]) with (let [ inside (str s)
 ...]) and rerun the test, you will get the string hi there, as a
 binary.   On the clojure side, the following is printed

 with [ inside s ]:

I was given a class java.lang.String
Chars are [\h \i \space \t \h \e \r \e]
Given string is 'hi there'
Bytes length is 8
OtpBinary size is 35

 with [ inside (str s) ]

I was given a class java.lang.String
Chars are [\h \i \space \t \h \e \r \e]
Given string is 'hi there'
Bytes length is 8
OtpBinary size is 8

So, I'm hoping this gives somebody an idea, because I'm stumped.

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



demo.clj
Description: Binary data


Re: String.getBytes does not translate to byte[]?

2009-05-13 Thread tsuraan

 I guess that if you enable reflection warnings, you'll get a warning on
 the line where you invoke the constructor.

 I think the reflective dispatch doesn't pick the good constructor and
 invokes OtpErlangBitstr(Object) instead of OtpErlangBitstr(byte[]).
 Thus your byte[] is serialized and the 35 above is the length of the
 serialized array.

 A type hint on s should fix the issue:

 (defmethod to-otp String [ #^String s ]
   (OtpErlangBinary. (.getBytes s utf-8)))

Ok, that worked, but I don't understand why.  How does forcing the
type of s to be String cause the dispatch to use the byte[]
constructor instead of the Object constructor?  This would make sense
if we were somehow coercing the return value of .getBytes to be a
byte[] instead of an Object, but I don't see how the type checker is
calling any constructor other than a byte[] constructor when that's
the return value of getBytes already.

Does this have anything to do with the fact that (class (first
(.getBytes hi))) gives java.lang.Byte instead of just plain byte?  I
had noticed that (and thus the subject of this topic), but in my
smaller tests it didn't seem to matter.

--~--~-~--~~~---~--~~
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
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: String.getBytes does not translate to byte[]?

2009-05-13 Thread tsuraan

 I guess that if you enable reflection warnings, you'll get a warning on
 the line where you invoke the constructor.

As a bit of an aside, is there a reason that using multimethods with
class-based dispatch doesn't add type hints by itself?  It seems sort
of strange that it's necessary to define your methods with (defmethod
name Class [ #^Class arg ] ...) instead of just being able to do
(defmethod name Class [ arg ] ...).

--~--~-~--~~~---~--~~
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
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: String.getBytes does not translate to byte[]?

2009-05-13 Thread tsuraan

 It's a type hint, it's not a type coercion.

 Without the type hint, the compiler doesn't know the type of s, so it
 can't find the .getBytes method (nor, of course, its return type) and,
 in doubt, picks the broader constructor: OtpErlangBinary(Object).
 With the type hint, the compiler know that s must be treated as a
 String, it find .getBytes, sees that it returns a byte[] and is able to
 select the right constructor for OtpErlangBinary.

Is the OtpErlangBinary constructor that's being used actually
determined at compile time, rather than at run time?

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



String.getBytes does not translate to byte[]?

2009-05-12 Thread tsuraan

I'm trying to encode a java string into utf-8 for encapsulation within
an OtpErlangBinary
(http://erlang.org/doc/apps/jinterface/java/com/ericsson/otp/erlang/OtpErlangBinary.html).
 When I try to construct an OtpErlangBinary from the results of
String.getBytes(encoding), I get bad data.  A string (pure ascii) with
20 characters becomes a 47-byte OtpErlangBinary, and none of the bytes
in that binary seem to correspond to the bytes of the string.  The
simple function that I have looks like this:

(defmethod to-otp String [ s ]
  (new OtpErlangBinary (.getBytes s utf-8)))

And the OtpErlangBinary gets 47 bytes of data for a 20 byte string.
However, if I change that code to read:

(defmethod to-otp String [ s ]
  (new OtpErlangBinary (.getBytes (str s) utf-8)))

(notice the (str s)), the code works.  It seems really strange to me
that this should happen, but I don't know clojure well enough to
determine what's going on under the hood.  Is there some way to dump
the java code equivalent of those two functions, so I can compare
them?   I've tried making a minimal test case for converting strings
into OtpErlangBinaries, but I can't get this bug to manifest in any
circumstances other than this one program.

Any tips for debugging would be much appreciated.  I'm running clojure
1.0.0, with java 1.6.0, and erlang jinterface 1.4.

--~--~-~--~~~---~--~~
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
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: String.getBytes does not translate to byte[]?

2009-05-12 Thread tsuraan

 Maybe there's something about the particular [ s ] object that you're
 passing in?

I believe that you're right; in general, the getBytes seems to work.
It is just in this one freakish case that it doesn't, but I have no
idea how to tell what's special about my string.  I'm not exactly
proficient in Java, and I'm a complete clojure newbie, so I really
have no idea how to proceed with debugging this.

Under what circumstances would (str s) give something different from
s, when (.getClass s) gives java.lang.String?

Also, sorry for the horrible subject line; that was my initial guess,
and I had a big email written up about it, but then I started testing
my assumptions and they were all garbage.  I rewrote the email, but
forgot about the subject...

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---