mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-08-14 10:45:06 +02:00
Updated info for Chapel 1.12.0
This commit is contained in:
@@ -27,7 +27,7 @@ writeln( "There are ", 3, " commas (\",\") in this line of code" );
|
|||||||
stdout.writeln( "This goes to standard output, just like plain writeln() does");
|
stdout.writeln( "This goes to standard output, just like plain writeln() does");
|
||||||
stderr.writeln( "This goes to standard error" );
|
stderr.writeln( "This goes to standard error" );
|
||||||
|
|
||||||
// Variables don't have to be explicitly typed as long as
|
// Variables don't have to be explicitly typed as long as
|
||||||
// the compiler can figure out the type that it will hold.
|
// the compiler can figure out the type that it will hold.
|
||||||
var myVar = 10; // 10 is an int, so myVar is implicitly an int
|
var myVar = 10; // 10 is an int, so myVar is implicitly an int
|
||||||
myVar = -10;
|
myVar = -10;
|
||||||
@@ -65,9 +65,9 @@ const almostPi: real = 22.0/7.0;
|
|||||||
param compileTimeConst: int = 16;
|
param compileTimeConst: int = 16;
|
||||||
|
|
||||||
// The config modifier allows values to be set at the command line
|
// The config modifier allows values to be set at the command line
|
||||||
// and is much easier than the usual getOpts debacle
|
// and is much easier than the usual getOpts debacle
|
||||||
// config vars and consts can be changed through the command line at run time
|
// config vars and consts can be changed through the command line at run time
|
||||||
config var varCmdLineArg: int = -123;
|
config var varCmdLineArg: int = -123;
|
||||||
config const constCmdLineArg: int = 777;
|
config const constCmdLineArg: int = 777;
|
||||||
// Set with --VarName=Value or --VarName Value at run time
|
// Set with --VarName=Value or --VarName Value at run time
|
||||||
|
|
||||||
@@ -119,9 +119,9 @@ a *= thatInt; // Times-equals ( a = a * thatInt; )
|
|||||||
b &&= thatBool; // Logical-and-equals ( b = b && thatBool; )
|
b &&= thatBool; // Logical-and-equals ( b = b && thatBool; )
|
||||||
a <<= 3; // Left-bit-shift-equals ( a = a << 10; )
|
a <<= 3; // Left-bit-shift-equals ( a = a << 10; )
|
||||||
// and many, many more.
|
// and many, many more.
|
||||||
// Unlike other C family languages there are no
|
// Unlike other C family languages there are no
|
||||||
// pre/post-increment/decrement operators like
|
// pre/post-increment/decrement operators like
|
||||||
// ++j, --j, j++, j--
|
// ++j, --j, j++, j--
|
||||||
|
|
||||||
// Swap operator
|
// Swap operator
|
||||||
var old_this = thisInt;
|
var old_this = thisInt;
|
||||||
@@ -155,7 +155,7 @@ writeln( (a,b,thisInt,thatInt,thisBool,thatBool) );
|
|||||||
|
|
||||||
// Type aliasing
|
// Type aliasing
|
||||||
type chroma = int; // Type of a single hue
|
type chroma = int; // Type of a single hue
|
||||||
type RGBColor = 3*chroma; // Type representing a full color
|
type RGBColor = 3*chroma; // Type representing a full color
|
||||||
var black: RGBColor = ( 0,0,0 );
|
var black: RGBColor = ( 0,0,0 );
|
||||||
var white: RGBColor = ( 255, 255, 255 );
|
var white: RGBColor = ( 255, 255, 255 );
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ select( inputOption ){
|
|||||||
writeln( "Chose 'otherOption'" );
|
writeln( "Chose 'otherOption'" );
|
||||||
writeln( "Which has a body" );
|
writeln( "Which has a body" );
|
||||||
}
|
}
|
||||||
otherwise {
|
otherwise {
|
||||||
writeln( "Any other Input" );
|
writeln( "Any other Input" );
|
||||||
writeln( "the otherwise case doesn't need a do if the body is one line" );
|
writeln( "the otherwise case doesn't need a do if the body is one line" );
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ do{
|
|||||||
writeln( jSum );
|
writeln( jSum );
|
||||||
|
|
||||||
// For loops are much like those in python in that they iterate over a range.
|
// For loops are much like those in python in that they iterate over a range.
|
||||||
// Ranges themselves are types, and can be stuffed into variables
|
// Ranges themselves are types, and can be stuffed into variables
|
||||||
// (more about that later)
|
// (more about that later)
|
||||||
for i in 1..10 do write( i , ", ") ;
|
for i in 1..10 do write( i , ", ") ;
|
||||||
writeln( );
|
writeln( );
|
||||||
@@ -240,28 +240,28 @@ for x in 1..10 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ranges and Domains
|
// Ranges and Domains
|
||||||
// For-loops and arrays both use ranges and domains to
|
// For-loops and arrays both use ranges and domains to
|
||||||
// define an index set that can be iterated over.
|
// define an index set that can be iterated over.
|
||||||
// Ranges are single dimensional
|
// Ranges are single dimensional
|
||||||
// Domains can be multi-dimensional and can
|
// Domains can be multi-dimensional and can
|
||||||
// represent indices of different types as well.
|
// represent indices of different types as well.
|
||||||
// They are first-class citizen types, and can be assigned into variables
|
// They are first-class citizen types, and can be assigned into variables
|
||||||
var range1to10: range = 1..10; // 1, 2, 3, ..., 10
|
var range1to10: range = 1..10; // 1, 2, 3, ..., 10
|
||||||
var range2to11 = 2..11; // 2, 3, 4, ..., 11
|
var range2to11 = 2..11; // 2, 3, 4, ..., 11
|
||||||
var rangeThistoThat: range = thisInt..thatInt; // using variables
|
var rangeThistoThat: range = thisInt..thatInt; // using variables
|
||||||
var rangeEmpty: range = 100..-100 ; // this is valid but contains no indices
|
var rangeEmpty: range = 100..-100 ; // this is valid but contains no indices
|
||||||
|
|
||||||
// Ranges can be unbounded
|
// Ranges can be unbounded
|
||||||
var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ;
|
var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ;
|
||||||
// 1, 2, 3, 4, 5, ...
|
// 1, 2, 3, 4, 5, ...
|
||||||
// Note: the range(boundedType= ... ) is only
|
// Note: the range(boundedType= ... ) is only
|
||||||
// necessary if we explicitly type the variable
|
// necessary if we explicitly type the variable
|
||||||
|
|
||||||
var rangeNegInfto1 = ..1; // ..., -4, -3, -2, -1, 0, 1
|
var rangeNegInfto1 = ..1; // ..., -4, -3, -2, -1, 0, 1
|
||||||
|
|
||||||
// Ranges can be strided using the 'by' operator.
|
// Ranges can be strided using the 'by' operator.
|
||||||
var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10
|
var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10
|
||||||
// Note: the range(stridable=true) is only
|
// Note: the range(stridable=true) is only
|
||||||
// necessary if we explicitly type the variable
|
// necessary if we explicitly type the variable
|
||||||
|
|
||||||
// Use by to create a reverse range
|
// Use by to create a reverse range
|
||||||
@@ -275,9 +275,9 @@ var rangeCountBy: range(stridable=true) = -5..#12 by 2; // -5, -3, -1, 1, 3, 5
|
|||||||
writeln( rangeCountBy );
|
writeln( rangeCountBy );
|
||||||
|
|
||||||
// Can query properties of the range
|
// Can query properties of the range
|
||||||
// Print the first index, last index, number of indices,
|
// Print the first index, last index, number of indices,
|
||||||
// stride, and ask if 2 is include in the range
|
// stride, and ask if 2 is include in the range
|
||||||
writeln( ( rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
|
writeln( ( rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
|
||||||
rangeCountBy.stride, rangeCountBy.member( 2 ) ) );
|
rangeCountBy.stride, rangeCountBy.member( 2 ) ) );
|
||||||
|
|
||||||
for i in rangeCountBy{
|
for i in rangeCountBy{
|
||||||
@@ -309,7 +309,7 @@ stringSet += "b";
|
|||||||
stringSet += "c";
|
stringSet += "c";
|
||||||
stringSet += "a"; // Redundant add "a"
|
stringSet += "a"; // Redundant add "a"
|
||||||
stringSet -= "c"; // Remove "c"
|
stringSet -= "c"; // Remove "c"
|
||||||
writeln( stringSet );
|
writeln( stringSet );
|
||||||
|
|
||||||
// Both ranges and domains can be sliced to produce a range or domain with the
|
// Both ranges and domains can be sliced to produce a range or domain with the
|
||||||
// intersection of indices
|
// intersection of indices
|
||||||
@@ -332,13 +332,13 @@ var intArray2: [{1..10}] int; //equivalent
|
|||||||
for i in 1..10 do
|
for i in 1..10 do
|
||||||
intArray[i] = -i;
|
intArray[i] = -i;
|
||||||
writeln( intArray );
|
writeln( intArray );
|
||||||
// We cannot access intArray[0] because it exists outside
|
// We cannot access intArray[0] because it exists outside
|
||||||
// of the index set, {1..10}, we defined it to have.
|
// of the index set, {1..10}, we defined it to have.
|
||||||
// intArray[11] is illegal for the same reason.
|
// intArray[11] is illegal for the same reason.
|
||||||
|
|
||||||
var realDomain: domain(2) = {1..5,1..7};
|
var realDomain: domain(2) = {1..5,1..7};
|
||||||
var realArray: [realDomain] real;
|
var realArray: [realDomain] real;
|
||||||
var realArray2: [1..5,1..7] real; // Equivalent
|
var realArray2: [1..5,1..7] real; // Equivalent
|
||||||
var realArray3: [{1..5,1..7}] real; // Equivalent
|
var realArray3: [{1..5,1..7}] real; // Equivalent
|
||||||
|
|
||||||
for i in 1..5 {
|
for i in 1..5 {
|
||||||
@@ -350,7 +350,7 @@ for i in 1..5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Arrays have domains as members that we can iterate over
|
// Arrays have domains as members that we can iterate over
|
||||||
for idx in realArray.domain { // Again, idx is a 2*int tuple
|
for idx in realArray.domain { // Again, idx is a 2*int tuple
|
||||||
realArray[idx] = 1 / realArray[idx[1],idx[2]]; // Access by tuple and list
|
realArray[idx] = 1 / realArray[idx[1],idx[2]]; // Access by tuple and list
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +377,7 @@ var thatArray : [{0..5}] int;
|
|||||||
// Simply assign one to the other.
|
// Simply assign one to the other.
|
||||||
// This copies thisArray into thatArray, instead of just creating a reference.
|
// This copies thisArray into thatArray, instead of just creating a reference.
|
||||||
// Modifying thisArray does not also modify thatArray.
|
// Modifying thisArray does not also modify thatArray.
|
||||||
thatArray = thisArray;
|
thatArray = thisArray;
|
||||||
thatArray[1] = -1;
|
thatArray[1] = -1;
|
||||||
writeln( (thisArray, thatArray) );
|
writeln( (thisArray, thatArray) );
|
||||||
|
|
||||||
@@ -389,12 +389,12 @@ writeln( (thisArray, thatArray) );
|
|||||||
var thisPlusThat = thisArray + thatArray;
|
var thisPlusThat = thisArray + thatArray;
|
||||||
writeln( thisPlusThat );
|
writeln( thisPlusThat );
|
||||||
|
|
||||||
// Arrays and loops can also be expressions, where loop
|
// Arrays and loops can also be expressions, where loop
|
||||||
// body's expression is the result of each iteration.
|
// body's expression is the result of each iteration.
|
||||||
var arrayFromLoop = for i in 1..10 do i;
|
var arrayFromLoop = for i in 1..10 do i;
|
||||||
writeln( arrayFromLoop );
|
writeln( arrayFromLoop );
|
||||||
|
|
||||||
// An expression can result in nothing,
|
// An expression can result in nothing,
|
||||||
// such as when filtering with an if-expression
|
// such as when filtering with an if-expression
|
||||||
var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i;
|
var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i;
|
||||||
|
|
||||||
@@ -407,7 +407,7 @@ var evensOrFivesAgain = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
|
|||||||
// Or over the values of the array
|
// Or over the values of the array
|
||||||
arrayFromLoop = [ value in arrayFromLoop ] value + 1;
|
arrayFromLoop = [ value in arrayFromLoop ] value + 1;
|
||||||
|
|
||||||
// Note: this notation can get somewhat tricky. For example:
|
// Note: this notation can get somewhat tricky. For example:
|
||||||
// evensOrFives = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
|
// evensOrFives = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
|
||||||
// would break.
|
// would break.
|
||||||
// The reasons for this are explained in depth when discussing zipped iterators.
|
// The reasons for this are explained in depth when discussing zipped iterators.
|
||||||
@@ -431,7 +431,7 @@ proc addThree( n ) {
|
|||||||
doublePrint( addThree( fibonacci( 20 ) ) );
|
doublePrint( addThree( fibonacci( 20 ) ) );
|
||||||
|
|
||||||
// Can also take 'unlimited' number of parameters
|
// Can also take 'unlimited' number of parameters
|
||||||
proc maxOf( x ...?k ) {
|
proc maxOf( x ...?k ) {
|
||||||
// x refers to a tuple of one type, with k elements
|
// x refers to a tuple of one type, with k elements
|
||||||
var maximum = x[1];
|
var maximum = x[1];
|
||||||
for i in 2..k do maximum = if (maximum < x[i]) then x[i] else maximum;
|
for i in 2..k do maximum = if (maximum < x[i]) then x[i] else maximum;
|
||||||
@@ -439,7 +439,7 @@ proc maxOf( x ...?k ) {
|
|||||||
}
|
}
|
||||||
writeln( maxOf( 1, -10, 189, -9071982, 5, 17, 20001, 42 ) );
|
writeln( maxOf( 1, -10, 189, -9071982, 5, 17, 20001, 42 ) );
|
||||||
|
|
||||||
// The ? operator is called the query operator, and is used to take
|
// The ? operator is called the query operator, and is used to take
|
||||||
// undetermined values (like tuple or array sizes, and generic types).
|
// undetermined values (like tuple or array sizes, and generic types).
|
||||||
|
|
||||||
// Taking arrays as parameters.
|
// Taking arrays as parameters.
|
||||||
@@ -463,7 +463,7 @@ writeln( defaultsProc( x=11 ) );
|
|||||||
writeln( defaultsProc( x=12, y=5.432 ) );
|
writeln( defaultsProc( x=12, y=5.432 ) );
|
||||||
writeln( defaultsProc( y=9.876, x=13 ) );
|
writeln( defaultsProc( y=9.876, x=13 ) );
|
||||||
|
|
||||||
// Intent modifiers on the arguments convey how
|
// Intent modifiers on the arguments convey how
|
||||||
// those arguments are passed to the procedure
|
// those arguments are passed to the procedure
|
||||||
// in: copy arg in, but not out
|
// in: copy arg in, but not out
|
||||||
// out: copy arg out, but not in
|
// out: copy arg out, but not in
|
||||||
@@ -489,18 +489,18 @@ writeln( "Outside After: ", (inVar, outVar, inoutVar, refVar) );
|
|||||||
// Similarly we can define intents on the return type
|
// Similarly we can define intents on the return type
|
||||||
// refElement returns a reference to an element of array
|
// refElement returns a reference to an element of array
|
||||||
proc refElement( array : [?D] ?T, idx ) ref : T {
|
proc refElement( array : [?D] ?T, idx ) ref : T {
|
||||||
return array[ idx ]; // returns a reference to
|
return array[ idx ]; // returns a reference to
|
||||||
}
|
}
|
||||||
|
|
||||||
var myChangingArray : [1..5] int = [1,2,3,4,5];
|
var myChangingArray : [1..5] int = [1,2,3,4,5];
|
||||||
writeln( myChangingArray );
|
writeln( myChangingArray );
|
||||||
// Store reference to element in ref variable
|
// Store reference to element in ref variable
|
||||||
ref refToElem = refElement( myChangingArray, 5 );
|
ref refToElem = refElement( myChangingArray, 5 );
|
||||||
writeln( refToElem );
|
writeln( refToElem );
|
||||||
refToElem = -2; // modify reference which modifies actual value in array
|
refToElem = -2; // modify reference which modifies actual value in array
|
||||||
writeln( refToElem );
|
writeln( refToElem );
|
||||||
writeln( myChangingArray );
|
writeln( myChangingArray );
|
||||||
// This makes more practical sense for class methods where references to
|
// This makes more practical sense for class methods where references to
|
||||||
// elements in a data-structure are returned via a method or iterator
|
// elements in a data-structure are returned via a method or iterator
|
||||||
|
|
||||||
// We can query the type of arguments to generic procedures
|
// We can query the type of arguments to generic procedures
|
||||||
@@ -520,7 +520,7 @@ genericProc( 1.0+2.0i, 3.0+4.0i );
|
|||||||
|
|
||||||
// We can also enforce a form of polymorphism with the 'where' clause
|
// We can also enforce a form of polymorphism with the 'where' clause
|
||||||
// This allows the compiler to decide which function to use.
|
// This allows the compiler to decide which function to use.
|
||||||
// Note: that means that all information needs to be known at compile-time.
|
// Note: that means that all information needs to be known at compile-time.
|
||||||
// The param modifier on the arg is used to enforce this constraint.
|
// The param modifier on the arg is used to enforce this constraint.
|
||||||
proc whereProc( param N : int ): void
|
proc whereProc( param N : int ): void
|
||||||
where ( N > 0 ) {
|
where ( N > 0 ) {
|
||||||
@@ -534,7 +534,7 @@ proc whereProc( param N : int ): void
|
|||||||
|
|
||||||
whereProc( 10 );
|
whereProc( 10 );
|
||||||
whereProc( -1 );
|
whereProc( -1 );
|
||||||
// whereProc( 0 ) would result in a compiler error because there
|
// whereProc( 0 ) would result in a compiler error because there
|
||||||
// are no functions that satisfy the where clause's condition.
|
// are no functions that satisfy the where clause's condition.
|
||||||
// We could have defined a whereProc without a where clause that would then have
|
// We could have defined a whereProc without a where clause that would then have
|
||||||
// served as a catch all for all the other cases (of which there is only one).
|
// served as a catch all for all the other cases (of which there is only one).
|
||||||
@@ -543,7 +543,7 @@ whereProc( -1 );
|
|||||||
// We can define the unary operators:
|
// We can define the unary operators:
|
||||||
// + - ! ~
|
// + - ! ~
|
||||||
// and the binary operators:
|
// and the binary operators:
|
||||||
// + - * / % ** == <= >= < > << >> & | ˆ by
|
// + - * / % ** == <= >= < > << >> & | ˆ by
|
||||||
// += -= *= /= %= **= &= |= ˆ= <<= >>= <=>
|
// += -= *= /= %= **= &= |= ˆ= <<= >>= <=>
|
||||||
|
|
||||||
// Boolean exclusive or operator
|
// Boolean exclusive or operator
|
||||||
@@ -569,14 +569,14 @@ Note: You could break everything if you get careless with your overloads.
|
|||||||
This here will break everything. Don't do it.
|
This here will break everything. Don't do it.
|
||||||
proc +( left: int, right: int ): int{
|
proc +( left: int, right: int ): int{
|
||||||
return left - right;
|
return left - right;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Iterators are a sisters to the procedure, and almost
|
// Iterators are a sisters to the procedure, and almost
|
||||||
// everything about procedures also applies to iterators
|
// everything about procedures also applies to iterators
|
||||||
// However, instead of returning a single value,
|
// However, instead of returning a single value,
|
||||||
// iterators yield many values to a loop.
|
// iterators yield many values to a loop.
|
||||||
// This is useful when a complicated set or order of iterations is needed but
|
// This is useful when a complicated set or order of iterations is needed but
|
||||||
// allows the code defining the iterations to be separate from the loop body.
|
// allows the code defining the iterations to be separate from the loop body.
|
||||||
iter oddsThenEvens( N: int ): int {
|
iter oddsThenEvens( N: int ): int {
|
||||||
for i in 1..N by 2 do
|
for i in 1..N by 2 do
|
||||||
@@ -601,15 +601,15 @@ for i in absolutelyNothing( 10 ){
|
|||||||
writeln( "Woa there! absolutelyNothing yielded ", i );
|
writeln( "Woa there! absolutelyNothing yielded ", i );
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can zipper together two or more iterators (who have the same number
|
// We can zipper together two or more iterators (who have the same number
|
||||||
// of iterations) using zip() to create a single zipped iterator, where each
|
// of iterations) using zip() to create a single zipped iterator, where each
|
||||||
// iteration of the zipped iterator yields a tuple of one value yielded
|
// iteration of the zipped iterator yields a tuple of one value yielded
|
||||||
// from each iterator.
|
// from each iterator.
|
||||||
// Ranges have implicit iterators
|
// Ranges have implicit iterators
|
||||||
for (positive, negative) in zip( 1..5, -5..-1) do
|
for (positive, negative) in zip( 1..5, -5..-1) do
|
||||||
writeln( (positive, negative) );
|
writeln( (positive, negative) );
|
||||||
|
|
||||||
// Zipper iteration is quite important in the assignment of arrays,
|
// Zipper iteration is quite important in the assignment of arrays,
|
||||||
// slices of arrays, and array/loop expressions.
|
// slices of arrays, and array/loop expressions.
|
||||||
var fromThatArray : [1..#5] int = [1,2,3,4,5];
|
var fromThatArray : [1..#5] int = [1,2,3,4,5];
|
||||||
var toThisArray : [100..#5] int;
|
var toThisArray : [100..#5] int;
|
||||||
@@ -629,10 +629,10 @@ for (i, j) in zip( toThisArray.domain, -100..#5 ){
|
|||||||
}
|
}
|
||||||
writeln( toThisArray );
|
writeln( toThisArray );
|
||||||
|
|
||||||
// This is all very important in undestanding why the statement
|
// This is all very important in undestanding why the statement
|
||||||
// var iterArray : [1..10] int = [ i in 1..10 ] if ( i % 2 == 1 ) then j;
|
// var iterArray : [1..10] int = [ i in 1..10 ] if ( i % 2 == 1 ) then j;
|
||||||
// exhibits a runtime error.
|
// exhibits a runtime error.
|
||||||
// Even though the domain of the array and the loop-expression are
|
// Even though the domain of the array and the loop-expression are
|
||||||
// the same size, the body of the expression can be though of as an iterator.
|
// the same size, the body of the expression can be though of as an iterator.
|
||||||
// Because iterators can yield nothing, that iterator yields a different number
|
// Because iterators can yield nothing, that iterator yields a different number
|
||||||
// of things than the domain of the array or loop, which is not allowed.
|
// of things than the domain of the array or loop, which is not allowed.
|
||||||
@@ -641,8 +641,8 @@ writeln( toThisArray );
|
|||||||
// They currently lack privatization
|
// They currently lack privatization
|
||||||
class MyClass {
|
class MyClass {
|
||||||
// Member variables
|
// Member variables
|
||||||
var memberInt : int;
|
var memberInt : int;
|
||||||
var memberBool : bool = true;
|
var memberBool : bool = true;
|
||||||
|
|
||||||
// Classes have default constructors that don't need to be coded (see below)
|
// Classes have default constructors that don't need to be coded (see below)
|
||||||
// Our explicitly defined constructor
|
// Our explicitly defined constructor
|
||||||
@@ -659,28 +659,28 @@ class MyClass {
|
|||||||
proc setMemberInt( val: int ){
|
proc setMemberInt( val: int ){
|
||||||
this.memberInt = val;
|
this.memberInt = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc setMemberBool( val: bool ){
|
proc setMemberBool( val: bool ){
|
||||||
this.memberBool = val;
|
this.memberBool = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc getMemberInt( ): int{
|
proc getMemberInt( ): int{
|
||||||
return this.memberInt;
|
return this.memberInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc getMemberBool( ): bool {
|
proc getMemberBool( ): bool {
|
||||||
return this.memberBool;
|
return this.memberBool;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct using default constructor, using default values
|
// Construct using default constructor, using default values
|
||||||
var myObject = new MyClass( 10 );
|
var myObject = new MyClass( 10 );
|
||||||
myObject = new MyClass( memberInt = 10 ); // Equivalent
|
myObject = new MyClass( memberInt = 10 ); // Equivalent
|
||||||
writeln( myObject.getMemberInt( ) );
|
writeln( myObject.getMemberInt( ) );
|
||||||
// ... using our values
|
// ... using our values
|
||||||
var myDiffObject = new MyClass( -1, true );
|
var myDiffObject = new MyClass( -1, true );
|
||||||
myDiffObject = new MyClass( memberInt = -1,
|
myDiffObject = new MyClass( memberInt = -1,
|
||||||
memberBool = true ); // Equivalent
|
memberBool = true ); // Equivalent
|
||||||
writeln( myDiffObject );
|
writeln( myDiffObject );
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ var myOtherObject = new MyClass( 1.95 );
|
|||||||
myOtherObject = new MyClass( val = 1.95 ); // Equivalent
|
myOtherObject = new MyClass( val = 1.95 ); // Equivalent
|
||||||
writeln( myOtherObject.getMemberInt( ) );
|
writeln( myOtherObject.getMemberInt( ) );
|
||||||
|
|
||||||
// We can define an operator on our class as well but
|
// We can define an operator on our class as well but
|
||||||
// the definition has to be outside the class definition
|
// the definition has to be outside the class definition
|
||||||
proc +( A : MyClass, B : MyClass) : MyClass {
|
proc +( A : MyClass, B : MyClass) : MyClass {
|
||||||
return new MyClass( memberInt = A.getMemberInt( ) + B.getMemberInt( ),
|
return new MyClass( memberInt = A.getMemberInt( ) + B.getMemberInt( ),
|
||||||
@@ -715,46 +715,46 @@ class GenericClass {
|
|||||||
type classType;
|
type classType;
|
||||||
var classDomain: domain(1);
|
var classDomain: domain(1);
|
||||||
var classArray: [classDomain] classType;
|
var classArray: [classDomain] classType;
|
||||||
|
|
||||||
// Explicit constructor
|
// Explicit constructor
|
||||||
proc GenericClass( type classType, elements : int ){
|
proc GenericClass( type classType, elements : int ){
|
||||||
this.classDomain = {1..#elements};
|
this.classDomain = {1..#elements};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy constructor
|
// Copy constructor
|
||||||
// Note: We still have to put the type as an argument, but we can
|
// Note: We still have to put the type as an argument, but we can
|
||||||
// default to the type of the other object using the query (?) operator
|
// default to the type of the other object using the query (?) operator
|
||||||
// Further, we can take advantage of this to allow our copy constructor
|
// Further, we can take advantage of this to allow our copy constructor
|
||||||
// to copy classes of different types and cast on the fly
|
// to copy classes of different types and cast on the fly
|
||||||
proc GenericClass( other : GenericClass(?otherType),
|
proc GenericClass( other : GenericClass(?otherType),
|
||||||
type classType = otherType ) {
|
type classType = otherType ) {
|
||||||
this.classDomain = other.classDomain;
|
this.classDomain = other.classDomain;
|
||||||
// Copy and cast
|
// Copy and cast
|
||||||
for idx in this.classDomain do this[ idx ] = other[ idx ] : classType;
|
for idx in this.classDomain do this[ idx ] = other[ idx ] : classType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define bracket notation on a GenericClass
|
// Define bracket notation on a GenericClass
|
||||||
// object so it can behave like a normal array
|
// object so it can behave like a normal array
|
||||||
// i.e. objVar[ i ] or objVar( i )
|
// i.e. objVar[ i ] or objVar( i )
|
||||||
proc this( i : int ) ref : classType {
|
proc this( i : int ) ref : classType {
|
||||||
return this.classArray[ i ];
|
return this.classArray[ i ];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define an implicit iterator for the class
|
// Define an implicit iterator for the class
|
||||||
// to yield values from the array to a loop
|
// to yield values from the array to a loop
|
||||||
// i.e. for i in objVar do ....
|
// i.e. for i in objVar do ....
|
||||||
iter these( ) ref : classType {
|
iter these( ) ref : classType {
|
||||||
for i in this.classDomain do
|
for i in this.classDomain do
|
||||||
yield this[i];
|
yield this[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var realList = new GenericClass( real, 10 );
|
var realList = new GenericClass( real, 10 );
|
||||||
// We can assign to the member array of the object using the bracket
|
// We can assign to the member array of the object using the bracket
|
||||||
// notation that we defined ( proc this( i: int ){ ... } )
|
// notation that we defined ( proc this( i: int ){ ... } )
|
||||||
for i in realList.classDomain do realList[i] = i + 1.0;
|
for i in realList.classDomain do realList[i] = i + 1.0;
|
||||||
// We can iterate over the values in our list with the iterator
|
// We can iterate over the values in our list with the iterator
|
||||||
// we defined ( iter these( ){ ... } )
|
// we defined ( iter these( ){ ... } )
|
||||||
for value in realList do write( value, ", " );
|
for value in realList do write( value, ", " );
|
||||||
writeln( );
|
writeln( );
|
||||||
@@ -777,23 +777,23 @@ writeln( );
|
|||||||
module OurModule {
|
module OurModule {
|
||||||
// We can use modules inside of other modules.
|
// We can use modules inside of other modules.
|
||||||
use Time; // Time is one of the standard modules.
|
use Time; // Time is one of the standard modules.
|
||||||
|
|
||||||
// We'll use this procedure in the parallelism section.
|
// We'll use this procedure in the parallelism section.
|
||||||
proc countdown( seconds: int ){
|
proc countdown( seconds: int ){
|
||||||
for i in 1..seconds by -1 {
|
for i in 1..seconds by -1 {
|
||||||
writeln( i );
|
writeln( i );
|
||||||
sleep( 1 );
|
sleep( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submodules of OurModule
|
// Submodules of OurModule
|
||||||
// It is possible to create arbitrarily deep module nests.
|
// It is possible to create arbitrarily deep module nests.
|
||||||
module ChildModule {
|
module ChildModule {
|
||||||
proc foo(){
|
proc foo(){
|
||||||
writeln( "ChildModule.foo()");
|
writeln( "ChildModule.foo()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module SiblingModule {
|
module SiblingModule {
|
||||||
proc foo(){
|
proc foo(){
|
||||||
writeln( "SiblingModule.foo()" );
|
writeln( "SiblingModule.foo()" );
|
||||||
@@ -806,7 +806,7 @@ module OurModule {
|
|||||||
use OurModule;
|
use OurModule;
|
||||||
|
|
||||||
// At this point we have not used ChildModule or SiblingModule so their symbols
|
// At this point we have not used ChildModule or SiblingModule so their symbols
|
||||||
// (i.e. foo ) are not available to us.
|
// (i.e. foo ) are not available to us.
|
||||||
// However, the module names are, and we can explicitly call foo() through them.
|
// However, the module names are, and we can explicitly call foo() through them.
|
||||||
SiblingModule.foo(); // Calls SiblingModule.foo()
|
SiblingModule.foo(); // Calls SiblingModule.foo()
|
||||||
|
|
||||||
@@ -821,13 +821,13 @@ foo(); // Less explicit call on ChildModule.foo()
|
|||||||
proc main(){
|
proc main(){
|
||||||
|
|
||||||
// Parallelism
|
// Parallelism
|
||||||
// In other languages, parallelism is typically done with
|
// In other languages, parallelism is typically done with
|
||||||
// complicated libraries and strange class structure hierarchies.
|
// complicated libraries and strange class structure hierarchies.
|
||||||
// Chapel has it baked right into the language.
|
// Chapel has it baked right into the language.
|
||||||
|
|
||||||
// A begin statement will spin the body of that statement off
|
// A begin statement will spin the body of that statement off
|
||||||
// into one new task.
|
// into one new task.
|
||||||
// A sync statement will ensure that the progress of the main
|
// A sync statement will ensure that the progress of the main
|
||||||
// task will not progress until the children have synced back up.
|
// task will not progress until the children have synced back up.
|
||||||
sync {
|
sync {
|
||||||
begin { // Start of new task's body
|
begin { // Start of new task's body
|
||||||
@@ -848,7 +848,7 @@ proc main(){
|
|||||||
printFibb( 20 ); // new task
|
printFibb( 20 ); // new task
|
||||||
printFibb( 10 ); // new task
|
printFibb( 10 ); // new task
|
||||||
printFibb( 5 ); // new task
|
printFibb( 5 ); // new task
|
||||||
{
|
{
|
||||||
// This is a nested statement body and thus is a single statement
|
// This is a nested statement body and thus is a single statement
|
||||||
// to the parent statement and is executed by a single task
|
// to the parent statement and is executed by a single task
|
||||||
writeln( "this gets" );
|
writeln( "this gets" );
|
||||||
@@ -867,26 +867,26 @@ proc main(){
|
|||||||
// NOTE! coforall should be used only for creating tasks!
|
// NOTE! coforall should be used only for creating tasks!
|
||||||
// Using it to iterating over a structure is very a bad idea!
|
// Using it to iterating over a structure is very a bad idea!
|
||||||
|
|
||||||
// forall loops are another parallel loop, but only create a smaller number
|
// forall loops are another parallel loop, but only create a smaller number
|
||||||
// of tasks, specifically --dataParTasksPerLocale=number of task
|
// of tasks, specifically --dataParTasksPerLocale=number of task
|
||||||
forall i in 1..100 {
|
forall i in 1..100 {
|
||||||
write( i, ", ");
|
write( i, ", ");
|
||||||
}
|
}
|
||||||
writeln( );
|
writeln( );
|
||||||
// Here we see that there are sections that are in order, followed by
|
// Here we see that there are sections that are in order, followed by
|
||||||
// a section that would not follow ( e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6, ).
|
// a section that would not follow ( e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6, ).
|
||||||
// This is because each task is taking on a chunk of the range 1..10
|
// This is because each task is taking on a chunk of the range 1..10
|
||||||
// (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
|
// (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
|
||||||
// in parallel.
|
// in parallel.
|
||||||
// Your results may depend on your machine and configuration
|
// Your results may depend on your machine and configuration
|
||||||
|
|
||||||
// For both the forall and coforall loops, the execution of the
|
// For both the forall and coforall loops, the execution of the
|
||||||
// parent task will not continue until all the children sync up.
|
// parent task will not continue until all the children sync up.
|
||||||
|
|
||||||
// forall loops are particularly useful for parallel iteration over arrays.
|
// forall loops are particularly useful for parallel iteration over arrays.
|
||||||
// Lets run an experiment to see how much faster a parallel loop is
|
// Lets run an experiment to see how much faster a parallel loop is
|
||||||
use Time; // Import the Time module to use Timer objects
|
use Time; // Import the Time module to use Timer objects
|
||||||
var timer: Timer;
|
var timer: Timer;
|
||||||
var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into
|
var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into
|
||||||
|
|
||||||
// Serial Experiment
|
// Serial Experiment
|
||||||
@@ -906,7 +906,7 @@ proc main(){
|
|||||||
timer.stop( ); // Stop timer
|
timer.stop( ); // Stop timer
|
||||||
writeln( "Parallel: ", timer.elapsed( ) ); // Print elapsed time
|
writeln( "Parallel: ", timer.elapsed( ) ); // Print elapsed time
|
||||||
timer.clear( );
|
timer.clear( );
|
||||||
// You may have noticed that (depending on how many cores you have)
|
// You may have noticed that (depending on how many cores you have)
|
||||||
// that the parallel loop went faster than the serial loop
|
// that the parallel loop went faster than the serial loop
|
||||||
|
|
||||||
// The bracket style loop-expression described
|
// The bracket style loop-expression described
|
||||||
@@ -926,15 +926,15 @@ proc main(){
|
|||||||
writeln( uranium.read() );
|
writeln( uranium.read() );
|
||||||
|
|
||||||
var replaceWith = 239;
|
var replaceWith = 239;
|
||||||
var was = uranium.exchange( replaceWith );
|
var was = uranium.exchange( replaceWith );
|
||||||
writeln( "uranium was ", was, " but is now ", replaceWith );
|
writeln( "uranium was ", was, " but is now ", replaceWith );
|
||||||
|
|
||||||
var isEqualTo = 235;
|
var isEqualTo = 235;
|
||||||
if ( uranium.compareExchange( isEqualTo, replaceWith ) ) {
|
if ( uranium.compareExchange( isEqualTo, replaceWith ) ) {
|
||||||
writeln( "uranium was equal to ", isEqualTo,
|
writeln( "uranium was equal to ", isEqualTo,
|
||||||
" so replaced value with ", replaceWith );
|
" so replaced value with ", replaceWith );
|
||||||
} else {
|
} else {
|
||||||
writeln( "uranium was not equal to ", isEqualTo,
|
writeln( "uranium was not equal to ", isEqualTo,
|
||||||
" so value stays the same... whatever it was" );
|
" so value stays the same... whatever it was" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -989,14 +989,14 @@ proc main(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heres an example of using atomics and a synch variable to create a
|
// Heres an example of using atomics and a synch variable to create a
|
||||||
// count-down mutex (also known as a multiplexer)
|
// count-down mutex (also known as a multiplexer)
|
||||||
var count: atomic int; // our counter
|
var count: atomic int; // our counter
|
||||||
var lock$: sync bool; // the mutex lock
|
var lock$: sync bool; // the mutex lock
|
||||||
|
|
||||||
count.write( 2 ); // Only let two tasks in at a time.
|
count.write( 2 ); // Only let two tasks in at a time.
|
||||||
lock$.writeXF( true ); // Set lock$ to full (unlocked)
|
lock$.writeXF( true ); // Set lock$ to full (unlocked)
|
||||||
// Note: The value doesnt actually matter, just the state
|
// Note: The value doesnt actually matter, just the state
|
||||||
// (full:unlocked / empty:locked)
|
// (full:unlocked / empty:locked)
|
||||||
// Also, writeXF() fills (F) the sync var regardless of its state (X)
|
// Also, writeXF() fills (F) the sync var regardless of its state (X)
|
||||||
|
|
||||||
@@ -1005,10 +1005,10 @@ proc main(){
|
|||||||
do{
|
do{
|
||||||
lock$; // Read lock$ (wait)
|
lock$; // Read lock$ (wait)
|
||||||
}while ( count.read() < 1 ); // Keep waiting until a spot opens up
|
}while ( count.read() < 1 ); // Keep waiting until a spot opens up
|
||||||
|
|
||||||
count.sub(1); // decrement the counter
|
count.sub(1); // decrement the counter
|
||||||
lock$.writeXF( true ); // Set lock$ to full (signal)
|
lock$.writeXF( true ); // Set lock$ to full (signal)
|
||||||
|
|
||||||
// Actual 'work'
|
// Actual 'work'
|
||||||
writeln( "Task #", task, " doing work." );
|
writeln( "Task #", task, " doing work." );
|
||||||
sleep( 2 );
|
sleep( 2 );
|
||||||
@@ -1027,13 +1027,13 @@ proc main(){
|
|||||||
|
|
||||||
// 'maxloc' gives max value and index of the max value
|
// 'maxloc' gives max value and index of the max value
|
||||||
// Note: We have to zip the array and domain together with the zip iterator
|
// Note: We have to zip the array and domain together with the zip iterator
|
||||||
var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues,
|
var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues,
|
||||||
listOfValues.domain);
|
listOfValues.domain);
|
||||||
|
|
||||||
writeln( (sumOfValues, maxValue, idxOfMax, listOfValues[ idxOfMax ] ) );
|
writeln( (sumOfValues, maxValue, idxOfMax, listOfValues[ idxOfMax ] ) );
|
||||||
|
|
||||||
// Scans apply the operation incrementally and return an array of the
|
// Scans apply the operation incrementally and return an array of the
|
||||||
// value of the operation at that index as it progressed through the
|
// value of the operation at that index as it progressed through the
|
||||||
// array from array.domain.low to array.domain.high
|
// array from array.domain.low to array.domain.high
|
||||||
var runningSumOfValues = + scan listOfValues;
|
var runningSumOfValues = + scan listOfValues;
|
||||||
var maxScan = max scan listOfValues;
|
var maxScan = max scan listOfValues;
|
||||||
@@ -1046,14 +1046,14 @@ Who is this tutorial for?
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
This tutorial is for people who want to learn the ropes of chapel without having to hear about what fiber mixture the ropes are, or how they were braided, or how the braid configurations differ between one another.
|
This tutorial is for people who want to learn the ropes of chapel without having to hear about what fiber mixture the ropes are, or how they were braided, or how the braid configurations differ between one another.
|
||||||
It won't teach you how to develop amazingly performant code, and it's not exhaustive.
|
It won't teach you how to develop amazingly performant code, and it's not exhaustive.
|
||||||
Refer to the [language specification](http://chapel.cray.com/language.html) and the [module documentation](http://chapel.cray.com/docs/latest/) for more details.
|
Refer to the [language specification](http://chapel.cray.com/language.html) and the [module documentation](http://chapel.cray.com/docs/latest/) for more details.
|
||||||
|
|
||||||
Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to see if more topics have been added or more tutorials created.
|
Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to see if more topics have been added or more tutorials created.
|
||||||
|
|
||||||
### What this tutorial is lacking:
|
### What this tutorial is lacking:
|
||||||
|
|
||||||
* Exposition of the standard modules
|
* Exposition of the [standard modules](http://chapel.cray.com/docs/latest/modules/modules.html)
|
||||||
* Multiple Locales (distributed memory system)
|
* Multiple Locales (distributed memory system)
|
||||||
* Records
|
* Records
|
||||||
* Parallel iterators
|
* Parallel iterators
|
||||||
@@ -1061,11 +1061,11 @@ Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to
|
|||||||
Your input, questions, and discoveries are important to the developers!
|
Your input, questions, and discoveries are important to the developers!
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
The Chapel language is still in-development (version 1.11.0), so there are occasional hiccups with performance and language features.
|
The Chapel language is still in-development (version 1.12.0), so there are occasional hiccups with performance and language features.
|
||||||
The more information you give the Chapel development team about issues you encounter or features you would like to see, the better the language becomes.
|
The more information you give the Chapel development team about issues you encounter or features you would like to see, the better the language becomes.
|
||||||
Feel free to email the team and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman).
|
Feel free to email the team and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman).
|
||||||
|
|
||||||
If you're really interested in the development of the compiler or contributing to the project,
|
If you're really interested in the development of the compiler or contributing to the project,
|
||||||
[check out the master Github repository](https://github.com/chapel-lang/chapel).
|
[check out the master Github repository](https://github.com/chapel-lang/chapel).
|
||||||
It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
|
It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
|
||||||
@@ -1074,10 +1074,10 @@ Installing the Compiler
|
|||||||
|
|
||||||
Chapel can be built and installed on your average 'nix machine (and cygwin).
|
Chapel can be built and installed on your average 'nix machine (and cygwin).
|
||||||
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
|
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
|
||||||
and its as easy as
|
and its as easy as
|
||||||
|
|
||||||
1. `tar -xvf chapel-1.11.0.tar.gz`
|
1. `tar -xvf chapel-1.12.0.tar.gz`
|
||||||
2. `cd chapel-1.11.0`
|
2. `cd chapel-1.12.0`
|
||||||
3. `make`
|
3. `make`
|
||||||
4. `source util/setchplenv.bash # or .sh or .csh or .fish`
|
4. `source util/setchplenv.bash # or .sh or .csh or .fish`
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user