text:
Talk:Reentrancy (computing)

Definition of "reentrant"
This definition is way too narrow. Wouter Lievens 09:46, 8 Apr 2005 (UTC)

 * Then what definition you think is more appropriate? -- Taku 20:50, Apr 8, 2005 (UTC)

 * I know the term is used outside of the context of concurrency, but I can't exactly say how and where :-) Wouter Lievens 15:44, 26 May 2005 (UTC)

 * Would be better if "can be called SAFELY" is explained in more detail. —Preceding unsigned comment added by T pradeepkumar (talk • contribs)

 * Narrow, wrong, without purpose, and not consistent with any usual definition (there are several incompatible ones).KiloByte (talk) 15:22, 26 November 2010 (UTC)

The mention of FreeBSD's VFS is relevant, however the follow up about DragonFlyBSD seems to me to be off-topic. —Preceding unsigned comment added by 62.253.64.17 (talk • contribs)

I don't think recursion is correct in this context. A function can be re-entered from more than one thread without being called recursively. Recursive implies the function calls itself. Peter Ritchie 19:48, 5 October 2006 (UTC)

 * "Recursive" may also mean that a function invokes a callback, which may re-call the function recursively without corruption or unexpected effects. Or when a function is temporarily interrupted by a signal, and the signal handler calls the function again within the context of the same thread. -- intgr 14:08, 10 November 2006 (UTC)

 * "Recursive" does in no case mean that "a function invokes a callback, which may re-call the function" or "when a function is temporarily interrupted by a signal, and the signal handler calls the function again within the context of the same thread". "Recursive" means that a function is defined (and relies) on the "output" of an anterior call to itself.
 * Indeed the cases where "a function invokes a callback, which may re-call the function" or "when a function is temporarily interrupted by a signal, and the signal handler calls the function again within the context of the same thread" are very good examples for the concept of reentrancy. Thus, in my opinion the term "recursive(ly)" should be removed entirely from this article. DvG 14:35, 13 August 2007 (UTC)
 * agree; removed it. it's not hard to imagine pathological situations where non-reentrant functions could still be used correctly and recursively by design. 12.219.83.157 06:08, 16 September 2007 (UTC)
 * Reentrancy is also an embedded systems development concern, but at a much lower level that does appeared to be addressed here. With respect to embedded systems reentrancy is at the assembly language level and is concerned with interrupts and there effects on the task and processes of the system when returning from an interrupt and the assmbly language genertaied by the complier/assembler pair (and linker).  Just thought you should know this subject as presented here seems narrow. thanks EM1SS&CSE 18:08, 18 October 2007 (UTC)

Shouldn't it be "multiple threads" instead of "multiple processes"?

 * processes/threads are both orthogonal as the signal handler example above shows. a single-threaded task can still have re-entrancy bugs if it relies on interrupts. 12.219.83.157 06:15, 16 September 2007 (UTC)

Incorrect claim "Idempotence implies reentrancy, but the contrary is not necessary true."
Here is a function which is idempotent but not reentrant:

int global; int f(int * i) { global++; *i = global; global--; }

Or am I misunderstanding something? —Preceding unsigned comment added by 199.172.169.86 (talk) 10:15, 25 February 2011 (UTC)

 * I believe you're correct. That seemed odd to me too. I've removed the claim. spikey (talk) 16:05, 15 April 2014 (UTC)

Functional programming
I don't know very much about functional programming, but aren't functional programming languages reentrant (variables and functions, and even syntax (in Scheme for example) ? —Preceding unsigned comment added by 83.214.221.148 (talk • contribs)

 * I don't know about Scheme, but I would say that purely functional languages like Haskell are inherently reentrant (except for the IO monad). --Pezezin 22:57, 19 March 2007 (UTC)

This article is inaccurate. Someone more generous than I should get out an OS textbook and revise it. JBW012307

The lisp dialects are re-entrant they just don't seem to have a need to call it other than recursion :). W/re the usage of re-entrant as presented here, isn't Scheme's call/cc an example of what is being discussed? If so, I don't understand why there is an implicit suggestion that re-entrant subrs are directly correlated with thread safety and `concurrency' issues i.e. w/ call/cc the stack is elsewhere thread or no.Lambda-mon key (talk) 01:05, 5 March 2010 (UTC)

Serially Reentrant
Back in the day, I remember the concept of serially reentrant. A subroutine was serially reentrant even though it manipulated global variables because a semaphore guaranteed at most one thread was actively executing in the subroutine at a given time. The global variables had to be protected by the semaphore in order for this work properly. Static local variables (those not allocated in a stack frame or from a heap) would similarly be protected. —Preceding unsigned comment added by 70.108.186.46 (talk • contribs)

 * sure sounds like plain old thread-safety to me. 12.219.83.157 06:09, 16 September 2007 (UTC)

 * Semaphores (basically locks and wait conditions) are used for thread-safety, where multiple independent threads access the same data (if at least one of them is also changing the data). This does not make it reentrant. If an interrupt is called while the semaphore is blocked by the main program, that interrupt cannot block the semaphore as well. The interrupt would have to wait for the semaphore to be released (which is what happens in multi-threading). But the interrupt is also blocking the main thread from executing, so the semaphore is never released. You get a dead-lock. You would need a semaphore-based data access by the operating system or the CPU, that is aware of interrupts, but that is beyond the scope of any (user space) programmer. 80.153.93.87 (talk) 15:28, 13 January 2016 (UTC)
 * There are multiple serialization mechanisms. Interrupt handlers in a multiprocessor need lower level synchronization, e.g., Compare-And-Swap (CS) on an IBM System/370. For tasks (analogous to threads), OS services like ENQ/DEQ and semaphores are adequate for ensuring reentrancy. For both interrupt handlers and user code, deadlocks are an issue if the serialization is not properly thought out. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:15, 3 June 2022 (UTC)
 * There are multiple serialization mechanisms. Interrupt handlers in a multiprocessor need lower level synchronization, e.g., Compare-And-Swap (CS) on an IBM System/370. For tasks (analogous to threads), OS services like ENQ/DEQ and semaphores are adequate for ensuring reentrancy. For both interrupt handlers and user code, deadlocks are an issue if the serialization is not properly thought out. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:15, 3 June 2022 (UTC)

 * the IBM term (back in time starting with OS/360) was "serial reusable" as a given attribute at linking time (Linkage Editor). --Pqz602 (talk) 18:52, 19 May 2022 (UTC)
 * Yes, and the serialization for a serially reusable module was within a job, not globally. You could not share a serially reusable module between jobs. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:15, 3 June 2022 (UTC)
 * Yes, and the serialization for a serially reusable module was within a job, not globally. You could not share a serially reusable module between jobs. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:15, 3 June 2022 (UTC)

Alternative
I think the definition is too sloppy: Consider the case of an object oriented language. An object x could refer to another object y. Now a method in the class of object x returns a value which depends on the state of object y. If the class of object y is mutable, then this is a side effect which influences the result of the method.

Now the problem with the definition is that in its strict sense, this method *is* re-entrant because there is no static data involved in this example. But I am led to believe that in its true meaning the method is *not* reentrant because the return value depends on side effects.

So I suggest the following definition: A reentrant piece of code is a pure function in mathematical terms, which means that its output solely depends on its input parameters, without any side effects.

This implies that the piece of code cannot use static, global or any other data which is not an input parameter. It also implies that the code cannot call other code which does not obeye these requirements. Finally, it implies that the piece of code is thread safe, because the code can only use variables which are local to the current thread (which are usually held on the stack by most programming languages). —Preceding unsigned comment added by 217.83.33.125 (talk • contribs)

 * But that is not what "reentrant" means in most contexts. While a function taking only immutable arguments is indeed reentrant by definition, it's not particularly useful in real life - passing references to complex mutable objects is much more efficient and useful in many cases. As far as I know, "reentrant" does not imply the complete lack of side-effects, but merely that the API is designed with reentrancy in mind. -- intgr 14:04, 10 November 2006 (UTC)

 * Java's String class is immutable. Its methods take other String objects and primitives as arguments. All these methods would be reentrant according to my definition. I don't think that they are not particularly useful - to the contrary: I couldn't do without them. Regarding the term "reentrancy in mind": Well, unless we have a clear definition of the term reentrant, we couldn't even argue what this term means. 217.83.74.51 10:23, 16 November 2006 (UTC)

 * The String class is an exception rather than the rule – nearly all methods taking Strings as arguments are bound to a mutable class anyway. My "reentrancy in mind" comment above relied on the original definition on the article: "[A] routine is described as reentrant if it can be safely called recursively or from multiple processes". -- intgr 15:40, 16 November 2006 (UTC)

 * I agree with intgr : functions whose output solely depends on its input parameters without any side effects is a sufficient requirement for reentrancy; however, it's not a necessary one. In fact, if that were necessary and sufficient, we wouldn't need all the other items on the list (not that the other items in the list hold all that much value either).  As a counter-example to what's proposed, let's imagine that we have a processing queue that has a counter for how many items are in the queue.  This counter can be read without a lock.  You might get a slightly stale value if you read it when another thread is updating it (but all values are instantly stale anyway).  A function that reads and returns the value of this counter is useful and reentrant, though it operates on global non-static data.  Acertain (talk) 03:36, 28 December 2009 (UTC)

Why?
int f(int i) { int priv = i;  priv = priv + 2; return priv; } int g(int i) { int priv = i;  return f(priv) + 2; } int main {  g(1); return 0; }

Why is this example reentrant? Is  unique to each simultaneous process/thread or is it shared by all? --Abdull 10:40, 13 July 2007 (UTC)

 * is unique to each execution of  and   because priv is allocated on the stack of the current thread. Possibly this could be mentioned in the article, but I don't think it's necessary, either. -- Johngiors 06:50, 26 September 2007 (UTC)

Why not?
int f(int i) { return i + 2; } int g(int i) { return f(i) + 2; } int main {  g(1); return 0; }

the parameter values are unique for each call. —Preceding unsigned comment added by 85.144.94.32 (talk) 13:59, 1 May 2008 (UTC)

Agreed. I have re-written the reentrant version without temporary variables, as I think they only served to obfuscate the code. TOGoS (talk) 23:00, 17 June 2008 (UTC)

the common misconception
"Despite a common misconception, this is not the same as being designed in such a way that a single copy of the program's instructions, in memory, can be shared."
 * So, what is the term/buzzword for that? Is it Thread safety? In which case, it should be added to the sentence, and the "See Also" section could be removed.

--Jerome Potts 17:16, 19 August 2007 (UTC)

 * removed that line bc it doesn't make sense; whether or not the executable code is physically shared among processes would only seem relevant for self-modifying code, which nobody uses. author probably meant the data on the heap, not the "instructions"... but still, its not useful. 12.219.83.157 06:05, 16 September 2007 (UTC)

Almost blatently copied
Sections of this article are almost redundant copies of the first external link: http://www.ibm.com/developerworks/linux/library/l-reent.html

Compare:

Reentrance and thread-safety are separate concepts: a function can be either reentrant, thread-safe, both, or neither...

and

Non-reentrant functions are thread-unsafe. Furthermore, it may be impossible to make a non-reentrant function thread-safe.

to: Don't confuse reentrance with thread-safety. From the programmer perspective, these two are separate concepts: a function can be reentrant, thread-safe, both, or neither. Non-reentrant functions cannot be used by multiple threads. Moreover, it may be impossible to make a non-reentrant function thread-safe.

TheShagg 20:26, 12 October 2007 (UTC)

Relation to thread safety
I don't think the following statement is correct:

"Non-reentrant functions are thread-unsafe. Furthermore, it may be impossible to make a non-reentrant function thread-safe."

I think you can have a thread safe function that is non reentrant. Maybe the write meant something like this?

"Thread-unsafe functions are non-reentrant. Furthermore, it may be [or even is] impossible to make a thread-unsafe function reentrant" —Preceding unsigned comment added by Hnassif (talk • contribs) 17:30, 19 October 2007 (UTC)
 * Right now it states "Non-reentrant functions are not thread-safe. Furthermore, it may be impossible to make a non-reentrant function thread-safe (quote?).". This does not make any sense at all, particularly coupled with the statement at the beginning "Reentrance is stronger property than thread-safety: a function can be thread-safe, both, or neither.". —Preceding unsigned comment added by 87.166.65.202 (talk) 17:54, 14 January 2008 (UTC)

The article seems to be assuming a different definition of reentrancy from the one with which I am familiar -- in particular, the definition with which I'm familiar says that a function is reentrant iff it's safe for the function to be called multiple times simultaneously from the same thread of execution. Using that definition, the notions of thread-safety and reentrancy are orthogonal (a function can be one, the other, both or neither). If this (useful!) notion is not called reentrancy, what /is/ it called? 212.44.26.44 (talk) 17:05, 24 August 2009 (UTC)

Async-signal-safe, maybe? 68.255.109.73 (talk) 18:18, 4 December 2010 (UTC)

(-) ads (+) added explanations (-) simplified intro (!) citation needed
Ad ads ;). There's been mentioned 2 guys for no aparent reason. It is nice they recomend something, sure. Your favourite OS teacher doesn't?

Explanations. I thought it might be nice to add some explanations for girls, who cram, and guys, who are just mildly curious. I also called it a derivation. It might not be a best name. Feel free to change mine mistakes ;).

Simplification. There we're 2 sentences which I thought would better be swapped. To me the second seemed more like natural explanation. Hmm

Citations. There are few claims in "derivation and explanation of rules" that I have no support. I am too lazy to look it up and ,hey, wiki-kids might practice google hunting. 86.61.232.26 (talk) 23:56, 26 April 2009 (UTC)

Reentrant interrupt handler
We are given two examples of best practise: 're-enable interrupts as soon as possible', and 'avoid early re-enabling of interrupts unless it is necessary'. These would appear to be mutually exclusive.

On a tangent: why does the article use 're-enable' and 're-entered', but then use the dubious 'reentrant'? Shouldn't it be re-entrant? —Preceding unsigned comment added by 59.95.22.6 (talk) 18:36, 20 November 2009 (UTC)

It does seem that the correct usage here is 're-entrant'. Lambda-mon key (talk) 00:51, 5 March 2010 (UTC)

Difference of "re-entrant" and "pure"
Is there a difference between the concepts of a re-entrant function a pure function? What about locks to singleton objects - is that a point of difference?

If they are the same, then this should be pointed out in both articles (see pure function). Otherwise, I think the difference ought to be explained, as it would make the definition richer.

Does anyone know the difference (and a few definitive sources to cite)? 203.171.122.38 (talk) 09:46, 23 October 2010 (UTC)

No idea about definitive sources, but:

 * a reentrant function can have side-effects
 * a reentrant function can access global state. Depending on your definition, it can even _modify_ global state in thread-unsafe ways, as long as everything is back to normal when it finishes.
 * a pure function can be thread-unsafe and nonreentrant, provided its API indicates when it is appropriate to call it. Being pure is about being side effect-free and the output being a function of the input, nothing else.

Hope that helps. 68.255.109.73 (talk) 18:22, 4 December 2010 (UTC)

Italics
The long runs of italic text in the Derivations section is hard to read. Are these a quote? If so, that should be explicit. Normal text with perhaps a numbered list or bullet list would be easier to read. Sluggoster (talk) 17:51, 9 November 2010 (UTC)

Let's purge the entire article and start anew
The current version of this article is so factually wrong I can't fathom where it could be pulled from. Not to mention being completely unreferenced -- the only paragraph with references is unrelated to the rest of the article.

Let's start with debunking every single of the conditions listed: var counter:integer; function serial:integer; assembler; asm MOV EAX, 1 LOCK XADD counter, EAX end; { like counter++ in C but atomic -- sorry for having no clue about AT&T syntax }
 * Must hold no static (or global) non-constant data.

This function is re-entrant for every definition I am aware of.

int get_queue(int i) { return &queues[i]; }
 * Must not return the address to static (or global) non-constant data.

Example 1.
 * Must work only on the data provided to it by the caller.

May use any such locks as long as it handles it being taken by other instances.
 * Must not rely on locks to singleton resources.

void search_village_for_the_grail {   while(get_an_undug_spot) { start: do_the_digging; if (grail_found) *((char*)start) = RET; } } This code works with both unthreaded and threaded reentrancy.
 * Must not modify its own code. (unless executing in its own unique thread storage)

Or do it with proper care -- like queuing the calls and coordinating somehow. Users of the reentrant outer function don't need to know about the complexity.
 * Must not call non-reentrant computer programs or routines.

Usual definitions
The definition I have been taught on MIM UW is concerned with a single thread. While the function is being executed, it may be called again, either normally or spontaneously (via an interrupt/signal/etc), and execution of the first call is completely blocked until the second finishes. In this case, there is no option of waiting for the first call to release any lock, it is often possible, though, to save any global state on the stack and restore it before returning.

This is especially important for Unix signals, when you cannot use non-reentrant functions like malloc (in most implementations) which severely hinders what the program can try to do. Note that this definition does not imply thread safety.

Another definition some sources use is having the function calleable from different thread but not from the same one. This is equivalent to thread safety, and thus uninteresting.

The third possible definition is being both reentrant and thread-safe. This means that anyone can call the function in any case, regardless of which thread is executing. These concepts go largely orthogonal if efficiency is not vital -- and can be tricky to obtain together if it is.

In any case, the definition provided by the article is useless. It basically boils down to (mostly) pure functions with allowed output but not input.

KiloByte (talk) 15:22, 26 November 2010 (UTC)

 * A fourth definition is given in the Qt documentation: a function is reentrant if it can be called simultaneously from multiple threads, but only if each invocation uses its own data. As a remark on that page says, every thread-safe function (defined as a function which can be called simultaneously from multiple threads, even when the invocations use shared data) is thus reentrant, but not necessarily vice versa. The Wikipedia article should mention these alternative definitions and maybe provide unified terminology suggestions.
 * Jaan Vajakas (talk) 21:47, 27 November 2012 (UTC)

Reentrancy vs recursion
A yet another glaring factual error: this version claimed reentrancy is a requirement for recursion. It's not, for two reasons: void f(int x) { acquire_global_data; mess_with_global_data(x); release_global_data; if (x > 0) f(x - 1); } void process_dir_and_parents(char *path) {     if (!path || *path != '/') path = get_absolute_path(path); // not reentrant process_dir(path); chop_last_element(path); if (*path) process_dir_and_parents(path); // here, the path is always absolute } KiloByte (talk) 13:36, 26 May 2012 (UTC)
 * recursive calls can happen only explicitely, unlike interrupts, so this code works:
 * possible arguments for a recursive call may be a subset of those called from the outside:

 * While I don't want to defend the old text, your new wording is at best ambiguous with a possible interpretation that is factually inaccurate as well. I think it would have been better if you had simply removed the old statement. —Ruud 13:59, 26 May 2012 (UTC)

 * Good idea, I removed this, together with an unrelated vague statement about functional programming as well. KiloByte (talk) 22:45, 26 May 2012 (UTC)

 * What I assume the old text intended: non-reentrant functions usually break some invariant that is expected to hold on entry during execution, but re-establish it before exit. However if you make the recursive call while the invariant is broken things may go wrong. —Ruud 14:04, 26 May 2012 (UTC)

Further example is wrong
The page gives an example of a function. f is not thread-safe. Then the article literally concludes from the non-thread-safety "Hence, f is not reentrant". First, the article itself explains that functions can be reentrant and not thread-safe. Second, Qt's page on reentrancy gives basically the same code as an example of a reentrant function. It does not return the value, but that is not part of the definition of reentrancy, and the member variable might as well be global static if you use a static instance of the class. 80.153.93.87 (talk) 15:46, 13 January 2016 (UTC)

Second example could avoid global variables
This would make swap a pure function without any side effects (as long as addresses of x and y are not shared). But with shared addresses consider When isr finishes, x==3 and z==2. When then swap finishes the second time, x==3 and y==1. Hardly what was expected as the result of swap in main. So I don't think this last code is an example of a reentrant routine, which does its task atomically.--H3xc0d3r (talk) 14:45, 26 January 2017 (UTC)

 * "So I don't think this last code is an example of a reentrant routine, which does its task atomically"
 * This is not true, as Yttril says in his answer on Stackoverflow:
 * "'The point is that 'corruption' doesn't have to be messing up the memory on your computer with unserialised writes: corruption can still occur even if all individual operations are serialised. It follows that when you're asking if a function is thread-safe, or re-entrant, the question means for all appropriately separated arguments: using coupled arguments does not constitute a counter-example.'"
 * Maggyero (talk) 06:50, 25 June 2018 (UTC)

Incorrect rules for reentrancy
Reentrancy (computing) is incorrect in toto:

 * 1) Reentrant routines may contain global data if they serialize access. Serialization can be done using either atomic instructions or operating facilities such as semaphores.
 * 2) Reentrant code may modify itself; in fact, some of the reentrant code in OS/360 did just that, with appropriate serialization.
 * 3) Reentrant code can call non reentrant code, with appropriate serialization.

Note: a refreshable procedure, or even a pure procedure, is not necessarily reentrant; it still needs appropriate serialization. - Shmuel (Seymour J.) Metz Username:Chatul (talk) 16:19, 25 May 2018 (UTC)

 * You seem to confuse reentrancy with thread safety. Reentrancy has nothing to do with multithreading and serialized access. A reentrant function may not be thread safe as the 3rd example of the article shows.
 * Maggyero (talk) 07:50, 25 June 2018 (UTC)

 * No, reentrant has meant safe for concurrent execution since the early 1960s. A wiki article can not be its own RS. Shmuel (Seymour J.) Metz Username:Chatul (talk) 21:42, 12 July 2018 (UTC)

 * That is basically correct. Reentrancy was usually used by OS/360 service rotines, even of Uni-CPU. The main reason was to save mainstorage and also performance (load time). A reentrant program could be made resident in storage and accessed by all users (tasks). Main storage was expensive, slow (magnetic cores in the 60ies) and a 512kB System was a very big system at this time. Also using online service (TSO, IMS, DB2, CICS, ....) the most common used programs could be made resident, if, and only if they are "reentrant". The above 3 rules are not precise:
 * reentrant routines may use global data using serialization. The global data are not allowed to be inside the routine itself.
 * reentrant code may never change its own coding. I have serviced some nightmares at customers systems at the time of first multiprocessor systems, where those common mistake blow up the system. See Shmuel (Seymour J.) Metz Username:Chatul ref to IBMs Linkage Editor Manual in next section "Provenance of reentrancy", last sentence.
 * if reentrant code calls non-reentrant routines, you need not only serialization in common sense, i.e. lock shared data, but you have to mask (disable) interrupts and pin this execution to only one processor until return. That is a very very bad option and sometimes used during migration processes. Those programmers would not be very happy if such coding was detected and they had to answer for a reason of such procedure..
 * --Pqz602 (talk) 16:29, 20 May 2022 (UTC)
 * It's a bit more complicated than that.
 * OS/360 has reentrant routines that modify themselves with appropriate serialization. That's generally considered bad form and, AFAIK, IBM has cleaned up all such code in current (z/OS) MVS.
 * There is no requirement to disable interrupts, although that is one way to serialize in OS/360 with 65MP support. Typically, MVS replaced code that used SSM with code that acquired and released locks.
 * In OS/360, a reentrant routine can safely invoke a serially reusable routing via the LINK macro with no explicit serialization; LINK provides the required serialization.
 * In MVS (end of text added from Shmuel (Seymour J.) Metz Username:Chatul)
 * In MVS (end of text added from Shmuel (Seymour J.) Metz Username:Chatul)

 * ENQ/DEQ is more close to application/subtask serialization. If I remember correct you are not allowed within interrupt-handling (always reentrant code) to use any SVC already at OS/360-time (MFT/MVT). For some minimum time within that interrupt-handling you have to avoid a CPU-switch, solved by running disabled for housekeeping. It is a real hack with those crossmemory/cross-cpu posting or unlocking. Starting with MP IBMs S/W-teams had to rewrite "some" code .... --Pqz602 (talk) 18:31, 22 May 2022 (UTC)

 * ENQ and DEQ are used by both application code and OS code. As with any SVC other than ABEND, they are not allowed in an interrupt handler or in a type 1 SVC. In MVS terms, they are only allowed in TCB mode.
 * In OS/360 through z/OS, interrupt handlers always run disabled and each CPU has its own prefixed storage area (PSA), so there is no need for additional serialization at entry. Once other code is involved, e.g., Dispatcher, I/O Supervisor, storage management, then of course those routines need to do additional serialization.
 * 65MP support uses the test and set (TS) instruction for low level serialization, and set system mask causes a program check so the program interrupt handler can serialize and deserialize; that is certainly a hack, and I would even call it a kludge, but it did minimize the code that IBM had to change. MVS uses the newer instruction compare and swap (CDS) and compare double and swap (CDS), and uses locks rather than SSM; that required more of a code change than 65MP had.
 * In MVS there are two broad categories of locks; spin locks are for brief low level activities, run disabled and do not allow switching the CPU to other work. Suspend locks have more overhead, but allow other work to proceed if the lock is not available. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:29, 23 May 2022 (UTC)
 * just one more complaint to the article itsself: Rule 2 has written
 * ...It may, however, modify itself if it resides in its own unique memory. That is, if each new invocation uses a different physical machine code location where a copy of the original code is made, it will not affect other invocations even if it modifies itself during execution of that particular invocation (thread). ...
 * The bold text is exactly the definition of "serial reusable" from OS/360 time and later. You are NOT re-entering the original code (which is never reentrant originally due to its self-modification). "reentrant" code will always be able to run as one physical code for muliple tasks (and CPUs). --Pqz602 (talk) 14:18, 21 May 2022 (UTC)
 * ...It may, however, modify itself if it resides in its own unique memory. That is, if each new invocation uses a different physical machine code location where a copy of the original code is made, it will not affect other invocations even if it modifies itself during execution of that particular invocation (thread). ...
 * The bold text is exactly the definition of "serial reusable" from OS/360 time and later. You are NOT re-entering the original code (which is never reentrant originally due to its self-modification). "reentrant" code will always be able to run as one physical code for muliple tasks (and CPUs). --Pqz602 (talk) 14:18, 21 May 2022 (UTC)

Unnecessary atomicity requirement
do you think that the last paragraph about the atomicity requirement in the current introduction of the article is correct? To me atomicity is not necessary, as demonstrated by the 3rd example in the article (Reentrant but not thread-safe), where  is a global variable that is not modified atomically.
 * Maggyero (talk) 07:39, 25 June 2018 (UTC)

Provenance of reentrancy
The claim It is a concept from the time when no multitasking operating systems existed. is false. The concept originated with OS/360 Shmuel (Seymour J.) Metz Username:Chatul (talk) 15:03, 20 August 2018 (UTC)

History
When was the concept of reentrant subroutines first developed? Was it before or after the widespread support for 1. hardware interrupts and 2. recursive subroutines? I'm guessing it preceded the introduction of preemptive multitasking OS. Cesiumfrog (talk) 06:42, 12 September 2019 (UTC)

 * Reentrancy came in with IBM Operating System/360 (OS/360) and Time Sharing System/360 (TSS/360) in the 1960s, long after the Univac 1103A, LISP and Algol 60. IBM introduced the concept for the multiprogramming options of OS/360, eventually known as MFT and MVT, both of which were preemptive, although initially only MVT allowed an application to ATTACH subtasks until OS/360 Release 15/16.. Shmuel (Seymour J.) Metz Username:Chatul (talk) 17:16, 12 September 2019 (UTC)

 * We should separate in History between OS/360 and TSS until ~1970, when TSO was implemented within OS/360. Until this time OS/360 was a "Batch-System". Around 1971 TSO substitutes TSS functions into MVS (MFT/MVT,...). The virtual storage concept of TSS was added a bit later, VS1/VS2 and some years later MVS. I don't dig just now to the time scale, but supported this S/W since 1969, H/W /360 some years before. Also UNIX was implemented later on within MVS. So .... we should also differ between UNIX and those IBM Architecture using examples and requirements for reentrancy. I will add a z/OS 2.3.0 ref to Linkage- Editor/Binder Options from Program Management users's Guide. It is a bit complicated to seperate on time-line, but the basics are still used since the 60ies from TSS via OS/3xx to z/OS, mixing a bit with UNIX's implementations.
 * Reentrant executable machine-code was basically not changed (se TSS ref), but ... special addressing allowed using parts of reentrant programs in areas dedicated and unique to each task (dynamically loaded/attached). In this case there is no need for serialization. If common (global) areas would be modified, of course - needs serialization.
 * I don't know UNIX, but further on PL/I and Fortran in these times had an "Checkout" version, producing object-code (intermediate code) which may be changed at run-time. The Checkout-compilers themselves have been reentrant, but this should not be mixed with native executed machine-code-programs. The "Checkout-source-code" will be interpreted (first by source to intermediate code, and then this intermediate code). Those interpreted source code (attributes) should not be mixed with compiled and loaded machine-code. Using C or Java samples don't make it better - Reentrancy is based on the machinecode of a processing system. Compiler/Interpreter options may already define or inhibit this reentrant attribute for machine loaded code. --Pqz602 (talk) 11:05, 26 May 2022 (UTC)
 * TSO does not substitute TSS function into MVT, SVS or MVS. Rather, TSO provides time sharing with its own syntax and API. While TSS supports some OS/360 facilities for compatibility, it has new access methods and is very different from both base OS/360 and TSO, especially as regards reentrant programs; OS/360 has no equivalent to the Protye Section (PSECT) of TSS. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:03, 27 May 2022 (UTC)
 * I know those differences and discussions since start of TSO. I have written "substitutes TSS function s , means conceptual the timesharing of online-users in seperate address-spaces in opposite to the batch-processing at this time. TSS introduced also already virtual storage (years before VS1 and VS2) and my VM-collegues at the time of first VM-Systems referred to TSS as the first VM-System. Those comparisons are a bit dangerous in details, but useful for general understanding. --Pqz602 (talk) 10:01, 3 June 2022 (UTC)
 * I know those differences and discussions since start of TSO. I have written "substitutes TSS function s , means conceptual the timesharing of online-users in seperate address-spaces in opposite to the batch-processing at this time. TSS introduced also already virtual storage (years before VS1 and VS2) and my VM-collegues at the time of first VM-Systems referred to TSS as the first VM-System. Those comparisons are a bit dangerous in details, but useful for general understanding. --Pqz602 (talk) 10:01, 3 June 2022 (UTC)
 * I know those differences and discussions since start of TSO. I have written "substitutes TSS function s , means conceptual the timesharing of online-users in seperate address-spaces in opposite to the batch-processing at this time. TSS introduced also already virtual storage (years before VS1 and VS2) and my VM-collegues at the time of first VM-Systems referred to TSS as the first VM-System. Those comparisons are a bit dangerous in details, but useful for general understanding. --Pqz602 (talk) 10:01, 3 June 2022 (UTC)

I have been IBM-CE in the 60ies, with beginning of OS/360 for those CPUs too, and later teached MFT/MVT (+Compiler) Lessons some years starting 1969/70. Until the first true Multi-CPU-Systems IBM had two main-definitions for executable programs, running in separate storage regions (variable size, MVT) or storage partitions (fixed size, MFT), each program-work named as task:
 * serial reusable, those programs need to be loaded only once, could be used again without loading again. If you started a subtask (within same region/partition) using those programs, they had to be loaded with one copy for each task.
 * reentrant, those programs could be used with one loaded Program-code by more than one task.

Just at this early years, remember, all interrupts have been handled by only one CPU without problems until sometime at end 70ies the first (tightly coupled) MP-Systems had been delivered - 2 CPUs. Any interrupt handler did the houskeeping via some standard (minor) register conventions. The interrupt handler routines must have been reentrant, because stored within operating system and serving all tasks.

With multiple CPUs each code not bounded to one processor has to be reentrant, because after each interrupt the next free CPU continues running that program. After teaching years (rotation job) and moving to service at customer locations i had some mightmares of first installations to serve running programms on Dual-Processor systems which have been linked with attribute reentrant, but did not regard reentrant-rules. The most common error was the use of (register-)save-areas in static storage inside program instead of dynamically allocations. Each processor has its own register-set, so .... results in garbage if save-areas get mixed. This relates to subtasks as well as to programs(tasks) in different partitions/regions.

In first time of small /360 Systems Customer are running programs within 8 to 16kiloBytes without operating system one program at a time. So common coding uses the initialization code later for data-workarea. Those coding was later on also kept for a while with small storage systems. A 512kB Mainstorage /360 was a big system, and MVT/MFT has to handle Programs within this "big" storage. This changes with first virtuell storage systems, but storage constraints are always real until today, just only other measures. Those spare-storage-programs are neither "serial reusable" nor "reentrant", but ..... they are still living somewhere .....

BTW: just pointing it here - "serial reentrant" ist not a correct term and was never used in old times. Either a program is reentrant and interruptable anywhere (from anyone) or otherwise it is no more reentrant. Serial reusable means - scrap the old copy and reload again, start always at defined entrypoint. serial reusable has to be locked on one processor only, but is still interruptable. Recurrency is just an other independent term, but if you run a recurrent function with non-reentrant code, you will get the code and work-areas multiplied with each (single) run of the loop, which will kill your system very quickly running out of storage.

Just a bit history, sorry if already known. It's just for sorting some of the terminologie discussed here by their original meaning. regards Peter --Pqz602 (talk) 18:24, 19 May 2022 (UTC)

Sorry, just an add-on: "task" as used in my post means the same as "thread" in these wiki-programming posts. Thread was at least not used by the former time main frame programmers. (and task is still used in Win10, most NT based Windows Systems are using the architecture similar to OS/360 and follower) --Pqz602 (talk) 18:56, 19 May 2022 (UTC):
 * A serially reusable module only needs to be loaded once within a partition (region), but each partition (region) had its own copy. Only reentrant modules are eligiible to be included in the shared Link Pack Area (LPA).
 * Only in a multiprocessor is reentrancy relevant for an interrupt handler in OS/360. Interrupt handlers ran disabled except for a few special points where they briefly enabled a recursiv e interrupt.
 * Neither reentrant nor serially reusable routines are bound to a single CPU, other than interrupt handlers, and doing so would not have accomplished anything.
 * In a multiprocessor, reentrancy is relevant to both enabled and disabled code.
 * In the 1960s, IBM already had tightly coupled multiprocessing on the 9020 and 360/67, not just on the 360/65.
 * In a few places you wrote serially reusable when non reusable is appropriate, e.g., recurrent invocation of serially reusable routine does not cause memory exhaustion but recurrent loading of non reusable code may. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:03, 27 May 2022 (UTC)

The code in Reentrant and thread-safe is not reentrant
The code in Reentrancy (computing) is not reentrant; it can execute concurrently on two different processors.

The code needs serialization to be reentrant. Shmuel (Seymour J.) Metz Username:Chatul (talk) 20:17, 15 September 2019 (UTC)

 * No, it doesn't need serialization. If this is running on two separate processors, a call to isr on the second processor will create separate stack-based instances of x and y than those for the first processor. Thus, no two invocations of void swap(int* x, int* y) will ever (unless swap is used incorrectly elsewhere) operate on pointers to the same memory locations.
 * Benjamin J. Crawford (talk) 11:07, 3 October 2019 (UTC)

 * In other words, a reentrant function is "dumb" in that it assumes it is allowed to operate on memory which it is explicitly passed (through pointers in this case). It is the responsibility of the caller to ensure thread-safety. Reentrancy only makes the guarantee that the function doesn't depend on "external"/globally shared state. Benjamin J. Crawford (talk) 11:07, 3 October 2019 (UTC)

 * Reentrancy is not an issue for routines that operate only on local data in the stack, but it is an issue when shared data are involved; interrupt routines normally need to deal with shared data. You can write a reentrant routine to swap two words, but it requires some sort of serialization. On some processors there are atomic instructions that serialize storage access, on others you need to use a lock or similar mechanism. The location of the serialization is part of the design of the software; typically interface documentation will require that certain locks be held and require that other locks not be held. YMMV. Shmuel (Seymour J.) Metz Username:Chatul (talk) 22:28, 2 October 2019 (UTC)

 * I agree that in the typically useful case, memory access serialisation through some atomic operation is necessary for an ISR. I also agree that, by design, swap is not inherently reentrant, which isn't completely clear from the description given on the page. From reading the passage however, it clearly implies later on that x and y are taken to be unshared local to a single isr invokation. If you consider inlining the swap function, the snippet is reentrant. I suppose in this instance, it's important to limit your analysis to the code given, and not consider a general case. Perhaps it would be useful to explain which of the Rules for reentrancy you believe this violates and why. Benjamin J. Crawford (talk) 11:07, 3 October 2019 (UTC)

 * The problem is the sentence An implementation of swap that allocates tmp on the stack instead of on the heap is both thread-safe and reentrant. That implementation is not reentrant when two invocations refer to the same variable. The usage of swap by isr is reentrant, but swap itself is not. Shmuel (Seymour J.) Metz Username:Chatul (talk) 16:51, 3 October 2019 (UTC)
 * Do you mean that a function might be swapping two values, at least one of which is static and defined outside a function? The caller might call swap but an interrupt could invoke the caller a second time, and that would cause swap to give invalid results? Wouldn't that be an example of the fact that it is always possible to break something if you try hard enough? Johnuniq (talk) 02:02, 4 October 2019 (UTC)
 * I completely agree with Johnuniq here. The mistake you're making is in abusing the swap function by not otherwise adhering to parallel processing mandates. If you pass in pointers to data used in overlapping invocations, that's the programmer's fault. The idea of reentrancy is solely to express that you don't need to worry that swap is "behind-the-scenes" shared-state dependent. Benjamin J. Crawford (talk) 02:26, 5 October 2019 (UTC)
 * There is no parallel processing mandate that requires that an ISR operate only on local data, and an ISR normally needs to manipulate global data. BTDT,GTTS. In this case, you do need to worry, because the swap function is not coded to operate correctly when, e.g., doing a swap to update the head of a queue. Shmuel (Seymour J.) Metz Username:Chatul (talk) 20:33, 6 October 2019 (UTC)
 * Again, you're not staying true to the example given. Sure, an ISR may very well need to operate on global data, but this isn't the case here. If the ISR indeed does need to swap two values in memory where race conditions may arise, locking (serialisation) can be done in the ISR itself, before and after calling the swap function. This does not change the fact that this example is both reentrant and thread-safe. Benjamin J. Crawford (talk) 13:35, 7 October 2019 (UTC)

 * Again, you're not reading the first sentence of the article: An implementation of swap that allocates tmp on the stack instead of on the heap is both thread-safe and reentrant. The fact that the author code contrived code that didn't expose the lack of reentrancy doesn't make it reentrant. The contrived example of isr is irrelevant unless the previous text establishes it as part of the context for claiming reentrancy.

 * I must say that this example is perhaps too contrived to be sufficiently confusing, and requires clarification. I will say in closing that the example does explicitly state that there is no dependence on shared data so it's difficult to assert that this is incorrect in any real way as it stands. I believe you have the sufficient fluency to add appropriate serialisation to this section of the article. I'd look forward to seeing that if you have the time. Benjamin J. Crawford (talk) 13:52, 15 October 2019 (UTC)

 * No, that wouldn't be an example of the fact that it is always possible to break something, nor do I agree that it is a fact. It's an example of failing to properly serialize a function. Shmuel (Seymour J.) Metz Username:Chatul (talk) 20:33, 6 October 2019 (UTC)

Confusing
I haven't contributed to Wikipedia in forever, so hopefully I'm doing this Talk thing correctly (and if not, it's an honest mistake!), but...

This article confuses the heck out of me. I'm not a computer scientist, but perhaps for that very reason I can be helpful. My observation is that most confusion and frustration comes about when there is a misunderstanding about the common ground. It's like when you don't quite hear everything your wife/husband/partner says, all you hear is "blah blah blah grocery store blah blah blah" and you ask them to repeat it, and they say "blah blah blah GROCERY STORE!!! blah blah," … and you are like, look, I got the GROCERY STORE part, I didn't get what came before and after that!!!

So, just to begin:

After fifteen minutes, I still have no idea what the first two sentences even mean. Take sentence one:

"In computing, a computer program or subroutine is called reentrant if multiple invocations can safely run concurrently."

I don't know what does this means. What is an "invocation?" Is an "invocation" the same as a "thread"? If so, does that mean we're just talking about multi-threaded programming? If not, how does this apply to other situations I might encounter?

How about "concurrently"? What does that mean? "Concurrently" can not mean "at the same time" (as in time on a wall clock), because the next sentence says "The concept applies even on a single processor system." Obviously, a single processor can't possibly be executing one machine-level instruction at a time, therefore, logically, "concurrently" must not mean "at the same time."

Next, still in sentence two, a re-entrant procedure is interrupted in the middle of its execution and then called again. What does this mean? Interrupted how? You mean by the OS or by something internal to the code itself? How can it be called again if it was interrupted? In my little universe, if I interrupt a running code by typing ^C, that's it. Game over, there's no picking back up. So what does "interrupt" mean here? Is it the same as pausing? And when we say it can be called again, do we mean, called again by the same thread, after it comes back and finishes the first time? Or a different thread? Or a different process?

I'm sure all of this is very basic and fundamental stuff, but at the moment it leaves me thinking that the underlying concepts probably aren't nearly as complex or confusing as the terms being used to try to describe them. I hope that my comments are taken at intended, which is to explain - to people who actually know this stuff and who might be baffled why this article is confusing - why it is, in fact, confusing, at least to some people. Thanks.Petwil (talk) 13:38, 7 February 2020 (UTC)

 * It is very basic and fundamental stuff, but that doesn't mean that more explanatory text is not in order. I'll try to address your questions, in no particular order.

 * Concurrently refers to both time actually running on a CPU and time waiting for a CPU.

 * An invocation means that something called it, whether s part of a process, a thread within a process or some other context. The requirement is that regradless of the invocation contexts, two instances running concurrently produce correct results.

 * Let me give a concrete example of concurrency, once on a single CPU and once on multiple CPUs.

 * Process A calls foo
 * An interrupt causes higher priority process B to become ready before the first invocation of foo completes
 * Process B calls foo
 * Process B, while running foo, waits for some event
 * The CPU is now available to continue running the instance of foo in Process A
 * There may be multiple waits in both processes

With multiple CPUs

 * Process A calls foo
 * Process B calls foo before the first invocation of foo completes
 * Either process A or Process B may need to wait for an event to complete, but in this example we are assuming that there are enough available CPUs that they begin running as soon as eligible.

To a first approximation you need the same code to make foo reentrant whether the first (single CPU) or second (multiple CPU) scenario applies. Shmuel (Seymour J.) Metz Username:Chatul (talk) 18:32, 7 February 2020 (UTC)
 * It's a bit "computer slang": a program (thread, task) is said "running" from the time it is started (invoked, called) until it's final completion (stop, return). A reentrant program-code may be used/entered from multiple callers/tasks at time, anyone else is already using this program-code (and still "running" concurrently). On a single-CPU System this happens for example, if caller1 waits for I/O response of 6msec, meanwhile caller2 runs some CPU-instructions of the same code (until he must also wait), and so on until program end.
 * Interrupt: as long as interrupts are allowed (they may be suppressed, "masked" by the CPU), typically any ended I/O operation is signaled to the cpu(s), which decides then to interrupt current processing and call an interrupt-handler (service-code of op-system), which does housekeeping and gives control to that task/thread, which requested the I/O-operation and was waiting for I/O-completion. There are other interrupt-possibilities, but that's the most common.--Pqz602 (talk) 21:23, 19 May 2022 (UTC)

The self-contradiction in the "Reentrant but not thread-safe" example should be fixed
I have a computer science background but am new to this concept. I found Reentrancy_(computing) to be unnecessarily confusing because of the recently added comment in the code:

This is self-contradictory because the name of the section and the description preceding the code example say that it is reentrant. I see in the edit history that this comment was added, removed, readded within the last few months.

I think we can agree that the article as a whole would be better if there isn't a part that says two opposing things simultaneously, right? Rather than leaving it as it is now, someone who knows this stuff better than me should clarify the ambiguities so that it's no longer possible to interpret the description and example in different "contexts" to arrive at different conclusions about whether it's reentrant or not. Maybe adding to the description something like "assuming that the ISR itself can't be interrupted and there is only 1 processor, so the ISR will finish and swap its 2 ints correctly before restoring tmp so that the interrupted instance will still see the value it expects in tmp"

Citizenofinfinity (talk) 11:11, 19 February 2021 (UTC)

The code in Reentrant but not thread-safe is not reentrant
The code in #Reentrant but not thread-safe is not reentrant unless it is running on a uniprocessor with interrupts disabled. There is no serialization on the global variable tmp between and. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 18:03, 13 February 2022 (UTC)

Notes; A program that serializes self-modification may be reentrant,.....
I cannot believe this sentence. If a program once is modified in its code, a second caller will never get the original coding. Serialization does not prohibit the code-change nor restores the original code. Those code may even not be "serial reusable", must be refreshed by reloading und always start "initially" again.

A selfmodifying code will never be reentrant in terms of reentrant's original meaning. --Pqz602 (talk) 22:05, 19 May 2022 (UTC)

 * Would like to add a main "protest": the whole "thread-safe" stories should not discussed her together with reentrancy. There is also too much reference to the Unix-world and C-Language belongings. The serialization of shared variables is a complete other stuff and has nothing to do with reentrant code. I agree basically with the reentrancy description, but thread-safe used in this context generates more confusion than understanding.

 * The point is: all processors (old /360 and new PC-CPUs) are using a set of (former) called base-registers. At least min. two registers are dedicated: one for execution-address and one for data-address (stack or dynamically allocated storage -- unique use for each task). As long as those conventions are used - by operating-system via interrupt-handler and the task-coding those programs are reentrant, because each interrupt returns to the interrupted execution-address and ISR restores the tasks data-pointer. Those data are commonly also use a register-save area, at OS/360+ times all 16 baseregisters chained with each call of further subroutines. Any change of shared variables outside the tasks ownership should be serialized, whether the code is "reentrant" or not.

 * I'm just speaking on machine-code-level. Whether C-Compilers issuing static or dynamic allocation of data-areas at initialization and protect static from changes is just an other business. Any change of task-internal coding or static-data inhibits the attribute "reentrant" for this portion of coding. Elder /360 Compilers will issue warnings at compilation time, if you try to modify internal code or static areas (using the corresponding compiler-options).

 * The thread-safe story should be discussed separately.--Pqz602 (talk) 09:32, 20 May 2022 (UTC)
 * A program is reentrant if it executes correctly when two invocations run concurrently. Serialization pf shared data, including data within the program, is very much relevant. A read-only program may fail to be reentrant it it modifies shared data without proper serialization, and a program that modifies itself may still be reentrant if it has proper serialization, although I would discourage the latter. The use of base registers and truncatated addressing doesn't really change that. --Shmuel (Seymour J.) Metz Username:Chatul (talk) 11:29, 20 May 2022 (UTC)
 * "a program that modifies itself may still be reentrant if it has proper serialization" ...is pure theory and practical nonsense. For what reason should I put (n) processors in a serialization lock (where they - with a bit of luck - never get out from wait), just to force them using all the same code instead of making such code "serial reusable" (in old terms). This other attribute forces the operating system to load the code again for each call and let all processors run that function equally, but in separated (duplicated) code. The sense of "reentrant" is making code resident for use by one copy only from all processors simultaneously, per definition running all the the same code.
 * Its own Code changing at execution is a very old and strange storage saving technique, which was banned at least with using virtual storage in mid-70ies. With multi-processors there is normally no control on flow of executions and interrupts. Also serialization requires a minimum of disabling interupts and wait states. It is horrible to use the attribute "reentrant" with code forcing total (for all using tasks) waitstates and may result in some kind of "russian roulette".
 * The same is valid for " A read-only program may fail to be reentrant it it modifies shared data without proper serialization,". A read-only program has to change nothing, otherwhise it is not read-only. "Modifying shared data" is no problem, as long as those data are not static (inside) that program - see before. Shared data outside that code will be locked for modification time only, whereas its own code-manipulation (as before) needs to lock the whole programcode putting every processor using the same code into waitstate (otherwhise you will get unpredictable results).
 * The program attribute "reentrant" has a special meaning and consequences, not only just that 2 guys may call the code at same time, and hopefully get the same result. --Pqz602 (talk) 10:59, 21 May 2022 (UTC)
 * The program attribute "reentrant" has a special meaning and consequences, not only just that 2 guys may call the code at same time, and hopefully get the same result. --Pqz602 (talk) 10:59, 21 May 2022 (UTC)

Short description
A recent edit added an incorrect short description. I was going to correct it but then I realized that I had come up with text that was much two long. So, the question is, how to word it so that it covers both scenarios below without being verbose?

 * 1) Foo calls Baz on CPU A and at approximately the same time Bar calls Baz on CPU B. No interrupt is involved.
 * 2) Foo calls Baz on CPU A, Foo is interrupted, Bar is dispatched on CPU A, Bar calls Baz, periodically interrupts cause alternating dispatches of Foo and Bar, with the two invocations of Baz interleaved on a coarse time frame.

In both cases Baz has to deal with serialization of data. Shmuel (Seymour J.) Metz Username:Chatul (talk) 13:57, 19 February 2023 (UTC)

I’m ashamed to say I’m not a computer scientist, I just skimmed the introduction and tried to summarize it as best I could. If the concept is that complicated it's probably better to just set the short description as "concept in computer programming" and leave it at that OlliverWithDoubleL (talk) 23:24, 19 February 2023 (UTC)

title: Talk:Reentrancy (computing)


text:
Transverse isotropy

A transversely isotropic material is one with physical properties that are symmetric about an axis that is normal to a plane of isotropy. This transverse plane has infinite planes of symmetry and thus, within this plane, the material properties are the same in all directions. Hence, such materials are also known as "polar anisotropic" materials. In geophysics, vertically transverse isotropy (VTI) is also known as radial anisotropy.

This type of material exhibits hexagonal symmetry (though technically this ceases to be true for tensors of rank 6 and higher), so the number of independent constants in the (fourth-rank) elasticity tensor are reduced to 5 (from a total of 21 independent constants in the case of a fully anisotropic solid). The (second-rank) tensors of electrical resistivity, permeability, etc. have two independent constants.

Example of transversely isotropic materials
An example of a transversely isotropic material is the so-called on-axis unidirectional fiber composite lamina where the fibers are circular in cross section. In a unidirectional composite, the plane normal to the fiber direction can be considered as the isotropic plane, at long wavelengths (low frequencies) of excitation. In the figure to the right, the fibers would be aligned with the $$x_2$$ axis, which is normal to the plane of isotropy.

In terms of effective properties, geological layers of rocks are often interpreted as being transversely isotropic. Calculating the effective elastic properties of such layers in petrology has been coined Backus upscaling, which is described below.

Material symmetry matrix
The material matrix $$\underline{\underline{\boldsymbol{K}}}$$ has a symmetry with respect to a given orthogonal transformation ($$\boldsymbol{A}$$) if it does not change when subjected to that transformation. For invariance of the material properties under such a transformation we require

\boldsymbol{A}\cdot\mathbf{f} = \boldsymbol{K}\cdot(\boldsymbol{A}\cdot\boldsymbol{d}) \implies \mathbf{f} = (\boldsymbol{A}^{-1}\cdot\boldsymbol{K}\cdot\boldsymbol{A})\cdot\boldsymbol{d} $$ Hence the condition for material symmetry is (using the definition of an orthogonal transformation)

\boldsymbol{K} = \boldsymbol{A}^{-1}\cdot\boldsymbol{K}\cdot\boldsymbol{A} = \boldsymbol{A}^{T}\cdot\boldsymbol{K}\cdot\boldsymbol{A} $$ Orthogonal transformations can be represented in Cartesian coordinates by a $$3\times 3$$ matrix $$\underline{\underline{\boldsymbol{A}}}$$ given by

\underline{\underline{\boldsymbol{A}}} = \begin{bmatrix} A_{11} & A_{12} & A_{13} \\ A_{21} & A_{22} & A_{23} \\ A_{31} & A_{32} & A_{33} \end{bmatrix}~. $$ Therefore, the symmetry condition can be written in matrix form as

\underline{\underline{\boldsymbol{K}}} = \underline{\underline{\boldsymbol{A}^T}}~\underline{\underline{\boldsymbol{K}}}~\underline{\underline{\boldsymbol{A}}} $$ For a transversely isotropic material, the matrix $$\underline{\underline{\boldsymbol{A}}}$$ has the form

\underline{\underline{\boldsymbol{A}}} = \begin{bmatrix} \cos\theta & \sin\theta & 0 \\ -\sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}~. $$ where the $$x_3$$-axis is the axis of symmetry. The material matrix remains invariant under rotation by any angle $$\theta$$ about the $$x_3$$-axis.

In physics
Linear material constitutive relations in physics can be expressed in the form

\mathbf{f} = \boldsymbol{K}\cdot\mathbf{d} $$ where $$\mathbf{d},\mathbf{f}$$ are two vectors representing physical quantities and $$\boldsymbol{K}$$ is a second-order material tensor. In matrix form,

\underline{\underline{\mathbf{f}}} = \underline{\underline{\boldsymbol{K}}}~\underline{\underline{\mathbf{d}}} \implies \begin{bmatrix} f_1\\f_2\\f_3 \end{bmatrix} = \begin{bmatrix} K_{11} & K_{12} & K_{13} \\ K_{21} & K_{22} & K_{23} \\ K_{31} & K_{32} & K_{33} \end{bmatrix} \begin{bmatrix} d_1\\d_2\\d_3 \end{bmatrix} $$ Examples of physical problems that fit the above template are listed in the table below. Using $$\theta=\pi$$ in the $$\underline{\underline{\boldsymbol{A}}}$$ matrix implies that $$K_{13} = K_{31} = K_{23} = K_{32} = 0$$. Using $$\theta=\tfrac{\pi}{2}$$ leads to $$K_{11} = K_{22}$$ and $$K_{12} = -K_{21}$$. Energy restrictions usually require $$K_{12}, K_{21} \ge 0$$ and hence we must have $$K_{12} = K_{21} = 0$$. Therefore, the material properties of a transversely isotropic material are described by the matrix

\underline{\underline{\boldsymbol{K}}} = \begin{bmatrix} K_{11} & 0 & 0 \\ 0 & K_{11} & 0 \\ 0 & 0 & K_{33} \end{bmatrix} $$

Condition for material symmetry
In linear elasticity, the stress and strain are related by Hooke's law, i.e.,

\underline{\underline{\boldsymbol{\sigma}}} = \underline{\underline{\mathsf{C}}}~\underline{\underline{\boldsymbol{\varepsilon}}} $$ or, using Voigt notation,

\begin{bmatrix} \sigma_1 \\ \sigma_2 \\ \sigma_3 \\ \sigma_4 \\ \sigma_5 \\ \sigma_6 \end{bmatrix} = \begin{bmatrix} C_{11} & C_{12} & C_{13} & C_{14} & C_{15} & C_{16} \\ C_{12} & C_{22} & C_{23} & C_{24} & C_{25} & C_{26} \\ C_{13} & C_{23} & C_{33} & C_{34} & C_{35} & C_{36} \\ C_{14} & C_{24} & C_{34} & C_{44} & C_{45} & C_{46} \\ C_{15} & C_{25} & C_{35} & C_{45} & C_{55} & C_{56} \\ C_{16} & C_{26} & C_{36} & C_{46} & C_{56} & C_{66} \end{bmatrix} \begin{bmatrix} \varepsilon_1 \\ \varepsilon_2 \\ \varepsilon_3 \\ \varepsilon_4 \\ \varepsilon_5 \\ \varepsilon_6 \end{bmatrix} $$ The condition for material symmetry in linear elastic materials is.

\underline{\underline{\mathsf{C}}} = \underline{\underline{\mathsf{A}_\varepsilon}}^T~\underline{\underline{\mathsf{C}}}~\underline{\underline{\mathsf{A}_\varepsilon}} $$ where

\underline{\underline{\mathsf{A}_\varepsilon}} = \begin{bmatrix} A_{11}^2 & A_{12}^2 & A_{13}^2 & A_{12}A_{13} & A_{11}A_{13} & A_{11}A_{12} \\ A_{21}^2 & A_{22}^2 & A_{23}^2 & A_{22}A_{23} & A_{21}A_{23} & A_{21}A_{22} \\ A_{31}^2 & A_{32}^2 & A_{33}^2 & A_{32}A_{33} & A_{31}A_{33} & A_{31}A_{32} \\ 2A_{21}A_{31} & 2A_{22}A_{32} & 2A_{23}A_{33} & A_{22}A_{33}+A_{23}A_{32} & A_{21}A_{33}+A_{23}A_{31} & A_{21}A_{32}+A_{22}A_{31} \\ 2A_{11}A_{31} & 2A_{12}A_{32} & 2A_{13}A_{33} & A_{12}A_{33}+A_{13}A_{32} & A_{11}A_{33}+A_{13}A_{31} & A_{11}A_{32}+A_{12}A_{31} \\ 2A_{11}A_{21} & 2A_{12}A_{22} & 2A_{13}A_{23} & A_{12}A_{23}+A_{13}A_{22} & A_{11}A_{23}+A_{13}A_{21} & A_{11}A_{22}+A_{12}A_{21} \end{bmatrix} $$

Elasticity tensor
Using the specific values of $$\theta$$ in matrix $$\underline{\underline{\boldsymbol{A}}}$$, it can be shown that the fourth-rank elasticity stiffness tensor may be written in 2-index Voigt notation as the matrix
 * $$ \underline{\underline{\mathsf{C}}} =

\begin{bmatrix} C_{11}&C_{12}&C_{13}&0&0&0\\ C_{12}&C_{11}&C_{13}&0&0&0\\ C_{13}&C_{13}&C_{33}&0&0&0\\ 0&0&0&C_{44}&0&0\\ 0&0&0&0&C_{44}&0\\ 0&0&0&0&0&(C_{11}-C_{12})/2 \end{bmatrix} =\begin{bmatrix} C_{11} &  C_{11}-2C_{66} &  C_{13} & 0 & 0  & 0 \\ C_{11}-2C_{66} &  C_{11} &  C_{13} & 0 & 0  & 0 \\ C_{13} & C_{13}  &  C_{33} & 0 & 0  & 0 \\ 0 & 0 & 0 & C_{44} & 0  & 0 \\ 0 & 0 & 0 & 0 & C_{44}  & 0 \\ 0 & 0 & 0 & 0 & 0  & C_{66} \end{bmatrix}. $$

The elasticity stiffness matrix $$C_{ij}$$ has 5 independent constants, which are related to well known engineering elastic moduli in the following way. These engineering moduli are experimentally determined.

The compliance matrix (inverse of the elastic stiffness matrix) is

\underline{\underline{\mathsf{C}}}^{-1} = \frac{1}{\Delta} \begin{bmatrix} C_{11} C_{33} - C_{13}^2 & C_{13}^2 - C_{12} C_{33} & (C_{12} - C_{11}) C_{13} & 0 &  0 & 0 \\ C_{13}^2 - C_{12} C_{33} & C_{11} C_{33} - C_{13}^2 & (C_{12} - C_{11}) C_{13} & 0 & 0 & 0 \\ (C_{12} - C_{11}) C_{13} & (C_{12} - C_{11}) C_{13} & C_{11}^2 - C_{12}^2 & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\Delta}{C_{44}} & 0 & 0 \\ 0& 0 & 0 & 0 & \frac{\Delta}{C_{44}} & 0 \\ 0 & 0 & 0 & 0 & 0 & \frac{2 \Delta}{(C_{11}-C_{12})} \end{bmatrix} $$ where $$\Delta := (C_{11} - C_{12}) [(C_{11} + C_{12}) C_{33} -2 C_{13}C_{13}]$$. In engineering notation,

\underline{\underline{\mathsf{C}}}^{-1} = \begin{bmatrix} \tfrac{1}{E_{\rm x}} & - \tfrac{\nu_{\rm yx}}{E_{\rm x}} & - \tfrac{\nu_{\rm zx}}{E_{\rm z}} & 0 & 0 & 0 \\ -\tfrac{\nu_{\rm xy}}{E_{\rm x}} & \tfrac{1}{E_{\rm x}} & - \tfrac{\nu_{\rm zx}}{E_{\rm z}} & 0 & 0 & 0 \\ -\tfrac{\nu_{\rm xz}}{E_{\rm x}} & - \tfrac{\nu_{\rm xz}}{E_{\rm x}} & \tfrac{1}{E_{\rm z}} & 0 & 0 & 0 \\ 0 & 0 & 0 & \tfrac{1}{G_{\rm xz}} & 0 & 0 \\ 0 & 0 & 0 & 0 & \tfrac{1}{G_{\rm xz}} & 0 \\ 0 & 0 & 0 & 0 & 0 & \tfrac{2(1+\nu_{\rm xy})}{E_{\rm x}} \end{bmatrix} $$ Comparing these two forms of the compliance matrix shows us that the longitudinal Young's modulus is given by
 * $$E_L = E_{\rm z} = C_{33}-2C_{13}C_{13}/(C_{11}+C_{12})$$

Similarly, the transverse Young's modulus is
 * $$E_T= E_{\rm x} = E_{\rm y} = (C_{11}-C_{12})(C_{11}C_{33}+C_{12}C_{33}-2C_{13}C_{13})/(C_{11}C_{33}-C_{13}C_{13})$$

The inplane shear modulus is
 * $$G_{xy}=(C_{11}-C_{12})/2=C_{66}$$

and the Poisson's ratio for loading along the polar axis is
 * $$\nu_{LT}=\nu_{zx} = C_{13}/(C_{11}+C_{12})$$.

Here, L represents the longitudinal (polar) direction and T represents the transverse direction.

In geophysics
In geophysics, a common assumption is that the rock formations of the crust are locally polar anisotropic (transversely isotropic); this is the simplest case of geophysical interest. Backus upscaling is often used to determine the effective transversely isotropic elastic constants of layered media for long wavelength seismic waves.

Assumptions that are made in the Backus approximation are:
 * All materials are linearly elastic
 * No sources of intrinsic energy dissipation (e.g. friction)
 * Valid in the infinite wavelength limit, hence good results only if layer thickness is much smaller than wavelength
 * The statistics of distribution of layer elastic properties are stationary, i.e., there is no correlated trend in these properties.

For shorter wavelengths, the behavior of seismic waves is described using the superposition of plane waves. Transversely isotropic media support three types of elastic plane waves: Solutions to wave propagation problems in such media may be constructed from these plane waves, using Fourier synthesis.
 * a quasi-P wave (polarization direction almost equal to propagation direction)
 * a quasi-S wave
 * a S-wave (polarized orthogonal to the quasi-S wave, to the symmetry axis, and to the direction of propagation).

Backus upscaling (long wavelength approximation)
A layered model of homogeneous and isotropic material, can be up-scaled to a transverse isotropic medium, proposed by Backus.

Backus presented an equivalent medium theory, a heterogeneous medium can be replaced by a homogeneous one that predicts wave propagation in the actual medium. Backus showed that layering on a scale much finer than the wavelength has an impact and that a number of isotropic layers can be replaced by a homogeneous transversely isotropic medium that behaves exactly in the same manner as the actual medium under static load in the infinite wavelength limit.

If each layer $$i$$ is described by 5 transversely isotropic parameters $$(a_i, b_i, c_i, d_i, e_i)$$, specifying the matrix
 * $$ \underline{\underline{\mathsf{C}_i}} =\begin{bmatrix}

a_i & a_i - 2e_i & b_i & 0 & 0 & 0 \\ a_i-2e_i &   a_i &   b_i & 0 & 0 & 0 \\ b_i &  b_i  &  c_i &  0 &  0 & 0 \\ 0  &   0  &  0 & d_i & 0 & 0\\ 0  &   0  &  0 & 0 & d_i & 0\\ 0  &   0  &  0 & 0 & 0 & e_i\\ \end{bmatrix} $$ The elastic moduli for the effective medium will be

\underline{\underline{\mathsf{C}_{\mathrm{eff}}}} = \begin{bmatrix} A   & A-2E &  B & 0 & 0 & 0 \\ A-2E  &   A  &  B & 0 & 0 & 0 \\ B   &   B  &  C & 0 & 0 & 0 \\ 0   &   0  &  0 & D & 0 & 0 \\ 0   &   0  &  0 & 0 & D & 0  \\ 0   &   0  &  0 & 0 & 0 & E \end{bmatrix} $$ where

\begin{align} A &= \langle a-b^2c^{-1}\rangle + \langle c^{-1}\rangle^{-1} \langle bc^{-1}\rangle^2 \\ B &= \langle c^{-1}\rangle^{-1} \langle bc^{-1}\rangle \\ C &= \langle c^{-1}\rangle^{-1} \\ D &= \langle d^{-1}\rangle^{-1} \\ E &= \langle e\rangle \\ \end{align} $$

$$\langle \cdot\rangle$$ denotes the volume weighted average over all layers.

This includes isotropic layers, as the layer is isotropic if $$b_i = a_i - 2e_i$$, $$a_i = c_i$$ and $$d_i = e_i$$.

Short and medium wavelength approximation
Solutions to wave propagation problems in linear elastic transversely isotropic media can be constructed by superposing solutions for the quasi-P wave, the quasi S-wave, and a S-wave polarized orthogonal to the quasi S-wave. However, the equations for the angular variation of velocity are algebraically complex and the plane-wave velocities are functions of the propagation angle $$\theta$$ are. The direction dependent wave speeds for elastic waves through the material can be found by using the Christoffel equation and are given by

\begin{align} V_{qP}(\theta)   &= \sqrt{\frac{C_{11} \sin^2(\theta) + C_{33} \cos^2(\theta)+C_{44}+\sqrt{M(\theta)}}{2\rho}} \\ V_{qS}(\theta) &= \sqrt{\frac{C_{11} \sin^2(\theta) + C_{33} \cos^2(\theta)+C_{44}-\sqrt{M(\theta)}}{2\rho}} \\ V_{S}        &= \sqrt{\frac{C_{66} \sin^2(\theta) + C_{44}\cos^2(\theta)}{\rho}} \\ M(\theta)     &= \left[\left(C_{11}-C_{44}\right) \sin^2(\theta) -  \left(C_{33}-C_{44}\right)\cos^2(\theta)\right]^2 + \left(C_{13} + C_{44}\right)^2 \sin^2(2\theta) \\ \end{align} $$ where $$\begin{align}\theta\end{align}$$ is the angle between the axis of symmetry and the wave propagation direction, $$\rho$$ is mass density and the $$C_{ij}$$ are elements of the elastic stiffness matrix. The Thomsen parameters are used to simplify these expressions and make them easier to understand.

Thomsen parameters
Thomsen parameters are dimensionless combinations of elastic moduli that characterize transversely isotropic materials, which are encountered, for example, in geophysics. In terms of the components of the elastic stiffness matrix, these parameters are defined as:

\begin{align} \epsilon & = \frac{C_{11} - C_{33}}{ 2C_{33} } \\ \delta & = \frac{(C_{13} + C_{44})^2-(C_{33} - C_{44})^2}{ 2C_{33}(C_{33} - C_{44}) } \\ \gamma & = \frac{C_{66} - C_{44}}{ 2C_{44} } \end{align} $$ where index 3 indicates the axis of symmetry ($$\mathbf{e}_3$$). These parameters, in conjunction with the associated P wave and S wave velocities, can be used to characterize wave propagation through weakly anisotropic, layered media. Empirically, the Thomsen parameters for most layered rock formations are much lower than 1.

The name refers to Leon Thomsen, professor of geophysics at the University of Houston, who proposed these parameters in his 1986 paper "Weak Elastic Anisotropy".

Simplified expressions for wave velocities
In geophysics the anisotropy in elastic properties is usually weak, in which case $$\delta, \gamma, \epsilon \ll 1$$. When the exact expressions for the wave velocities above are linearized in these small quantities, they simplify to

\begin{align} V_{qP}(\theta) & \approx V_{P0}(1 + \delta \sin^2 \theta \cos^2 \theta + \epsilon \sin^4 \theta) \\ V_{qS}(\theta) & \approx V_{S0}\left[1 + \left(\frac{V_{P0}}{ V_{S0}}\right)^2(\epsilon-\delta) \sin^2 \theta \cos^2 \theta\right] \\ V_{S}(\theta) & \approx V_{S0}(1 + \gamma \sin^2 \theta ) \end{align} $$ where

V_{P0}= \sqrt{C_{33}/\rho} ~; V_{S0}= \sqrt{C_{44}/\rho} $$ are the P and S wave velocities in the direction of the axis of symmetry ($$\mathbf{e}_3$$) (in geophysics, this is usually, but not always, the vertical direction). Note that $$\delta$$ may be further linearized, but this does not lead to further simplification.

The approximate expressions for the wave velocities are simple enough to be physically interpreted, and sufficiently accurate for most geophysical applications. These expressions are also useful in some contexts where the anisotropy is not weak.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: Transverse isotropy


text:
Baianism

Baianism is a term applied to the school of thought of Catholic theologian Michael Baius (1513-1589). Its foremost apologists, Baius among them, largely claimed this school and its teachings to be a return to a sort of Augustinianism, against the reliance on Scholasticism and Scholastic writings which held sway over most Catholic theologians at the time. It is the immediate historical predecessor of Jansenism, and, as with Jansenism, has been deemed heterodox by the Catholic Church.

Michel Baius (Michel de Bay)

Michel de Bay was born at Meslin in Hainaut, the son of Jean de Bay, a farmer. He studied humanities in Brugelette and in Enghien and in 1533 he began studying philosophy at the Old University of Leuven. From 1535 he also studied theology at Pope Adrian VI College. He was ordained a priest in 1542, and was appointed director of the Standonck-College in Leuven. In 1550, De Bay obtained a license in theology and became president of the College Adrian. He also substituted for the professor of Holy Scripture, who was then absent at the Council of Trent.

While Chancellor Ruard Tapper and Josse Ravesteyn, Professor of Theology were at the Council of Trent, Baius and his colleague Jean Hessels took the occasion to introduce new methods and new doctrines. They believed that Catholic apologists were seriously handicapped by their reliance on the authority and methods of the Scholastics, and that if instead of appealing to the writings of St. Thomas as the ultimate criterion of truth they were to insist more on the authority of the Bible and of the works of the Early Fathers, such as St. Cyprian, St. Jerome, and St. Augustine, they would find themselves on much safer ground, and their arguments would be more likely to command the respect of their opponents.

At the request of the Franciscans, the Sorbonne university of Paris censured eighteen propositions embodying the main innovations of Baius and Hessels. Baius answered the censure in a memoir now lost, and the controversy only increased. Pope Pius IV, through Cardinal Granvelle, Archbishop of Mechelen imposed silence upon both Baius and the Franciscans, without, however, rendering any doctrinal decision. In 1561, Baius attended the Council of Trent as a theologian of the King of Spain. Baius returned to Louvain in 1564 and the same year published new tracts. Ravestein, who had succeeded Tapper as chancellor, informed Rome, requesting decisive action. On 1 October 1567, Pope Pius V signed the papal bull "Ex omnibus afflictionibus", in which were to be found a number of condemned propositions, but without mention of Baius' name. Baius kept neutral at first, but when the papal bull (1567) was brought to the university and read to the faculty, he subscribed with the other professors. Baius abjured to Morillon, de Granvelle's vicar general, all the errors condemned in the Bull, but was not then and there required to sign his recantation.

At Leuven, Baius achieved a great name as a leader in the anti-scholastic reaction of the 16th century. The champions of this reaction fought under the banner of Augustine of Hippo though paradoxically undermined Augustine's doctrine of grace; as a result, Baius' heterodox-Augustinian predilections brought him into conflict with Rome on questions of grace, free-will and the like. In 1570, at Ravestein's death, Baius became dean of the faculty. Then rumors went abroad that the new dean was by no means in accord with orthodox teaching. Followers and adversaries suggested a clear pronouncement. It came under the title of the "Explicatio articulorum", in which Baius averred that, of the many condemned propositions, some were false and justly censured, some only ill expressed, while still others, if at variance with the terminology of the Scholastics, were yet the genuine sayings of the Fathers; at any rate, with more than forty of the seventy-nine articles he claimed to have nothing whatever to do. Baius was made Chancellor of Louvain, Dean of St. Peter's Collegiate Church, and "conservator" of the university's privileges. In 1579 Pope Gregory XIII issued the bull, "Provisionis nostræ" confirming the preceding papal decision.

Baianist doctrine
Baius' system is contained in a series of opuscula, or pamphlets: • "On Free Will"

• "Justice and Justification"

• "Sacrifice"

• "Meritorious Works"

• "Man's Original Integrity and the Merits of the Wicked"

• "The Sacraments"

• "The Form of Baptism"

• "Original Sin"

• "Charity"

• "Indulgences"

• "Prayers for the Dead"

Baius himself collected all these pamphlets in M. Baii opuscula theologica (Louvain, 1566). The Maurist monk Gabriel Gerberon gave a more complete edition: M. Baii opera cum bullis pontificum et aliis ad ipsius causum spectantibus (Cologne, 1696). This edition was put on the Index in 1697 on account of its second part, or Baiana, which the censors deemed to show too much sympathy for Baius. The gist of Baianism is also found in the 79 propositions censured by Pius V. The first 60 are easily identified in Baius' printed works, and the remaining 19 – "tales quae vulgo circumferrentur", says an old manuscript copy of the bull "Ex omnibus"– represent the oral teaching of the Baianist wing.

Baius believed in three states of man, which he laid out in the preface to "Man's Original Integrity", writing: "What was in the beginning the integrity natural to man? Without that question one can understand neither the first corruption of nature (by original sin) nor its reparation by the grace of Christ."

(1) State of innocent nature
The writings of the Church Fathers strongly assert the actual conjunction of nature and grace in the first man. From this, Baius inferred a necessary connection between grace and the natural state of man. He believed that primitive innocence was not supernatural, but the natural state of mankind. In this state, Baius believed, the nature of man was to adhere to God through the observance of the commandments and through the gifts of the Holy Spirit.

Baius believed that the primitive state of man necessarily included destination to heaven; immunity from ignorance, suffering, and death; and the inherent power of meriting. He held that these were not gratuitous gifts of grace, but natural to mankind.

(2) State of Fallen Nature
The downfall of man is not, and cannot be, according to Baius, the mere forfeiting of gratuitous or supernatural gifts, but some positive evil reaching deep into our very nature. That evil is original sin. By original sin Baius understands, instead of a simple privation of grace, habitual concupiscence itself, transmitted according to the laws of heredity and developed according to the laws of physical and psychical growth. It is a sin or moral evil by itself, even in irresponsible children, and that outside of all relation to a will, be it original or personal.

Baius considers human liberty unnecessary for moral responsibility; he argues that a moral agent can be bound by internal determinism, as long as there is no external compulsion. He holds that, without Redemption, only tainted actions can proceed from tainted human nature. They may sometimes appear virtuous, but it is only an appearance (vitia virtutes imitantia). In truth all human actions, not purified by Redemption, are vices pure and simple and damning vices at that (vitia sunt et damnant).

(3) State of Redeemed Nature
In Baius's schema, the gifts of primitive innocence, forfeited by original sin, are restored by Jesus Christ. Then and then only do they become graces, not, indeed, on account of their supernatural character, but because of fallen man's positive unworthiness. Aided by grace, the redeemed can perform virtuous actions and acquire merits for heaven. This does not, for Baius, entail a higher status, an inner renovation or sanctifying grace. Moral action, whether called justice, or charity, or obedience to the law, is the sole instrument of justification and virtue and merit. The role of grace consists exclusively in keeping concupiscence under control, and in thus enabling us to perform moral actions and fulfil the law.

Baius speaks of the remission of sin as necessary for justification, but this is only a fictio iuris; in fact, a catechumen before baptism, or a penitent before absolution may, by simply keeping the precepts, have more charity than certain so-called just men. If the catechumen and penitent are not styled just, it is only in deference to Holy Scripture, which requires for complete justice both newness of life (i.e. moral action) and pardon of sin (i.e. of the reatus, or liability to punishment). To grant that kind of pardon is the only object and efficacy of the sacraments of the dead, baptism and penance. With regard to the sacraments of the living, the Eucharist–the only one on which Baius expressed his views–has no other sacrificial value than that of being a good moral action drawing the recipient close to God.

Catholic view
The Catholic teaching, already outlined against the Pelagians by various councils and popes from the fifth century, is fully presented against the Reformers by the Council of Trent, especially Session V, Decree on Original Sin, and Session VI, Decree on Justification. Those two sessions, both anterior to Baius' writings, contain three statements which are obviously irreconcilable with Baius' three main positions described above: (1) Man's original justice is represented as a supernatural gift; (2) Original Sin is described not as a deep deterioration of human nature, but as the forfeiture of purely gratuitous privileges; (3) Justification is depicted as an interior renovation of the soul by inherent grace. A more precise determination of the Catholic doctrine is given in the consensus Catholicorum theologorum. That consensus was voiced with no uncertainty by such universities as Paris, Salamanca, Alcalá and Louvain itself, and by such theologians as Cunerus Petri (d. 1580–"De gratiâ", Cologne, 1583); Suarez (d. 1617–"De gratiâ Dei" in Op. Omn., VII, Paris, 1857); Robert Bellarmine (d. 1623–"De gratiâ et libero arbitrio", in Controversiæ, IV, Milan, 1621); Juan Martínez de Ripalda (d. 1648–"Adversus Baium et Baianos", Paris, 1872); Stayaert (d. 1701–"In propositiones damnatas assertiones", Louvain, 1753); Honoré Tournély (d. 1729–"De Gratiâ Christi", Paris, 1726); Casini (d. 1755–"Quid est homo?" ed. Scheeben, Mainz, 1862).

Influence of Baianism
Even apart from Jansenism, which is a direct offshoot of Baianism, some traces of Baius' ideas about the natural and the supernatural are to be found in the history of theology. The Augustinian School, represented by such men as Henry Noris, Fulgentius Bellelli and Giovanni Lorenzo Berti, adopted, though with qualifications, the idea of man's natural aspiration to the possession of God and beatific vision in Heaven. The standard work of that school, "Vindiciæ Augustinianæ", was even once denounced to the Holy See, but no censure ensued. Later Benedict Stattler, Georg Hermes, Anton Günther, J. B. Hirscher and Johannes von Kuhn evolved a notion of the supernatural which is akin to that of Baius. While admitting relatively supernatural gifts, they denied that the partaking of Divine nature and the adoption to eternal life differ essentially from our natural moral life. That theory was opposed by Kleutgen and seems now to have died out. Matulewicz, "Doctrina Russorum de Statu iustitiæ originalis" (Cracow, 1903), says that modern Russian theology embodies in great measure the views of Baius.

Baianism is a type of Augustinianism that sought to purify Augustinianism from Scholastic mutations that merged it with Aristotle. "But this was condemned as simply a form of Pelagianism where nature was sufficient to itself."

title: Baianism


text:
Wikipedia talk:666,666th pool

This pool is evil

Needless to say, this pool is evil. Now let me make a more evil proposal:

 * The winner marries the 666,666th article's contributor regardless of gender, age, religion, social class, and geological separation.

This pool is so evil. We'll make it truly satanic. (I am worse than Sun Myung Moon, ha!) -- Toytoy 09:56, Apr 8, 2005 (UTC)

 * If I win the pool, I promise to marry the 666,666th article contributor, provided she's female and wants to marry me.   — J I P | Talk 09:49, 8 Apr 2005 (UTC)

 * But what if the winner is the contributor of the 666,666th article?   — J I P | Talk 06:36, 13 Apr 2005 (UTC)

 * Cool, let the winner try: Image:Autofellatio.jpg or Image:Autocunnilingus.jpg. -- Toytoy 09:45, Apr 15, 2005 (UTC)

 * Maybe that's a bit too evil.... Sango  123  23:01, May 22, 2005 (UTC)

 * Well, I DISAGREE. 666 666 is actually a lucky number. -- S iva1979 Talk to me  19:40, 6 July 2006 (UTC)

What will the article be?
I say hexhexhexium, or possibly List of people vanished in the Rapture. Nickptar 18:28, 16 Apr 2005 (UTC)

Can I vote more than once?
Well I'm going to.

--Mark J 19:17, 18 Jun 2005 (UTC)

Close pool now!
It's time to close this pool. Is anyone ready?? Georgia guy 00:23, 19 Jun 2005 (UTC)

 * Close it before people like me sneak in last minute changes! Sango  123  00:29, Jun 19, 2005 (UTC)

Linebreak
I've added a linebreak at the current time. All guesses before it were wrong. Ingoolemo  talk 2005 June 28 05:21 (UTC)

 * I turned it into a double line break to increase its visibility. Sango  123  July 3, 2005 17:43 (UTC)

Stop making articles!
I propose a one-week mortorium on the creation of new articles. There are simply too many already in existence (and it would greatly enhance my odds of winning this pool). Wikipedians may of course continue to edit existing articles. Rast 14:17, July 18, 2005 (UTC)
 * That's just silly! What we really need to do is start deleting more articles -- Joolz 16:13, 18 July 2005 (UTC)

Someone stole my date!
Whattup with User:Kostja picking the same date as me, with no time difference? Bastahdz. —RaD Man (talk) 06:19, 2 August 2005 (UTC)
 * Unless he means 16:49? Kostja?  —RaD Man (talk) 06:24, 2 August 2005 (UTC)
 * He didn't sign it properly, either; "August 8th: Kostja (Talk) 16:49, 8 Aug 2005 (UTC)" seems to indicate that his guess was made six days from today. It doesn't matter, though.  The winner is obviously going to be Angela or (long shot) Neutrality.  And "close" only counts in horseshoes. Rast 15:09, August 2, 2005 (UTC)
 * Then obviously time travel is involved, so he will be the winner. Unless his vote causes the time to change... Nickptar 21:03, 2 August 2005 (UTC)

So who won?
And what was the 666,666th article? :) —RaD Man (talk) 02:26, 4 August 2005 (UTC)
 * No one, yet. We didn't hit it. humblefool®Deletion Reform 04:15, 4 August 2005 (UTC)

 * Holy crap its coming soon. The WikiApocylapse is coming! Better join the church! Redwolf24 04:27, 4 August 2005 (UTC)

What is the 666,666th article? We already hit it. --Jojit fb 06:54, 4 August 2005 (UTC)

For those wanting to relive the moment, I froze it in time. See the image to the right, which anyone can use. Zscout370 (Sound Off) 06:56, 4 August 2005 (UTC)
 * Another user took a better shot, so I am going to delete my image and we could use the one on the main page instead. Zscout370 (Sound Off) 15:22, 4 August 2005 (UTC)

One day out
Ohhh. I was so close. :( Well done Neutrality. Angela. 04:30, August 4, 2005 (UTC)
 * Yes you were! If I may ask, what method(s) did you use to forecast the date, or were you just (almost) lucky?  —RaD Man (talk) 07:08, 4 August 2005 (UTC)
 * Just luck. I guessed August 3 because it was my birthday. :) Angela. 23:34, August 10, 2005 (UTC)
 * You would have won if the deletionists hadn't woken up and started clearing out the VfD backlog! -- Joolz 16:54, 4 August 2005 (UTC)

Exact time of 666,666th article?
What was the exact time of creation of the 666,666th article? Up to one minute. — J I P | Talk 08:00, 4 August 2005 (UTC)
 * Once we figure out what article got it, we go to New Pages and we can get the exact time it was posted. Zscout370 (Sound Off) 08:01, 4 August 2005 (UTC)
 * I hear that 666666 (the original 666,666th article) was deleted pretty much right after its creation. Is it possible to find out the exact time when it was created? Or otherwise, can we find out the 666,667th article (which should now be the 666,666th one)? — J I P | Talk 14:03, 4 August 2005 (UTC)
 * That article was deleted at 06:45, restored at 06:46 and then deleted again at 06:49 ;) -- Joolz 16:50, 4 August 2005 (UTC)

2 Winners?
Wasn't there two winners? Project2501a had as his guess Thursday. I guess technically he was sort of right. Well, I'm going to give Neutrality 99% of the win, and Project2501a can have 1%. Nice work to all who were close. --Lord Voldemort (Dark Mark) 13:50, 4 August 2005 (UTC)

 * I hear Sasquatch might be up for some honors (or stoning). Oh - wait.  I forgot the marriage bit. Ha. Never mind.  --Mothperson cocoon 13:59, 4 August 2005 (UTC)

Sort of right? no fair! It's not my fault that Thurday's suck and there's people trying to kill me, i tell you! and there's a dead man in my house. I demand you do something about it. I'd prefer you do it before the buldozer knocks my house over, please. See, now, I'll have to call the Vogon constructor fleet and a United Confederaship full of Microsoft Laywers! Cabal! Cabal! Rogue admin! Project2501a 15:11, 4 August 2005 (UTC)

 * BWAHAHAHAHAHAHAHAHAHAHAHAHA*

Project2501a 15:11, 4 August 2005 (UTC)

PS: I would take you all out to Millyway's but you have flies in your eyes.

title: Wikipedia talk:666,666th pool