Friday, December 2, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 8 topics

"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 03 01:16AM +0100

On 02.12.2016 19:14, xerofoify wrote:
> 181 qSortrecursive(p->next_, h);
> 182 }
> 183 }
 
You can either swap the data in the nodes, or you can swap nodes by
unlinking them and reinserting.
 
To unlink a node that you have a pointer to, without copying data, and
without searching from the start of the list, you need a doubly linked list.
 
That said, quicksort is not really suited for linked lists. It's quick
(on average) because one can determine the two halves of an array in
constant time. With a linked list this is a linear time operation.
 
With a linked list you can instead use a merge sort.
 
Essentially this is the reason why you cannot do
 
std::list<T> items;
std::sort( items.begin(), items.end() ); //! Nah.
 
but must do e.g.
 
items.sort();
 
Well I've never understood why `std::sort` isn't just overloaded for
`std::list`, forwarding to the `sort` member function, that is, I've
never understood why `std::sort` /requires/ random access iterators, why
it can't just do the practical thing for the container at hand.
 
But, there is an issue.
 
 
Cheers & hth.,
 
- Alf
Jerry Stuckle <jstucklex@attglobal.net>: Dec 02 07:50PM -0500

On 12/2/2016 5:53 PM, xerofoify wrote:
> No there isn't. They should how to create a linked list not quicksort by swapping nodes. Here's the complete question how do I get this to work for when I have iterators not to invalidate the data by swapping the nodes in order to implement quicksort by swapping nodes data. There are no examples online or in any textbook I can find. I am looking for actual code not pseduo code.
 
If you swap a node, then by definition any iterator pointing at that
node will become invalid, at least as far as being properly positioned.
 
For instance, if your list's nodes contained values 5,10,7,1 and you
have a forward iterator pointing at the first node and a backwards
iterator pointing at the last node, and swap the nodes. Now your
forward iterator is pointing at the last node, and your backward
iterator is pointing at the first node. Advancing either one will fall
off one end of the list or the other - not continue to step through the
list.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
ruben safir <ruben@mrbrklyn.com>: Dec 02 09:17PM -0500

On 12/02/2016 05:53 PM, xerofoify wrote:
> No there isn't.
 
I guess your in an alternate universe. This is a standard HS home work
assignment
xerofoify <xerofoify@gmail.com>: Dec 02 08:44PM -0800

On Friday, December 2, 2016 at 9:17:40 PM UTC-5, ruben safir wrote:
> > No there isn't.
 
> I guess your in an alternate universe. This is a standard HS home work
> assignment
 
for (Node *j = l; j != h; j = j->next_) {
163 if (j->data_ <= x) {
I am confused about why this two lines are segfaulting for me through.
xerofoify <xerofoify@gmail.com>: Dec 02 08:52PM -0800

This is my complete code.
#pragma once
#include <utility>
#include<iostream>
template<typename T>
class DList {
private:
 
/*This is the Node object used for each list element
data members
@data - represents the data held inside the Node and of type T or the List's data type
@prev - previous element in the list
@next - next element in the list
*/
struct Node {
T data_;
Node* next_;
Node* prev_;
/*constructor
takes the following values as parameters
@ T data - type of data and value of data to be stored for this Node's data,
safe empty state by default
@Node* next - next Node in list
sets to NULL pointer by default
@Node* prev - pre Node in list
sets to NULL pointer by default
*/
Node(const T& data = T{}, Node* next = nullptr, Node* prev = nullptr) {
data_ = data;
next_ = next;
prev_ = prev;
}
};
/* head_ is the first node in the list and tail_ is the last node */
Node* head_;
Node* tail_;
/*Number of elements in the list*/
int size_;
public:
/*Iterator that is const in nature, i.e. cannot modifty the iterator after creation*/
class const_iterator {
protected:
Node* curr;
private:
friend class DList;
/*Constructor that sets Node to Node passed*/
const_iterator(Node* pass) {
curr = pass;
}
public:
/* A Constructor that sets internal Node to nullptr*/
const_iterator() {
curr = nullptr;
}
/*This function checks that the passed iterator is equal to the current
one including pointing to the same Node in the list*/
bool operator==(const_iterator rhs) {
return curr == rhs.curr;
}
/*This function is the opposite of the one above in that it
checks if the iterator passed is not equal in both being the
same object and pointing to the same Node in the list*/
bool operator!=(const_iterator rhs) {
return curr != rhs.curr;
}
/*This makes the interal Node point to the next Node in
the list before returning the current object as a point*/
const_iterator operator++() {
curr = curr->next_;
return *this;
}
/*This does the same as above but returns the previos
Node in the list as a iterator rather then *this*/
const_iterator operator++(int) {
const_iterator next = *this;
curr = curr->next_;
return next;
}
 
/*This moves the internal Node to the previous
object before returning the current object's
pointer*/
const_iterator operator--() {
curr = curr->prev_;
return *this;
}
/*Same as above but return a new iterator
that points to the previous Node rather
than *this*/
const_iterator operator--(int) {
const_iterator prev = *this;
curr = curr->prev_;
return prev;
}
/*Return the data held by this Node*/
const T& operator*() const {
return curr->data_;
}
};
/*This is the same as above except not const in nature i.e. can modifiy*/
class iterator :public const_iterator {
friend class DList;
/*Constructor that takes a parameter sets the Node to the Node passed*/
iterator(Node* pass) {
this->curr = pass;
}
/*Returns Node for Quicksort*/
Node* getNode() {
return this->curr;
}
public:
/*Constructor for this class
One that takes no parameters sets interal node used by interator to nullptr
*/
iterator() {
this->curr = nullptr;
}
/*Return the data held by this Node*/
T& operator*() {
return this->curr->data_;
}
/*This makes the interal Node point to the next Node in
the list before returning the current object as a point*/
iterator operator++() {
this->curr = this->curr->next_;
return *this;
}
/*This does the same as above but returns the previos
Node in the list as a iterator rather then *this*/
iterator operator++(int) {
iterator next = *this;
this->curr = this->curr->next_;
return next;
}
/*This moves the internal Node to the previous
object before returning the current object's
Same as above but return a new iterator */
iterator operator--() {
this->curr = this->curr->prev_;
return *this;
}
/*This moves the internal Node to the previous
object before returning the current object's
Same as above but return a new iterator
that points to the previous Node rather
than *this*/
iterator operator--(int) {
iterator prev = *this;
this->curr = this->curr->prev_;
return prev;
}
};
private:
//Swap function for nodes
void swap ( Node* a, Node* b ) {
Node *t = a;
a = b;
b = t;
}
//Partion function for nodes
Node* partition(Node *l, Node *h)
{
T x = h->data_;
 
Node *i = l->prev_;
Node* j = new Node();
for (j; j != h; j = j->next_) {
if (j->data_ <= x) {
i = (i == nullptr)? l : i->next_;
swap(i, j);
}
}
i = (i == nullptr)? l : i->next_;
swap(i, h);
return i;
}
/*this does qsort recursively on the elements from the Node at the first iterator passed up to
and including the Node at iterator two*/
void qSortrecursive(iterator first, iterator second) {
Node* h = first.getNode();
Node* l = second.getNode();
if (h != NULL && l != h && l != h->next_)
{
struct Node *p = partition(l, h);
qSortrecursive(l, p->prev_);
qSortrecursive(p->next_, h);
}
}
/*This does qsort as above but Iterative and not recursively*/
void qSortIterative(iterator first, iterator second) {
Node* h = first.getNode();
Node* l = second.getNode();
if (h != NULL && l != h && l != h->next_) {
struct Node *p = partition(l, h);
qSortIterative(l, p->prev_);
qSortIterative(p->next_, h);
 
}
}
public:
/*Constructor sets list to empty state
i.e. head_ and tail_ are nullptr and
size is 0, no Nodes*/
DList() {
head_ = new Node();
tail_ = new Node();
head_->next_ = tail_;
tail_->prev_ = head_;
size_ = 0;
}
/*Creates and returns a iterator to the beginning of the list*/
iterator begin() {
iterator begin(head_->next_);
return begin;
}
/*Returns a iterator to one after the end of the list after
creating a iterator that does so*/
iterator end() {
iterator end(tail_);
return end;
}
/*This is the same as iterator begin but creates a const_iterator
rather then a iterator*/
const_iterator begin() const {
const_iterator begin(head_->next_);
return begin;
}
/*This creates a const iterator to the Node after the end of the list*/
const_iterator end() const {
const_iterator end(tail_);
return end;
}
/* Pushs a new Node into the list's first element with a value
passed to it as the Node's data member*/
void push_front(const T& data) {
Node* first = head_->next_; //it is ok if this
//is back sentinel
Node* temp = new Node(data, first, head_);
head_->next_ = temp;
first->prev_ = temp;
size_++;
}
/* Pushs a new Node into the list's last element with a value
passed to it as the Node's data member*/
void push_back(const T& data) {
Node* last = tail_->prev_;
Node* temp = new Node(data, tail_, last);
tail_->prev_ = temp;
last->next_ = temp;
size_++;
}
/* Removes the Node at the beginning of the list*/
void pop_front() {
Node* first = head_->next_;
if (first != tail_) {
Node* secondFirst = first->next_;
head_->next_ = secondFirst;
secondFirst->prev_ = head_;
delete first;
size_--;
}
}
/*Removes the Node at the end of the list*/
void pop_back() {
Node* last = tail_->prev_;
if (last != head_) {
Node* secondLast = last->prev_;
tail_->prev_ = secondLast;
secondLast->next_ = tail_;
delete last;
size_--;
}
}
/*Insert Node at the point of the iterator passed with
the data passed becoming the inseted Node's data member*/
iterator insert(iterator loc, const T& data) {
Node* curr = loc.curr;
std::cout << loc.curr;
Node* prev = curr->prev_;
Node* New = new Node(data, curr, prev);
prev->next_ = New;
curr->prev_ = New;
size_++;
loc--;
return loc;
}
/*Removes the element at the position passsed in the iterator argument*/
void erase(iterator it) {
Node* loc = it.curr;
Node* next = loc->next_;
Node* prev = loc->prev_;
prev->next_ = next;
next->prev_ = prev;
size_--;
delete loc;
}
/*Removes all elements from the first to the last*/
void erase(iterator first, iterator last) {
iterator it = first;
while(++it != last) {
erase(it);
it = first;
}
erase(first);
}
/*Searchs for a Node with the data passed as a arugment if found
return a iterator founding to it otherwise return iterator pointing
to one element beyond end of list*/
iterator search(T& data) {
iterator it = begin();
while (it != end()) {
if (it.curr->data_ == data) {
return it;
}
it++;
}
return end();
}
/*Searchs for a Node with the data passed as a arguument if found
return a const iterator founding to it otherwise return iterator pointing
to one element beyond end of list*/
const_iterator search(const T& data) const {
const_iterator it = begin();
while (it != end()) {
if (it.data_->data_ == data) {
return it;
}
it++;
}
return end();
}
/*Quicksort wrapper for iterative verision*/
void sortIterative() {
iterator last = end()--;
qSortIterative(begin(),last);
}
void qSort(){
iterator last = end()--;
qSortrecursive(begin(),last);
}
/*Returns true if list has size set to zero or no Nodes otherwise false*/
bool empty() const {
if (size_ == 0) {
return true;
}
else {
return false;
}
}
/*Returns size of list*/
int size() const {
return size_;
}
/*Destructor, destorys and cleans up each Node's member when the
list is destoryed*/
~DList() {
if (empty()) {
return;
}
iterator itBegin = begin();
iterator itEnd = end();
erase(itBegin,itEnd);
}
/*Copy Constructor, creates a new List that is a copy of the src list
passed as a argument*/
DList(const DList& src) {
head_ = new Node();
tail_ = new Node();
head_->next_ = tail_;
tail_->prev_ = head_;
size_ = src.size_;
if (src.empty() == false) {
iterator i = end();
const_iterator c = src.end();
c--;
while(c != src.begin()){
i = insert(i,*c);
c--;
}
push_front(*c);
}
}
/*Copy Assigment operator, assigns a new List that is a copy of the src list
passed as a argument*/
DList& operator=(const DList& src) {
head_ = new Node();
tail_ = new Node();
head_->next_ = tail_;
tail_->prev_ = head_;
size_ = src.size_;
if (src.empty() == false && src.head_ != head_) {
iterator i = end();
const_iterator c = src.end();
c--;
while(c != src.begin()){
i = insert(i,*c);
c--;
}
push_front(*c);
}
return *this;
}
 
/*Move constructor - sets list to list passed in agrument src but steals or
moves it other rather then copies the values of the Nodes and themselves*/
DList(DList&& src) {
if (src.head_ == tail_) {
head_ = tail_ = nullptr;
size_ = 0;
}
else {
head_ = std::move(src.head_);
tail_ = std::move(src.tail_);
size_ = std::move(src.size_);
src.head_ = nullptr;
src.tail_ = nullptr;
size_ = src.size_;
}
}
/*Move Assignment operator - sets list to list passed in agrument src but steals or
moves it other rather then copies the values of the Nodes and themselves*/
DList& operator=(DList&& src) {
head_ = std::move(src.head_);
tail_ = std::move(src.tail_);
size_ = std::move(src.size_);
src.head_ = nullptr;
src.tail_ = nullptr;
size_ = src.size_;
return *this;
}
};
The reason I am asking is there appears to be no good examples for quicksort *with Node* swap not data swap which is what I want. So can someone point me to an example that does it by swapping the nodes and not the data.
bartekltg <bartekltg@gmail.com>: Dec 03 08:05AM +0100

On 02.12.2016 19:14, xerofoify wrote:
> //Swap function for nodes
> 154 void swap ( Node* a, Node* b )
> 155 { Node t = *a; *a = *b; *b = t; }
 
You are not swapping nodes, nor you swaping values! ;-)
 
 
For example, we have 5 nodes:
 
{value, pointer next, pointer prev}
 
0 { 111, 1, null }
1 { 222, 2 , 0 }
2 { 333, 3 , 1 }
3 { 444, 4 , 2 }
4 { 555, null , 3 }
 
It looks like that:
 
111 - 222 - 333 - 444 - 555
 
And now you swap node number 1 and 3.
You swap everything inside dereferenced node.
 
 
0 { 111, 1, null }
1 { 444, 4 , 2 }
2 { 333, 3 , 1 }
3 { 222, 2 , 0 }
4 { 555, null , 3 }
 
And now draw the linked list...
 
111 - 222 - 333 - 444 - 555
 
Hmm, I'm quite sure this is the same list;) Just put in memory
in different way.
 
If you want to swap two element, a and b, in a linked list,
you have to go to neighbours of a and b and (up to four objects!)
and change its "next" and "prev" pointers.
 
Of course you have to update pointers in a and b too.
 
Be carefull, a and b can be neighbour, a or b (or both)
can be on the edge of the list, and you have to keep track of the head.
 
The first problem is just a one "if" statement.
The second one can be taken care of with sentinel nodes,
on the head and on the tail. Or more "ifs" ;-)
 
 
And, as others, I have to say it is veri ineffective way of sorting
list.
 
If you have to/want to do it with qsort, do not swap objects.
Traverse through the sub-list and move nodes with data>x on
one list, and the other ones to the second list. Then link
both new list and link it to the rest (nodes outside your sublist,
l->prev and h->next (*), there you see that sentinel nodes are usefull).
 
*) I assumed l is the first element, and h is the last (but still a
valid object you want to sort, not like in STL, where 'last' is not
included)
 
 
This new qsort will be much faster, but still worse than mergesort.
The number of operation in one level is similar.
It has the same number of 'levels' if the partition is each time
ideal, in the other case - qsort has more.
 
 
 
 
 
bartekltg
bartekltg <bartekltg@gmail.com>: Dec 03 08:25AM +0100

On 03.12.2016 01:16, Alf P. Steinbach wrote:
 
> I've
> never understood why `std::sort` /requires/ random access iterators, why
> it can't just do the practical thing for the container at hand.
 
...So I can made a container with random access iterator and
do not have to rewrite whole <algorithm> header.
Or I write my own iterator.
 
 
> Well I've never understood why `std::sort` isn't just overloaded for
> `std::list`, forwarding to the `sort` member function, that is,
 
This is other, valid, question. Why std::sort do not check if
the container do not have method sort, and use default only
if needed.
One reason I can thing of is that iterators do not have information
about the container. Do it have information about the type of the
container, I don't remember, but I do not see why it can't.
But probably I'm wrong ;)
 
 
bartekltg
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 03 12:58AM +0100

On 02.12.2016 16:55, Mr Flibble wrote:
 
[snip]
> not correspond to your bullet points. multiset and multimap have
> identical data structures: the only difference is multimap value_type is
> a pair in which the key is the first part.
 
Hm, the above two sentences contradict each other. :)
 
The last sentence even contradicts itself.
 
As you note in the last part of that sentence, with a multimap multiple
occurrences of the same key need to be distinguished, because they can
be associated with different values.
 
Therefore, contrary to the assertion in the first part of that sentence,
they do not naturally have "identical structures". There are
interpretations where this assertion holds, but they are meaningless.
For example, one structure can be implemented in terms of the other,
they can both be implemented in terms of arrays, and so on etc.; there
is no meaning in that, and it does not relate to the bullet points.
 
With a multiset you only need a count of each value.
 
With a multimap you need to distinguish each value, even identical ones,
because they can have different associated information.
 
 
Cheers & hth.,
 
- Alf
Jerry Stuckle <jstucklex@attglobal.net>: Dec 02 07:44PM -0500

On 12/2/2016 5:49 PM, ruben safir wrote:
>>> no, actually
 
>> How so?
 
> it is undefined on the order of evaluation
 
It is perfectly defined. The addition is performed before the
assignment. The variable is only changed once - in the assignment.
There is no undefined operation.
 
Now there is undefined behavior in the expression i = i++ + 1. But that
is a different situation.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Melzzzzz <mel@zzzzz.com>: Dec 03 01:51AM +0100

On Sat, 3 Dec 2016 00:58:19 +0100
 
> As you note in the last part of that sentence, with a multimap
> multiple occurrences of the same key need to be distinguished,
> because they can be associated with different values.
 
You are wrong. Value is completely non essential for that data
structure. With that said, I can't figure out purpose of multiset at
all... but generally you are right. multiset does not needs to store
actual nodes. count and key are enough.
 
 
 
 
--
press any key to continue or any other to quit
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Dec 03 01:54AM

On 02/12/2016 23:58, Alf P. Steinbach wrote:
 
> With a multiset you only need a count of each value.
 
> With a multimap you need to distinguish each value, even identical ones,
> because they can have different associated information.
 
Wrong; again multiset and multimap are identical data structures both
being a binary search tree with a node for each element irregardless of
whether there are any duplicate keys. The only difference between
multiset and multimap is the key is part of a pair for multimap.
 
/Flibble
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Dec 03 02:07AM

On 03/12/2016 01:54, Mr Flibble wrote:
> being a binary search tree with a node for each element irregardless of
> whether there are any duplicate keys. The only difference between
> multiset and multimap is the key is part of a pair for multimap.
 
Basically for a std::multiset the key_type is ALSO the value_type; if
the multiset has 10 equivalent keys it must have 10 equivalent values
(elements) i.e. NOT a single value (element) with a count of 10. Keys
that are equivalent do not have to be identical (comparable with ==
rather than <) and indeed can be complex objects with mutable state that
does not contribute to order.
 
I am surprised Alf that someone with your experience doesn't know how
std::multiset works or how it needs to be implemented.
 
/Flibble
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 03 03:04AM +0100

On 03.12.2016 01:51, Melzzzzz wrote:
>> because they can be associated with different values.
 
> You are wrong. Value is completely non essential for that data
> structure.
 
A map data structure is a collection of (key, value) pairs. For example,
the keys can be student id's, and the values can be the grades they have
in some course. Or the keys can be main country codes, and the values
codes for the languages spoken there, like ("NO", "NB") and ("NO", "NN").
 
The "multi" in /multimap/ means that the same key can occur twice or
more, then generally with different associated values for each
occurrence, as in the country/language code example.
 
For more details see <url:
http://en.cppreference.com/w/cpp/container/multimap>.
 
 
> With that said, I can't figure out purpose of multiset at
> all...
 
:) See above.
 
 
> but generally you are right. multiset does not needs to store
> actual nodes. count and key are enough.
 
Well, that depends.
 
I was referring to concepts and common usage.
 
However, `std::multiset`, as opposed to the mathematical idea of
multiset, guarantees that the order of the keys that compare equivalent
is the order of insertion and does not change, i.e. it provides a stable
sort. To make sense of that -- the /order/ of equivalent key values,
what? -- you need to know that `std::multiset` can work with a custom
comparison function that can use only part of the value stored, as key.
And for this case Mr. Flibble would be right, if that was what he meant.
But then I think he would have mentioned it.
 
A count is not sufficient for the general functionality of `std::multiset`.
 
But a tree with just a count for each value, can implement a multiset
(although not the full general `std::multiset` in the C++ standard
library), and can not implement a multimap of any kind.
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 03 03:11AM +0100

On 03.12.2016 03:07, Mr Flibble wrote:
 
> I am surprised Alf that someone with your experience doesn't know how
> std::multiset works or how it needs to be implemented.
 
Oh, thanks for compliment. :)
 
But I wasn't referring to `std::multiset` specifically: I wasn't
considering what data structure you need to implement `std::multiset`.
 
After listing three possibilities I noted that with the middle one, with
(only) a count for each value, the most you can use that tree for, or at
least the natural application, is /a multiset/.
 
That's general, programming language-independent terminology.
 
 
Cheers & hth.,
 
- Alf
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Dec 03 02:17AM

On 03/12/2016 02:11, Alf P. Steinbach wrote:
> (only) a count for each value, the most you can use that tree for, or at
> least the natural application, is /a multiset/.
 
> That's general, programming language-independent terminology.
 
This is a C++ newsgroup not a mathematics newsgroup so if someone uses
the terms "multiset" and "multimap" it is a fair assumption that they
are actually referring to the C++ Standard Library containers rather
than the mathematical concepts: you should have been more clear about
what you meant by providing appropriate qualifications.
 
/Flibble
Ramine <ramine@1.1>: Dec 02 08:20PM -0500

Hello..........
 
Functional programming is stupid
 
What it wants to sell that it uses pure functions so that it
avoids race conditions, but since Haskel uses Mvars, it is like
blocking queues , it is prone to Deadlocks and to starvation,
so Functional programming doesn't compose well in the parallel
programming world.
 
So what i advice is to use Object oriented programming with
transactional memory or a scalable reader-writer lock that wraps the
reads and writes, because transactional memory is easy and because
scalable reader-writer lock is easy , so i think it ensure a level of
security that is acceptable.
 
In the criterion of expressivity and productivity , i don't think
that Functional programming buys much, so i think that Object oriented
progrmming will still be used and a prefered tool in the future.
 
 
Thank you,
Amine Moulay Ramdane.
bleachbot <bleachbot@httrack.com>: Dec 03 12:33AM +0100

bleachbot <bleachbot@httrack.com>: Dec 03 12:38AM +0100

bleachbot <bleachbot@httrack.com>: Dec 03 01:44AM +0100

bleachbot <bleachbot@httrack.com>: Dec 03 02:17AM +0100

bleachbot <bleachbot@httrack.com>: Dec 03 02:20AM +0100

Ramine <ramine@1.1>: Dec 02 08:17PM -0500

Hello..........
 
Functional programming is stupid
 
What it wants to sell that it uses pure functions so that it
avoids race conditions, but since Haskel uses Mvars, it is like
blocking queues , it is prone to Deadlocks and to starvation,
so Fuinctional programming doesn't compose well in the parallel
programming world.
 
So what i advice is to use Object oriented programming with
transactional memory or a scalable reader-writer lock that wraps the
reads and writes, because transactional memory is easy and because
scalable reader-writer lock is easy , so i think it ensure a level of
security that is acceptable.
 
In the criterion of expressivity and productivity , i don't think
that Functional programming buys much, so i think that Object oriented
progrmming will still be used and a prefered tool in the future.
 
 
Thank you,
Amine Moulay Ramdane.
Ramine <ramine@1.1>: Dec 02 07:44PM -0500

I correct my logic, please read again my final post...
 
Hello...
 
Here is my final solution that i think works efficiently...
 
First it is better to do this:
 
I think that C++ and ADA and Object Pascal must make the data types
objects, and make datastructures objects and make IO objects etc. and
wrap those objects with a scalable reader-writer lock or transactional
memory because it is easy to do it this way, and the compiler designers
and implementors must test those objects correctly to ensure that they
work correctly, this will ensure a level of security that avoids race
conditions that is tolerable, so no need for pure functions and Mvars of
Haskel and Lisp.
 
And second you have to use set() and get() wrapped with a
scalable reader-writer lock or transactional memory to access the
properties of the object because it is easy to do it this way.
 
and third you can add also this:
 
About C++ and my following enhancement to it...
 
C++ must add properties that you can access only from the constructor
and can not be accessed from the methods of the object.
 
This way you will be able to implement more cleanly my following
implementation:
 
First you have to call a constructor that will put the global variables
as pointer that are shared by threads in there respective queues..
 
And after that each method that wants to access a shared global variable
will take the shared global variable from the queue and copy it in a
local variable and work with it locally, and after that it will put it
back in its global queue , and other threads will block waiting
for the variables on there respective queues, it's like message passing
and it's like pure functions with Mvars in Haskel and this mechanism is
good and will avoid race conditions in Object oriented programming.
 
If you say to me that pure functions of Lisp and Haskel are pure
functions , but with my previous implementation you still can
by error forget to put your global variables that is
shared by threads in the properties that can not be accessed
by the object or in there respective global queues, i will say that
my implementation easy the job for us, because defining what is shared
and putting it in the properties that can not be accessed from the
object is easy and is as easy as making an error on sequential
programming, so in my opinion this level of security can be tolerated in
Object oriented programming without using Functional programming, other
than that we also have Transactional memory that is composable and easy
to use to solve our parallel programming problems in Object oriented
programming.
 
 
For Deadlocks use this:
 
Use Lock Hierarchies to Avoid Deadlock
 
http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163
 
 
Thank you,
Amine Moulay Ramdane.
Ramine <ramine@1.1>: Dec 02 06:38PM -0500

Hello.......
 
Fist solution:
 
I think that C++ and ADA and Object Pascal must make the data types
objects, and make datastructures objects and make IO objects etc. and
wrap those objects with a scalable reader-writer lock or transactional
memory, and the compiler designers and implementors must test those
objects correctly to ensure that they work correctly, this will ensure a
level of security that avoids race conditions that is tolerable,
so no need for pure functions and Mvars of Haskel and Lisp.
 
Or you can use this solution:
 
About C++ and my following enhancement to it...
 
C++ must add properties that you can access only from the constructor
and can not be accessed from the methods of the object.
 
This way you will be able to implement more cleanly my following
implementation:
 
First you have to call a constructor that will put the global variables
as pointers for example in there respective queues..
 
And after that each method that wants to access a global variable will
take the global variable from the queue and copy it in a local
variable and work with it locally, and after that it will put
it back in its global queue , and other threads will block waiting
for the variables on there respective queues, it's like message passing
and it's like pure functions with Mvars in Haskel and this mechanism is
good and will avoid race conditions in Object oriented programming.
 
If you say to me that pure functions of Lisp and Haskel are pure
functions , but with my previous implementation you still can
by error forget to put your global variables that is
shared by threads in the properties that can not be accessed
by the object or in there respective global queues, i will say that
my implementation easy the job for us, because defining what is shared
and putting it in the properties that can not be accessed from the
object is easy and is as easy as making an error on sequential
programming, so in my opinion this level of security can be tolerated in
Object oriented programming without using Functional programming, other
than that we also have Transactional memory that is composable and easy
to use to solve our parallel programming problems in Object oriented
programming.
 
 
For Deadlocks use this:
 
Use Lock Hierarchies to Avoid Deadlock
 
http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163
 
 
Thank you,
Amine Moulay Ramdane.
Ramine <ramine@1.1>: Dec 02 06:33PM -0500

Hello.......
 
Fist solution:
 
I think that C++ and ADA and Object Pascal must make the data types
objects, and make datatrctures objects and make IO objects etc. and wrap
of those objects with a scalable reader-writer lock or transactional
memory, and the compiler designers an implementors must test those
objects correctly to ensure that they work correctly, this will ensure a
level of security that avoids race conditions that is tolerable,
so no need for pure functions and Mvars of Haskel and Lisp.
 
Or you can use this solution:
 
About C++ and my following enhancement to it...
 
C++ must add properties that you can access only from the constructor
and can not be accessed from the methods of the object.
 
This way you will be able to implement more cleanly my following
implementation:
 
First you have to call a constructor that will put the global variables
as pointers for example in there respective queues..
 
And after that each method that wants to access a global variable will
take the global variable from the queue and copy it in a local
variable and work with it locally, and after that it will put
it back in its global queue , and other threads will block waiting
for the variables on there respective queues, it's like message passing
and it's like pure functions with Mvars in Haskel and this mechanism is
good and will avoid race conditions in Object oriented programming.
 
If you say to me that pure functions of Lisp and Haskel are pure
functions , but with my previous implementation you still can
by error forget to put your global variables that is
shared by threads in the properties that can not be accessed
by the object or in there respective global queues, i will say that
my implementation easy the job for us, because defining what is shared
and putting it in the properties that can not be accessed from the
object is easy and is as easy as making an error on sequential
programming, so in my opinion this level of security can be tolerated in
Object oriented programming without using Functional programming, other
than that we also have Transactional memory that is composable and easy
to use to solve our parallel programming problems in Object oriented
programming.
 
 
For Deadlocks use this:
 
Use Lock Hierarchies to Avoid Deadlock
 
http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163
 
 
Thank you,
Amine Moulay Ramdane.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: