I don't think that they are the same, unfortunately. In the `def` form the 
symbol is unquoted as so
much be known at the time that the form is compiled. In the second case, the 
symbol is quoted and so can also be
a variable. Hence, it cannot be guaranteed to be known at compile time.

The practical upshot of this, is that, with the `def` form, you can use the `x` 
in later in the same macro expansion. 
While with the intern you cannot, because the compiler doesn't know that `x` 
has been defined.

Phil


________________________________________
From: clojure@googlegroups.com [clojure@googlegroups.com] on behalf of Timothy 
Baldridge [tbaldri...@gmail.com]
Sent: 14 May 2017 00:04
To: clojure@googlegroups.com
Subject: Re: How to Create Clojure `defn` Functions automatically?

Okay, so I've read these SO articles about 4 times now, and I finally think I'm 
starting to understand what the `intern` solution is doing. I would recommend 
this then can we simply state that:

`(def x 42)`

is equal to

`(intern 'x 42)`

Except the first is a compiler special form (and hence requires a compiler 
and/or macro system) while the other is a function (and requires a namespace 
system). That will probably save people a ton of reading. Like I said, I 
program Clojure a lot, and it took me about 60 minutes of reading and thinking 
about this code before I finally figured out what the problem and the solution 
and the solution being presented.


On Sat, May 13, 2017 at 4:49 PM, Alan Thompson 
<clooj...@gmail.com<mailto:clooj...@gmail.com>> wrote:
I was just trying to answer a question posed by someone else, so I can't give 
details about the original motivation. I thought it was a good example of the 
capabilities of `intern` that I hadn't seen before, which could be useful in a 
dynamic case where one wanted to generate functions on the fly w/o using macros.

A previous answer the OP was referred 
to<http://stackoverflow.com/questions/7852351/clojure-macro-to-generate-functions>
 was incomplete for the new question and I was trying to fill in the missing 
parts.



On Sat, May 13, 2017 at 3:40 PM, Timothy Baldridge 
<tbaldri...@gmail.com<mailto:tbaldri...@gmail.com>> wrote:
Sorry, but this use of intern is a pointless. What does intern give you that a 
let over a defn doesn't?

On Sat, May 13, 2017 at 4:37 PM, Alan Thompson 
<clooj...@gmail.com<mailto:clooj...@gmail.com>> wrote:
If anyone is interested, I cleaned up the question to (hopefully) make it 
clearer, as well as adding the macro-calling-a-macro solution.

While some may consider it esoteric, I thought it was a good example of the 
power `intern` can provide, as well as a good way to avoid macros and stick to 
pure functions.

Here is the re-worked version:  
http://stackoverflow.com/questions/43958471/how-to-create-clojure-defn-functions-automatically-without-macros/

Alan

On Thu, May 11, 2017 at 10:15 AM, Alan Thompson 
<clooj...@gmail.com<mailto:clooj...@gmail.com>> wrote:
Actually someone else wrote the original CLJS question (1):  
http://stackoverflow.com/questions/43897632/mapped-calls-to-clojurescript-macro

It was marked as a duplicate of this question (2):  
http://stackoverflow.com/questions/43897632/mapped-calls-to-clojurescript-macro 
   This one also had an answer using `intern` to avoid the need for a macro.

I didn't think question (1) was an exact duplicate of (2), and I wanted to work 
out the details of solving (1) using `intern` instead of macros (it seemed like 
a good goal at the time...).  I tried to simplify question (1) w/o the CLJS 
callback stuff, and may have oversimplified.

Since question was closed as being a "duplicate" (in error, I think), I 
couldn't answer there and posed the Q&A style answer separately at (3):  
http://stackoverflow.com/questions/43904628/how-to-create-clojure-defn-functions-automatically

The main goal I had here was simply finding a good way to avoid macros when 
auto-generating functions, and to generalize/document the technique described 
in (2) using `intern`.

Alan

P.S.  Regarding (3), Joel Spolsky, creator of StackOverflow, has often 
encouraged people to post both a question and its answer on the site:  
https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions
      In fact, they even have a special button for this purpose.



On Thu, May 11, 2017 at 9:39 AM, Timothy Baldridge 
<tbaldri...@gmail.com<mailto:tbaldri...@gmail.com>> wrote:
I assume this is a real problem you are encountering since you wrote the 
original Stack Overflow questions. As Dragan mentioned, this example doesn't 
warrant such a complex solution, maps and keywords *are* function, so all you 
really need is `foo` as a getter. Or even if they weren't functions you still 
have `(partial get foo)`.

On Thu, May 11, 2017 at 10:27 AM, Alan Thompson 
<clooj...@gmail.com<mailto:clooj...@gmail.com>> wrote:
Since the original question was in CLJS, which has neither `intern` nor `eval`, 
does that mean the macro mapping another macro approach is the only solution 
there?


On Thu, May 11, 2017 at 9:18 AM, Alan Thompson 
<clooj...@gmail.com<mailto:clooj...@gmail.com>> wrote:
I like the idea of using `eval` and  `memoize`.  I'll have to keep that in mind.
Alan

On Thu, May 11, 2017 at 7:58 AM, Timothy Baldridge 
<tbaldri...@gmail.com<mailto:tbaldri...@gmail.com>> wrote:
This is a somewhat weird answer to a overcomplicated problem. As mentioned, the 
data is a map to start with, and maps are functions so treating the maps as 
data is probably the best approach. And like Dragan, I'm unsure why this 
example doesn't use `(data :able)`.

When I do need to generate functions at runtime, and I can't use macros (for 
the reasons mentioned), I'll either use a macro that creates a var, or use eval 
perhaps in conjunction with a memoize. I used this a lot in my work with 
JavaFx. Do some reflection, generate some code, eval the code and return a 
function, memoize that process so we can get the generated function via name. 
So the interface looks like this:

((get-setter button :text) "hey")

Get-setter does a ton of reflection, but calling the returned function remains 
fast due to the combination of eval and memoization.



On Thu, May 11, 2017 at 2:55 AM, Dragan Djuric 
<draga...@gmail.com<mailto:draga...@gmail.com>> wrote:
What's wrong with (foo :able) => "Adelicious!" and (:able foo) => "Adelicious!"?


On Thursday, May 11, 2017 at 9:20:19 AM UTC+2, Alan Thompson wrote:
A recent question on StackOverflow raised the question of the best way to 
automatically generate functions. Suppose you want to automate the creation of 
code like this:


(def foo
  {:able    "Adelicious!"
   :baker   "Barbrallicious!"
   :charlie "Charlizable"})
(def bar
  {:able    "Apple"
   :baker   "Berry"
   :charlie "Kumquat"})

(defn manual-my-foo [item] (get foo item))
(defn manual-my-bar [item] (get bar item))

(manual-my-foo :able) => "Adelicious!"
(manual-my-bar :charlie) => "Kumquat"

You could write a macro to generate one of these at a time, but you can't pass 
a macro to a higher-order function like `map`, so while this would work:


(generate-fn :foo)  ;=> creates `my-foo` w/o hand-writing it


this wouldn't work:


(map generate-fn [:foo :bar :baz])

While one could write a 2nd macro to replace `map`, this is a symptom of the 
"Turtles All the Way Down" problem. One workaround is to avoid macros 
altogether and use only functions to generate the required `my-foo` and 
`my-bar` functions.  The trick is to make use of the built-in Clojure function 
`intern`  both to save the newly generated functions into the global 
environment and to retrieve the pre-existing maps `foo` and `bar`.  Full 
details are available Q&A-style at the StackOverflow 
post<http://stackoverflow.com/questions/43904628/how-to-create-clojure-defn-functions-automatically/43904717#43904717>.

Enjoy,
Alan


--
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<mailto: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<mailto:clojure%2bunsubscr...@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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.



--
“One of the main causes of the fall of the Roman Empire was that–lacking 
zero–they had no way to indicate successful termination of their C programs.”
(Robert Firth)

--
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<mailto: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<mailto:clojure%2bunsubscr...@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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.



--
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<mailto: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<mailto:clojure%2bunsubscr...@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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.



--
“One of the main causes of the fall of the Roman Empire was that–lacking 
zero–they had no way to indicate successful termination of their C programs.”
(Robert Firth)

--
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<mailto: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<mailto:clojure%2bunsubscr...@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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.



--
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<mailto: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<mailto:clojure%2bunsubscr...@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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.



--
“One of the main causes of the fall of the Roman Empire was that–lacking 
zero–they had no way to indicate successful termination of their C programs.”
(Robert Firth)

--
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<mailto: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<mailto:clojure%2bunsubscr...@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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.


--
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<mailto: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<mailto:clojure%2bunsubscr...@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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.



--
“One of the main causes of the fall of the Roman Empire was that–lacking 
zero–they had no way to indicate successful termination of their C programs.”
(Robert Firth)

--
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 unsubscribe from this group and stop receiving emails from it, send an email 
to 
clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to