3 ms·
The languages you mention can't update data in flight, which is something Erlang can. Suppose you have the following code running in a thread: def print_na
by bjourne 6y ago
The languages you mention can't update data in flight, which is something Erlang can. Suppose you have the following code running in a thread:
def print_name(d):
print(d['name'])
d = {'name' : 'hello'}
while True:
print_name(d)
Now you hot hot-swap it while the while-loop is running:
def print_name(d):
print('hello', d['first_name'])
d = {'first_name' : 'there'}
while True:
print_name(d)
Erlang can do this. No other language that I'm aware of can.
- dig1 6y agoClojure has all sorts of facilities to do that (atoms, agents or refs). You can even listen for changes [1] and compare old and new values. [1] https://clojuredocs.org/clojure.core/add-watch https://clojuredocs.org/clojure.core/add-watch
- bjourne 6y agoInteresting, I didn't know that. I don't understand how the function you link to can be used to accomplish that. Can you give me an example?
- dig1 6y agoSure; here is example with atom: ;; define a map (def myvar (atom {:foo 1})) ;; add watcher for 'myvar'; it will call anonymous ;; function and set old-state with previous value and new-state ;; with new value, when 'myvar' was changed (add-watch myvar :dummy (fn [_ _ old-state new-state] (println "changed! - old: " old-state " new: " new-state))) ;; Run separate thread and and update :foo value to 2, after 6 seconds. ;; No scheduling is necessary, this is so it can be evaluated in REPL easily. (future (Thread/sleep 6000) (swap! myvar assoc :foo 2)) ;; Infinite loop. Sleep for 0.5 seconds just for printing purposes. (loop [] (println @myvar) (Thread/sleep 500) (recur)) and you will see output like this: {:foo 1} {:foo 1} {:foo 1} {:foo 1} {:foo 1} {:foo 1} {:foo 1} {:foo 1} changed! - old: {:foo 1} new: {:foo 2} {:foo 2} {:foo 2} {:foo 2} {:foo 2} {:foo 2} {:foo 2}
- bjourne 6y agoThat is an example of thread messaging - not hot-swapping. Had myvar been local to the thread it wouldn't have worked.
- dig1 6y agoI used different thread just for printing/add-watch purposes. But, using myvar or your-like example (hot loading function) in the same thread works without any problems as well - put function in a loop, change function body and reload namespace where myvar/function exists - loop will pick that up instantly.
- bjourne 6y agoIn your example, you modified the assoc while another thread was accessing it. That is a standard feature of languages with threading support and is not impressive. Let me give you a clearer example than my first one: def fn(): d = {'name' : 'hello'} while True: print(d['name']) threading.Thread(target=fn).run() This causes a thread to be started which prints "hello" indefinitely. Clojure cannot, while the thread is running, change the execution to, say: def fn(): d = {'name' : 'there'} while True: print(d['name']) time.sleep(0.5) Clojure cannot change the value of the local variable d because it has no reference to it. Clojure cannot add the line time.sleep(0.5) to the loop because it has no facility for "upgrading" running threads.
- dig1 6y agoCheck [1] to see what I'm talking about. I'd suggest you to investigate more before making such bold claims. [1] http://webcache.googleusercontent.com/search?q=cache:ieBuArSKu2MJ:travis-whitton.blogspot.com/2009/09/hot-code-swapping-with-clojure.html+&cd=3&hl=en&ct=clnk&gl=ba http://webcache.googleusercontent.com/search?q=cache:ieBuArS...
- bjourne 6y ago