Do I need a lock to access an immutable datastructure in multithreading context? - multithreading

I have an immutable datastructure that is a functional hashmap (see fash.scm) that is shared among several threads.
Imagine a thread wants to change the global hashmap to a new version. Do I need a lock to change the value? If that's is the case, I assume I also need to lock the value to read it, isn't it?
It seems to me it boils down to whether setting a value in Scheme is an atomic operation or not. According to this answer for C language, you must
acquire a lock for both read and write access of pointer.
If it matters I am using guile 2.2.3 and bigloo 4.3.

It all depends on what you want to do. In general, if the value can be guaranteed to be read (e.g. always a number), then it's okay not to lock when the value is read. For example,
(import (rnrs) (srfi :18))
(define count 0)
(define t
(thread-start!
(make-thread
(lambda ()
(let loop ()
(display count) (newline)
(thread-sleep! 0.1)
(loop))))))
(do ((i 0 (+ i 1))) ((= i 10))
(set! count (+ count 1))
(thread-sleep! 0.1))
This is pretty much safe to read. However if the value is, say a vector of length 1, then you may want to lock if the other threads may change the value to #f or a vector of length 0. For example:
(import (rnrs) (srfi :18))
(define count (vector 1))
(define t
(thread-start!
(make-thread
(lambda ()
(let loop ()
(display (vector-ref count 0)) (newline)
(thread-sleep! 0.1)
(loop))))))
(do ((i 0 (+ i 1))) ((= i 10))
(vector-set! count 0 (+ (vector-ref count 0) i))
(thread-sleep! 0.1))
(set! count #f) ;; if this happens, the you may want to lock on reader thread
I haven't check how fash is implemented, but as long as entries are not updated to unexpected values, I would think it's okay not to lock.

Related

Can someone breakdown what's happening in this piece of code?

I'm very new to LISP programming and I'm having a real hard time with the syntax. The following code is from my notes and I know what it does but I'd really appreciate a line by line breakdown to better understand what's happening here. The "when" loop seemed pretty simple to understand but specifically I'm having a hard time trying to understand the first 3 lines in the "do" loop. Also I'm not sure why (:= acc (1+ acc) was used in the last line of the when loop.
(defun count-lower-case-vowels (str)
(do ((i 0 (1+ i))
(acc 0)
(len (length str)))
((= i len) acc)
(when (or (equal (aref str i) #\a) (equal (aref str i) #\e)
(equal (aref str i) #\i) (equal (aref str i) #\o)
(equal (aref str i) #\u))
(:= acc (1+ acc)))))
I'm a big proponent of lots and lots of extra white space, to achieve visual code alignment (in 2D, yes, as if on a piece of paper) to improve readability:
(defun count-lower-case-vowels (str)
(do ( (i 0 (1+ i) ) ; loop var `i`, its init, step exprs
(acc 0 ) ; loop var `acc`, its init expr
(len (length str) ) ) ; loop var `len`, its init expr
((= i len) ; loop stop condition
acc) ; return value when loop stops
(if ; loop body: if
(find (aref str i) "aeiou") ; test
(setf acc (1+ acc))))) ; consequent
Is this better?
It is definitely not the accepted standard of LISP code formatting. But whatever makes it more readable, I think is for the best.
The i's step expression's meaning is that on each step after the loop didn't stop and its body was evaluated, (setf i (1+ i)) is called. acc and len have no step expressions, so for them nothing is called on each step.
As to the "when loop" you mention, it is not a loop at all, and is not a part at all of the do loop's looping mechanism. A when form is just like an if without the alternative, which also allows for multiple statements in the consequent, as if with an implicit progn:
(when test a1 a2 ...)
===
(if test (progn a1 a2 ...))
It just so happens that this loop's body consists of one form which is a when form. I have re-written it with an equivalent if.
do is a macro expecting 3 parameters:
(do ((i 0 (1+ i))
(acc 0)
(len (length str))) ;; first argument
((= i len) acc) ;; Second one
(when ...) ;; third
)
The first argument is itself a list, each element of this element being of the following form:
<var-name> <var-initial-value> <var-next-value>
In your case, the form (i 0 (1+ i)) means that in the body of the do macro (= in the third argument), you introduce a new, local variable called i. It starts with the value 0, and at each step of the loop, it gets updated to the value (1+ i) (i.e. it gets incremented by 1).
You see that the second element of this list is acc 0 with no <var-next-value> in it. It means that acc won't get updated automatically by the macro, and its value will change only according to what is done in the body.
The second argument is a list of one or (optionally) two elements <condition> <return-val> The first one <condition> is stating when to stop the iteration: once it evaluates to true, the macro stops. It gets evaluated before each iteration. The second, optional part, is a form stating what the do form returns. By default, it returns nil, but if you specify a form there, it will be evaluated before exiting the loop and return-val is returned instead.
The third argument is simply a list of forms that will get executed at each step, provided the condition is false.
Note that the code you have posted is older style.
Nowadays it can be written much shorter with loop and find:
(defun count-lower-case-vowels (string)
(loop for c across string
count (find c "aeiou")))

How to do looping in lisp?

Just started learning and coding lisp,
I'm trying to create a program that will continuously accept a number and stops only if and only if the last input number is twice the previous number.
Here's my code
----------
(let((a 0)
(b 0)
(count 0))
(loop
(= a b))
(princ"Enter Number: ")
(defvar a(read))
(format t "~% a = ~d" a)
(setq count (1+ count))
(while
(!= b(* a 2) || <= count 1)
(princ "Program Terminated Normally")
)
Thank you
a bit feedback
(let ((a 0)
(b 0)
(count 0))
(loop
(= a b)) ; here the LOOP is already over.
; You have a closing parenthesis
; -> you need better formatting
(princ"Enter Number: ")
(defvar a(read))
(format t "~% a = ~d" a)
(setq count (1+ count))
(while
(!= b(* a 2) || <= count 1)
(princ "Program Terminated Normally")
)
some improved formatting:
(let ((a 0)
(b 0)
(count 0))
(loop
(= a b)) ; LOOP ends here, that's not a good idea
(princ "Enter Number: ")
(defvar a(read)) ; DEFVAR is the wrong construct,
; you want to SETQ an already defined variable
(format t "~% a = ~d" a)
(setq count (1+ count))
(while ; WHILE does not exist as an operator
(!= b(* a 2) || <= count 1) ; This expression is not valid Lisp
(princ "Program Terminated Normally")
)
You may need to learn a bit more Lisp operators, before you really can write such loops. You also may want to use Lisp interactively and try out things, instead of trying to write code into an editor and never get feedback from a Lisp...
Here's an answer which definitely is not how you would do this in real life, but if you understand what it does you will understand one of the two big important things about Lisps.
(If you understand why the equivalent program would not work reliably in Scheme you'll also understand one of the important things about writing safe programs! Fortunately this is Common Lisp, not Scheme, so it's OK here.)
First of all let's write a little helper function to read integers. This is just fiddly detail: it's not important.
(defun read-integer (&key (prompt "Integer: ")
(stream *query-io*))
;; Read an integer. This is just fiddly details
(format stream "~&~A" prompt)
(values (parse-integer (read-line stream))))
OK, now here's a slightly odd function called mu (which stands for 'mutant U'):
(defun mu (f &rest args)
(apply f f args))
And now here is our program:
(defun read-integers-until-double-last ()
(mu (lambda (c getter current next factor)
(if (= next (* current factor))
(values current next)
(mu c getter next (funcall getter) factor)))
#'read-integer
(read-integer)
(read-integer)
2))
And here it is working:
> (read-integers-until-double-last)
Integer: 0
Integer: 4
Integer: 3
Integer: -2
Integer: -4
-2
-4
For extra mysteriosity you can essentially expand out the calls to mu here, which makes it either more clear or less clear: I'm not quite sure which:
(defun read-integers-until-double-last ()
((lambda (c)
(funcall c c
#'read-integer
(read-integer)
(read-integer)
2))
(lambda (c getter current next factor)
(if (= next (* current factor))
(values current next)
(funcall c c getter next (funcall getter) factor)))))
Again, this is not how you do it in real life, but if you understand what this does and how it does it you will understand quite an important thing about Lisps and their theoretical underpinnings. This is not all (not even most) of the interesting things about them, but it is a thing worth understanding, I think.

Does SBCL for lisp handle scope differently? It does not seem to pass scope into called functions?

When using emacs or my android app I run
(defun big (num) (setf num2 5)(little num)))
(defun little (num)(+ num2 num))
Little happily accepts num2 but when I run it in my SBCL repl (with sublimetext3) it does not.
Is this correct?
What is a workaround without creating a global variable for num2?
I could just pass a second argument (little num num2)
But this wont work when I am trying to mapcar little over a list. Because I can only have one argument when mapcaring correct?
Please read ยง6. Variables from Practical Common Lisp.
Unlike Emacs Lisp, Common Lisp relies on lexical scope by default (Emacs Lisp is dynamic by default). Dynamic scope (i.e. indefinite scope and dynamic extent) is provided by declaring variables special, and by convention, they are written with asterisks around their names (named "earmuffs"), like *standard-output*. You use defparameter or defvar to declare those variables. Since it has a global effect, you should never use them from inside functions; likewise, your usage of setf is not defined in Common Lisp: no variable named num2 was declared previously in the scope; besides, even if it did, using a global/special variable for local variable is bad style.
Dynamic scope
With special variables, you can for example locally rebind the standard output: the new value is only visible while the code is inside the body of the let binding:
(let ((*standard-output* *error-output*))
(print "Stream redirection"))
By default, print writes to the stream bound to *standard-output*; here, the stream is locally bound to the one given by *error-output*. As soon as you escape the let, *standard-output* reverts to its previous value (imagine there is a stack).
Lexical scope
With lexical scope, your code can only access the bindings that are visible in the text surrounding your code (and the global scope), and the extent is indefinite: it is possible to access a binding (sometimes indirectly) even after the code returns from the let:
(let ((closure
(let ((count 0))
(lambda () (print (incf count))))))
(funcall closure)
(funcall closure))
;; prints:
;; 1
;; 2
The lambda expression creates a closure, which captures the variable named count. Every time you call it, it will increase the count variable and print it. If you evaluate the same code another time, you define another closure and create another variable, with the same name.
Mapcar
Because I can only have one argument when mapcaring correct?
Not exactly; the function called by mapcar should be able to accept at least as many elements as the number of lists that are given to it (and it should also not require more mandatory arguments):
(mapcar (lambda (x y) (* x y))
'(1 2 3)
'(0 3 6))
=> (0 6 18)
(mapcar #'list '(1 2) '(a b) '(+ /))
=> ((1 a +) (2 b /))
The function can also be a closure, and can use special variables.
... with a closure
(defun adder (x)
(lambda (y) (+ x y)))
(mapcar (adder 10) '(0 1 2))
=> (10 11 12)
The adder functions takes a number x and returns a closure which accepts a number y and returns (+ x y).
... with a special variable
If you prefer dynamic scope, use earmuffs and give it a meaningful name:
(defparameter *default-offset* 0)
... and define:
(defun offset (x)
(+ x *default-offset*))
You can then mapcar too:
(let ((*default-offset* 20))
(mapcar #'offset '(1 2 3)))
=> (21 22 23)
As said by jkiiski in comments, you can also declare special variables with (declare (special ...)) where you usually put declarations (when entering a let, a defun, ...). You could also use the special operator progv. This can be useful to have "invisible" variables that are only known by a set of functions to exchange information. You rarely need them.

Clojure how to get access to one field from two threads?

Can't understand multithreading in clojure. Can't find examples of REAL multithreading. Most samples with atoms, refs, vars are singlethreaded. So, I have a quest. Two threads gaining access to one field, each thread can change it. I use atom for this purpose, so the Code is:
(do
(def field (atom "v0"))
(defn f1 []
(dotimes [i 100000]
(if (= i 9999)
(reset! field "v1"))))
(defn f2 []
(dotimes [i 100000]
(if (= i 777)
(reset! field "v2"))))
(do
(deref (future (Thread/sleep 10) (f1))
0 f2)
(prn #field)))
But nothing, the value of field is "v0". How to make normal twothreaded example with cycles in each thread and with access to variable???
watch the docs of deref:
clojure.core/deref
([ref] [ref timeout-ms timeout-val])
returns the in-transaction-value of ref, else returns the
most-recently-committed value of ref. When applied to a var, agent
or atom, returns its current state. When applied to a delay, forces
it if not already forced. When applied to a future, will block if
computation not complete. When applied to a promise, will block
until a value is delivered. The variant taking a timeout can be
used for blocking references (futures and promises), and will return
timeout-val if the timeout (in milliseconds) is reached before a
value is available. See also - realized?.
so your timeout is 0, that means it will return default value
which is f2 - a function value (not a function call), which is not being called obviously, so no reset! ever happens.
if you want "v1" you should deref like:
(deref (future (Thread/sleep 10) (f1)) 100 (f2))
if you want "v2":
(deref (future (Thread/sleep 10) (f1)) 0 (f2))

Simplest example of backwards continuations in Scheme without explicit mutation

I've written a small Scheme interpreter in C#, and realised that the way I had implemented it, it was very easy to add support for proper continuations.
So I added them... but want to "prove" that they way that I've added them is correct.
My Scheme interpreter however has no support for "mutating" state - everything is immutable.
So it was pretty easy to write a unit test to expose "upwards" continuations:
AssertEqual(Eval("(call/cc (lambda (k) (+ 56 (k 3))))"), 3);
However, I also want to write a unit test that demonstrates that if the continuation "escapes" then that still works too:
AssertEqual(Eval("(call/cc (lambda (k) k))", <some continuation>);
But of course, the above would just test that "I got a continuation"... not that it's actually a valid continuation.
All of the examples I can find, however, always end up using "set!" to demonstrate the escaped continuation.
What's the simplest Scheme example that demonstrates proper support for backwards continuations without relying on mutation?
Are backwards continuations any use without mutation? I am beginning to suspect that they are not, because you could only use it to execute the exact same calculation again... which is meaningless if there are no side-effects. Is this why Haskell does not have continuations?
I don't know if this is the simplest, but here's an example of using backwards continuations without any call to set! or similar:
(apply
(lambda (k i) (if (> i 5) i (k (list k (* 2 i)))))
(call/cc (lambda (k) (list k 1))))
This should evaluate to 8.
Slightly more interesting is:
(apply
(lambda (k i n) (if (= i 0) n (k (list k (- i 1) (* i n)))))
(call/cc (lambda (k) (list k 6 1))))
which computes 6! (that is, it should evaluate to 720).
You can even do the same thing with let*:
(let* ((ka (call/cc (lambda (k) `(,k 1)))) (k (car ka)) (a (cadr ka)))
(if (< a 5) (k `(,k ,(* 2 a))) a))
(Man, stackoverflow's syntax highlighting fails massively on scheme.)
I think you're right -- without mutation, backwards continuations do nothing that forward continuations can't.
Here's the best I've come up with:
AssertEqual(Eval("((call/cc (lambda (k) k)) (lambda (x) 5))", 5);
Not amazing, but it is a backwards continuation which I then "call" with the actual function I wish to invoke, a function that returns the number 5.
Ah and I've also come up with this as a good unit test case:
AssertEqual(Eval("((call/cc call/cc) (lambda (x) 5))", 5);
I agree with Jacob B - I don't think it's that useful without mutable state... but would be still be interested in a counter-example.
Functional Threads:
You can use a recursive loop to update state without mutation. including the state of the next continuation to be called. Now this is more complicated than the other examples given, but all you really need is the thread-1 and main loop. The other thread and "update" function are there to show that continuations can be used for more than a trivial example. Additionally, for this example to work you need an implementation with the named let. This can be translated into an equivalent form made with define statements.
Example:
(let* ((update (lambda (data) data)) ;is identity to keep simple for example
(thread-1
(lambda (cc) ;cc is the calling continuation
(let loop ((cc cc)(state 0))
(printf "--doing stuff state:~A~N" state)
(loop (call/cc cc)(+ state 1))))) ;this is where the exit hapens
(thread-2
(lambda (data) ;returns the procedure to be used as
(lambda (cc) ;thread with data bound
(let loop ((cc cc)(data data)(state 0))
(printf "--doing other stuff state:~A~N" state)
(loop (call/cc cc)(update data)(+ state 1)))))))
(let main ((cur thread-1)(idle (thread-2 '()))(state 0))
(printf "doing main stuff state:~A~N" state)
(if (< state 6)
(main (call/cc idle) cur (+ state 1)))))
Which outputs
doing main stuff state:0
--doing other stuff state:0
doing main stuff state:1
--doing stuff state:0
doing main stuff state:2
--doing other stuff state:1
doing main stuff state:3
--doing stuff state:1
doing main stuff state:4
--doing other stuff state:2
doing main stuff state:5
--doing stuff state:2
doing main stuff state:6

Resources