All Downloads are FREE. Search and download functionalities are using the official Maven repository.

example.ProceduralProgramming Maven / Gradle / Ivy

/*
 * Zorbage: an algebraic data hierarchy for use in numeric processing.
 *
 * Copyright (c) 2016-2021 Barry DeZonia All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list
 * of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright notice, this
 * list of conditions and the following disclaimer in the documentation and/or other
 * materials provided with the distribution.
 * 
 * Neither the name of the  nor the names of its contributors may
 * be used to endorse or promote products derived from this software without specific
 * prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */
package example;

import nom.bdezonia.zorbage.algebra.G;
import nom.bdezonia.zorbage.algorithm.StableSort;
import nom.bdezonia.zorbage.datasource.IndexedDataSource;
import nom.bdezonia.zorbage.procedure.Procedure1;
import nom.bdezonia.zorbage.procedure.Procedure3;
import nom.bdezonia.zorbage.type.complex.float64.ComplexFloat64Member;
import nom.bdezonia.zorbage.type.integer.int32.SignedInt32Member;
import nom.bdezonia.zorbage.type.real.float32.Float32Member;
import nom.bdezonia.zorbage.type.real.float64.Float64Member;

/**
 * @author Barry DeZonia
 */
class ProceduralProgramming {
	
	// Zorbage is designed to mix a few programming styles so that it is convenient
	// to compute what you need when you need it. Well known programming models
	// include object oriented programming, functional programming, and procedural
	// (also known as imperative) programming. In general, most numeric algorithms
	// are naturally defined as procedural or functional solutions. However
	// functional approaches can be significantly slower or use significantly more
	// resources. That is one reason why Zorbage prefers procedural code when
	// possible.
	
	// Zorbage thinks of procedural code as something similar to Pascal's approach.
	// Code can be organized in blocks of code called Procedures (or Functions).
	// Procedures and Functions can take inputs by reference. A Procedure or
	// Function can change a variable from a long distance if it desires. This
	// makes for efficient code in terms of speed and space. Java was designed with
	// some incomplete pass by reference capabilities (for instance, Java cannot
	// externally modify a single primitive value such as byte, short, int, long,
	// float, double, etc.). Zorbage can modify primitives externally.
	
	// An example to show how pass by reference works in Java and in Zorbage
	
	// typical Java
	
	void inc(int num) {
		num = num + 1;
	}
	
	void typicalJava() {
		int i = 7;
		inc(i);
		System.out.println(i);

		// Note here it prints 7 : external variable was not changed
	}
	
	// typical Zorbage
	
	Procedure1 inc =
			new Procedure1()
	{
		@Override
		public void call(SignedInt32Member a) {
			// assign to a the successor of a
			G.INT32.succ().call(a, a);
		}
	};
	
	void typicalZorbage() {
		SignedInt32Member i = new SignedInt32Member(7);
		inc.call(i);
		System.out.println(i);

		// Note here it prints 8 : external variable was changed
	}

	// Zorbage users should follow a couple conventions when designing their own
	// Procedures. One convention is that in a call() definition for a Procedure
	// you want data to flow from left to right. Think that defining
	// proc.call(a,b,c) might be assigning c = a + b. Basically the methods you
	// design should have inputs on the left and outputs on the right. If you
	// desire you can treat a parameter as both an input and an output. One
	// example is sorting. You pass a list to the Sort code and the data is
	// changed. There is no 2nd list to contain the results or to get returned.
	// Another trick is that unlike Functions that return one variable, Procedures
	// can modify multiple output variables at one time.
	
	void example1() {
		
		// make a list
		
		IndexedDataSource data = null;
		
		// elsewhere fill the data list
		
		// now sort it. notice that data is passed in and changed.
		
		StableSort.compute(G.FLT, data);
	}
	
	void example2() {
	
		// an example that shows multiple outputs
		
		Float64Member angle = new Float64Member(Math.PI / 2);
		
		Float64Member sin = G.DBL.construct();

		Float64Member cos = G.DBL.construct();

		G.DBL.sinAndCos().call(angle, sin, cos);
		
		// after this call sin = angle's sine value and cos = angle's cosine value
	}
	
	// One can imagine that this multiple output capability could come in handy
	// in a number of situations. It can reduce the number of computations you
	// make. For instance the sinAndCos() example above can be faster than
	// separately calling sin() and cos(). These two calcs use a lot of the
	// same intermediate data. A combined method can reuse information to speed
	// up the overall calculation. Another example where this feature might be
	// useful is the SummaryStats algorithm. It makes minimal passes over data
	// while calculating many statistics of interest.
	//   e.g.
	//
	//   SummaryStats.compute(list, min, q1, median, mean, q3, max);
	
	// Most of Zorbage's algorithms are static classes with a compute() method.
	// Procedures and Functions have a call() method. Algorithms and Procedures
	// and Functions are similarly designed and one can be used to wrap the
	// other when necessary. Zorbage chooses the static algorithm approach to
	// improve code readability. What Mean.compute() is doing is pretty easy
	// to understand.
	
	// Since Zorbage algorithms can modify their inputs, and one input can be
	// repeatedly used in a call the design of the procedure must follow
	// some rules.
	
	// One such example is some of the complex math code:
	
	@SuppressWarnings("unused")
	private final Procedure3 MULTIPLY =
			new Procedure3()
	{
		@Override
		public void call(ComplexFloat64Member a, ComplexFloat64Member b, ComplexFloat64Member c) {
			
			// Current code:
			
			// for safety must use tmps
			double r = a.r()*b.r() - a.i()*b.i();
			double i = a.i()*b.r() + a.r()*b.i();
			c.setR( r );
			c.setI( i );

			// Code comment for this topic:
			
			// see here that C ends up being calculated from A and B
			// If we did not use temporary variables and simply did this instead:

			c.setR(a.r()*b.r() - a.i()*b.i());
			c.setI(a.i()*b.r() + a.r()*b.i());
			
			// then if we did proc.call(a,b,a); with "a" being an output target then the 1st
			// line would calc fine but the second line would fail because a's r-value had
			// changed on the previous line and would now be used in the second line's
			// calculation.
			
			// Anyhow the upshot is that procedure definitions have to consider that every
			// input might be a duplicate use of one of the other inputs. Procedures
			// need to copy data to local variables for calculations and assign outputs
			// from local variables when this is necessary so that variable overwrites don't
			// happen during partial computations. You usually do not need to worry about
			// this much in practice but you should be aware of the possibility your
			// Procedure definition might need to use this approach.
		}
	};
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy