- Qucksort for Linked List - 7 Updates
- Tutorial on threaded binary tree part 1: simple unthreaded tree - 8 Updates
- Read again... - 1 Update
- cmsg cancel <o1t09v$ram$3@dont-email.me> - 5 Updates
- Functional programming is stupid - 1 Update
- I correct my logic, please read again my final post... - 1 Update
- Read again, i correct... - 1 Update
- I think that C++ and ADA and Object Pascal - 1 Update
"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:
Post a Comment