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> 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> > 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> >> 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/ques >>> tions/43958471/how-to-create-clojure-defn-functions-automati >>> cally-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-c >>>> lojure-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-ans >>>> wer-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. >>> >> >> >> >> -- >> “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.