SUSPICIOUS-SOURCE(1) SUSPICIOUS-SOURCE(1) NAME suspicious-source - search for files that are not the GPL's "preferred form of modification" SYNOPSIS suspicious-source [options] DESCRIPTION suspicious-source is a script that outputs a list of files which are not common source files. This should be run in the root of a source tree to find files which might not be the "preferred form of modification" that the GPL and other licenses require. The files inside version control system directories (like .bzr/ or CVS/) are not considered. OPTIONS -h, --help Show this help message and exit. -v, --verbose Print more information. -d directory, --directory=directory Check the files in the specified directory instead of the current directory. -m mimetype, --mimetype=mimetype Add mimetype to list of white-listed MIME types. -e extension, --extension=extension Add extension to list of white-listed extensions. AUTHORS suspicious-source and this manpage have been written by Benjamin Drung<EMAIL_ADDRESS>Both are released under the ISC license. DEBIAN Debian Utilities SUSPICIOUS-SOURCE(1)


Unless said otherwise, opaque objects are ``the same'' in all languages: they carry the same information, and have the same meaning in both languages. The mechanism described in the previous section can be used to pass references to MPI objects from language to language. An object created in one language can be accessed, modified or freed in another language.
We examine below in more detail issues that arise for each type of MPI object.
Datatypes encode the same information in all languages. E.g., a datatype accessor like MPI_TYPE_GET_EXTENT will return the same information in all languages. If a datatype defined in one language is used for a communication call in another language, then the message sent will be identical to the message that would be sent from the first language: the same communication buffer is accessed, and the same representation conversion is performed, if needed. All predefined datatypes can be used in datatype constructors in any language. If a datatype is committed, it can be used for communication in any language.
The function MPI_GET_ADDRESS returns the same value in all languages. Note that we do not require that the constant MPI_BOTTOM have the same value in all languages (see Section Constants ).
Example
! FORTRAN CODE REAL :: R(5) INTEGER :: TYPE, IERR, AOBLEN(1), AOTYPE(1) INTEGER (KIND=MPI_ADDRESS_KIND) :: AODISP(1) ! create an absolute datatype for array R AOBLEN(1) = 5 CALL MPI_GET_ADDRESS( R, AODISP(1), IERR) AOTYPE(1) = MPI_REAL CALL MPI_TYPE_CREATE_STRUCT(1, AOBLEN,AODISP,AOTYPE, TYPE, IERR) CALL C_ROUTINE(TYPE)
/* C code */ void C_ROUTINE(MPI_Fint *ftype) { int count = 5; int lens[2] = {1,1}; MPI_Aint displs[2]; MPI_Datatype types[2], newtype; /* create an absolute datatype for buffer that consists */ /* of count, followed by R(5) */ MPI_Get_address(&count, &displs[0]); displs[1] = 0; types[0] = MPI_INT; types[1] = MPI_Type_f2c(*ftype); MPI_Type_create_struct(2, lens, displs, types, &newtype); MPI_Type_commit(&newtype); MPI_Send(MPI_BOTTOM, 1, newtype, 1, 0, MPI_COMM_WORLD); /* the message sent contains an int count of 5, followed */ /* by the 5 REAL entries of the Fortran array R. */ }
Advice
to implementors.
The following implementation can be used: MPI addresses, as returned by MPI_GET_ADDRESS, will have the same value in all languages. One obvious choice is that MPI addresses be identical to regular addresses. The address is stored in the datatype, when datatypes with absolute addresses are constructed. When a send or receive operation is performed, then addresses stored in a datatype are interpreted as displacements that are all augmented by a base address. This base address is (the address of) buf, or zero, if buf = MPI_BOTTOM. Thus, if MPI_BOTTOM is zero then a send or receive call with buf = MPI_BOTTOM is implemented exactly as a call with a regular buffer argument: in both cases the base address is buf. On the other hand, if MPI_BOTTOM is not zero, then the implementation has to be slightly different. A test is performed to check whether buf = MPI_BOTTOM. If true, then the base address is zero, otherwise it is buf. In particular, if MPI_BOTTOM does not have the same value in Fortran and C, then an additional test for buf = MPI_BOTTOM is needed in at least one of the languages.
It may be desirable to use a value other than zero for
MPI_BOTTOM even in C,
so as to distinguish it from a NULL
pointer.
If MPI_BOTTOM = c then one can still avoid the test
buf = MPI_BOTTOM, by using the displacement from
MPI_BOTTOM, i.e., the regular address - c, as the MPI address
returned by MPI_GET_ADDRESS and stored in absolute datatypes.
( End of advice to implementors.)
MPI calls may associate callback functions with MPI objects: error handlers are associated with communicators and files, attribute copy and delete functions are associated with attribute keys, reduce operations are associated with operation objects, etc. In a multilanguage environment, a function passed in an MPI call in one language may be invoked by an MPI call in another language. MPI implementations must make sure that such invocation will use the calling convention of the language the function is bound to.
Advice
to implementors.
Callback functions need to have a language tag. This tag is set
when the callback function is passed in by the library function (which
is presumably different for each language and language support method),
and is used to generate
the right calling sequence when the callback function is invoked.
( End of advice to implementors.)
Advice to users.
If a subroutine written in one language or Fortran support method wants to
pass a callback routine including the predefined Fortran functions (e.g.,
MPI_COMM_NULL_COPY_FN) to another application routine written in another language
or Fortran support method, then it must be guaranteed that both routines use the callback
interface definition that is defined for the argument when passing the callback to an MPI
routine (e.g., MPI_COMM_CREATE_KEYVAL);
see also the advice to users on page Communicators
.
( End of advice to users.)
Advice
to implementors.
Error handlers, have,
in C, a variable length argument list.
It might be useful to
provide to the handler information on the language environment where
the error occurred.
( End of advice to implementors.)
All predefined named and unnamed datatypes as listed in Section Predefined Reduction Operations can be used in the listed predefined operations independent of the programming language from which the MPI routine is called.
Advice to users.
Reduce operations receive as one of their arguments the datatype of the
operands.
Thus, one can define ``polymorphic'' reduce
operations that work for C and Fortran datatypes.
( End of advice to users.)


RULES
- To start the game click on play
- The first player has to click 'Roll' to initialize the game after getting the value click hold to save/bank the value
- The second player repeats the same while passing the mouse in turns
- The first one to achieve 100 points wins
Player 1:
Dice Roll:
Round Total:
Total Score:
Player 2:
Dice Roll:
Round Total:
Total Score:


@* * Copyright (c) 2018, Salesforce.com, Inc. * All rights reserved. * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause *@ @(message: String) @error {
@message
}


Your State Pension
You can get your State Pension on
£159.55 a week
£691.38 a month, £8,296.60 a year
Your forecast
- is not a guarantee and is based on the current law
- is based on your latest National Insurance record up to
5 April 2017 - does not include any increase due to inflation
- may be different if there are any changes to your National Insurance information - there is more about this in the terms and conditions.
£155.65 is the most you can get
You cannot improve your forecast any more.
You’ll still need to pay National Insurance contributions until
View your National Insurance record
You’ve been in a contracted-out pension scheme
Like most people, you were contracted out of part of the State Pension.


Logo
search
view_module
refresh
more_vert
Select the subject
English
Science
Math
G.K
Social Study
Punjabi
Get Started


Vitro testing is based on human cell and tissue cultures.In vitro studies are conducted using components of an organism that have been isolated from their usual biological surroundings, such as microorganisms, cells, or biological molecules.
Researchers have developed a wide range of sophisticated computer models that simulate human biology and the progression of developing diseases. Studies show that these models can accurately predict the ways that new drugs will react in the human body and replace the use of animals in exploratory research and many standard drug tests.
Volunteers ae also another alternative. Volunteers are alwasya a good option but then again how many people are willing to volunteer.But it's still a good thing but it's still a good thing to have people who care enought about animals to volunteer.


Daniel Fallman, Erik Stolterman
Could be extremely relevant to look over as a means of guiding choices in the project.
rigour, interaction design, design studies
"Interaction design research is a unique discipline embracing practicing professionals, design educators, and academic researchers, but attracting attention from people with different backgrounds and interests has lead to the question of what constitutes ‘good research’. What is rigorous and relevant interaction design research and how do we recognise and evaluate it?"
"Inexperienced researchers and students going into interaction design research tend to find the choice and use of research methods quite overwhelming and difficult."
"Taken together, at least on the surface or as seen from other disciplines, interaction design research seems to lack rigour."
"A substantial amount of effort in interaction design research has been focused on developing new theoretical approaches, methods, tools and techniques intended to support interaction designers in their practice."
"one of the main reasons for having the discussion on rigor and relevance in the first place is the perceived need to establish the field academically while at the same time be practitioner oriented" [credited to Robey and Marcus 1998]
"in...interpretative –qualitative research, the researcher has an active and thus by definition non-objective role in collecting the data and interpreting what is going on in a certain situation"
"For instance, it appears very unlikely that two design researchers would come up with the same outcome even in the improbable case that they are provided exactly equal settings, materials, tools, users, etc. One could even argue that a specific quality and value of design research is its ‘unreliability’ and ‘invalidity’, manifested in creativity, innovation and different ways of seeing. Hence, in some situations, validity and reliability in its traditional sense might not even be desirable." [should raise discussion with Joe on this one]
"Fallman’s (2008) model is a triangle that presents a two-dimensional space for plotting the position of a design research activity drawn up in between three extremes: design practice, design studies and design exploration."
"each of the three forms of research has its own approach, outcomes, methods and internal logic. Rather, when it comes to the question of what constitutes rigorous and relevant research in interaction design, we suggest that the most important difference between the three research forms is that they have different purposes. The purpose of each approach determines what methods and techniques are useful."
"The process of design exploration should open up a critical and creative approach that challenges mainstream assumptions in design...This means that rigour can only be measured in relation to how well the approach does open up a design space and less how that is done.


Desktop notification (in reply to Chris)
In reply to Christian's comment on my last blog entry:
I read the spec right before writing the blog entry, and I basicly followed the discussion on xdg-list earlier.
The spec covers some basics. But from my point of view, the focus of the reference implementation and the spec is wrong.
First of all, your reference implementation is the most important point for now, simply because that's what people see. You could write a perfect spec, people will always check your reference implementation first. So all oddities (really mainly the odds, not the bugs) will affect the acceptance of the spec. My feeling is that Galago is currently trying to catch people with those nice popup effects seen on other operating systems - but I don't follow that project very closely, so I may be wrong here. Still it is a problem for your project if developers (and users) see your project as eye-candy only.
Then, back on topic, the filtering issue. You really want to do filtering on the daemon side, because else if the client would filter events, those would never show up in the event log. And besides that, this is the only way to ensure that all the filter information is managed and stored in a single place. But to be able to allow useful and flexible filtering in the daemon, the client must provide as much data as possible. And in order to allow easy configuration, the client must also provide information about the filter tags.
The spec currently provides two tags for filtering: The notification type id and the urgency level (I'd strongly suggest to provide more than 3 levels by default). The application name is pretty useless, as the spec explicitly states that this should be the formal name rather than a unique id. And formal names are not garantied to be unique and may change over time. The notification type id is a single string and thereby not suitable for non-trivial filtering. E.g. I can only say, that I'd interested to know whenever an IM buddy goes online. I cannot say Tell me when Harry goes online (sure, you could use something weird like im.user.harry.online
, but that's really only a work-around for a limitation in the system). Two criterions are simply not enough to perform useful filtering.
Then, the configuration issue: If you want to do filtering in the daemon (and you really want to do this if you plan to support event logging), then there must be a way for clients to tell the daemon about the different filter tags and the default settings, and at best also an interface to allow clients to change the settings easily. I proposed to use a simple XML file here, installed by every client that supports desktop notification, but that was just a suggestion, you could use any other file format. The file name would somehow include the application's unique id. You would also store thinks like the application icon and the sounds to play for a specific event and such within this file, which allows integration with desktop wide sound themes, etc.
What really bugs me about the spec and the way this is started in GNOME currently is the fact that important issues like filtering get nearly no attention, but instead the focus is on minor details like the appearance (esp. since the spec explicitly states that "applications can generate passive popups", which somehow makes it less suitable for a general desktop notification spec). I'd welcome if people would focus on the important parts first, and don't focus too much on details like how to display the messages (and there should be really more than one way to display notifications, atleast something non-disturbing like an icon in the systray).
Note that these are just my 2 cents. I'm not an expert in desktop notification, nor do I have any time or interested to work on the spec or the implementation (well, maybe an implementation for Xfce, once there's a usable spec, but not this year). So you may disregard my comments silently. But I really strongly recommend to revise the spec, because else I'm pretty sure, this won't be the standard for a long time.


license
"The license
keyword may be used with link
,
a
, area
, and form
elements. This keyword creates a
hyperlink.
The license
keyword indicates that the referenced document
provides the copyright license terms under which the main content of the current document is
provided.
This specification does not specify how to distinguish between the main content of a document and content that is not deemed to be part of that main content. The distinction should be made clear to the user.
Consider a photo sharing site. A page on that site might describe and show a photograph, and the page might be marked up as follows:
<!DOCTYPE HTML>

<title>Exampl Pictures: Kissat</title>
<link rel="stylesheet" href="/style/default">

Kissat

Return to photo index

Kissat

One of them has six toes!

MIT Licensed

Home | Photo index

© copyright 2009 Exampl Pictures. All Rights Reserved.

In this case the license
applies to just the photo (the main
content of the document), not the whole document. In particular not the design of the page
itself, which is covered by the copyright given at the bottom of the document. This could be made
clearer in the styling (e.g. making the license link prominently positioned near the photograph,
while having the page copyright in light small text at the foot of the page).
Synonyms: For historical reasons, user agents must also treat the keyword
"copyright
" like the license
keyword.


Functions that are used to calculate
Calculates the distance between two clusters.
- Parameters
-
| *c1 | Pointer to first cluster |
| *c2 | Pointer to second cluster |
- Precondition
- c1 != NULL
-
c1->size > 0
-
c2 != NULL
-
c2->size > 0
- Returns
- Distance between clusters
| void find_neighbours |
( |
struct cluster_t * |
carr, |
|
|
int |
narr, |
|
|
int * |
c1, |
|
|
int * |
c2 |
|
) |
| |
Finds the two closest clusters.
- Parameters
-
| *carr | Array of clusters where neighbours are to be found |
| narr | Number of elements in *carr |
| *c1 | Pointer to the index where one of the elements has been found |
| *c2 | Pointer to the index where the other element has been found |
- Precondition
- narr > 0
| float obj_distance |
( |
struct obj_t * |
o1, |
|
|
struct obj_t * |
o2 |
|
) |
| |
Calculates the distance between two objects.
- Parameters
-
| *o1 | Pointer to first object |
| *o2 | Pointer to second object |
- Precondition
- o1 != NULL
-
o2 != NULL
- Returns
- Distance between objects


WiPy¶
- Quick reference for the WiPy
- General information about the WiPy
- No floating point support
- Before applying power
- WLAN default behaviour
- Telnet REPL
- Local file system and FTP access
- FileZilla settings
- Upgrading the firmware Over The Air
- Boot modes and safe boot
- The heartbeat LED
- Details on sleep modes
- Additional details for machine.Pin
- Additional details for machine.I2C
- Known issues
- WiPy tutorials and examples


{% extends 'base.html' %} {% block title %}Citing{% endblock %} {% block content %}
Was the Database of Ring Theory useful to you? Please consider acknowledging the resource so that others can find it as well.
If you have a success story about how the site helped you in a publication or otherwise, we would also be appreciative of a notice via the suggestion form!
{% for name, format in styles.items %}{{ format|safe }}{% endfor %}


 In New Zealand alone households throw away 157,389 tonnes of food waste each year, which equals out to about $1.17 billion each year. Most of our food waste comes from either cooking too much food and not eating the leftovers or from food going off in our fridges and freezers.
Our most Wasteful item is Bread with 29 million loaves of bread being thrown away in New Zealand each year. Bread goes mouldy faster than lots of other types of food as well as wasting the crusts as often we don't like to eat them
Food waste is a growing issue, but there are many things that can be done to reduce our food waste. Some very easy things to do to reduce food waste is to start at home compost to compose all those fruits and vegetables that are far past their use by date.


DRUGS AND ALCOHOL POLICY STATEMENT
Vmax Marine Pte Ltd recognises the importance of safeguarding and promoting the
health and safety of its Employees, Client’s Employees, Stakeholders and
Communities who may be affected by our activities. The effective management of drug
and alcohol abuse is an integral part of this.
- It is the policy of the Company:
-
To comply with all current legislation, specifically the Health and Safety at Work
Act 1974, the Misuse of Drugs Act 1971, and the Transport and Works Act 1992.
-
Not to knowingly permit any Employee or any individual working on behalf of the Company
to report for work under the influence of alcohol or drugs, nor to consume them whilst at work.
-
Alcohol and unauthorised drugs are not to be taken or consumed for offshore projects.
-
To take appropriate action, likely to be dismissal or termination of contract and,
in certain circumstances, prosecution against anyone found to be in breach of this policy.
-
The policy is applicable to all Employees regardless of whether they are site or
office based or work in safety critical jobs. The Policy extends to Senior Management,
Contractors and casual staff.


| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When your program has stopped, the first thing you need to know is where it stopped and how it got there.
Each time your program performs a function call, information about the call is generated. That information includes the location of the call in your program, the arguments of the call, and the local variables of the function being called. The information is saved in a block of data called a stack frame. The stack frames are allocated in a region of memory called the call stack.
When your program stops, the GDB commands for examining the stack allow you to see all of this information.
One of the stack frames is selected by GDB and many GDB commands refer implicitly to the selected frame. In particular, whenever you ask GDB for the value of a variable in your program, the value is found in the selected frame. There are special GDB commands to select whichever frame you are interested in. See section Selecting a Frame.
When your program stops, GDB automatically selects the
currently executing frame and describes it briefly, similar to the
frame
command (see section Information about a Frame).
6.1 Stack Frames Stack frames 6.2 Backtraces 6.3 Selecting a Frame Selecting a frame 6.4 Information About a Frame Information on a frame
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The call stack is divided up into contiguous pieces called stack frames, or frames for short; each frame is the data associated with one call to one function. The frame contains the arguments given to the function, the function's local variables, and the address at which the function is executing.
When your program is started, the stack has only one frame, that of the
function main
. This is called the initial frame or the
outermost frame. Each time a function is called, a new frame is
made. Each time a function returns, the frame for that function invocation
is eliminated. If a function is recursive, there can be many frames for
the same function. The frame for the function in which execution is
actually occurring is called the innermost frame. This is the most
recently created of all the stack frames that still exist.
Inside your program, stack frames are identified by their addresses. A stack frame consists of many bytes, each of which has its own address; each kind of computer has a convention for choosing one byte whose address serves as the address of the frame. Usually this address is kept in a register called the frame pointer register (see section $fp) while execution is going on in that frame.
GDB assigns numbers to all existing stack frames, starting with zero for the innermost frame, one for the frame that called it, and so on upward. These numbers do not really exist in your program; they are assigned by GDB to give you a way of designating stack frames in GDB commands.
Some compilers provide a way to compile functions so that they operate without stack frames. (For example, the GCC option
`-fomit-frame-pointer' |
frame args
frame
command allows you to move from one stack frame to another,
and to print the stack frame you select. args may be either the
address of the frame or the stack frame number. Without an argument,
frame
prints the current stack frame.
select-frame
select-frame
command allows you to move from one stack frame
to another without printing the frame. This is the silent version of
frame
.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack.
backtrace
bt
You can stop the backtrace at any time by typing the system interrupt character, normally Ctrl-c.
backtrace n
bt n
backtrace -n
bt -n
backtrace full
bt full
bt full n
bt full -n
The names where
and info stack
(abbreviated info s
)
are additional aliases for backtrace
.
In a multi-threaded program, GDB by default shows the
backtrace only for the current thread. To display the backtrace for
several or all of the threads, use the command thread apply
(see section thread apply). For example, if you type thread
apply all backtrace, GDB will display the backtrace for all
the threads; this is handy when you debug a core dump of a
multi-threaded program.
Each line in the backtrace shows the frame number and the function name.
The program counter value is also shown--unless you use set
print address off
. The backtrace also shows the source file name and
line number, as well as the arguments to the function. The program
counter value is omitted if it is at the beginning of the code for that
line number.
Here is an example of a backtrace. It was made with the command `bt 3', so it shows the innermost three frames.
#0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8) at builtin.c:993 #1 0x6e38 in expand_macro (sym=0x2b600) at macro.c:242 #2 0x6840 in expand_token (obs=0x0, t=177664, td=0xf7fffb08) at macro.c:71 (More stack frames follow...) |
The display for frame zero does not begin with a program counter
value, indicating that your program has stopped at the beginning of the
code for line 993
of builtin.c
.
If your program was compiled with optimizations, some compilers will optimize away arguments passed to functions if those arguments are never used after the call. Such optimizations generate code that passes arguments through registers, but doesn't store those arguments in the stack frame. GDB has no way of displaying such arguments in stack frames other than the innermost one. Here's what such a backtrace might look like:
#0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8) at builtin.c:993 #1 0x6e38 in expand_macro (sym=<value optimized out>) at macro.c:242 #2 0x6840 in expand_token (obs=0x0, t=<value optimized out>, td=0xf7fffb08) at macro.c:71 (More stack frames follow...) |
The values of arguments that were not saved in their stack frames are shown as `<value optimized out>'.
If you need to display the values of such optimized-out arguments, either deduce that from other variables whose values depend on the one you are interested in, or recompile without optimizations.
Most programs have a standard user entry point--a place where system
libraries and startup code transition into user code. For C this is
main
(3).
When GDB finds the entry function in a backtrace
it will terminate the backtrace, to avoid tracing into highly
system-specific (and generally uninteresting) code.
If you need to examine the startup code, or limit the number of levels in a backtrace, you can change this behavior:
set backtrace past-main
set backtrace past-main on
set backtrace past-main off
show backtrace past-main
set backtrace past-entry
set backtrace past-entry on
main
(or equivalent) is called.
set backtrace past-entry off
show backtrace past-entry
set backtrace limit n
set backtrace limit 0
show backtrace limit
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Most commands for examining the stack and other data in your program work on whichever stack frame is selected at the moment. Here are the commands for selecting a stack frame; all of them finish by printing a brief description of the stack frame just selected.
frame n
f n
main
.
frame addr
f addr
On the SPARC architecture, frame
needs two addresses to
select an arbitrary frame: a frame pointer and a stack pointer.
On the MIPS and Alpha architecture, it needs two addresses: a stack pointer and a program counter.
On the 29k architecture, it needs three addresses: a register stack pointer, a program counter, and a memory stack pointer.
up n
down n
down
as do
.
All of these commands end by printing two lines of output describing the frame. The first line shows the frame number, the function name, the arguments, and the source file and line number of execution in that frame. The second line shows the text of that source line.
For example:
(gdb) up #1 0x22f0 in main (argc=1, argv=0xf7fffbf4, env=0xf7fffbfc) at env.c:10 10 read_input_file (argv[i]); |
After such a printout, the list
command with no arguments
prints ten lines centered on the point of execution in the frame.
You can also edit the program at the point of execution with your favorite
editing program by typing edit
.
See section Printing Source Lines,
for details.
up-silently n
down-silently n
up
and down
,
respectively; they differ in that they do their work silently, without
causing display of the new frame. They are intended primarily for use
in GDB command scripts, where the output might be unnecessary and
distracting.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are several other commands to print information about the selected stack frame.
frame
f
f
. With an
argument, this command is used to select a stack frame.
See section Selecting a Frame.
info frame
info f
The verbose description is useful when something has gone wrong that has made the stack format fail to fit the usual conventions.
info frame addr
info f addr
frame
command.
See section Selecting a Frame.
info args
info locals
info catch
up
,
down
, or frame
commands); then type info catch
.
See section Setting Catchpoints.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Please send FSF & GNU inquiries & questions to<EMAIL_ADDRESS>There are also other ways to contact the FSF.
These pages are maintained by the GDB developers.
Copyright Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.
This document was generated by GDB Administrator on March, 27 2008 using texi2html


'Absence of Malice'
A retrospective movie review by Walter Frith
The first amendment of the U.S. constitution guarantees freedom of the press. Many feel that with freedom comes responsibility and the media is often irresponsible in many of the stories it covers. A half a million people died through butchering in only six months in the tiny African nation of Rwanda. Yet the silly O.J. Simpson story which was in the public eye at the same time got more coverage overall in the press than the Rwanda situation did. People will say that the media was just giving people what they wanted but is this entirely true? '60 Minutes' continues to be a top ten show and managed to remain in the top 10 when a large number of the 1997 World Series games bumped many popular shows out of the top 10 that week. The success of '60 Minutes' is due largely in part to its responsible and original programming of issues that don't necessarily make the front page in other mainstream media. '60 Minutes' refused to cover any of the O.J. saga. It continues to be a respected and entertaining show.
I had a friend (more of an acquaintance, actually) who believed that 'Raiders of the Lost Ark' was such a great movie that it deserved an Oscar nomination for its writing. I'm not taking anything away from 'Raiders' but as great a film as it was, it was hardly a stupendously written film. It was an update of those Saturday afternoon serials people used to go to the movies and see in the 1930's. A grade 'A' film with a 'B' movie script. So, because of that, the Academy decided to go with five other original screenplays, 'Arthur', 'Atlantic City', 'Chariots of Fire'(the winner), 'Reds' and 'Absence of Malice'.
Set in Miami, the film told the story of a businessman (Paul Newman) who was implicated by a local newspaper in some illegal dealings. The reporter in charge of the story (Sally Field) is being tricked by a government bureaucrat into printing the false story about Newman. She hides behind her paper's legal department and the first amendment. Newman comes looking for her and his confrontation is also with the paper's editors and attorneys. Secretly, he plots to get even with those who have slandered him.
The story also focuses on Newman's relationship with his sister (Melinda Dillon) who lives in a convent and she is extremely repressed. Through constant meetings with Field, Newman states the moral position the media should take in reporting the truth and not speculation. One scene has the two of them on Newman's boat just a few miles off shore and Newman tells her the reason he wanted to meet like this is because he didn't want to meet in a place like a restaurant where she could easily get up and walk out. He also says at one point in the film he will tell her the truth about his business dealings if she wants to know as a "person" and not as a "reporter".
The film is directed splendidly by Sydney Pollack who captures a sense of simplicity in dealing with a complex issue and the Oscar nominated screenplay by Kurt Luedtke is filled with moral examinations and a climax set where an investigation of the paper's practices come under scrutiny. 'Absence of Malice' isn't just about media ethics, it's about observing how one man's life can be turned upside down by the press and remembering that none of us are immune from it.
Visit FILM FOLLOW-UP by Walter Frith at: http://home.netinc.ca/~wfrith/movies.htm
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Back to Synopsis of Joy, a functional language
Abstract: Joy is a high-level purely functional programming language which is not based on the application of functions but on the composition of functions. This paper gives a rationale for Joy by contrasting it with with other paradigms of functional languages. Joy differs from lambda calculus languages in that it has no variables and hence no abstraction. It differs from the combinatory calculus in that it does not use application. It differs from the categorical languages in uniformly using an untyped stack as the argument and value of the composed functions. One of the datatypes is that of programs, and the language makes extensive use of this, more than other reflective languages. The paper gives practical and theoretical introductions to various aspects of the language.
Keywords: lambda calculus, combinatory logic, lambda abstraction, function application, function composition, postfix notation
Joy is an attempt to design a high level programming language which is based on a computational paradigm that is different from the three paradigms on which existing functional languages are based. Two of these paradigms have been criticised in the literature, and Joy aims to overcome the complexity of the third by a simpler mechanism.
The remainder of this paper is organised as follows. The next two section of the paper assume some familiarity with three paradigms: the lambda calculus, combinatory calculus and, to a lesser extent, the basic notions of category theory. The purpose of these sections is to contrast Joy with these paradigms and to motivate the departure. The other sections are very specific to Joy and hence mostly self-contained. One section is a short tutorial introduction, another a discussion of theoretical aspects. The concluding section gives a more detached perspective.
All natural languages and most artificial languages contain as a component
a (..x..)
is an expression containing a variable,
then its lambda abstraction is generally written $\lambda$x(..x..)
and pronounced
"the function of one parameter x
which yields the result
(..x..)
".
The other construction is application, written in infix:
if f
is a function, then f @ x
is the result of applying the function to x
.
Functions of several parameters are still a nuisance because
one has to write g @
and h @
and so on.
There is a useful device called @
symbol is simply left out.
The notation makes the expression
+ 2 3potentially ambiguous. On one reading it is a prefix expression, entirely equivalent to the infix
2 + 3
or the postfix
2 3 +
, with +
as the binary operator and the two
numerals as operands. On another reading it is a nested infix
expression with binary application suppressed between the two
numerals as the main operator and a similar subordinate
suppressed operator between the curried +
and the 2
.
In practice there is no confusion because the context
disambiguates, particularly in nested expressions.
Prefix never needs parentheses,
that is why it was invented by Polish logicians.
Applicative notation needs parentheses in more complex expressions,
see section 3.
Syntax aside, there is a world of difference in the semantics between
prefix and applicative notation.
A similar ambiguity will arise later.
(As yet another applicative notation,
to eliminate parentheses completely,
Quine in his foreword to the
Sch\"{o}nfinkel (1924) reprint
suggested using prefix for application,
thus: @fx
, @@gxy
and so on.)
The lambda calculus is an immensely powerful system. It comes as a surprise that it is Turing complete, that all computable functions can be expressed in the lambda calculus with just variables, abstraction and application, and can then be computed by reduction. Even numbers can be represented, as Church numerals, and similarly for lists. However, any efficient implementation will need constants, and all practical programming languages based on the lambda calculus provide them. This includes the older language Lisp and its descendants, based on the untyped lambda calculus, and also the newer languages ML % ML, Miranda\footnote{ % "Miranda" is a trademark of Research Software Ltd.} and Haskell, based on a typed lambda calculus with parametric polymorphism. Central to all of them are the lambda calculus operations of abstraction and application.
The lambda calculus is a purely syntactic calculus, and its rules have to do with simplifying expressions. The few rules are deceptively simple but are in fact difficult to use correctly in real examples. The main difficulty arises from the variables which get in each other's way. Their purpose is to steer arguments into the right position. Can one do without variables, to make things easier for people or for computers, and still steer arguments into the right position? Brus et al (1987 p 364) write "if one wants to have a computational model for functional languages which is also close to their implementations, pure lambda calculus is not the obvious choice anymore".
One alternative is S
and K
can be used to define all other combinators one might
desire,
or even on their own to eliminate variables and hence lambda abstractions
lambda x (..x..)
.
Even recursion can be handled with the "paradoxical" S
and K
.
A similar y
combinator in Joy is discussed in section 5.
Y
and y
cannot be given a finite type,
so they are not definable in typed languages.
Joy, like Lisp, is untyped, hence it requires runtime checks.
So we can do without abstraction but with application together
with first and higher order functions.
The resultant system is simpler,
but because it is so low level,
it has never been proposed as a programming language.
However it did inspire
Backus (1978)
in his Turing award lecture
where he introduced his
Like the various lambda calculus languages,
the low level combinatory calculus and the higher level language
FP still use f = g
and x = y
then f @ x = g @ y
.
But the substitutivity property is shared with all other functions.
Meertens later (p 72) speaks of
"the need of a suitable system of combinators
for making functions out of component functions
without introducing extra names in the process.
Composition should be the major method, and not application."
This is in fact done in category theory
for the (concrete) category of functions,
their compositions and their types.
Like Backus, Meertens develops a system of combining functions
that is more suitable to formal manipulation
than the classical combinators.
Consider a long expression, here again written explicitly with
the application operator @
.
Note the need for parentheses.
square @ (first @ (rest @ (reverse @ [1 2 3 4]))) --> 9All the functions are unary, and unary functions can be composed. The
"."
.
The composition can be applied to the original list:
(square . first . rest . reverse) @ [1 2 3 4] --> 9One might even introduce definitions in the style of the first line, and then write as in the second line:
second = first . rest second-last = second . reverse (square . second-last) @ [1 2 3 4] --> 9This and also the preceding definitions would not make sense with application instead of composition. Importantly, a definition can be used to textually replace the definiendum by its definiens to obtain the original long composition expression. This is because the textual operation of compounding several expressions to make a larger one is mapped onto the semantic operation of composing the functions denoted by the expressions. The textual replacement is not possible in the original applicative expression because the parentheses get in the way.
Substitutivity is a highly desirable property for algebraic manipulation.
The only trouble is that the resultant composition expression
still has to be applied to an argument,
the list [1 2 3 4]
.
If we could elevate that list to the status of a function,
we could eliminate application entirely from the expression
and write
square . first . rest . reverse . [1 2 3 4] --> 9The numeral
9
would also need to denote a function.
Can this be done?
Indeed it can be.
We just let numerals and list constants denote functions
which take a fixed dummy argument, written ?
,
as argument and return a number or a list as value.
So we should now write
(square . first . rest . reverse . [1 2 3 4]) @ ? --> 9 @ ?We just have to pretend that
@ ?
is not there,
that everything is a function anyhow.
The dummy argument device is routinely used in
the category of functions,
and the pretense is argued to be a superior view.
All this works well with unary functions, but how is one to deal
with functions of several arguments?
In category theory there is the notion of products,
and in the category of functions it is a way of dealing
with interrelated car
and cdr
in Lisp).
Pairs would seem to be the obvious way to handle binary functions.
But this reintroduces pairs (of functions)
whereas in the lambda calculus pairs (of arguments)
were so elegantly eliminated by currying.
In category theory there is also the notion of exponentials,
and in the category of functions they are a way of dealing
with the interrelation between the type of functions,
the type of their arguments and the type of values.
Two important functions are needed:
explicit currying and explicit application (apply
in Lisp).
This makes such
Barr and Wells (1990 Chapter 6) give an example of a simple lambda expression with variables contrasted with first a complicated looking and then a reformulated categorical equivalent formula. Here the steering of arguments into the right place is essentialy done by the projection functions. Category theory has given rise to another model of computation: the CAM or Categorical Abstract Machine, described for example in Cousineau et al (1987). The machine language of the CAM is very elegant, but programs in that language look as inscrutable as low level programs in other machine languages. The language is of course suitable as the target language for compilation from any functional language. For more recent references, including to exciting hardware applications, see Hains and Foisy (1993).
Many categorical concepts have been successfully used
in otherwise applicative languages,
such as the polymorphically typed Haskell, see the recent
Bird and de Moor (1997)
for the now mature theory and for many references.
Compact "pointfree" definitions in the style of second-last
above
are used routinely,
but many need additional operators, even application,
for example (p 10):
length = sum . listr one where one a = 1Note the implicit application between
listr
and one
and again between one
and a
in the local where
definition.
The whole definition may be read as:
to compute the length of a list,
let one
be the function which ignores its argument (a
)
and always returns 1
, use this function to map (= listr
)
the given list to produce a list of just 1
s,
then take the sum of those.
At least for handling functions of several arguments categorical concepts are rather heavy artillery. Are there other ways? Consider again the runnning example. Written in plain prefix notation it needs no parentheses at all:
square first rest reverse [1 2 3 4] --> 9An expression with binary operators such as the infix expression
((6 - 4) * 3) + 2
is written in prefix notation also without parentheses as
+ * - 6 4 3 2 --> 8(Note in passing that the four consecutive numerals look suspiciously like a list of numbers.) We now have to make sense of the corresponding compositional notation
(+ . * . - . 6 . 4 . 3 . 2) @ ? --> 8 @ ?Clearly the "
2
-function" is applied to the dummy argument.
But the other "number functions" also have to be applied to something,
and each value produced has to be retained for pairwise consumption
by the binary operators.
The order of consumption is the reverse of the order
of production.
So there must be a stack of intermediate values which first grows
and later shrinks.
The dummy argument ?
is just an empty stack.
What we have gained is this:
The expression denotes a composition of unary square
or reverse
denote functions which expect as argument a stack whose top element
is a number or a list.
They return the same stack except that the top element has been replaced by
its square or its reversal.
Symbols for what are normally binary operations
also denote unary functions from stacks to stacks
except that they replace the top two elements by a new single one.
It is helpful to reverse the notation
so that compositions are written in the order of their evaluation.
A more compelling reason is given in the next section.
This still only has composition as a second order stack function. Others are easy enough to introduce, using a variety of possible notations. But now we are exactly where we were at the beginning of section 2: The next level, third order stack functions, calls for a lambda calculus with variables ranging over first order stack functions. The variables can be eliminated by translating into a lean or rich combinatory calculus. Application can be eliminated by substituting composition of second order stack functions, and so on. This cycle must be avoided. (But maybe the levels can be collapsed by something resembling reducibility in Russell's theory of types?)
In reflective languages such as Lisp, Snobol and Prolog,
in which program = data, it is easier to write
interpreters, compilers, optimisers and theorem provers
than in non-reflective languages.
It is straightforward to define higher order
functions, including the Y
combinator.
Backus (1978)
also introduces another language, the reflective
Y
combinator.
A mechanism similar to metacomposition is possible in Joy,
see section 6.
Joy is also reflective. As noted in passing earlier, expressions which denote compositions of stack functions which push a value already look like lists. Joy extends this to arbitrary expressions. These are now called quotations and can be manipulated by list operations. The effect of higher order functions is obtained by first order functions which take such quotations as parameters.
To add two integers, say 2 and 3, and to write their sum, you type the program
2 3 +This is how it works internally: the first numeral causes the integer 2 to be pushed onto a stack. The second numeral causes the integer 3 to be pushed on top of that. Then the addition operator pops the two integers off the stack and pushes their sum, 5. In the default mode there is no need for an explicit output instruction, so the numeral
5
is now written to the output file which
normally is the screen.
Joy has the usual arithmetic operators for integers,
and also two other
The example expression above is potentially ambiguous.
On one reading it is a postfix expression, equivalent to
prefix or infix, with binary +
as the main operator.
On another reading it is a nested infix expression,
with either of the two suppressed composition operators
as the main operator.
In practice there is no confusion,
but there is a world of difference in the semantics.
To compute the square of an integer, it has to be multiplied by itself. To compute the square of the sum of two integers, the sum has to be multiplied by itself. Preferably this should be done without computing the sum twice. The following is a program to compute the square of the sum of 2 and 3:
2 3 + dup *After the sum of 2 and 3 has been computed, the stack just contains the integer 5. The
dup
operator then pushes another copy of the 5
onto the stack.
Then the multiplication operator replaces the two integers by their product,
which is the square of 5.
The square is then written out as 25.
Apart from the dup
operator
there are several others for re-arranging the top of the stack.
The pop
operator removes the top element,
and the swap
operator interchanges the top two elements.
These operators do not make sense in true postfix notation,
so Joy uses the second reading of the ambiguous expression mentioned above.
A list of integers is written inside square brackets.
Just as integers can be added and otherwise manipulated,
so lists can be manipulated in various ways.
The following concat
enates two lists:
[1 2 3] [4 5 6 7] concatThe two lists are first pushed onto the stack. Then the
concat
operator pops them off the stack
and pushes the list [1 2 3 4 5 6 7]
onto the stack.
There it may be further manipulated or it may be written
to the output file.
Other list operators are first
and rest
for extracting parts of lists.
Another is cons
for adding a single element,
for example 2 [3 4] cons
yields [2 3 4]
.
Since concat
and cons
are not commutative,
it is often useful to use swoncat
and swons
which conceptually perform a swap
first.
Lisp programmers should note that there is no notion of dotted pairs
in Joy.
Lists are the most important
Joy makes extensive use of map
ping
elements of one list via a function to another list.
Consider the program
[1 2 3 4] [dup *] mapIt first pushes the list of integers and then the quoted program onto the stack. The
map
combinator then removes the list
and the quotation and constructs another list
by applying the program to each member of the given list.
The result is the list [1 4 9 16]
which is left on top of the stack.
The map
combinator also works for strings and sets.
Similarly, there are a filter
and a fold
combinator,
both for any aggregate.
The simplest combinator is i
(for 'interpret').
The quotation parameter [dup *]
of the map
example
can be used by the i
combinator to square a single number.
So [dup *] i
does exactly the same as just dup *
.
Hence i
undoes what quotation did, it is a dequotation
operator, just like eval
in Lisp.
All other combinators are also dequotation operators.
But now consider the program 1 2 3
and its quotation [1 2 3]
.
The program pushes three numbers, and the quotation is just a list literal.
Feeding the list or quotation to i
pushes the three numbers.
So we can see that lists are just a special case of quotations.
The familiar list operators can be used for quotations with good effect.
For example, the quotation [* +]
, if dequoted by a combinator,
expects three parameters on top of the stack.
The program 10 [* +] cons
produces the quotation [10 * +]
which when dequoted expects only two parameters because it supplies
one itself.
The effect is similar to what happens in the lambda calculus
when a curried function of three arguments is applied to one
argument.
As mentioned earlier,
a similar explicit application operation is available in FFP.
The device of
Combinators can take several quotation parameters.
For example the ifte
or if-then-else combinator
expects three in addition to whatever data parameters it needs.
Third from the top is an if-part.
If its execution yields truth,
then the then-part is executed, which is second from the top.
Otherwise the else-part on top is executed.
The order was chosen because
in most cases the three parts will be pushed just before
ifte
executes.
For example, the following yields the absolute value of an integer,
note the empty else-part.
[0 <] [0 swap -] [] ifte
Sometimes it is necessary to affect the elements just below the top element.
This might be to add or swap the second and third element,
to apply a unary operator to just the second element,
or to push a new item on whatever stack is left below
the top element.
The dip
combinator expects a quotation
parameter (which it will consume),
and below that one more element.
It saves that element away, executes the quotation on whatever
of the stack is left, and then restores the saved element.
So 2 3 4 [+] dip
is the same as 5 4
.
This single combinator was inspired by several
special purpose optimising combinators S'
, B'
and C'
in the combinatory calculus, see
Peyton Jones (1987, sections 16.2.5 and 16.2.6).
The stack is normally just a list, but even operators and
combinators can get onto it by e.g. [swap] first
.
Since the stack is the memory,
in Joy program = data = memory.
The stack can be pushed as a quotation onto the stack by stack
,
a quotation can be turned into the stack by unstack
.
A list on the stack, such as [1 2 3 4]
can be treated
temporarily as the stack by a quotation, say [+ *]
and the combinator infra
,
with the result [9 4]
.
In ==
symbol, and then a program.
After the first definition below,
the symbol square
can be used in place of dup *
.
square == dup * size == [pop 1] map sumThe second definition is the counterpart of the definition of
length
in
Bird and de Moor (1997 p 10)
mentioned in the previous section,
except that it is called size
because it also applies to sets.
(Note that no local definition of one
is needed.)
As in other programming languages,
definitions may be recursive,
but the effect of recursion can be obtained by other means.
Joy has several combinators which make recursive execution of programs
more succinct.
One of these is the genrec
combinator
which takes four program parameters
in addition to whatever data parameters it needs.
Fourth from the top is an if-part, followed by a then-part.
If the if-part yields true
,
then the then-part is executed and the combinator terminates.
The other two parameters are the rec1-part and the rec2part.
If the if-part yields false
,
the rec1-part is executed.
Following that the four program parameters and the combinator
are again pushed onto the stack bundled up in a quoted form.
Then the rec2-part is executed,
where it will find the bundled form.
Typically it will then execute the bundled form,
either with i
or with app2
,
or some other combinator.
The following pieces of code,
without any definitions,
compute the factorial,
the (naive) Fibonacci and quicksort.
The four parts are here aligned to make comparisons easier.
[null ] [succ] [dup pred ] [i * ] genrec [small] [ ] [pred dup pred ] [app2 + ] genrec [small] [ ] [uncons [>] split] [app2 swapd cons concat] genrecThe overloaded unary predicate
null
returns
true
for 0
and for empty aggregates.
Similarly small
returns true
for integers
less than 2
and for aggregates of less than two members.
The unary operators succ
and pred
return the successor and predecessor of integers or characters.
The aggregate operator uncons
returns two values,
it undoes what cons
does.
The aggregate combinator split
is like filter
but it returns two aggregates,
containing respectively those elements that did or did not pass
the test.
The app2
combinator applies the same quotation to
two elements below and returns two results.
The swapd
operator is an example of having
to shuffle some elements but leaving the topmost element intact.
This operator swaps the second and third element,
it is defined as [swap] dip
.
Of course the factorial and Fibonacci
functions can also be computed more efficiently in Joy using
accumulating parameters.
Two other general recursion combinators are linrec
and binrec
for computing
genrec
, except that the recursion occurs
automatically between the rec1-part and the rec2-part.
The following is a small program
which takes one sequence as parameter
and returns the list of all "abcd"
,
the heterogeneous list [foo 7 'A "hello"]
or the quotation [[1 2 3] [dup *] map reverse]
it will produce the list of 24 permutation strings or lists or quotations.
1 [ small ] 2 [ unitlist ] 3 [ uncons ] 4.1 [ swap 4.2.1 [ swons <IP_ADDRESS> [ small ] <IP_ADDRESS> [ unitlist ] <IP_ADDRESS> [ dup unswons [uncons] dip swons ] <IP_ADDRESS> [ swap [swons] cons map cons ] <IP_ADDRESS> linrec ] 4.3 cons map 4.4 [null] [] [uncons] [concat] linrec ] 5 linrec.
The unitlist
operator might have been defined as
[] cons
.
The unswons
operator undoes what swons
does,
and it might have been defined as uncons swap
.
An essentially identical program is in the Joy library
under the name permlist
.
It is considerably shorter than the one given here
because it uses two subsidiary programs
which are useful elsewhere.
One of these is insertlist
(essentially 4.2)
which takes a sequence and a further potential new member
as parameter and produces the list of all sequences
obtained by inserting the new member once in all possible
positions.
The other is flatten
(essentially 4.4)
which takes a list of sequences and concatenates
them to produce a single sequence.
The program given above is an example
of a non-trivial program which uses
the linrec
combinator three times
and the map
combinator twice,
with insertlist
and flatten
can be written in any lambda calculus notation.
But in Joy, as in other pointfree notations,
no local definitions are needed,
one simply takes the bodies of the
definitions and inserts them textually.
The semantics of Joy can be expressed by two functions
EvP
and Eva
,
whose types are:
EvP : PROGRAM * STACK -> STACK (evaluate concatenated program) EvA : ATOM * STACK -> STACK (evaluate atomic program)In the following a Prolog-like syntax is used (but without the comma separator): If
R
is a (possibly empty) program or list or stack, then
[F S T | R]
is the program or list or stack
whose first, second and third elements
are F
, S
and T
, and whose remainder is R
.
The first two equations express that programs
are evaluated sequentially from left to right.
EvP( [] , S) = S EvP( [A | P] , S) = EvP( P , EvA(A, S))The remaining equations concern atomic programs. This small selection is restricted to those literals, operators and combinators that were mentioned in the paper. The exposition also ignores the data types character, string and set.
(Push literals:) EvA( numeral , S) = [number | S] (e.g. 7 42 -123 ) EvA( true , S) = [true | S] (ditto "false") EvA( [..] , S) = [[..] | S] ([..] is a list or quotation) (Stack editing operators:) EvA( dup , [X | S]) = [X X | S] EvA( swap , [X Y | S]) = [Y X | S] EvA( pop , [X | S]) = S EvA( stack , S ) = [S | S] EvA(unstack, [L | S]) = L (L is a quotation of list) (Numeric and Boolean operators and predicates:) EvA( + , [n1 n2 | S]) = [n | S] where n = (n2 + n1) EvA( - , [n1 n2 | S]) = [n | S] where n = (n2 - n1) EvA( succ, [n1 | S]) = [n | S] where n = (n1 + 1) EvA( < , [n1 n2 | S]) = [b | S] where b = (n2 < n1) EvA( and , [b1 b2 | S]) = [b | S] where b = (b2 and b1) EvA( null, [n | S]) = [b | S] where b = (n = 0) EvA(small, [n | S]) = [b | S] where b = (n < 2) (List operators and predicates:) EvA( cons , [ R F | S]) = [[F | R] | S] EvA( first , [[F | R] | S]) = [F | S] EvA( rest , [[F | R] | S]) = [ R | S] EvA( swons , [ F R | S]) = [[F | R] | S] EvA( uncons, [[F | R] | S]) = [R F | S] EvA( null , [L | S]) = [b | S] where b = (L is empty) Eva( small , [L | S]) = [b | S] where b = (L has < 2 members) (Combinators:) Eva( i , [Q | S]) = EvP(Q, S) EvA( x , [Q | S]) = EvP(Q, [Q | S]) EvA( dip , [Q X | S]) = [X | T] where EvP(Q, S) = T EvA(infra, [Q X | S]) = [Y | S] where EvP(Q, X) = Y EvA( ifte, [E T I | S]) = if EvP(I, S) = [true | U] (free U is arbitrary) then EvP(T, S) else EvP(E, S) EvA( app2, [Q X1 X2 | S]) = [Y1 Y2 | S] where EvP(Q, [X1 | S]) = [Y1 | U1] (U1 is arbitrary) and EvP(Q, [X2 | S]) = [Y2 | U2] (U2 is arbitrary) EvA( map , [Q [] | S]) = [[] | S] EvA( map , [Q [F1 | R1] | S]) = [[F2 | R2] | S] where EvP(Q, [F1 | S]) = [F2 | U1] and EvA( map, [Q R1 | S]) = [R2 | U2] EvA( split , [Q [] | S]) = [[] [] | S] EvA( split , [Q [X | L] | S] = (if EvP(Q, [X | S]) = [true | U] then [FL [X | TL] | S] else [[X | FL] TL | S]) where EvA( split, [Q L | S]) = [TL FL | S] EvA( genrec , [R2 R1 T I | S]) = if EvP(I, S) = [true | U] then EvP(T, S) else EvP(R2, [[I T R1 R2 genrec] | W]) where EvP(R1, S) = W EvA( linrec, [R2 R1 T I | S]) = if EvP(I, S) = [true | U] then EvP(T , S) else EvP(R2, EvA(linrec, [R2 R1 I T | W])) where EvP(R1, S) = W EvA( binrec, [R2 R1 T I | S]) = if EvP(I, S) = [true | U] then EvP(T, S) else EvP(R2, [Y1 Y2 | V]) where EvP(R1, S) = [X1 X2 | V] and EvA(binrec, [R2 R1 T I X1 | V]) = [Y1 | U1] and EvA(binrec, [R2 R1 T I X2 | V]) = [Y2 | U2]
In any functional language expressions can be evaluated by
stepwise rewriting.
In primary school we did this with arithmetic expressions
which became shorter with every step.
We were not aware that the linear form really represents a tree.
The lambda calculus has more complicated rules.
The beta rule handles the application of abstractions to arguments,
and this requires possibly multiple substitutions of the same argument
expression for the multiple occurrences of the same variable.
Again the linear form represents a tree, so the rules
transform trees.
The explicit substitution can be avoided by using an
environment of name-value pairs,
as is done in many implementations.
In the combinatory calculus there is a tree rule for
each of the combinators.
The S
combinator produces duplicate subtrees,
but this can be avoided by sharing the subtree.
Sharing turns the tree into a directed acyclic graph,
but it gives lazy evaluation for free, see
Peyton Jones (1987, Chapter 15).
Rewriting in any of the above typically allows different ordering
of the steps.
If there are lengthening rules,
then using the wrong order may not terminate.
Apart from that there is always the question of efficiently
finding the next reducible subexpression.
One strategy, already used in primary school,
involved searching from the beginning at every step.
This can be used in prefix, infix and postfix
forms of expression trees,
and in the latter form the search can be eliminated entirely.
Postfix ("John Mary loves") is used in ancient Sanscrit
and its descendants such as modern Tibetan,
in subordinate clauses in many European languages,
and, would you believe, in the Startrek language Klingon.
Its advantage in eliminating parentheses entirely
has been known ever since Polish logicians
used prefix for that same purpose.
It can be given an alternative reading as an infix
expression denoting the compositions of unary functions.
Such expressions can be efficiently evaluated on a stack.
For that reason it is frequently used by compilers as
an internal language.
The imperative programming language Forth
and the typesetting language Postscript are
often said to be in postfix,
but that is only correct for a small fragment.
In the following example the lines are doubly labelled,
lines a)
to f)
represent the stack growing to the right
followed by the remainder of the program.
The latter now has to be read as a sequence of instructions,
or equivalently as denoting the composition
of unary stack functions.
1 a) 2 3 + 4 * b) 2 3 + 4 * c) 2 3 + 4 * 2 d) 5 4 * e) 5 4 * 3 f) 20If we ignore the gap between the stack and the expression, then lines
a)
to c)
are identical,
and lines d)
and e)
are also identical.
So, while the stack is essential for the semantics
and at least useful for an efficient implementation,
it can be completely ignored in a rewriting system
which only needs the three numbered steps.
Such a rewriting needs obvious axioms for each operator.
But it also needs a rule.
Program concatenation and function composition
are associative and have a (left and right) unit element,
the empty program and the identity function.
Hence meaning maps a syntactic monoid into a semantic monoid.
Concatenation of Joy programs denote the
composition of the functions which the
concatenated parts denote.
Hence if Q1
and Q2
are programs which denote the same function
and P
and R
are other programs,
then the two concatenations P Q1 R
and P Q2 R
also denote the same function.
In other words, programs Q1
and Q2
can replace each other in concatenations.
This can serve as a rule of inference for a rewriting system
because identity of functions is of course already an equivalence.
To illustrate rewriting in Joy,
the "paradoxical" y
combinator defined
recursively in the first definition below.
Then that needs to be the only recursive definition.
Alternatively it can be defined without recursion
as in the second definition.
y == dup [[y] cons] dip i y == [dup cons] swap concat dup cons iThe second definition is of greater interest. It expects a program on top of the stack from which it will construct another program which has the property that if it is ever executed by a combinator (such as
i
)
it will first construct a replica of itself.
Let [P]
be a quoted program.
Then the rewriting of the initial action of y
looks like this:
1 [P] y 2 == [P] [dup cons] swap concat dup cons i (def y) 3 == [dup cons] [P] concat dup cons i (swap) 4 == [dup cons P] dup cons i (concat) 5 == [dup cons P] [dup cons P] cons i (dup) 6 == [[dup cons P] dup cons P] i (cons) 7 == [dup cons P] dup cons P (i) 8 == [dup cons P] [dup cons P] cons P (dup) 9 == [[dup cons P] dup cons P] P (cons)What happens next depends on
P
.
Whatever it does, the topmost parameter that it will find on
the stack is the curious double quotation in line 9.
(It is amusing to see what happens when [P]
is the
empty program []
, especially lines 6 to 9.
Not so amusing is [i]
, and worse still is [y]
).
Actual uses of y
may be illustrated with the factorial function.
The first line below is a standard recursive definition.
The second one uses uses y
to perform anonymous recursion.
Note the extra two pop
s and the extra dip
which are needed to bypass the quotation constructed by line 9 above.
The third definition is discussed below.
In the three bodies the recursive step is initiated by
f1
, i
and x
respectively.
f1 == [ null] [ succ] [ dup pred f1 *] ifte f2 == [ [pop null] [pop succ] [[dup pred] dip i *] ifte ] y f3 == [ [pop null] [pop succ] [[dup pred] dip x *] ifte ] xBut the
y
combinator is inefficient because every recursive
call by i
in the body consumes the quotation on top
of the stack, and hence has to first replicate it to make it available
for the next, possibly recursive call.
The replication steps are the same as initial steps 6 to 9.
But all this makes y
rather inefficient.
However, first consuming and then replicating can be avoided by replacing
both y
and i
in the body of f2
by something else.
This is done in the body of f3
which uses the simple
x
combinator that could be defined as dup i
.
Since the definitions of f2
and f3
are not recursive, it is possible to just use the body of
either of them and textually insert it where it is wanted.
The very simple x
combinator does much the same job as the
(initially quite difficult)
metacomposition in FFP, see
Backus (1978 section 13.3.2),
which provided the inspiration.
A simple device similar to x
can be used for anonymous mutual recursion
in Joy.
The need to bypass the quotation by the pop
s and the dip
is eliminated in the genrec
, binrec
and linrec
combinators discussed in the previous section,
and also in some other special purpose variants.
In the implementation no such quotation is ever constructed.
To return to rewriting,
Joy has the extensional composition constructor concatenation
satisfying the substitution rule.
Joy has only one other constructor, quotation,
but that is intensional.
For example, altough the two stack functions
succ
and 1 +
are identical,
the quotations [succ]
and [1 +]
are not,
since for instance their size
s or their first
s
are different.
However, most combinators do not examine the insides
of their quotation parameters textually.
For these we have further substitution rule:
If Q1
and Q2
are programs which denote the same function
and C
is such a combinator,
then [Q1] C
and [Q2] C
denote the same function.
In other words, Q1
and Q2
can replace each other
in quotations embedded in suitable combinator contexts.
Unsuitable is the otherwise perfectly good combinator
rest i
.
For although succ
and 1 +
denote the same function,
[succ] rest i
and [1 +] rest i
do not.
The rewriting system gives rise
to a simple x
by 2 gives the same
result as adding it to itself.
The second says that the size
of a reverse
d list
is the same as the size
of the original list
in Joy algebra.
The second line gives the same equations without variables
in Joy.
2 * x = x + x size(reverse(x)) = size(x) 2 * == dup + reverse size == sizeOther equivalences express algebraic properties of various operations. For example the predecessor function is the inverse of the successor function, so their composition is the identity function
id
.
The conjunction function and
for truth values
is idempotent.
The less than relation <
is the converse of the
greater than relation >
.
Inserting a number with cons
into a list of numbers
and then taking the sum
of that gives the same result
as first taking the sum of the list and then adding the
other number.
succ pred == id dup and == id < == swap > cons sum == sum +
Some properties of operations have to be expressed by combinators.
In the first example below, the dip
combinator
is used to express the associativity of addition.
In the second example below app2
expresses one of the De Morgan laws.
In the third example it expresses that size
is a homomorphism from lists with concatenation
to numbers with addition.
The last example uses both combinators
to express that multiplication distributes from the right
over addition.
Note that the program parameter for app2
is first constructed from the multiplicand and *
.
[+] dip + == + + and not == [not] app2 or concat size == [size] app2 + [+] dip * == [*] cons app2 +
The sequence operator reverse
is a purely structural operator,
independent of the nature of its elements.
It does not matter whether they are individually replaced
by others before or after the reversal.
Such structural functions are called natural transformations
in category theory and polymorphic functions
in computer science.
This is how naturality laws are expressed in Joy:
[reverse] dip map == map reverse [rest] dip map == map rest [concat] dip map == [map] cons app2 concat [cons] dip map == dup [dip] dip map cons [flatten] map flatten == flatten flatten [transpose] dip [map] cons map == [map] cons map transposeA matrix is implemented as a list of lists, and for mapping it requires mapping each sublist by
[map] cons map
.
Transposition is a list operation
which abstractly interchanges rows and columns.
Such laws are proved by providing dummy parameters to both sides and showing that they reduce to the same result. For example
M [P] [transpose] dip [map] cons map M [P] [map] cons map transposereduce, from the same matrix
M
,
along two different paths with two different
intermediate matrices N1
and N2
,
to a common matrix O
.
To show that Joy is Turing complete,
it is necessary to show that some universal language can
be translated into Joy.
One such language is the untyped lambda calculus
with variables but without constants,
and with abstraction and application as the only constructors.
Lambda expressions can be translated into the SK
combinatory
calculus which has no abstraction
and hence is already closer to Joy.
Hence it is only required to translate
application and the two combinators
S
and K
into Joy counterparts.
The K
combinator applicative expression K y x
reduces to just y
.
The S
combinator applicative expression S f g x
reduces to (f x) (g x)
.
The reductions must be preserved by the Joy counterparts,
with quotation and composition as the only constructors.
The translation from lambda calculus to combinatory calculus
produces expressions such as K y
and S f g
,
and these also have to be translated correctly.
Moreover, the translation has to be such that
when the combinatory expression is applied to x
to enable a reduction,
the same occurs in the Joy counterpart.
Two Joy combinators are needed, k
and s
,
defined in the semantics by the evaluation function EvP
for atoms:
EvA( k, [Y X | S]) = EvP(Y, S) EvA( s, [F G X | S]) = EvP(F,[X | T]) where EvP(G, [X | S]) = TIn the above two clauses
Y
, F
and G
will be passed to the evaluation function EvP
for programs,
hence they will always be quotations.
The required translation scheme is as in the first line below,
where the primed variables represent the translations of their
unprimed counterparts.
K y => ['y] k S f g => ['g] ['f] s K y x => 'x ['y] k S f g x => 'x ['g] ['f] sThe second line shows the translations for the combinatory expression applied to
x
.
In both lines the intersymbol spaces
denote application in the combinatory source
and composition in the Joy target.
This is what
Meertens (1989 p 72)
asked for in the quote early in section 3.
Since x
is an argument,
its translation 'x
has to push something onto the Joy stack.

The reduction rule for S
requires
'x ['g] ['f] s
to reduce to ['x 'g] ['x 'f] b
,
where cons
ing the 'x
into the two quotations
can be done by cons2
.
The definition of y
is different from the one given
earlier which relied on b == concat i
.
So, apart from the base s
and k
,
another more Joy-like base is
pop
, swap
, dup
,
the sole combinator dip
,
and either cons
or cons2
.
Because of x
or y
, no recursive definitions
are ever required.
Since conditionals translated from the lambda calculus
are certain to be cumbersome,
a most likely early addition would be ifte
and truth values.
Instead of Church numerals there will be Joy numerals.
For efficiency one should allow constants such as decimal numerals,
function and predicate symbols in the lambda calculus,
and translate these unchanged into SK
or a richer calculus, then unchanged into Joy but in postfix order.
So far lists and programs can only be given literally
or built up using cons
,
they cannot be inspected or taken apart.
For this we need the null
predicate and the uncons
operator. Then first
and rest
can be defined as
uncons pop
and uncons swap pop
.
Other list operators and
the map
, fold
and filter
combinators
can now be defined without recursion using x
or y
.
Various extensions of Joy are possible.
Since the functions are unary,
they might be replaced by binary relations.
This was done in an earlier but now defunct version
written in Prolog which gave backtracking for free.
Another possible extension is to add impure features.
Joy already has get
and put
for explicit input and output,
useful for debugging,
it has include
for libraries, a help
facility
and various switches settable from within Joy.
There are no plans to add fully blown imperative
features such as assignable variables.
However,
Raoult and Sethi (1983)
propose a purely functional version for a language
of unary stack functions.
The stack has an everpresent extra element
which is conceptually on top of the stack,
a state consisting of variable-value pairs.
Most activity of the stack occurs below the state,
only the purely functional fetch X
and assign Y
perform a read or write from the state and
and they perform a push or a pop on the remainder of the stack.
The authors also propose uses of continuations for
such a language.
Adapting these ideas to Joy is still on the backburner,
and so are many other ideas like the relation
of the stack to linear logic and the use of categorial grammars
(nothing to do with category theory) for the rewriting.
Since the novelty of Joy is for programming in the small,
no object oriented extensions are planned
beyond a current simple device for hiding
selected auxiliary definitions from the outside view.
For any algebra, any relational structure,
any programming language it is possible to have
alternative sets of primitives and alternative sets of axioms.
Which sets are optimal depends on circumstances,
and to evolve optimal sets takes time.
One only needs to be reminded of the decade
of discussions on the elimination of goto
and the introduction of a small, orthogonal and complete
set of primitives for flow of control in imperative languages.
The current implementation and library of Joy
contain several experimental
operators and combinators whose true value is still unclear.
So, at present it is not known what would be an optimal
set of primitives in Joy for writing programs.
It is easy enough to eliminate the intensionality of quotation.
Lists and quotations would be distinguished textually,
and operators that build up like cons
and concat
are allowed on both.
But operators which examine the insides, like first
,
rest
and even size
are only allowed on lists.
It is worth pointing out that the earlier list of primitives
does not include or derive them.
Now the substitution rule for quotation is simply this:
if Q1
and Q2
denote the same program,
then so do [Q1]
and [Q2]
.
But maiming quotation in this manner comes at a price ---
compilers, interpreters, optimisers,
even pretty-printers
and other important kinds of program processing programs
become impossible,
although one remedy might be to "certify and seal off"
quotations after such processing.
As G\"{o}del showed,
any language that has arithmetic can,
in a cumbersome way, using what are now called G\"{o}del numbers,
talk about the syntax of any language, including its own.
Hofstadter (1985 p 449)
was not entirely joking when,
in response to Minsky's criticism of G\"{o}del for not inventing Lisp,
he was tempted to say 'G\"{o}del did invent Lisp'.
But we should add in the same tone
'And McCarthy invented quote
. And he saw that it was good'.
J.W. Backus. Can programming be liberated from the von {N}eumann style? a functional style and its algebra of programs. {\it Communications of the ACM}, 21(8):613, 1978. J.W. Backus, J. Williams, and E.W. Wimmers. An introduction to the programming language {FL}. In D.A. Turner, editor, {\it Research Topics in Functional Programming}, page~219, Addison Wesley, 1990. M. Barr and C. Wells. {\it Category Theory for Computer Science}. Prentice Hall, 1990. R. Bird and O. de~Moor. {\it Algebra of Programming}. Prentice Hall, 1997. T.H. Brus, M.C.J.D. van~Eekelen, M.O. van~Leer, and M.J. Plasmejer. Clean --- a language for functional graph rewriting. In G. Kahn, editor, {\it Functional Programming Languages and Computer Architecture}, page~367, Springer: LNCS vol. 272, 1987. G. Cousineau, P.-L. Curien, and M. Mauny. The categorical abstract machine. {\it Science of Computer Programming}, 9:203, 1987. H. Curry and R. Feys. {\it Combinatory Logic}. Volume~1, North Holland, 1958. G. Hains and C. Foisy. The data-parallel categorical abstract machine. In A. Bode, M. Reeve, and G. Wolf, editors, {\it PARLE '93 Parallel Architectures and Languages Europe}, page~56, Springer: LNCS vol. 694, 1993. D. Hofstadter. {\it Metamagical Themas: Questing for the Essence of Mind and Pattern}. Basic Books, 1985. L. Meertens. Constructing a calculus of programs. In J.L.A. {van de Snepscheut}, editor, {\it Mathematics of Program Construction}, page~66, Springer: LNCS vol. 375, 1989. S.L. PeytonJones. {\it The Implementation of Functional Languages}. Prentice Hall, 1987. J.-C. Raoult and R. Sethi. Properties of a notation for combining functions. {\it J. Assoc. for Computing Machinery}, 30:595, 1983. M. {Sch\"{o}nfinkel}. On the building blocks of mathematical logic. In J. van~Heijenoort, editor, {\it From Frege to {G\"{o}del}}, page~357, Harvard University Press, 1967. English Translation from the German original. Includes foreword by W.V.O. Quine.


Hello World
25 Aug 2014Hey there! My name is Narayanan "Naveen" Venkataraman. I am a student at The University of Chicago studying Analytics. My github contains code for the projects I'm currently working on including: classroom work, writing portfolio and open source contributions.
R projects
- Currency Arbitrage
- R For Excel Users - In partnership with John Taveras


Landing Page
Special Projects
This story is part of a series of specially designed stories that represents some of the best journalism The Post has to offer. Check out the rest of the special projects here.
TAYLOR JOHNSTON
05.25.17
Blackboard is a pain. That’s a given. Remember all those awful websites your high school tried to use to do online homework? It’s like those, but it’s centralized for all your college classes. The struggles are something you learn within a week of experiencing university life, and it becomes integral to you as a student very quickly. Just about every assignment, online quiz or test announcement will likely be found there, unless your teacher feels exceptionally unique and decides not to use Blackboard at all.
That being said, there are certainly ways to make it work for you. Learning to adapt to Blackboard can take a while, but the site can prove to be useful if you know what to do. Here are three major ways to make things easier for yourself which may save you a lot of time and stress in the long run.
One of the most frustrating things about the site right off the bat is that it routes through the university network, so it can’t “remember” your username and password, which you’ll find yourself typing in over and over and over, even within minutes because of how often you might be using it. If you allow your browser to remember your username and password, however, it takes a click of a button to access the site.
Depending on how the teacher grades your class, Blackboard may show your grade as a 65 percent even if you have a 100 percent so far in the class, so long as you have only done 65 percent of the coursework. Some teachers add in those points and assignments as time goes on, and others have them all there at the beginning that have a starting grade of zero. Make sure you figure out which style your teachers are, if they even upload the grades on Blackboard at all. Through that, you can get a better idea of how things are going in the semester.
Especially in large class sizes, many people will try to work on and review their submission until the last minute. In fact, sometimes so many people do it that Blackboard can fail to upload everyone’s files in time, potentially leaving you with a late assignment. Although some professors may be lenient on a minute or two, others may not be. In fact, some specifically state that Blackboard issue to make sure students do not fall prey to the slow upload speed.
The website certainly is not perfect, even if you know all the tips and tricks, but having a grasp on how it works and how to solve some of its issues certainly helps. Best of luck.
— Marco Omta is a junior studying music production. Please note that the views and opinions of the columnists do not reflect those of The Post. What helps you navigate Blackboard? Email Marco at<EMAIL_ADDRESS>Landing Page
This story is part of a series of specially designed stories that represents some of the best journalism The Post has to offer. Check out the rest of the special projects here.


Katensa:
Say, you wouldn't happen to be in need of some work would ya? Have you thought about a rewarding career contributing to the Helvetica Research Facility? We've got a project going, and offer several beneficial packages to our contractors.
"I'm listening. Tell me more about the project."


2 writes to OutputStream
System.Management.Automation (2)
engine\hostifaces\pipelinebase.cs (2)
41
OutputStream
= new ObjectStream();
110
OutputStream
= outputStream;
6 references to OutputStream
System.Management.Automation (6)
engine\hostifaces\LocalPipeline.cs (4)
358
pipelineProcessor.ExternalSuccessOutput =
OutputStream
.ObjectWriter;
675
if (
OutputStream
.IsOpen && !IsChild)
679
OutputStream
.Close();
970
LocalRunspace.ExecutionContext.ExternalSuccessOutput =
OutputStream
.ObjectWriter;
engine\hostifaces\pipelinebase.cs (2)
233
return
OutputStream
.PSObjectReader;
1055
OutputStream
.Close();


Witch Cleo:
I must find the leader of the brothers of blood. They are warriors united by their firm resolve and ambition. I must guide him to a priceless royal symbol of no monetary value...


Blueverve
Home
Our Approach
Process
Portfolio
Team
Blog
Contact Us
Blueverve produces mobile and web apps for small companies with big ideas.
Take a look at some of our work and then
say hello
.
Tabtale Website
Takes
Thomson Reuters
Climbing Monster
USkape
We'd love to hear about your great idea or your app in development.
Say Hello


Recipe 10.10. Blocking Duplicate Mails
Credit: Marina Pianu, Peter Cogolo
Problem
Many of the mails you receive are
duplicates. You need to block the duplicates with a fast, simple
filter before they reach a more time-consuming step, such as an
anti-spam filter, in your email pipeline.
Solution
Many mail systems, such
as the popular procmail, and KDE's KMail, enable you
to control your mail-reception pipeline. Specifically, you can insert
in the pipeline your filter programs, which get messages on standard
input, may modify them, and emit them again on standard output. Here
is one such filter, with the specific purpose of performing the task
described in the Problemblocking messages that are duplicates
of other messages that you have received recently:
#!/usr/bin/python
import time, sys, os, email
now = time.time( )
# get archive of previously-seen message-ids and times
kde_dir = os.expanduser('~/.kde')
if not os.path.isdir(kde_dir):
os.mkdir(kde_dir)
arfile = os.path.join(kde_dir, 'duplicate_mails')
duplicates = { }
try:
archive = open(arfile)
except IOError:
pass
else:
for line in archive:
when, msgid = line[:-1].split(' ', 1)
duplicates[msgid] = float(when)
archive.close( )
redo_archive = False
# suck message in from stdin and study it
msg = email.message_from_file(sys.stdin)
msgid = msg['Message-ID']
if msgid:
if msgid in duplicates:
# duplicate message: alter its subject
subject = msg['Subject']
if subject is None:
msg['Subject'] = '**** DUP **** ' + msgid
else:
del msg['Subject']
msg['Subject'] = '**** DUP **** ' + subject
else:
# non-duplicate message: redo the archive file
redo_archive = True
duplicates[msgid] = now
else:
# invalid (missing message-id) message: alter its subject
subject = msg['Subject']
if subject is None:
msg['Subject'] = '**** NID **** '
else:
del msg['Subject']
msg['Subject'] = '**** NID **** ' + subject
# emit message back to stdout
print msg
if redo_archive:
# redo archive file, keep only msgs from the last two hours
keep_last = now - 2*60*60.0
archive = file(arfile, 'w')
for msgid, when in duplicates.iteritems( ):
if when > keep_last:
archive.write('%9.2f %s\n' % (when, what))
archive.close( )
Discussion
Whether it is because of spammers' malice or
incompetence, or because of hiccups at my Internet ISP (Internet
service provider), at times I get huge amounts of duplicate messages
that can overload my mail-reception pipeline, particularly antispam
filters. Fortunately, like many other mail systems,
KDE's KMail, the one I use, lets me insert my own
filters in the mail reception pipeline. In particular, I can diagnose
duplicate messages, alter their headers (I use
"Subject" for clarity), and tell
later stages in the filters' pipeline to throw away
messages with such subjects or to shunt them aside into a dedicated
mailbox for later perusal, without passing them on to the antispam
and other filters.
The
email module from the Python Standard Library
performs all the required parsing of the message and lets me access
headers with dictionary-like indexing syntax. I need some
"memory" of recently seen messages.
Fortunately, I have noticed all duplicates happen within a few
minutes of each other, so I don't have to keep that
memory for longtwo hours are plenty. Therefore, I keep that
memory in a simple text file, which records the time when a message
was received and the message ID. I thought I might have to find a
more advanced way to keep this kind of FIFO (first-in, first-out)
archive, but I tried a simple approach firsta simple text file
that is entirely rewritten whenever a new nonduplicate message
arrives. This approach appears to perform quite adequately for my
needs (at most a couple hundred messages an hour), even on my
somewhat dated PC. "Do the simplest thing that could
possibly work" strikes again!
See Also
Documentation about package email and modules
time, sys and
os in the Library Reference
and Python in a Nutshell.
|


HOST
Section: BIND9 (1)Updated: Jun 30, 2000
Index Return to Main Contents
NAME
host - DNS lookup utilitySYNOPSIS
- host [-aCdlnrsTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] [-m flag] [-4] [-6] {name} [server]
DESCRIPTION
host
name is the domain name that is to be looked up. It can also be a dotted-decimal IPv4 address or a colon-delimited IPv6 address, in which case host will by default perform a reverse lookup for that address. server is an optional argument which is either the name or IP address of the name server that host should query instead of the server or servers listed in /etc/resolv.conf.
The -a (all) option is equivalent to setting the -v option and asking host to make a query of type ANY.
When the -C option is used, host will attempt to display the SOA records for zone name from all the listed authoritative name servers for that zone. The list of name servers is defined by the NS records that are found for the zone.
The -c option instructs to make a DNS query of class class. This can be used to lookup Hesiod or Chaosnet class resource records. The default class is IN (Internet).
Verbose output is generated by host when the -d or -v option is used. The two options are equivalent. They have been provided for backwards compatibility. In previous versions, the -d option switched on debugging traces and -v enabled verbose output.
List mode is selected by the -l option. This makes host perform a zone transfer for zone name. Transfer the zone printing out the NS, PTR and address records (A/AAAA). If combined with -a all records will be printed.
The -i option specifies that reverse lookups of IPv6 addresses should use the IP6.INT domain as defined in RFC1886. The default is to use IP6.ARPA.
The -N option sets the number of dots that have to be in name for it to be considered absolute. The default value is that defined using the ndots statement in /etc/resolv.conf, or 1 if no ndots statement is present. Names with fewer dots are interpreted as relative names and will be searched for in the domains listed in the search or domain directive in /etc/resolv.conf.
The number of UDP retries for a lookup can be changed with the -R option. number indicates how many times host will repeat a query that does not get answered. The default number of retries is 1. If number is negative or zero, the number of retries will default to 1.
Non-recursive queries can be made via the -r option. Setting this option clears the RD --- recursion desired --- bit in the query which host makes. This should mean that the name server receiving the query will not attempt to resolve name. The -r option enables host to mimic the behavior of a name server by making non-recursive queries and expecting to receive answers to those queries that are usually referrals to other name servers.
By default, host uses UDP when making queries. The -T option makes it use a TCP connection when querying the name server. TCP will be automatically selected for queries that require it, such as zone transfer (AXFR) requests.
The -4 option forces host to only use IPv4 query transport. The -6 option forces host to only use IPv6 query transport.
The -t option is used to select the query type. type can be any recognized query type: CNAME, NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, host automatically selects an appropriate query type. By default, it looks for A, AAAA, and MX records, but if the -C option was given, queries will be made for SOA records, and if name is a dotted-decimal IPv4 address or colon-delimited IPv6 address, host will query for PTR records. If a query type of IXFR is chosen the starting serial number can be specified by appending an equal followed by the starting serial number (e.g. -t IXFR=12345678).
The time to wait for a reply can be controlled through the -W and -w options. The -W option makes host wait for wait seconds. If wait is less than one, the wait interval is set to one second. When the -w option is used, host will effectively wait forever for a reply. The time to wait for a response will be set to the number of seconds given by the hardware's maximum value for an integer quantity.
The -s option tells host not to send the query to the next nameserver if any server responds with a SERVFAIL response, which is the reverse of normal stub resolver behavior.
The -m can be used to set the memory usage debugging flags record, usage and trace.
IDN SUPPORT
If host has been built with IDN (internationalized domain name) support, it can accept and display non-ASCII domain names. host appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. If you'd like to turn off the IDN support for some reason, defines the IDN_DISABLE environment variable. The IDN support is disabled if the variable is set when host runs.
FILES
SEE ALSO
COPYRIGHT
Copyright © 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")Copyright © 2000-2002 Internet Software Consortium.
Index
This document was created by man2html, using the manual pages.
Time: 05:29:04 GMT, December 24, 2015


Match Play. 0-0 to 7. Should Red double? If doubled, should White take?
pips Red=136 White=130
(CorrectAnswer= 0/0, ErrorScore= 0)
This is very deceptive position. The double from Red is clear and obvious and looks very threatening.
At first sight this looks like a pass for White, but the race is level, White has a stronger home board than Red and Red is not guaranteed to make the five-point prime. If Red does make the prime then White can launch an attack against Red’s rear checkers – Red cannot do everything in one roll.
All this adds up to a trivially easy take for White and dropping is a huge blunder. A very instructive position.
At first sight this looks like a pass for White, but the race is level, White has a stronger home board than Red and Red is not guaranteed to make the five-point prime. If Red does make the prime then White can launch an attack against Red’s rear checkers – Red cannot do everything in one roll.
All this adds up to a trivially easy take for White and dropping is a huge blunder. A very instructive position.
Cube analysis 2-ply cubeless equity +0.419 (Money: +0.417) 0.683 0.185 0.009 - 0.317 0.138 0.005 Cubeful equities: 1. Double, take +0.652 2. Double, pass +1.000 (+0.348) 3. No double +0.602 (-0.050) Proper cube action: Double, take