# How to type hint eval'd \`fn\`-calls

**URL:** https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309
**Category:** How to?
**Tags:** clojure
**Created:** [May 28, 2019, 10:11am UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309 "2019-05-28T10:11:55Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![saikyun](https://clojureverse.org/user_avatar/clojureverse.org/saikyun/32/1958_2.png) [@saikyun](https://clojureverse.org/u/saikyun)
#### Post date: [May 28, 2019, 10:11am UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309/1 "2019-05-28T10:11:55Z")

</div>

How do I `eval` a `fn` declaration and keep type hints? I can’t get it to work. The expected result is that `(eval generated-fn2)` won’t give me reflection warnings.

```clojure
(require '[clojure.java.io :as io])
​
(set! *warn-on-reflection* true)
(set! *print-meta* true)
​
(def file (io/file "hej"))
(.getName file) ;; reflection warning
​
(def generated-fn `(fn [~'file] (.getName ~'file)))
​
(eval generated-fn) ;; reflection warning 
​
(def generated-fn2 `(fn [~(with-meta 'file {:tag java.io.File})] (.getName ~'file)))
(prn generated-fn2) ;; (clojure.core/fn [^java.io.File file] (.getName file))
(eval generated-fn2) ;; reflection warning, but why?
​
(clojure.core/fn [^java.io.File file] (.getName file)) ;; no reflection warning

```

Here’s the problem on repl.it, if someone wants to give it a go there: [https://repl.it/repls/ExcitedDetailedRedundancy](https://repl.it/repls/ExcitedDetailedRedundancy)

---

<div class="post-metadata">

### Author: ![borkdude](https://clojureverse.org/user_avatar/clojureverse.org/borkdude/32/306_2.png) [@borkdude](https://clojureverse.org/u/borkdude)
#### Post date: [May 28, 2019, 10:30am UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309/2 "2019-05-28T10:30:02Z")

</div>

This should do the trick:

```auto
(def generated-fn2 `(fn [^java.io.File file#] (.getName file#)))

```

---

<div class="post-metadata">

### Author: ![saikyun](https://clojureverse.org/user_avatar/clojureverse.org/saikyun/32/1958_2.png) [@saikyun](https://clojureverse.org/u/saikyun)
#### Post date: [May 28, 2019, 10:34am UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309/3 "2019-05-28T10:34:35Z")

</div>

Huh, thanks a lot. Any idea why? I’m guessing what my code is doing is meta’ing the symbol being eval’d, rather than emitting a symbol with metadata, whereas your code somehow expresses that the metadata should be emitted? Thanks again, this is great.

---

<div class="post-metadata">

### Author: ![saikyun](https://clojureverse.org/user_avatar/clojureverse.org/saikyun/32/1958_2.png) [@saikyun](https://clojureverse.org/u/saikyun)
#### Post date: [May 28, 2019, 10:58am UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309/4 "2019-05-28T10:58:18Z")

</div>

Okay, next problem. I want to use this gensym inside another syntax-quote, how would I do this? I tried `let`ing it etc, but having a hard time figuring it out.

```auto
(def generated-fn2 `(fn [^java.io.File file#]
                      ~@(for [_ (range 3)]
                          `(.getName file#))))

```

This becomes two different symbols since it’s two different syntax-quotes.

---

<div class="post-metadata">

### Author: ![athos](https://clojureverse.org/user_avatar/clojureverse.org/athos/32/730_2.png) [@athos](https://clojureverse.org/u/athos)
#### Post date: [May 28, 2019, 2:39pm UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309/6 "2019-05-28T14:39:45Z")

</div>

For the first question, you need to quote `java.io.File`, otherwise it would be evaluated into the `File` class object (not a symbol).

For the second one, you’ll need to use `gensym` explicitly:

```auto
(def generated-fn2
  (let [file (gensym)]
    `(fn [~(with-meta file {:tag 'java.io.File})]
       ~@(for [_ (range 3)]
           `(.getName ~file)))))

```

---

<div class="post-metadata">

### Author: ![saikyun](https://clojureverse.org/user_avatar/clojureverse.org/saikyun/32/1958_2.png) [@saikyun](https://clojureverse.org/u/saikyun)
#### Post date: [May 29, 2019, 8:47am UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309/7 "2019-05-29T08:47:58Z")

</div>

Hey, thanks! That works wonders! Sadly can’t set two answers as the accepted.

---

<div class="post-metadata">

### Author: ![system](https://clojureverse.org/uploads/default/original/2X/5/51079bf9e4b7d9466242c06cf1e43b9f8bd6da14.png) [@system](https://clojureverse.org/u/system)
#### Post date: [November 27, 2019, 8:48pm UTC](https://clojureverse.org/t/how-to-type-hint-evald-fn-calls/4309/8 "2019-11-27T20:48:01Z")

</div>

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.
