Hello Brent, thank you for the response. You're right, better keep a clear distinction between invoking and evaluating.
On Thursday, November 25, 2021 at 3:35:09 PM UTC+1 brent....@gmail.com wrote: > Ok so I think taking a step back, I think their is some complecting going > on here. I don't see how you see "that invoking a map without arguments > evaluates it" as a generalization. I believe Rich's intention behind map's, > set's, and vector's being callable is that they naturally behave as > primitive (mathematically) functions, which map a key space to an output > space. So first, there aren't any natural meanings for calling a map with > zero arguments. (If anything, I think it should return nil. Because > sometimes we would call functions using apply like (apply f [a b c]), and > sometimes that list is empty, like (apply {} []). This is just like how (+) > evaluates to 0. But I digress...). > > What you are generally talking about is controlling code evaluation. You > are specifically storing code within the values (and potentially keys) of > the map. Really, this code is just lists, aka data. It is really important > to keep the phases of evaluation separate, otherwise this makes macro > writing very confusing (and coding in general). What you are suggesting > complects calling a map (keys to values), with evaling a map (recursively > eval any non quoted lists). These are separate actions/ideas. When we do > want to operate in different phases, then we really do want to call eval > explicitly as this is a "dramatic" action. Eval takes literal data and > pipes them through unless they are lists, where it treats the first arg as > a function/special-form, and the output can be very different from the > input. In contrast, often transformations on maps result in other maps. My > take here is, again, this should be explicit. In your intended behavior > example (({}) :b), it is calling eval behind the scenes. This is very > hidden and leads to very different performance implications. My take is you > are suggesting reducing code size but not actually addressing duplication, > and in the process making special behaviors less intuitive. (One other > thing is what you suggest doesn't blend nicely with -> as you'd still have > to call .invoke at the end instead of just calling eval.) > > ----- > > To support your cause, however, I think there are many tools to help you > with code manipulation and code analysis during runtime. > > If you want your code to work as is but have code analysis phases, you can > use macros to insert code analyzing phases without impacting the evaluation > and runtime implications of the code itself. > > For example: > (def code-size (atom 0)) > (defmacro count-code [some-code] > (reset! code-size (count (str some-code))) > some-code) > > (count-code {:a :b}) ;; => {:a :b} > @code-size ;; => 7 > > From there, you can write code analysis walkers as functions (not macros) > and use them at runtime with explicit quoted forms at the repl, or insert > them into your macros for analyzing "production" code. > On Wednesday, November 24, 2021 at 2:52:43 PM UTC-5 dieter.v...@gmail.com > wrote: > >> Hello Brent, >> >> The use case I had in mind was to keep a map readable during development. >> Take a simple map: {:type QTDIR :path (hash "a string")}. It's easier to >> play with this data if evaluation of certain symbols and functions is >> delayed. >> >> Thanks you both for your answer, >> kind regards, >> Dieter >> >> >> >> >> On Mon, Nov 22, 2021 at 3:39 AM Brent Millare <brent....@gmail.com> >> wrote: >> >>> I'm curious why you are saving hashmaps that have clojure code within it >>> with the intention of evaluating this code as embedded in the hashmap? What >>> is the use case? Are you trying to delay evaluation? Regardless, eval >>> always incurs a cost and should generally be avoided if you can use >>> "runtime" techniques instead. Is the embedded code trusted? >>> >>> Best, >>> Brent >>> >>> On Sunday, November 21, 2021 at 9:22:47 AM UTC-5 dieter.v...@gmail.com >>> wrote: >>> >>>> Hello, >>>> >>>> It seems to be a design decision that 0-arity invoke of a composite >>>> data type gives an ArityException: the composite data type does not >>>> implement the IFn when no arguments are given. >>>> Is there a certain design decision behind this behavior? (or a certain >>>> use-case) >>>> >>>> >>>> repl> ;composite data type evaluates to itself >>>> repl> {:a 1 :b (hash "word")} >>>> {:a 1 :b -304538205} >>>> repl> '{:a 1 :b (hash "word")} >>>> {:a 1 :b (hash "word")} >>>> repl> (def mydata '{:a 1 :b (hash "word")}) >>>> repl> mydata >>>> {:a 1 :b (hash "word")} >>>> repl> ;composite data type implements IFn for its keys >>>> repl> (mydata :b) >>>> (hash "word") >>>> repl> ; there is no '0-arity' implementation of IFn for composite data >>>> type >>>> repl> ({}) >>>> ... (ArityException)... >>>> repl> (mydata) >>>> ... (ArityException)... >>>> repl> ; instead i have to type eval >>>> repl> ((eval mymap) :b) >>>> -304538205 >>>> >>>> I know its only 4 letters and a space extra, but software composition >>>> is supposed to avoid code duplication and perhaps the idea makes sense >>>> that >>>> invoking a map without arguments evaluates it... Hence the question about >>>> the choice made for the current behavior. >>>> >>>> A possible small workaround >>>> (defrecord qid [qid] >>>> clojure.lang.IFn >>>> (invoke [this] (eval qid)) >>>> But expect this to throw alot of bugs: this record is not the same >>>> simple map. >>>> (issues with other protocols, reducers, transducers and much more I >>>> don't know of.) >>>> >>>> I hope this is the right google group to ask this question. >>>> kind regards, >>>> Dieter >>>> >>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clo...@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+u...@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 a topic in the >>> Google Groups "Clojure" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/clojure/d16Ow0MvhPU/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> clojure+u...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/clojure/ff296de8-ce0f-4798-a1cc-cd3e4b38c631n%40googlegroups.com >>> >>> <https://groups.google.com/d/msgid/clojure/ff296de8-ce0f-4798-a1cc-cd3e4b38c631n%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/c781128a-40fc-4148-b3e6-dc7775f43b9cn%40googlegroups.com.