What does parallel binding mean in Clojure - clojure

I see the binding of recur is "parallel", however I don't get what that means.
I've tested the code below:
(defn parallelTest
"parallel binding test of recur "
[]
(loop [vectorA [1 2 3 4 5]
A (first vectorA)]
(if-not (= A nil)
(do (println vectorA) (println A)
(recur (rest vectorA) (first vectorA)))) ;Recur!
))
(parallelTest)
the output is
user=>
[1 2 3 4 5]
1
(2 3 4 5)
1
(3 4 5)
2
(4 5)
3
(5)
4
()
5
nil
so I assume the bindings are happened simultaneously instead of one by one?

Yes, in computer science, "in parallel" will generally mean simultaneously, as opposed to "sequentially" (in a specified order) or "concurrently" (in an arbitrary indeterminate order, which could be parallel or sequential with arbitrary sequence). Parallel binding is typically understood to mean that a result (left hand side) of one binding is not in the scope of the creation (right hand side) of another (as opposed to sequential binding, as seen in Clojure's let statement).

Sequential binding
a = 1
b = 2
Here
1 is evaluated
then bound to a
then 2 is evaluated
then bound to b
Parallel binding
a,b = 1,2
Here,
1 and 2 are evaluated, either in a determined order (such as left to right) or not, depending on the language specifications
the two results are bound to a and b, respectively.
If the expressions (here 1 and 2) are independant and side-effect free, it doesn't matter which binding you use, but in parallel you need to be aware of the exact evaluation order.
Now, in your case,
first (rest vectorA)
then (first vectorA) are evaluated (left to right)
then the results are bound to vectorA and A, respectively.
which is a parallel binding, as opposed to for example a let binding in Clojure which is sequential.

Related

Display parallel Clojure array and range values

The following function takes a range of Celcius temperatures, converts them to Fahrenheit, and puts them into an array.
(defn build-f [size]
(map float (vec (map #(+(/(* % 9)5)32) (range size)))))
My goal is then to print each converted temperature in the following format:
C[0] = 32 F
C[1] = 33.8 F
...
The format doesn't really matter. I'm new to functional programming and still thinking the OOP
way.
I tried to use the map function to do that. What should I go with? Map, reduce, for, doall?
So far I came up with the following:
display-format function should display something like this C[0] =. I'm not sure how to place that [index] there though.
(defn display-format [t-scale]
(println t-scale "=" ))
display-array function should use the map function to apply display-format
function to the array.
(defn display-array [t-scale array]
(map (display-format t-scale) array))
Am I going in the right direction?
Update:
Here the code I was going for. Hope it helps someone.
(defn display-table [from-scale array to-scale]
(map #(println (str from-scale "[" %1 "] = " %2 " " to-scale))
(range (count array)) array))
Please see this list of documentation. Especially study the Clojure CheatSheet.
For your purposes, study
doseq for looping over the values to print output
format for using %d and similar output formatting options
str for concatenating strings
I'd suggest making a function celcius->farenheit and then calling that in a loop. Call double on the input arg and it will avoid any worries about int vs float all the way downstream.
I always prefer mapv over map to eliminate problems from laziness
Enjoy!

If statement with comparison

I am trying to do a comparison to find the largest number in a list. I know I could just use the (max 1 2 4 3) but I'm trying to write the function myself. However, I'm not too sure where the error is. Whenever I run this, the maximum is always 2. Am I doing a comparison wrong somewhere or forget something?
(defn maxVal [list]
(def maxValue 0)
(doseq [x list]
(println x maxValue)
(if > x maxValue)
(do (println x ">" maxValue)
(def maxValue x)))
(var-get #'maxValue))
(maxVal '(1 4 3 2))
The problem is that your code is evaluating > as a value, not invoking it as a function.
(if > x maxValue)
...evaluates to x, because the function > is neither nil nor false, and thus is truthy when evaluated as a boolean -- and x is in the "if true" position, just as maxValue is in the "else" position in this if. Consequently, the current indentation (while it reflects intent accurately) is a bit misleading; the do should be outside the if, since it takes place no matter what happened prior.
Presumably, what you instead want is:
(if (> x maxValue)

How to place a negative number in a list

How can I assign a negative number to a list of numbers?
I read elsewhere that you can use (- number) to negate a number, but for some reason, this is not working as expected in a list: '((- 1) 2 3)).
(- 1) is an expression that evaluates to -1. Quoting (the ' in front of your code) prevents the evaluation of an expression. Therefore:
> '((- 1) 2 3)
'((- 1) 2 3)
but
> (list (- 1) 2 3)
'(-1 2 3)
or, if you read up about quasiquoting and you want to show off
> `(,(- 1) 2 3)
'(-1 2 3)

n-Queens - Logic Error - determining a vertical threat

In this program I will be determining if placing a queen will cause a threat on the board. This will use positions 1 - 8 (could be expanded) as the rows and columns. If no piece is located in a column then the y for that row will be 0 (otherwise it is the corresponding y). An empty board would be as follows: ((1 0)(2 0)(3 0)(4 0)(5 0)(6 0)(7 0)(8 0))
I wrote the following program to determine if a given move will result in a vertical threat:
(defun THREAT? (x y)
(not (eq
(cdr (nth (car x) y ))
0
)
)
)
And this will be my input:
(THREAT? '(1 3) '(1 0)(2 4)(3 7)(4 3)(5 2)(6 8)(7 5)(8 1))
My idea with this is that I grab the car of the first argument (the x value that I am checking) use that to access the correct element in the second list and find the cdr of that element which will give me its y value. Then I check if it is 0 or not and if it is not 0, then it will be a threat. I have yet to add functionality for checking horizontal and diagonal so I suspect I could easily achieve this through either conditionals or if statements but I want to clear up issues in my understanding of this before moving on
My error is the following:
*** - EVAL: 2 is not a function name; try using a symbol instead
Any and all help is greatly appreciated!
After fixing that error I found that my program will always return true. when inputting '(1 3) '((1 0)...) it will return true despite the fact that (1 0)'s 0 should find that it is equal to 0, returning true and then negating the true thus returning false and yet my program will always return true.
Edit: Fixed previous error message
To see why (threat? '(1 3) '((1 0) (2 4) (3 7) (4 3) (5 2) (6 8) (7 5) (8 1))) returns true, you must look at the definition of nth
Note that the elements are numbered from zero, not one.
So, (nth 1 '((1 0) (2 4) (3 7) ...)) returns (2 4) (here we are again :-) and not (1 0).
The error message comes from the third argument (2 4), which is correct, because 2 is not a function name.
Lisp evaluates all arguments before passing it to a function. In the case of (2 4), it searches for a function named 2 and fails. The same would happen with the remaining unquoted arguments.
Your threat? function expects only two arguments, so I suppose, this should be something like
(threat? '(1 3) '((1 0) (2 4) (3 7) (4 3) (5 2) (6 8) (7 5) (8 1)))

Difficulty in understanding let and lambda usage in Scheme

I am having hard time to understand the scope of the following code:
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
if I use:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
the code work however if i tried with:
(+ (create-counter)(create-counter)(create-counter)(create-counter))
This does not work and give me a 0. Can someone please help me to understand this thoroughly? if possible, please compare to other language like C/C++ it would be easier for me to catch the hold of this. Thanks
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
Translates to:
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
A simple C++14 function returning a closure object.
When you do this:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
It is:
auto c = create_counter();
auto r = c()+c()+c()+c();
return r;
It creates one counter, then runs it 4 times, returning 0 1 2 3 and adding to 6.
In this case:
(+ ((create-counter))((create-counter))((create-counter))((create-counter)))
It is:
auto r = create_counter()()+create_counter()()+create_counter()()+create_counter()();
return r;
Which creates 4 counters, and runs each one once. The first time you run a counter you get 0. So this adds to 0.
The closure object has state. It returns a bigger number each time you call it.
Now you may not be familiar with C++11/14 lamnda.
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
Is
struct counter {
int x,count;
int operator()(){
int r=count;
count+=x;
return r;
};
};
counter create_counter(int x=1){
return {x,0};
}
with some syntax sugar.
I fixed what seems to be a syntax error in your original code. I am no expert, so maybe I got it wrong.
As an aside, a briefer create counter looks like:
auto create_counter(int x=1){
return [=,count=0]()mutable{
int r=count;
count+=x;
return r;
};
}
When you call "create-counter", it creates a counter and then returns a procedure that refers to that particular counter. When you call "create-counter" four times, you're creating four separate counters; each procedure refers to its own counter. When you call "create-counter" once and then the resulting procedure four times, it's creating just one counter, and incrementing it four times.
It's a bit hard to compare this to C, since C and C++ are quite weak in the area of closures; it's not easy to return a function that's defined inside of another function.
The closest analog might be a "counter" object in C++; think of "create-counter" as the constructor for an object containing a single integer, and the resulting procedure as an "increment" method that increments the counter contained in that object. In your second example, then, you're creating four distinct objects, where in your first example, you're creating one object and calling its "increment" method four times.