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.

Reply via email to