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