Re: Any way to replace function body?

2019-02-22 Thread Gary Johnson
You have several options for this in Clojure. However, rebinding the same 
toplevel var that holds the original function is probably not the right way 
to do this if you want to be able to retrieve the old function value later. 
Consider the following approaches:

1. Define a single multi-arity function:

(defn fetch-data
  ([arg1 arg2] (db/fetch-data ...))
  ([arg1 arg2 & args]
(let [result (fetch-data arg1 arg2)]
  ;; do something with the remaining args
  (transform-result result

2. Derive the second function by composition:

(defn fetch-data [arg1 arg2] (db/fetch-data ...))

(def fetch-transformed-data
  (comp transform-result fetch-data))

3. Use "let" to rebind the function's definition within a lexical scope:

(defn fetch-data [arg1 arg2] (db/fetch-data ...))

;; ...somewhere later in my program...
(let [fetch-data (fn [arg1 arg2] (transform-result (fetch-data arg1 arg2)))]
  (fetch-transformed-data "foo" "bar"))

;; Note: While this works, it is pretty sketchy. You should probably just 
call the new local version of the function something else.

4. Use "binding" to rebind the function's definition within a dynamic scope:

(defn ^:dynamic fetch-data [arg1 arg2] (db/fetch-data ...))

;; ...somewhere later in my program...
(let [fetch-data-orig fetch-data]
  (binding [fetch-data (fn [arg1 arg2] (transform-result (fetch-data-orig 
arg1 arg2)))]
(fetch-data "foo" "bar")))

;; Note: You can't use binding to create a self-referential (recursive) 
function or you will trigger an infinite recursion. Use let to close over 
the original value of fetch-data before referencing it within the body of 
the new function used with binding.


There are probably several other approaches that you could experiment with 
as well if you wanted to look a bit farther afield. IMO, I would just go 
with the function composition solution. It's clear and concise and doesn't 
require you to remember the specifics of dealing with recursion in dynamic 
binding forms.


Happy hacking!
  Gary



On Saturday, January 19, 2019 at 2:58:29 PM UTC, Janko Muzykant wrote:
>
> Hi,
>
> Is there an way to replace body of existing (interned) function with own 
> code still being able to call original fn? 
> Suppose, I have a function:
>
> (defn fetch-data [arg1 arg2]
>   (db/fetch-data ...))
>
> I would like to intern a slightly modified version of this fn. Something 
> like this:
>
> (defn fetch-data [& args]
>   (let [result (apply original-fetch-data args)]
> (transform-result result)))
>
> The problem I see is how to keep the reference to original fetch-data fn 
> (here denoted by original-fetch-data),
> so it could be still called in a altered version of fetch-data function.
>
> Best,
> JM.
>
>
>
>

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


Re: Any way to replace function body?

2019-01-21 Thread Wesley Hall
Janko, 

It's a little hard to see exactly, but you might want to have a quick 
glance at the docs for, "with-redefs" in the core library. This will give 
you a slightly more structured way to redefine vars with actual scoping, 
even if that scope is your entire app it might be a more controlled 
approach. 

On Saturday, 19 January 2019 22:15:43 UTC, Janko Muzykant wrote:
>
> Awsome! This is exactly what I was looking for :)
>
> Thanks James and thanks everyone for other suggestions.
>
>
> On Saturday, January 19, 2019 at 5:20:06 PM UTC+1, James Reeves wrote:
>>
>> Yes, the alter-var-root function allows you to change a var's definition:
>>
>>   (alter-var-root
>>#'fetch-data
>>(fn [original-fetch-data]
>>  (fn [& args]
>>(let [result (apply original-fetch-data args)]
>>  (transform-result result))
>>
>> On Sat, 19 Jan 2019 at 14:58, Janko Muzykant  wrote:
>>
>>> Hi,
>>>
>>> Is there an way to replace body of existing (interned) function with own 
>>> code still being able to call original fn? 
>>> Suppose, I have a function:
>>>
>>> (defn fetch-data [arg1 arg2]
>>>   (db/fetch-data ...))
>>>
>>> I would like to intern a slightly modified version of this fn. Something 
>>> like this:
>>>
>>> (defn fetch-data [& args]
>>>   (let [result (apply original-fetch-data args)]
>>> (transform-result result)))
>>>
>>> The problem I see is how to keep the reference to original fetch-data fn 
>>> (here denoted by original-fetch-data),
>>> so it could be still called in a altered version of fetch-data function.
>>>
>>> Best,
>>> JM.
>>>
>>>
>>>
>>> -- 
>>> 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 the Google 
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to clojure+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>> -- 
>> James Reeves
>> booleanknot.com
>>
>

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


Re: Any way to replace function body?

2019-01-20 Thread Mars0i
To make the point explicit, bar now contains the original foo function:
(bar) ;=> 42

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


Re: Any way to replace function body?

2019-01-20 Thread Mars0i
Functions are values.  Why not just this:

(defn foo [] 42)
(def bar foo)
(defn foo [] (inc (bar)))
(foo) ;=> 43

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


Re: Any way to replace function body?

2019-01-19 Thread Janko Muzykant
Awsome! This is exactly what I was looking for :)

Thanks James and thanks everyone for other suggestions.


On Saturday, January 19, 2019 at 5:20:06 PM UTC+1, James Reeves wrote:
>
> Yes, the alter-var-root function allows you to change a var's definition:
>
>   (alter-var-root
>#'fetch-data
>(fn [original-fetch-data]
>  (fn [& args]
>(let [result (apply original-fetch-data args)]
>  (transform-result result))
>
> On Sat, 19 Jan 2019 at 14:58, Janko Muzykant  > wrote:
>
>> Hi,
>>
>> Is there an way to replace body of existing (interned) function with own 
>> code still being able to call original fn? 
>> Suppose, I have a function:
>>
>> (defn fetch-data [arg1 arg2]
>>   (db/fetch-data ...))
>>
>> I would like to intern a slightly modified version of this fn. Something 
>> like this:
>>
>> (defn fetch-data [& args]
>>   (let [result (apply original-fetch-data args)]
>> (transform-result result)))
>>
>> The problem I see is how to keep the reference to original fetch-data fn 
>> (here denoted by original-fetch-data),
>> so it could be still called in a altered version of fetch-data function.
>>
>> Best,
>> JM.
>>
>>
>>
>> -- 
>> 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 the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
> -- 
> James Reeves
> booleanknot.com
>

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


Re: Any way to replace function body?

2019-01-19 Thread John Newman
dispacio  has a 
shadow-extend-like capability:

(defp assoc string? [s i c] (str (subs s 0 i) c (subs s (inc i

And then

(assoc "abc" 2 'x);#_=> "abx"

Using alter-var-root in dispacio correctly would prevent var replacement 
warnings I believe, similar to s/instrument, but I haven't figured out how 
to do it yet in a cross-platform way. PRs welcome. 

V/r

John
On Saturday, January 19, 2019 at 9:58:29 AM UTC-5, Janko Muzykant wrote:
>
> Hi,
>
> Is there an way to replace body of existing (interned) function with own 
> code still being able to call original fn? 
> Suppose, I have a function:
>
> (defn fetch-data [arg1 arg2]
>   (db/fetch-data ...))
>
> I would like to intern a slightly modified version of this fn. Something 
> like this:
>
> (defn fetch-data [& args]
>   (let [result (apply original-fetch-data args)]
> (transform-result result)))
>
> The problem I see is how to keep the reference to original fetch-data fn 
> (here denoted by original-fetch-data),
> so it could be still called in a altered version of fetch-data function.
>
> Best,
> JM.
>
>
>
>

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


Re: Any way to replace function body?

2019-01-19 Thread James Reeves
Yes, the alter-var-root function allows you to change a var's definition:

  (alter-var-root
   #'fetch-data
   (fn [original-fetch-data]
 (fn [& args]
   (let [result (apply original-fetch-data args)]
 (transform-result result))

On Sat, 19 Jan 2019 at 14:58, Janko Muzykant  wrote:

> Hi,
>
> Is there an way to replace body of existing (interned) function with own
> code still being able to call original fn?
> Suppose, I have a function:
>
> (defn fetch-data [arg1 arg2]
>   (db/fetch-data ...))
>
> I would like to intern a slightly modified version of this fn. Something
> like this:
>
> (defn fetch-data [& args]
>   (let [result (apply original-fetch-data args)]
> (transform-result result)))
>
> The problem I see is how to keep the reference to original fetch-data fn
> (here denoted by original-fetch-data),
> so it could be still called in a altered version of fetch-data function.
>
> Best,
> JM.
>
>
>
> --
> 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.
>


-- 
James Reeves
booleanknot.com

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


Re: Any way to replace function body?

2019-01-19 Thread Chris Nuernberger
There has to be.  Trace, profile, and debugging libraries for clojure do it
all the time.  I might check the source for some of those.

On Sat, Jan 19, 2019 at 9:06 AM jason poage  wrote:

> Why would you want to overwrite a function if you need reference to the
> original function? Why not just rename the wrapper function to something
> else?
>
> Or you could use (source function-name) to get the function body and
> essentially rename the function.
>
> Sent from my iPhone
>
> On Jan 19, 2019, at 07:50, Janko Muzykant  wrote:
>
> Hi,
>
> Is there an way to replace body of existing (interned) function with own
> code still being able to call original fn?
> Suppose, I have a function:
>
> (defn fetch-data [arg1 arg2]
>   (db/fetch-data ...))
>
> I would like to intern a slightly modified version of this fn. Something
> like this:
>
> (defn fetch-data [& args]
>   (let [result (apply original-fetch-data args)]
> (transform-result result)))
>
> The problem I see is how to keep the reference to original fetch-data fn
> (here denoted by original-fetch-data),
> so it could be still called in a altered version of fetch-data function.
>
> Best,
> JM.
>
>
>
> --
> 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.
>

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


Re: Any way to replace function body?

2019-01-19 Thread jason poage
Why would you want to overwrite a function if you need reference to the 
original function? Why not just rename the wrapper function to something else?

Or you could use (source function-name) to get the function body and 
essentially rename the function.

Sent from my iPhone

> On Jan 19, 2019, at 07:50, Janko Muzykant  wrote:
> 
> Hi,
> 
> Is there an way to replace body of existing (interned) function with own code 
> still being able to call original fn? 
> Suppose, I have a function:
> 
> (defn fetch-data [arg1 arg2]
>   (db/fetch-data ...))
> 
> I would like to intern a slightly modified version of this fn. Something like 
> this:
> 
> (defn fetch-data [& args]
>   (let [result (apply original-fetch-data args)]
> (transform-result result)))
> 
> The problem I see is how to keep the reference to original fetch-data fn 
> (here denoted by original-fetch-data),
> so it could be still called in a altered version of fetch-data function.
> 
> Best,
> JM.
> 
> 
> 
> -- 
> 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.


Re: Any way to replace function body?

2019-01-19 Thread Pankaj Doharey
Checkout multi-arity functions in clojure.
On Sat, 19 Jan 2019 at 8:28 PM, Janko Muzykant  wrote:

> Hi,
>
> Is there an way to replace body of existing (interned) function with own
> code still being able to call original fn?
> Suppose, I have a function:
>
> (defn fetch-data [arg1 arg2]
>   (db/fetch-data ...))
>
> I would like to intern a slightly modified version of this fn. Something
> like this:
>
> (defn fetch-data [& args]
>   (let [result (apply original-fetch-data args)]
> (transform-result result)))
>
> The problem I see is how to keep the reference to original fetch-data fn
> (here denoted by original-fetch-data),
> so it could be still called in a altered version of fetch-data function.
>
> Best,
> JM.
>
>
>
> --
> 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.


Any way to replace function body?

2019-01-19 Thread Janko Muzykant
Hi,

Is there an way to replace body of existing (interned) function with own 
code still being able to call original fn? 
Suppose, I have a function:

(defn fetch-data [arg1 arg2]
  (db/fetch-data ...))

I would like to intern a slightly modified version of this fn. Something 
like this:

(defn fetch-data [& args]
  (let [result (apply original-fetch-data args)]
(transform-result result)))

The problem I see is how to keep the reference to original fetch-data fn 
(here denoted by original-fetch-data),
so it could be still called in a altered version of fetch-data function.

Best,
JM.



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