title: How can I define a clojure type that implements the servlet interface?
body: <p>I'm attempting to use deftype (from the bleeding-edge clojure 1.2 branch) to create a java class that implements the java Servlet interface.  I would expect the code below to compile (even though it's not very useful).</p>
  
  <pre><code>(ns foo [:import [javax.servlet Servlet ServletRequest ServletResponse]])
  
  (deftype servlet [] 
     javax.servlet.Servlet 
     (service [this 
           #^javax.servlet.ServletRequest request
           #^javax.servlet.ServletResponse response]
     nil))
  </code></pre>
  
  <p>But it doesn't compile.  The compiler produces the message:</p>
  
  <pre><code>Mismatched return type: service, expected: void, had: java.lang.Object
    [Thrown class java.lang.IllegalArgumentException]
  </code></pre>
  
  <p>Which doesn't make sense to me, because I'm returning nil.  So the fact that the return type of the method is void shouldn't be a problem.  For instance, for the java.util.Set interface:</p>
  
  <pre><code>(deftype bar [#^Number n] java.util.Set (clear [this] nil))
  </code></pre>
  
  <p>compiles without issue.</p>
  
  <p>So what am I doing wrong with the Servlet interface?</p>
  
  <p>To be clear: 
  I know that the typical case is to subclass one of the servlet abstract classes rather than  implement this interface directly, but it should still be possible to do this.  </p>
  
  <p><strong>Stack Trace:</strong></p>
  
  <p>The stack trace for the (deftype servlet... is:</p>
  
  <pre><code>Mismatched return type: service, expected: void, had: java.lang.Object
    [Thrown class java.lang.IllegalArgumentException]
  
  Restarts:
   0: [ABORT] Return to SLIME's top level.
  
  Backtrace:
    0: clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:6461)
    1: clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:6119)
    2: clojure.lang.Compiler$NewInstanceExpr$DeftypeParser.parse(Compiler.java:6003)
    3: clojure.lang.Compiler.analyzeSeq(Compiler.java:5289)
    4: clojure.lang.Compiler.analyze(Compiler.java:5110)
    5: clojure.lang.Compiler.analyze(Compiler.java:5071)
    6: clojure.lang.Compiler.eval(Compiler.java:5347)
    7: clojure.lang.Compiler.eval(Compiler.java:5334)
    8: clojure.lang.Compiler.eval(Compiler.java:5311)
    9: clojure.core$eval__4350.invoke(core.clj:2364)
   10: swank.commands.basic$eval_region__673.invoke(basic.clj:40)
   11: swank.commands.basic$eval_region__673.invoke(basic.clj:31)
   12: swank.commands.basic$eval__686$listener_eval__687.invoke(basic.clj:54)
   13: clojure.lang.Var.invoke(Var.java:365)
   14: foo$eval__2285.invoke(NO_SOURCE_FILE)
   15: clojure.lang.Compiler.eval(Compiler.java:5343)
   16: clojure.lang.Compiler.eval(Compiler.java:5311)
   17: clojure.core$eval__4350.invoke(core.clj:2364)
   18: swank.core$eval_in_emacs_package__320.invoke(core.clj:59)
   19: swank.core$eval_for_emacs__383.invoke(core.clj:128)
   20: clojure.lang.Var.invoke(Var.java:373)
   21: clojure.lang.AFn.applyToHelper(AFn.java:169)
   22: clojure.lang.Var.applyTo(Var.java:482)
   23: clojure.core$apply__3776.invoke(core.clj:535)
   24: swank.core$eval_from_control__322.invoke(core.clj:66)
   25: swank.core$eval_loop__324.invoke(core.clj:71)
   26: swank.core$spawn_repl_thread__434$fn__464$fn__465.invoke(core.clj:183)
   27: clojure.lang.AFn.applyToHelper(AFn.java:159)
   28: clojure.lang.AFn.applyTo(AFn.java:151)
   29: clojure.core$apply__3776.invoke(core.clj:535)
   30: swank.core$spawn_repl_thread__434$fn__464.doInvoke(core.clj:180)
   31: clojure.lang.RestFn.invoke(RestFn.java:398)
   32: clojure.lang.AFn.run(AFn.java:24)
   33: java.lang.Thread.run(Thread.java:637)
  </code></pre>