--- layout: post title: "Where to put unit tests" description: "This article provides arguments for (and against) putting unit tests in libraries different from the production code." date: 2013-06-17 09:22 UTC tags: [Unit Testing] --- {% include JB/setup %}
{{ page.description }}
One of my readers ask me "whether unit tests should be done in separate assemblies or if they should be done in [...] the production assemblies?" As he puts it, he "always took for granted that the test should go into separate assemblies," but is this really true, and if it is: what are the arguments?
Despite the fundamental nature of this question, I haven't seen much explicit treatment of it, and to answer it, I had to pause and think. The key to the answer, I think, is to first understand why you write automated tests at all. (This way of thinking about questions and answers is closely related to the (Lean) technique of 5 whys.)
As always, the short answer is that it depends, but that's not very helpful, so here are some common reasons.
In my experience, most people focus on the quality control aspect of automated testing. If your only purpose of having automated tests is to have a good regression test suite, then it seems that it doesn't really matter where the tests go.
Still, even if that's your only reason for unit testing, I think putting the unit tests in a separate library is the best choice:
In short, if you put unit tests in the same library as your production code, all that unit test must adhere to the same standards as your production code. Obviously, if you have no standards for your production code, this doesn't apply, but then you probably have bigger problems.
While I find regression testing useful in itself, I find Test-Driven Development (TDD) particularly valuable because it provides feedback about the API I'm building. In the spirit of GOOS, if the test is difficult to write, it's probably because the API is difficult to use. You'll only get this feedback if you test against the public API of your code; the unit test is the first client of your API.
However, if your unit tests reside in the same library as your production code, you can easily invoke internal classes and members from your unit tests. You simply lose the opportunity to get valuable feedback about the usability of your code. (Note that this argument also applies to the use of the [InternalsVisibleTo] attribute, which means that you should never use it.)
For me, this reason alone is enough that I always prefer putting unit tests in separate libraries.
Although I think that there are strong arguments against putting unit tests in production code, there may also be reasons in favor. As one answer on Stack Overflow describes, shipping your production code with a test suite can be valuable as a self-diagnostics tool. This might be particularly valuable if you deploy your production code to heterogeneous environments, and you're unable to predict and test the configuration of all environments before you ship your code.
In the end, the answer depends on your context. If you understand why you (want to) have unit tests, you'll be able to answer the initial question: should unit tests go in a separate library, or can they go in the same library as the production code? In mainstream scenarios I will strongly recommend putting tests in a separate library, but you may have special circumstances where it makes sense to put the tests together with the production code. As long as you understand the pros and cons, you can make your own informed decision.
Comments
Another big issue with having tests in your production code is that you will drag along depencencies to test libraries. You mention this in the second issue above but I think it would be a good idea to state it more explicitly.
Could you share your opinion on bundling test projects with their target projects in source control repositories? I use Git, but I would imagine this is applicable in many source control implementations.
I currently keep my tests in their own projects, as you generally recommend here, and also track them in their own Git repository, separately from the tested project. However, I'm finding that when I create a new branch to add a new feature in the project, I create the same branch in the test project. This is critical especially in situations where the new behavior necessarily causes existing tests to fail. If I forget to create a new branch in the test project to match the new branch in the project under test, it can sometimes lead to annoying clean-up work that was preventable.
I am beginning to question why I'm not combining the test project and the tested project in the same Git repository, so that when I branch out on a new idea, I only need to do it once, and my tests are forever in sync with my tested code. I haven't come across a scenario where that would cause problems - can you think of any compelling reason not to keep the projects in the same source control repository?
Jeff, thank you for writing.
If I were to exaggerate a bit, I would claim that I've used Test-Driven Development (TDD) longer than I've used source control systems, so it has never occurred to me to keep tests in a separate repository. It sounds really... inconvenient, but I've never tried it, so I don't know if it's a good or bad idea. Yet, in all that time, I've never had any problems keeping tests and production code in the same version control repository.
With TDD, the tests are such an integral part of the code base that I wouldn't like to experiment with keeping them in a different repository. Additionally, when you use a test suite as a regression test suite, it's important that you version tests and production code together. This also means tagging them together.
If you take a look at the various code bases I maintain on GitHub, you will also see that all of them include unit tests as part of each repository.


"This is as rock; tolk in the True Speech."
from A Wizard of Earthsea by
Ursula K. Le Guin
This document contains materials used to teach Nemerle during the "Nemerle Programming Language" course taught at our institute. It should make a good tutorial.
There are references to various languages throughout this document. If you don't know much about these languages -- just ignore these remarks. As for remarks for the C language -- unless otherwise stated they also apply to C# and Java.
Some links: grokking?!, don't panic.
This page is a part of the Grokking Nemerle tutorial.
This chapter explains what a basic program looks like in Nemerle. This is the longest and probably the hardest lesson, so don't worry if you don't understand everything at once.
Contents |
In order to run programs written in Nemerle you need to compile them to .NET bytecode first. This is done with the ncc (Nemerle Compiler Compiler) command. Assuming the Nemerle is installed properly on your system, you need to do the following:
You cannot define either functions or values at the top level in Nemerle. You need to pack them into classes or modules. For C#, Java and C++ programmers: a module is a class with all members static, there can be no instance of module class.
For now you should consider the module to be a form of packing related functions together.
class SomeClass { // ... some comment ... some_field : int; /* ... some ... ... multiline comment ... */ other_field : string; }
The above example also introduces two kinds of comments used in Nemerle. The comments starting with // are active until the end of line, while the comments starting with /* are active until */. This is the same as in C (well, C99).
Classes can contain methods (functions) as well as fields
(values). Both kind of members can be prefixed with access attributes:
In the method declaration header you first write modifiers, then the name of the method, then parameters with a type specification and finally a type of values returned from this function.
Typing constraints are in general written after a colon (:).
class Foo { public SomeMethod () : void { // ... } private some_other_method (_x : int) : void { // ... } private Frobnicate (_x : int, _y : string) : int { // we return some int value here 0 } internal foo_bar () : void { // ... } }
Fields define global values inside the module.
Fields accept the same access attributes as methods. However, there is one additional very important attribute for fields -- mutable.
By default fields are read only, that is they can be assigned values only in the module initializer function (codenamed this; we will talk about it later). If you want to assign values to fields in other places you need to mark a field mutable.
class Bar { public mutable qux : int; private quxx : int; mutable bar : float; }
Nemerle makes no distinction between an expression and a statement, there are only expressions. The idea is to easily operate on values, which every expression returns as a result of its computation. The exception is a throw keyword, which breaks control flow by throwing an exception (the breaking statements were adopted in Nemerle using the block construct, which makes jumps localised and fit well into the expressions-only concept).
Also { } sequence is an expression, which have its value - the value of the last expression in it. This eliminates the need for return statement in functions. The value returned from a function is the last value computed in its body. You can think that there is an implicit return at the end of each function. This is the same as in ML languages.
Despite all that, the most basic example looks almost like in C#. The entry point for a program is a function called Main. It is also possible to take command line arguments and/or return integer return code from the Main method, consult .NET reference for details.
Note that unlike in ML function call requires ().
class Hello { public static Main () : void { System.Console.WriteLine ("Hello cruel world!") } }
However, the following example (computing Fibonacci sequence) looks somewhat different. You can see the usage of a conditional expression. Note how the value is returned from the function without any explicit return statement.
Note that this example and the following ones are not complete. To be compiled they need to be packed into the module, equipped with the Main function and so on.
fib (n : int) : int { if (n < 2) 1 else fib (n - 1) + fib (n - 2) }
It is possible to use regular imperative loops like while and for. Both work as in C. In the example of the for loop the first expression is put before the loop, the second expression is the condition (the loop is executed as long as the condition holds) and the last expression is put at the end of the loop.
However, the most important thing about this example is the variable definition used here. Variables (values that can be changed) are defined using the mutable expression. You do not specify a type, but you do specify an initial value. The type of the defined variable is inferred from the initial value (for example the type of 1 is obviously an int). The variable introduced with mutable is visible until the end of the current sequence. Lexical scoping rules apply: the definition of a new value with the same name hides the previous one.
Sequence is a list of expressions enclosed in braces ({}) and separated with semicolons (;). An optional semicolon is allowed at the end of the sequence. Note that the function definition also introduces a sequence (as the function body is written in {}).
mutable defines variables that can be updated using the assignment operator (=). In contrast def defines values that cannot be updated -- in our example we use tmp as such value.
Older versions of the Nemerle compiler required a semicolon after the closing brace inside a sequence. This is no longer mandatory: note that for expression's closing brace is not followed by a semicolon. In some rare cases this can introduce compilation errors -- remember that you can always put a semicolon there!
fib (n : int) : int { mutable last1 = 1; mutable last2 = 1; for (mutable cur = 1; cur < n; ++cur) { def tmp = last1 + last2; last1 = last2; last2 = tmp; } last2 }
In this example we see no gain from using def. instead of int as you would do in C# (both are 3 characters long :-). However, in most cases type names are far longer. For example:
FooBarQuxxFactory fact = new FooBarQuxxFactory (); // C# def fact = FooBarQuxxFactory (); // Nemerle
Local functions are functions defined within other functions. For this reason they are also called nested functions.
There are three reasons for defining local functions. The first one is not to pollute the class namespace. We have the private keyword for that, so this does not seem to be any good reason.
The second one is that local functions can access variables defined in an outer function. This allows for somewhat different (better?) code structuring than in C. You can have several variables and local functions using them defined in a function.
The most important reason for local function is however the fact that you can pass them to other functions so that they can be run from there, implementing for example iterators for data structures. This is explained in more detail later.
Local functions are defined just like other values with the def keyword. A local function definition looks similar to the global one (despite the lack of access modifiers, leading def and the trailing semicolon).
sum_cubes (v1 : int, v2 : int, v3 : int) : int { def cube (x : int) : int { x * x * x } cube (v1) + cube (v2) + cube (v3) }
Using local functions is one of way of implementing loops in Nemerle.
module Sum { public Main () : void { def sum (x : int) : int { if (x <= 0) 0 else x + sum (x - 1) } System.Console.WriteLine ("Sum of numbers from "+ "20 to 0 is: {0}", sum (20)) } }
Notice how the local function is used to organize the loop. This is typical for Nemerle. It is therefore quite important for you to grok this concept. Some external links -- tail recursion, recursion.
Here goes another example of a loop constructed with a local function.
fib (n : int) : int { def my_loop (last1 : int, last2 : int, cur : int) : int { if (cur >= n) last2 else my_loop (last2, last1 + last2, cur + 1) } my_loop (1, 1, 1) }
If you are concerned about performance of such form of writing loops -- fear you not. When the function body ends with a call to another function -- no new stack frame is created. It is called a tail call. Thanks to it the example above is as efficient as the for loop we have seen before.
You can specify types of parameters as well as return types for local functions. However in some (most?) cases the compiler can guess (infer) the types for you, so you can save your fingers by not typing them. This is always safe, that is the program should not in principle change the meaning if type annotations are added.
Sometimes the compiler is unable to safely infer the type information, in which case an error message will be generated to indicate that type annotations are required.
In the following example we have omitted the return type, as well as types of the parameters. Compiler can figure out the types, because literals 1 are used in a few places, which are of the type int.
fib (n : int) : int { def my_loop (last1, last2, cur) { if (cur >= n) last2 else my_loop (last2, last1 + last2, cur + 1) } my_loop (1, 1, 1) }
One of the best things about Nemerle is that you can use rich class libraries that come with the Framework as well as the third party libraries. Links to the documentation about .NET class libraries can be found here.
New objects are constructed by simply naming the type and supplying arguments to its constructor. Note that unlike in C# or Java you don't use the new keyword to construct new objects. Methods of objects can be invoked later, using the dot operator (some_object.SomeMethod (some_argument)). Static methods are invoked using the NameSpace.TypeName.MethodName () syntax. We will talk more about this object oriented stuff later.
Now some example:
the_answer_to_the_universe () : int { // Construct new random number generator. // This is object construction, explained in more detail later def r = System.Random (); // Return new random number from [0, 99] range. // This is again object invocation, explained later r.Next (100) }
For more information about The answer to the Ultimate Question of Life, the Universe and Everything please visit this site. Please note that this program run on a computer not as powerful as Deep Thought will be right only in 1% of cases.
There are several methods of output formatting in Nemerle.
The most basic .NET methods of displaying stuff on the screen is the System.Console.WriteLine method. In the simplest form it takes a string to be displayed. If you however supply it with more then one argument, the first one is treated as a format string and occurrences of {N} are replaced with the value of (N+2)-th parameter (counting from one).
print_answer () : void { def the_answer = the_answer_to_the_universe (); System.Console.WriteLine ("The answer to the Ultimate "+ "Question of Life, the "+ "Universe and Everything "+ "is {0}", the_answer) }
There are however other means, for example the Nemerle.IO.printf macro that works much like the printf(3) C function or Printf.printf in OCaml. (Well it doesn't yet handle most formatting modifiers, but patches are welcome ;-)
printf_answer () : void { def the_answer = the_answer_to_the_universe (); Nemerle.IO.printf ("The answer is %d\n", the_answer); }
If you have ever programmed in Bourne shell, perl, python, php (or some other P-language), you know about string interpolation. It basically takes a string "answer is $the_answer" and replaces $the_answer with value of the variable the_answer. The good news is that we have this feature in Nemerle:
interpolate_answer () : void { def the_answer = the_answer_to_the_universe (); Nemerle.IO.print ("The answer is $the_answer\n"); }
It comes in two flavors -- the first one is the Nemerle.IO.print (without f) function -- it does string interpolation on its sole argument and prints the result on stdout.
The second version is the $ operator, which returns a string and can be used with other printing mechanisms:
interpolate2_answer () : void { def the_answer = the_answer_to_the_universe (); System.Console.WriteLine ($ "The answer is $the_answer"); }
Both versions support special $(...) quotations allowing any code to be expanded, not just variable references:
interpolate3_answer () : void { System.Console.WriteLine ( $ "The answer is $(the_answer_to_the_universe ())"); }
The $-expansion works on all types.
The type of array of T is denoted array [T]. This is a one-dimensional, zero-based array. There are two special expressions for constructing new arrays: array ["foo", "bar", "baz"] will construct a 3-element array of strings, while array (100) creates a 100-element array of something. The something is inferred later, based on an array usage. The empty array is initialized with 0, 0.0, etc. or null for reference types.
The assignment operator (=) can be also used to assign elements in arrays.
Note the ar.Length expression -- it gets the length of array ar. It looks like a field reference in an array object but under the hood it is a method call. This mechanism is called property.
Our arrays are subtypes of System.Array, so all methods available for System.Array are also available for array [T].
class ArraysTest { static reverse_array (ar : array [int]) : void { def loop (left, right) { when (left < right) { def tmp = ar[left]; ar[left] = ar[right]; ar[right] = tmp; loop (left + 1, right - 1) } } loop (0, ar.Length - 1) } static print_array (ar : array [int]) : void { for (mutable i = 0; i < ar.Length; ++i) Nemerle.IO.printf ("%d\n", ar[i]) } static Main () : void { def ar = array [1, 42, 3]; print_array (ar); Nemerle.IO.printf ("\n"); reverse_array (ar); print_array (ar); } }
One interesting thing about this example is the usage of the type enforcement operator -- colon (:). We use it to enforce the left type to be int. We could have as well written def loop (left : int, right) {. This are simply two ways to achieve the same thing.
Another interesting thing is the when expression -- it is an if without else. For symmetry purposes we also have if without then called unless. As you might have already noted unless is equivalent to when with the condition negated.
In Nemerle the if expression always needs to have the else clause.
Multidimensional arrays (unlike arrays of arrays) are also available. Type of two-dimensional integer array is array [2, int], while the expression constructing it is array .[2] [[1, 2], [3, 4]]. They are accessed using the comma-syntax: t[1,0].
Both single- and multidimensional empty arrays can be created with array (size) or array (size1, size2, ...). Empty means that they contain nulls or zeros.
Note that there exist two ways of obtaining multidimensional storage. The first one is the mentioned multidimentional array (type array [N, int]). The second one is array of arrays (type array [array [int]]), which is just a standard array, but its elements are other arrays. This is useful, because you can initialize only some parts of this array, while multidimensional array allocates all the memory at once. Elements of such a array of arrays are accessed by x[2][3].
The equality predicate is written == and the inequality is != as in C.
The boolean operators (&&, || and !) are all available and work the same as in C.
1.1. Write a program that prints out to the console:
1 bottle of beer. 2 bottles of beer. 3 bottles of beer. ... 99 bottles of beer.
With an appropriate amount of beer instead of .... The program source code should not exceed 30 lines.
1.2. Implement bogo sort algorithm for an array of integers. (WARNING: you should not implement destroy the universe step). Test it by sorting the following array: [4242, 42, -42, 31415].
1.3. As 1.2, but don't use the imperative loops -- rewrite them with recursion.
This page is a part of the Grokking Nemerle tutorial.
Classes and modules can be put in namespaces. Namespaces at the conceptual level prepend a string to names of objects defined within them.
namespace Deep.Thought { class Answer { public static Get () : int { 42 } } } namespace Loonquawl { class Brain { public static Run () : void { System.Console.WriteLine ("The answer {0}", Deep.Thought.Answer.Get ()) } } }
As you can see, the name of the Get function is first prepended with the name of the module (Answer) and then with the current namespace (Deep.Thought), forming its full name: Deep.Thought.Answer.Get.
Another example is the WriteLine method of the Console module, defined in the System namespace.
In order not to write System.Console.WriteLine or Deep.Thought.Answer.Get all the time you can import all declarations from the specified namespace into the current scope with the using directive.
Thus the Loonquawl.Brain module from the example above could be:
namespace LoonquawlUsing { using System.Console; using Deep.Thought.Answer; class Brain { public static Run () : void { WriteLine ("The answer is {0}", Get ()) } } }
While we see not much gain from the using directive in this example, it can be handy when you use the WriteLine method 100 times, and/or your classes are in Some.Very.Long.Namespaces.
Note that unlike in C# all methods of a class can be imported into the current namespace. Thus, using is not limited to namespaces, but it also works for classes. The new thing is also the fact, that currently opened namespaces are used as prefix in all type lookups - for example if there is using System;, then you can write Xml.XmlDocument (), or with an additional using System.Xml; you can write XmlDocument (). Neither of these is possible in C#.
It is also possible to create (shorter) aliases for namespaces and types. It is sometimes useful in case when two namespaces share several types, so they cannot be imported with using simultaneously. This works in similar way to C#.
namespace LoonquawlAlias { using SC = System.Console; using DTA = Deep.Thought.Answer; class Brain { public static Run () : void { SC.WriteLine ("The answer is {0}", DTA.Get ()) } } }
This page is a part of the Grokking Nemerle tutorial.
In Nemerle you can pass functions as arguments of other functions, as well as return them as results. This way functions are not worse than any other data types (think about Equal Rights for Functions movement :-)
In C# there are delegates. This concept is quite similar to functional values. However, functional values are far more efficient and their types need not be declared before use.
As a first example consider:
// C# delegate int IntFun (int); class Delegates { static int f(int x) { return x * 2; } static int run_delegate_twice(IntFun f, int v) { return f(f(v)); } static void Main () { System.Console.WriteLine("{0}", run_delegate_twice(new IntFun (f), 3)); } }
// Nemerle class Functions { static f (x : int) : int { x * 2 } static run_funval_twice (f : int -> int, v : int) : int { f (f (v)) } public static Run () : void { System.Console.WriteLine ("{0}", run_funval_twice (f, 3)) } }
In this example delegates seem just like function pointers in C. Functional values do not appear any better, except maybe for the shorter syntax. However, the real power of delegates comes from the fact that methods can be used as delegates (thus effectively embedding the this pointer in the delegate). This is much like "functional objects" design pattern in C++. We will not show it here, please refer to the C# manual for details.
Still using methods as delegates does not demonstrate their full power. The funny part begins when we use nested functions as functional values.
class MoreFunctions { static run_twice (f : int -> int, v : int) : int { f (f (v)) } static run_adder (x : int) : void { def f (y : int) : int { x + y }; System.Console.WriteLine ("{0}", run_twice (f, 1)) } public static Run () : void { run_adder (1); run_adder (2); } }
This example prints 3 and 5. Note how x is captured in the local function f.
Types of functions taking more than one argument are represented as tuples. For example, the following function:
some_function (_arg1 : int, _arg2 : string, _arg3 : SomeFoo) : float { // ... System.Convert.ToSingle (_arg1) }
has the type int * string * Foo -> float. Functions that take no arguments pretend to take one argument of the type void. Thus the function:
other_function () : string { "kaboo" }
possesses the type void -> string.
Lambda expressions are just a syntactic sugar to defined unnamed local functions. Unnamed local functions are useful when you need to pass some function to the iterator, so you use it just once.
Lambda expressions are defined using the fun keyword, followed by formal parameters, an optional return type and the function body.
def x = Nemerle.Collections.List.Map ([1, 2, 3], fun (x) { 2 * x }); def y = Nemerle.Collections.List.FoldLeft (x, 0, fun (val : int, acc) { acc + val }); assert (y == 12);
In general:
fun (parms) { exprs }
is equivalent to:
{ def tmp (parms) { exprs }; tmp }
This feature is similar to anonymous delegates in C# 2.0.
2.1. Write a function
string_pow : int * (string -> string) * string -> string;
The call string_pow (3, f, "foo") should result in calling f three times, i.e. returning result of f (f (f ("foo"))). When you are done, write a second version of string_pow using recursion (if you used imperative loop) or imperative loop (otherwise).
Test it by passing function that replaces "42" with "42ans". You can try passing the functional argument to string_pow as a lambda expression. This method might be useful.
This page is a part of the Grokking Nemerle tutorial.
Tuples are forms of nameless data structures. They are usable when you need to return two or three values from a function.
A tuple is constructed with:
(expr1, expr2, ..., exprN)
and deconstructed with:
def (id1, id2, ..., idN) = expr;
This def thing defines values called id1 through idN and puts respective tuple members into them.
Tuple types are written using the * operator. For example, pair of integers (42, 314) has the type int * int, while ("Zephod", 42.0, 42) has the type string * float * int.
An example follows:
/** Parses time in HH:MM format. */ parse_time (time : string) : int * int { def arr = time.Split (array [':']); (System.Int32.Parse (arr[0]), System.Int32.Parse (arr[1])) } seconds_since_midnight (time : string) : int { def (hours, minutes) = parse_time (time); (hours * 60 + minutes) * 60 } foo () : void { def secs = seconds_since_midnight ("17:42"); ... }
Another example could be:
// split (3.7) => (3, 0.7) split (x : double) : int * double { def floor = System.Math.Floor (x); (System.Convert.ToInt32 (floor), x - floor) }
List literals are special forms of writing lists. Lists are data structures that are used very often in Nemerle - often enough to get their own syntax. Lists in Nemerle are somewhat different than the ArrayList type in .NET.
Of course you are free to use the .NET ArrayList.
Anyway, to construct a list consisting of a given head (first element) and a tail (rest of elements, also a list), write:
head :: tail
To construct a list with specified elements write:
[ element_1, element_2, ..., element_n ]
This way you can also construct an empty list ([]).
This page is a part of the Grokking Nemerle tutorial.
Variants (called data types or sum types in SML and OCaml) are forms of expressing data of several different kinds.
Matching is a way of destructuring complex data structures, especially variants.
Contents |
The simplest example of variants are enum types known from C.
// C enum Color { Red, Yellow, Green }
// Nemerle variant Color { | Red | Yellow | Green }
Note that you can define C#-like enum types in Nemerle anyway.
// Nemerle enum Color { | Red | Yellow | Green }
However, the variant options might be more useful because they can carry some extra data with them:
variant RgbColor { | Red | Yellow | Green | Different { red : float; green : float; blue : float; } }
So if color is neither red, yellow nor green, it can be represented with RGB. You can create variant object just like any other object, by using its constructor (which is always implicitly provided):
// ... def _blue = RgbColor.Different (0f, 0f, 1f); def _red = RgbColor.Red ();
You can think about variants as of a union with a selector in C. In OO world sometimes modeling variants with sub classing can be seen sometimes:
// C# class Color { class Red : Color { } class Green : Color { } class Yellow : Color { } class Different : Color { float red; float green; float blue; public Different (float red, float green, float blue) { this.red = red; this.green = green; this.blue = blue; } } }
Of course you need to write a constructor, mark fields public and so on. When you're done -- using this kind of stuff is quite hard -- you need to use lots of runtime type checks.
On the other hand, Nemerle provides an easy and convenient method of dealing with variants -- pattern matching.
Pattern matching is accomplished with the match expression. Its semantics are to check each pattern in turn, from top to bottom, and execute expression after the first pattern that matched. If no pattern matched, the exception is raised. This is like the switch statement known from C, but using a large dose of steroids.
string_of_color (color : Color) : string { match (color) { | Color.Red => "red" | Color.Yellow => "yellow" | Color.Green => "green" | Color.Different (r, g, b) => System.String.Format ("rgb({0},{1},{2})", r, g, b) } }
The main idea behind patterns is that they match values that look like them. For example, the Nemerle compiler creates a default constructor for the Different variant option with the following body:
public this (red : float, green : float, blue : float) { this.red = red; this.green = green; this.blue = blue; }
Therefore, the constructor call Color.Different (r, g, b) creates a new variant option instance with specified arguments. The pattern looks the same -- it binds actual values of red, green and blue fields to r, g and b respectively. You can also spell the field names explicitly:
| Color.Different (red = r, green = g, blue = b) => System.String.Format ("rgb({0},{1},{2})", r, g, b)
We have already seen a so called "constructor pattern" in action. It is used to match over variants. The constructor pattern consists of variant option name (starting with an uppercase letter) followed by optional tuple or record pattern.
// examples of constructor patterns // plain one, without sub-pattern: Color.Red // followed by tuple pattern: Color.Different (r, g, b) // followed by record pattern: Color.Different (red = r, green = g, blue = b)
The variable pattern matches any value, and binds it to a specified variable. The variable pattern is an identifier starting with a lowercase letter. They are used mostly inside other patterns, but here we give a (rather pointless) example of using them as the top-level pattern:
// it prints 42 match (42) { | x => // here x is bound to 42 printf ("%d\n", x) }
The throw-away pattern, written _, matches any value and has no further effects. It is a way of specifying the default: case in matching.
match (color) { | Color.Red => "red" | _ => "other" }
The tuple pattern consists of one or more patterns separated by commas and surrounded by parens. We have already used them in the section about tuples above. There they were used in def expressions.
// matches any pair, binding its elements // to specified variables (first_element, second_element) // matches a pair whose first element is Foo (Foo, _)
The record pattern consists of class name and zero or more named patterns separated by commas enclosed in parentheses. It matches a class, whose field values are matched by sub-patterns.
class Foo { public number : int; public name : string; } StringOfFoo (f : Foo) : string { if (f.name == "") f.number.ToString () else f.name } // do the same as above StringOfFooMatch (f : Foo) : string { match (f) { | Foo where (name = "", number = k) => k.ToString () | Foo where (name = s) => s } }
It might be doubtful if string_of_foo_match is any better than string_of_foo. Record patterns are mostly useful when used inside a complex pattern, or when they contain complex patterns.
The literal pattern is an integer, character or string constant. It matches the exact specified value.
StringOfInt (n : int) : string { match (n) { | 0 => "null" | 1 => "one" | 2 => "two" | 3 => "three" | _ => "more" } } IntOfString (n : string) : int { | "null" => 0 | "one" => 1 | "two" => 2 | "three" => 3 | _ => 42 }
Note lack of match in the second example. When the function body starts with | -- the match expression is automagically inserted.
The as pattern tries to match a value with a pattern enclosed within it, and in case of success binds the value that matched to a specified variable. We will show it later.
There are also two patterns related to types. The first one is the type enforcement pattern. Its job is to give a hint to type inference engine. It consists of a pattern followed by a colon and a type, like: x : Foo or (x,y) : Foo * Bar. It requires type of the matched value to be statically known to subtype the type specified.
The other pattern related to type is the type check pattern. Is is used to check whether the value matched has the specified type. It consists of a variable followed by the keyword is and a type. If the runtime type of the value matched is subtype of the type specified, the branch is taken and the matched value is bound to specified variable.
match (some_value) { | x is SomeType => // use x | x is SomeOtherType => // use x | _ => ... }
The example above, while simple, is not the best usage of variants. Variants are best at handling tree-like data structures. A common example of tree data structures are XML documents. However, we will deal with plain binary trees first.
The following example defines the type of trees of integers (representing sets).
variant Tree { | Node { left : Tree; elem : int; right : Tree; } | Null } // return tree t with element e inserted Insert (t : Tree, e : int) : Tree { match (t) { | Tree.Node (l, cur, r) => if (e < cur) Tree.Node (insert (l, e), cur, r) else if (e > cur) Tree.Node (l, cur, insert (r, e)) else // node already in the tree, // return the same tree t | Tree.Null => Tree.Node (Tree.Null (), e, Tree.Null ()) } } // check if specified integer is in the tree Contains (t : Tree, e : int) : bool { match (t) { | Tree.Node (l, cur, r) when e < cur => Contains (l, e) | Tree.Node (l, cur, r) when e > cur => Contains (r, e) | Tree.Node => true | Tree.Null => false } }
As you can see binary trees are not very interesting, so we will go to XML. Whether XML is interesting remains a doubtful question, but at least it is somewhat more practical.
variant Node { | Text { value : string; } | Element { name : string; children : list [Node]; } }
This variant defines a simplistic data structure to hold XML trees. An XML node is either a text node with a specified text inside, or an element node, with a name and zero or more children. A sequence of children is represented as a Nemerle list data structure (Nemerle has even a special syntax for lists). The type is written here list [Node] -- a list of nodes. We will learn more about polymorphic variants later.
For example the following tree:
<tree> <branch> <leaf/> </branch> <branch> Foo </branch> </tree>
would be represented by:
Node.Element ("tree", [Node.Element ("branch", [Node.Element ("leaf", [])]), Node.Element ("branch", [Node.Text ("Foo")])])
Of course XML by itself is just a data format. Using data in the above form wouldn't be too easy. So we want some different internal representation of data, and use XML only to save it or send it over the network.
class Refrigerator { minimal_temperature : float; content : list [RefrigeratorContent]; } variant RefrigeratorContent { | Beer { name : string; volume : float; } | Chips { weight : int; } | Ketchup }
Now we'll write simple XML parsing function.
ParseRefrigerator (n : Node) : Refrigerator { | Node.Element ("refrigerator", Node.Element ("minimal-temperature", [Node.Text (min_temp)]) :: content) => Refrigerator (System.Float.Parse (min_temp), ParseRefrigeratorContent (content)) | _ => throw System.ArgumentException () } ParseRefrigeratorContent (nodes : list [Node]) : list [RefrigeratorContent] { | [] => [] | node :: rest => def food = match (node) { | Node.Element ("ketchup", []) => RefrigeratorContent.Ketchup () | Node.Element ("beer", [Node.Element ("name", [Node.Text (name)]), Node.Element ("volume", [Node.Text (volume)])]) => RefrigeratorContent.Beer (name, System.Float.Parse (volume)) | Node.Element ("chips", [Node.Element ("weight", [Node.Text (weight)])]) => RefrigeratorContent.Chips (System.Int32.Parse (weight)) | _ => throw System.ArgumentException () }; food :: ParseRefrigeratorContent (rest) }
The reader will easily note that a) this code looks a bit like a junk, b) it can be generated automatically and c) in C# it would be even worse. Later we will learn how to write macros to generate this kind of code automatically.
But let's leave the ideology behind. There are probably few interesting things about this example. The first is the usage of list patterns and constructors. We can check if a list is empty, and if not, deconstruct it with the following code:
match (l) { | [] => // the list is empty // ... | head :: rest => // the list isn't empty, the first element // of the list is bound to the 'head' variable // and the rest of the list to 'rest' // ... }
We can also construct new lists with :: operator -- it prepends an element to an existing list. If we know all list elements in advance we can use the [ ... ] thing in both expressions and patterns.
The second interesting thing is that we throw an exception in case of problems. We will talk about it later, for now assume, it just terminates the program with an error message.
2.2 (2 points). Write a function that reads XML from specified files and puts it into the Node variant defined above. Then write a function to dump your data in a lispy format, something like:
(tree (branch (leaf) ) (branch ($text "Foo") ) )
For an extra point implement indentation of output.
(tree (branch (leaf)) (branch ($text "Foo")))
Then copy the Parser functions from above, fix any errors you find in
them and try to parse the following file:
<?xml version='1.0' encoding='utf-8' ?> <refrigerator> <minimal-temperature>-3.0</minimal-temperature> <beer> <name>Hyneken</name> <volume>0.6</volume> </beer> <beer> <name>Bydweisser</name> <volume>0.5</volume> </beer> <beer> <name>Plsner</name> <volume>0.5</volume> </beer> <chips> <weight>500</weight> </chips> <ketchup/> </refrigerator>
Warning: you do not need to write the XML parser. You should not do it, actually. Use the System.Xml namespace from the .NET Framework. In order to link with the System.Xml library you need to compile with the -r:System.Xml option. For example:
ncc -r System.Xml myprogram.n
should do.
This page is a part of the Grokking Nemerle tutorial.
Contents |
This feature (in this form) comes from python. When you call a function you can name some of its parameters (which allows putting them in a different order than in the definition).
frobnicate (foo : int, do_qux : bool, do_baz : bool, do_bar : bool) : int { // this is completely meaningless if (do_qux && !do_baz) foo * 2 else if (do_bar) foo * 7 else if (do_baz) foo * 13 else 42 } Main () : void { // Parameters' names can be omitted. def res1 = frobnicate (7, true, false, true); // This is the intended usage -- the first // (main) parameter comes without a name // and the following flags with names def res2 = frobnicate (7, do_qux = true, do_baz = false, do_bar = true); // You can however name every parameter: def res3 = frobnicate (foo = 7, do_qux = true, do_baz = false, do_bar = true); // And permute them: def res3 = frobnicate (do_qux = true, do_bar = true, do_baz = false, foo = 7); // You can also omit names for any number of leading // parameters and permute the trailing ones. def res2 = frobnicate (7, true, do_bar = true, do_baz = false); () }
The rules behind named parameters are simple:
Named parameters can be used only when names of parameters are known (which basically mean they do not work in conjunction with functional values).
The void literal is written: ().
The void literal is quite a tricky thing, since it represents the only value of type void, which, judging from the name, should be ergh... void. In fact, in some other functional languages this type is called unit, but in Nemerle the name comes from System.Void and the void type is an alias for it.
In C# the void type is used as a return type of functions. It does not make much sense to use it elsewhere. It could be needed, however, if, for example, you want to use the Hashtable [a, b] type as a set representation of strings. You can use Hashtable [string, void] then. And this is the place to use the void value -- when you call a set method, you need to pass something as a value to set -- and you pass the void value.
You can also use the void value to return it from a function -- as you remember, the return value of function is the last expression in its body. However, in most cases the last expression will already have the right void type.
You can overload existing operators or add new ones simply by specifying them as a static method in some type. The name of method should be some quoted (with @) operator. For example, the following class definition:
class Operand { public val : int; public this (v : int) { val = v } public static @<-< (x : Operand, y : Operand) : Operand { Operand (x.val + y.val); } }
contains the <-< binary operator processing Operand objects. It can be used like:
def x = Operand (2); def y = Operand (3); def z = x <-< y; assert (z.val == 5);
Unary operators can be created by giving only one parameter to the method.
Nemerle has very powerful code-generating macros. They are more akin to Lisp macros than macros found in C preprocessor. We are not going to explain here how to write macros (if you are curious, please see macros tutorial), but will describe a few often used macros.
First of all, if, while, for, foreach, when, using, lock, etc. are all macros.
When you write code like:
using (stream = System.IO.FileStream ("file.txt")) { lock (this) { ... } }
it first gets transformed into
def stream = System.IO.FileStream ("file.txt", System.IO.FileMode.Open); try { System.Threading.Monitor.Enter (this); try { ... } finally { System.Threading.Monitor.Exit (this) } } finally { def disp = (stream : System.IDisposable); when (disp != null) disp.Dispose () } }
The transformation is done by macros, which also introduce using and lock syntax to the language.
The greatest thing is that programmer is allowed to define his own macros, introducing his own syntax.
Design by contract macros allows you to specify assertions about your program. In other languages they are usually laying around in comments, while in Nemerle you can explicitly decorate code. This way contracts are instantly checked during program execution.
Other examples of macros:
You can see a page about macro usage for some other high level examples.
This page is a part of the Grokking Nemerle tutorial.
Once again a definition from Wikipedia.
OOP is all about objects. Objects consist of some data and methods to operate on this data. In functional programming we have functions (algorithm) and data. The things are separate. One can think about objects as of records (structures) with attached functions.
Nemerle allows programmers to program in this style. Moreover, the class library is very deeply object oriented. Therefore OOP is unavoidable in Nemerle.
Contents |
While talking about XML, we have shown an example of a refrigerator. It was a degenerated object -- a record.  Now we will try to extend it a bit.
class Refrigerator { public mutable minimal_temperature : float; public mutable content : list [RefrigeratorContent]; public AddContent (elem : RefrigeratorContent) : void { content = elem :: content } } variant RefrigeratorContent { | Beer { name : string; volume : float; } | Chips { weight : int; } | Ketchup }
Now, in addition to fields with content and temperature, the refrigerator has a method for adding new content.
The definition of method looks much like the definition of a function within a module.
It is quite important to understand the difference between classes and objects. Classes are type definitions, while objects (class instances) are values. Classes define templates to create new objects.
Non static methods defined in class C have access to a special value called this. It has type C and is immutable. It refers to the current object. You can use the dot (.) operator to access fields of current object. You can see how this is used in the AddContent method.
The this value is quite often used in object oriented programming. Therefore it can be omitted for brevity. For example:
public AddContent (elem : RefrigeratorContent) : void { content = elem :: content }
However, if the method had a formal parameter called content, or a local value with such a name, one would need to use this.content to access the field.
There is one special method in a class called a constructor. It is called whenever you request creation of new instance of an object. It the responsibility of the constructor to setup values of all fields within an object. Fields start with value of null, 0 or 0.0.
public this () { minimal_temperature = -273.15; content = []; }
Constructors can take parameters. For example, if we wanted to set the minimal_temperature already at the object construction stage, we could write:
public this (temp : float) { minimal_temperature = temp; content = []; }
For variant options Nemerle provides a default constructor, that assigns each field. If you do not provide a constructor for a regular class, an empty one is generated. If you need the field-assigning constructor, you can use [Record] attribute, like this:
[Record] class Foo { x : int; y : float; z : string; }
The following constructor is generated:
public this (x : int, y : float, z : string) { this.x = x; this.y = y; this.z = z; }
The constructor is called with the name of the class when creating new objects. Other methods are called using the dot operator. For example in refr.AddContent (Ketchup ()) the refr is passed to the AddContent method as the this pointer and Ketchup () is passed as elem formal parameter.
module Party { Main () : void { def refr = Refrigerator (); refr.AddContent (Beer ("Tiskie", 0.60)); refr.AddContent (Ketchup ()); } }
Fortunately, objects are not just a fancy notation for a function application on records.
Classes can inherit from other classes. The fact that a class B inherits from a class A has a few consequences. The first one is that B has now all the fields and methods of A. The second one is that B is now subtype of A. This means that all the functions operating on A can now also operate on B.
Class A is often called parent or base class of B (which is derived class).
In the following example we can see how we can call methods defined in the base class (AddContent), as well as from the derived class (MoveToBedroom).
Static methods and the constructor are not derived. The parameterless constructor is defined in this example. As the first thing to do, it calls parameterless constructor of the base class. It does it, so the derived fields are initialized first. Then it initializes the new fields.
The call to the parameterless parent constructor is in fact redundant. When there is no call to the parent class constructor, such a parameterless parent constructor call is assumed in the first line of a constructor.
class RefrigeratorWithRolls : Refrigerator { public mutable position_x : int; public mutable position_y : int; public MoveBy (dx : int, dy : int) : void { position_x += dx; position_y += dy; } public MoveToBedroom () : void { position_x = 42; position_y = -42; } public this () { base (); position_x = 0; position_y = 0; } } class TheDayAfter { static Main () : void { def refr = RefrigeratorWithRolls (); for (mutable i = 0; i < 10; ++i) refr.AddContent (Beer ("Liech", 0.5)); refr.MoveToBedroom (); // drink } }
The funny part begins where objects can react to calling some methods in a way dependent on the class of the object. It is possible to define virtual methods, which means they can be redefined in a derived class. Then when we have a function working on the base class, whenever it calls the virtual method, an appropriate method is selected base on actual object type.
This feature is called polymorphism in object-oriented world. We will, however, mostly use this word for another kind of polymorphism -- parametric polymorphism.
When one wants to override a virtual method from a base class, it needs to be declared with the override modifier.
using Nemerle.IO; class Refrigerator { public mutable minimal_temperature : float; public mutable content : list [RefrigeratorContent]; public virtual AddContent (elem : RefrigeratorContent) : void { content = elem :: content } public this () { minimal_temperature = -273.15; content = []; } } class RestrictedRefrigerator : Refrigerator { public override AddContent (elem : RefrigeratorContent) : void { match (elem) { | Ketchup => // don't add! printf ("Ketchup is not healthy!\n") | _ => content = elem :: content } } public this () { } }
Here we can see how the AddKetchup calls different methods depending on actual object type. The first call adds ketchup, the second call refuses to do so.
module Shop { AddKetchup (refr : Refrigerator) : void { refr.AddContent (Ketchup ()) } Main () : void { def r1 = Refrigerator (); def r2 = RestrictedRefrigerator (); AddKetchup (r1); AddKetchup (r2); } }
The .NET Framework supports only single inheritance. This means that any given class can derive from just one base class. However, it is sometimes needed for a class to be two or more different things depending on context. .NET supports it (just like Java) through interfaces. An interface is a contract specifying a set of methods given class should implement. A class can implement zero or more interfaces (in addition to deriving from some base class).
Implementing interface implies subtyping it. That is if you have a class A implementing I and method taking I as parameter, then you can pass A as this parameter.
Interfaces most commonly state some ability of type. For example, the ability to convert itself to some other type or to compare with some other types.
using Nemerle.IO; interface IPrintable { Print () : void; } class RefrigeratorNG : Refrigerator, IPrintable { public Print () : void { printf ("I'm the refrigerator!\n") } public this () { } } module RP { PrintTenTimes (p : IPrintable) : void { for (mutable i = 0; i < 10; ++i) p.Print () } Main () : void { def refr = RefrigeratorNG (); PrintTenTimes (refr) } }
The base class must come first after the colon in class definition. Then come interfaces in any order.
This page is a part of the Grokking Nemerle tutorial.
Parametric polymorphism is a wise way to say that function can operate on values of any type. Kind of System.Object and/or void* on steroids. This is very much like Generics in C# 2.0 or Java 5.0 and somewhat less like templates in C++.
Both functions and types can be parameterized over types.
Here we define a list of values of any type (it is also defined in Nemerle standard library but this is not the point here).
variant list [T] { | Cons { hd : T; tl : list [T]; } | Nil }
Here we used T as a type parameter to the list type. The ML-lovers would rather write 'a instead and read it alpha (it is a convention to use identifiers starting with an apostrophe for type parameters). They are allowed to do so, as the apostrophe is allowed in identifiers in Nemerle. We will however stick to a C++-like convention.
In the body of the list definition T can be used like any other type name. It is called type variable in this scope.
Next we define the method parameterized on a type (it is reflected by listing [something] after Head). Since the algorithm of taking the head out of the list does not depend on the type of the actual values stored in the list, we can use the same T, but we could have used 'b or foobar42 as well. This method for list[int], list[string] and even list[list[int]] would look exactly the same. Therefore we can use generic T type.
You can see that the type of elements of the list (a parameter in list[T]) is used as return type of this method. This way we can ensure that we take an int out of list[int] and not some generic System.Object.
class List { public static Head[T] (l : list[T]) : T { match (l) { | Cons (hd, _) => hd | Nil => throw System.ArgumentException () } } }
It is sometimes necessary for types to be substituted for type variables to conform to some specific interface. This concept is known as F-bounded polymorphism. We will address this issue in more detail, as it is probably new for most readers.
For example the elements stored in a tree need to provide a comparison method. Thus, we can define an appropriate interface and then require 'a in Tree['a] to conform to it:
interface IComparable ['a] { CompareTo (elem : 'a) : int; } variant Tree['a] where 'a : IComparable['a] { | Node { left : Tree['a]; elem : 'a; right : Tree['a]; } | Tip }
In fact the IComparable interface is already defined in the standard library, but that is not the point.
Now, once we ensured that elements in the tree conform to IComparable, we can use the CompareTo method. For example, to insert a thing into the tree we can use the following function:
module TreeOperations { public Insert['a] (t : Tree['a], e : 'a) : Tree['a] where 'a : IComparable['a] { match (t) { | Node (l, c, r) => if (e.CompareTo (c) < 0) Node (Insert (l, e), c, r) else if (e.CompareTo (c) > 0) Node (r, c, Insert (r, e)) else Node (r, e, l) | Tip => Node (Tip (), e, Tip ()) } } }
The people familiar with C# or Java will ask why not simply use something like:
interface IComparable { CompareTo (elem : IComparable) : int; } variant Tree { | Node { left : Tree; elem : IComparable; right : Tree; } | Tip }
But this is only half good. The most often case for using a tree is to store elements of some specific type, for example strings. We don't want integers and strings to be stored in the same tree, for the very simple reason that we cannot compare integer with string in a reasonable way. Well, even if we could, we plainly cannot predict what other types beside integers and strings implement IComparable and thus can be passed to string's CompareTo.
But the design above makes it impossible to ensure statically whether we're using the tree with correct types. When inserting nodes to the tree we upcast them all to IComparable. We will get runtime exception when string's CompareTo is passed integer argument. The second drawback is that when we extract elements out of the tree, we need to downcast them to a specific type. This is second possibility for runtime errors.
To fully understand this issue please look at the following example:
interface IFrobincatable { Frobnicate (x : int) : void; } class C1 : IFrobincatable { public this () {} public Frobnicate (_ : int) : void {} } class C2 : IFrobincatable { public this () {} public Frobnicate (_ : int) : void {} } module M { f1['a] (o : 'a) : 'a where 'a : IFrobincatable { o.Frobnicate (3); o } f2 (o : IFrobincatable) : IFrobincatable { o.Frobnicate (3); C1 () } Main () : void { def x1 = f1 (C1 ()); // x1 : C1 def x2 = f1 (C2 ()); // x2 : C2 def x3 = f2 (C1 ()); // x3 : IFrobincatable def x4 = f2 (C2 ()); // x4 : IFrobincatable () } }
In the Main function you can see what types get the x1, x2 etc values.
This page is a part of the Grokking Nemerle tutorial.
In Nemerle you can use exceptions in a similar way you would use them in C#. The only difference is the syntax for the catch handlers -- it looks more or less like matching, you can even use the _ to denote any exception that has to be caught.
some_function (foo : string) : void { when (foo == null) throw System.ArgumentException ("foo"); // do something } some_other_function () : void { try { some_function () } catch { | e is System.ArgumentException => printf ("a problem:\n%s\n", e.Message) } finally { printf ("yikes") } } some_other_function_2 () : void { try { some_function () } catch { | e is System.ArgumentException => printf ("invalid argument\n") | _ => // just like: // | _ is System.Exception => printf ("a problem\n") } } some_other_function_3 () : void { def f = open_file (); try { some_function () } finally { f.close () } } class MyException : System.Exception { public this () {} }
This page is a part of the Grokking Nemerle tutorial.
Contents |
Properties are syntactic sugar for get/set design pattern commonly found in Java. Accessing a property looks like accessing a field, but under the hood it is translated to a method call.
class Button { text : string; public Text : string { get { text } set { text = value; Redraw () } } } def b = Button (); b.Text = b.Text + "..."
Indexers are other form of properties, but instead of exposing field access syntax array access syntax is used. All .NET indexers have names, though one indexer can be marked as the default indexer (well, in fact one name of indexer is marked as default, but there can be several indexers with that name, subject to the regular overloading rules).
For example the System.Hashtable default indexer is called Item and System.String one is called Chars. The C# language allows definition of default indexer only. Nemerle allows also other indexers (like VB.NET). In the current release default indexer is always Item.
class Table { store : array [array [string]]; public Item [row : int, column : int] : string { get { store[row][column] } set { store[row][column] = value } } } def t = Table (); t[2, 3] = "foo"; t[2, 2]
Delegates are half-baked functional values. In fact there is little place for usage of delegates in Nemerle itself. However other .NET languages all speak delegates, so they are good way to expose functional values for them and vice versa.
Delegates are in essence named functional types. They are defined with delegate keyword:
delegate Foo (_ : int, _ : string) : void; delegate Callback () : void;
Later delegate name can be used to construct delegate instances. Any functional value of corresponding type can be used to create delegate instance (local functions and lambda expressions in particular).
Delegate instance can be invoked using regular function call syntax, as well as the Invoke special method. Please consult class library documentation for details.
The += operator has special meaning on delegate instances -- it calls the System.Delegate.Combine method that makes one function that calls two other in sequence. This operator is probably more useful with events.
module X { some_fun () : void { mutable f = Foo (fun (_, _) {}); f (3, "foo"); // same as f.Invoke (3, "foo"); f += fun (_, s) { System.Console.WriteLine (s) }; f (42, "bar"); } }
Events are kind of specialized properties for delegates. They are used in a GUI system for connecting signals (setting function to call when a button is pressed etc.). They can be also used to call user defined function on certain events, like class being loaded by the runtime system.
Events are defined like fields, but they are marked with the event keyword, and always have a delegate type. Inside the class events are seen as fields of these delegate type, but outside only the += and -= operators are available. They are used to connect and disconnect delegates. Implicit conversion from functional values to delegate instances is provided.
class Button { public event OnClick : Callback; } def b = Button (); b.OnClick += fun () { ... }


Name:
Username:
Date of Birth:
Email:
Telephone No:
NIC No:
Gender:
Male
Female
Other
Password:
Reenter Password:
Registration


Fuzzy Logic based Light Intensity Controller
- Tech Stack: C++, Arduino, Matlab, Fuzzy logic
- Github URL: Project Link
Intelligent control systems are dramatically changing domestic
technology. The so-called smart homes are environments where
technological tools provide convenience and comfort to residents
and contribute to the reduction of energy consumption. The term
smart is used due to high communication capability between
devices and the use of algorithms that analyze the profile of
each resident in order to optimize the use of resources and
provide custom routines.
Existing home automation devices have
the following limitations:
- Context-insensitive i.e they are not application-specific Ex:- Lighting lights for a party.
- Unable to adjust the control parameters dynamically in accordance with the varying surrounding environment.
- No adjustment of power consumption with change in environmental conditions.
- The scale of adjustment is fixed, no scope for adjusting light intensity using expressions like “little large”,”little low” using linguistic expressions.
We will try to solve the above limitations using fuzzy logic in our controller for home automation system to make it more adaptive, case sensitive instead of crisp scaling and frequent tunings as in conventional systems. The design of such a controller will also be simplified using fuzzy logic which gives us an added advantage.


Welcome
Welcome to the Great Art website! Here you will find information and updates on a wide variety of artists, as well as a vast collection of their works.
We hope you enjoy this website, and learn a lot from it!
News
Exhibitions - 2015
Gretchen Albrecht at Old Government House, Auckland. Works from the University of Auckland Collection (July 15th - September 11th)
Colloquy, Two Rooms Gallery, Auckland. Exhibition and Book Launch (July 10th - August 8th)
Selections from the Rutherford Trust Collection Masterworks from 40 leading New Zealand artists including Gretchen Albrecht. Aratoi Wairarapa Museum of Art & History, Masterton, NZ (May 22nd - August 16th)
Swimming into Darkness, Nadene Milne Gallery, Arrowtown New paintings by Gretchen Albrecht (April 16th - May 7th)
An Interview with Gretchen Albrecht
Video courtesy of TheRealArtRoadshow.
May 26, 2011


 Need some marketing copy conjured out of thin air? If you pay me money, I'll do those things for you. I might even do them well.
Below are my starting rates. Rates are subject to change and may be adjusted on a per-project basis. I can give you a full estimate before we start working on a project.
Note: the industry standard for a manuscript page (ms pg) is 250 words.


Demo of HeyGraph: Canvas-based Network Graph diagramming tool
This is a demo of HeyGraph, a Javascript and canvas based tool for visualing network graphs. Currently only a force directed layout is available. Additionally the visual appearance is limited to the white dots on a blue background demonstrated above. The graph displayed has been generated at random. Refresh the page to see another random graph visualised. Please view this page in Google Chrome for the best performance.
The source for HeyGraph is available under an MIT license on GitHub. You can read more about the tool on my blog
Below is the JSON that describes the Javascript used to initialise the HeyGraph component.


Time and Habits
Good produtivity and habits probably don't come naturally to me. I think I am doing ok at the moment though becuase everything is new and exciting, so motivation is high. I know I can't rely on this being high all the time so need to observe some of the techniques from the readings. I like the idea of timeboxing, setting how long you are going to spend on this task before you do it has really helped keep me on track. I liked what I read finding the goldilocks zone with flow, where you have to break problems down into smaller problems that are the right level of difficulty to help you get into a flow. I want to try this going forward. :)


APOD Viewer
APOD at NASA
NASA Open APIs
APOD Viewer
APOD at NASA
NASA Open APIs
media
explanation
navigate_before
navigate_next
Explanation


{% include "includes/head.html" %} {% include "includes/navbar.html" %} {% include "includes/header.html" %}


Because my adopted Korean sister could understand me, people assumed I was speaking in Korean and she was translating for me. In order to overcome my speech impediment, I was sent to special education classes to have oral-motor speech therapy. I hazily remember sitting in a classroom with children that had mental and physical disabilities and not understanding what my problem was. I didn’t understand that no one outside of my immediate family had trouble understanding me.


refcounted
component was not thread-safe due to an incorrect implementation and
could deadlock under heavy usage conditions. This problem has been
corrected.refcounted
不是线程安全的，在重度使用的条件下有可能会死锁。该问题已被修正。Revised May 4th 2010
© Copyright 2006-2010 Joaquín M López Muñoz. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)


I'm a Software Developer who is motivated to develop systems that will make daily business functions and process easier.
My capabilities also includes analyzing systems, writing scripts to update/extract/modify data as well as debugging systems and also being innovative to come up with solutions to improve current business functions. It also includes doing technical implementation of enhancements to already implemented systems. My skills also includes front-end development with manual testing in order to understand the needs and requirements end users.
Skills: Software Development (Web and Desktop Application), Web Design & Development, Graphics Designing, Proficient with Microsoft package, Data management using Microsoft SQL and Network Trouble shooting.
Software Developer - Innovation Group South Africa
Randburg - Gauteng
Dinwiddie High School
Germiston - Gauteng
IIE Bachelor of Information Technology in Business Systems - Rosebank College
Braamfontein - Gauteng
My passion for software development allows me to expand my creativity and technical thinking skills with a willingness of constant learning and personal development ,where i use the free time to learn and keep myself updated of any new features to current technology and breach the skills gap by learning new skills.
With the experience and skills developed i have learnt the importance of hardwork, creative thinking, decision making, clear communication skills, adpatability, ability to work under pressure with deadlines, time management and being a team player.


class: inverse, middle, left, my-title-slide, title-slide # What are GAMs? ### Eric Pedersen (with material heavily borrowed from David Miller) ### 1000–1230 CST (1600–1830 UTC) July 30th, 2020 --- ## Overview - A very quick refresher on GLMs - What is a GAM? - How do GAMs work? (*Roughly*) - What is smoothing? - Fitting and plotting simple models --- # A (very fast) refresher on GLMs --- ## What is a Generalized Linear model (GLM)? Models that look like: `\(y_i \sim Some\ distribution(\mu_i, \sigma_i)\)` `\(link(\mu_i) = Intercept + \beta_1\cdot x_{1i} + \beta_2\cdot x_{2i} + \ldots\)` --- ## What is a Generalized Linear model (GLM)? Models that look like: `\(y_i \sim Some\ distribution(\mu_i, \sigma_i)\)` `\(link(\mu_i) = Intercept + \beta_1\cdot x_{1i} + \beta_1\cdot x_{2i} + \ldots\)`
 The average value of the response, `\(\mu_i\)`, assumed to be a linear combination of the covariates, `\(x_{ji}\)`, with an offset --- ## What is a Generalized Linear model (GLM)? Models that look like: `\(y_i \sim Some\ distribution(\mu_i, \sigma_i)\)` `\(link(\mu_i) = Intercept + \beta_1\cdot x_{1i} + \beta_1\cdot x_{2i} + \ldots\)`
 The model is fit (not really...) by maximizing the log-likelihood: `\(\text{maximize} \sum_{i=1}^n logLik (Some\ distribution(y_i))\)` `\(\text{ with respect to } Intercept, \ \beta_1,\ \beta_2, \ ...\)` --- ## With normally distributed data (for continuous unbounded data): `\(y_i = Normal(\mu_i , \sigma_i)\)` `\(Identity(\mu_i) = Intercept + \beta_1\cdot x_{1i} + \beta_1\cdot x_{2i} + \ldots\)` ![](01-1D-smoothing_files/figure-html/gaussplot-1.png) --- ## With Poisson-distributed data (for count data): `\(y_i = Poisson(\mu_i)\)` `\(\text{ln}(\mu_i) = Intercept + \beta_1\cdot x_{1i} + \beta_1\cdot x_{2i} + \ldots\)` ![](01-1D-smoothing_files/figure-html/poisplot-1.png) --- # Why bother with anything more complicated? --- ## Is this linear? ![](01-1D-smoothing_files/figure-html/islinear-1.png) --- ## Is this linear? Maybe? ```r lm(y ~ x1, data=dat) ``` ``` ## `geom_smooth()` using formula 'y ~ x' ``` ![](01-1D-smoothing_files/figure-html/maybe-1.png) --- # What is a GAM? The Generalized additive model assumes that `\(link(\mu_i)\)` is the sum of some *nonlinear* functions of the covariates `\(y_i \sim Some\ distribution(\mu_i, \sigma_i)\)` `\(link(\mu_i) = Intercept + f_1(x_{1i}) + f_2(x_{2i}) + \ldots\)`
 -- But it is much easier to fit *linear* functions than nonlinear functions, so GAMs use a trick: 1. Transform each predictor variable into several new variables, called basis functions 2. Create nonlinear functions as linear sums of those basis functions ---  ![](01-1D-smoothing_files/figure-html/basis-plot-1.png) --- ![](01-1D-smoothing_files/figure-html/basis-animate-1.gif) --- #This means that writing a GAM in code is as simple as: ```r mod <- gam(y~s(x,k=10),data=dat) ``` --- # You've seen basis functions before: ```r glm(y ~ I(x) + I(x^2) + I(x^3) +...) ``` -- Polynomials are one type of basis function! -- ... But not a good one. ![](01-1D-smoothing_files/figure-html/unnamed-chunk-5-1.gif) --- # One of the most common types of smoother are cubic splines (We won't get into the details about how these are defined) ```r glm(y ~ ns(x,df = 4)) ``` -- But even cubic splines can overfit: ![](01-1D-smoothing_files/figure-html/unnamed-chunk-7-1.png) --- # How do we prevent overfitting? The second key part of fitting GAMs: penalizing overly wiggly functions We want functions that fit our data well, but do not overfit: that is, ones that are not too *wiggly*. -- Remember from before: `\(\text{maximize} \sum_{i=1}^n logLik (y_i)\)` `\(\text{ with respect to } Intercept, \ \beta_1,\ \beta_2, \ ...\)` --- # How do we prevent overfitting? The second key part of fitting GAMs: penalizing overly wiggly functions We want functions that fit our data well, but do not overfit: that is, ones that are not too *wiggly*. We can modify this to add a *penalty* on the size of the model parameters: `\(\text{maximize} \sum_{i=1}^n logLik (y_i) - \lambda\cdot \mathbf{\beta}'\mathbf{S}\mathbf{\beta}\)` `\(= \text{maximize} \sum_{i=1}^n logLik (y_i) - \lambda\cdot \sum_{a=1}^{k}\sum_{b=1}^k \beta_a\cdot\beta_b\cdot P_{a,b}\)` `\(\text{ with respect to } Intercept, \ \beta_1,\ \beta_2, \ ...\)` --- # How do we prevent overfitting? `\(\sum_{i=1}^n logLik (y_i) - \lambda\cdot \mathbf{\beta}'\mathbf{S}\mathbf{\beta}\)`
 -- The penalty `\(\lambda\)` trades off between how well the model fits the observed data ( `\(\sum_{i=1}^n logLik (y_i)\)` ), and how wiggly the fitted function is ( `\(\mathbf{\beta}'\mathbf{S}\mathbf{\beta}\)` ).
 -- The matrix `\(\mathbf{S}\)` measures how wiggly different function shapes are. Each type of smoother has its own penalty matrix; `mgcv` handles this.
 -- Some combinations of parameters correspond to a penalty value of zero; these combinations are called the *null space* of the smoother --- # For instance, for smoothing splines: We can create a penalty matrix that penalizes the squared second derivative: `\(\int_{x_1}^{x_n} [f^{\prime\prime}]^2 dx = \boldsymbol{\beta}^{\mathsf{T}}\mathbf{S}\boldsymbol{\beta}\)` -- ![](01-1D-smoothing_files/figure-html/pen-plot-1.png) --- ![](01-1D-smoothing_files/figure-html/pen-ani1-1.png) ![](01-1D-smoothing_files/figure-html/pen-ani2-1.gif) --- # You've also (probably) already seen penalties before: Single-level random effects are another type of smoother!  --- # You've also (probably) already seen penalties before: Single-level random effects are another type of smoother! You've probably seen random effects written like: `\(y_{i,j} =\alpha + \beta_j + \epsilon_i\)`, `\(\beta_i \sim Normal(0, \sigma_{\beta}^2)\)` -- * The basis functions are the different levels of the discrete variable: `\(f_j(x_i)=1\)` if `\(x_i\)` is in group `\(j\)`, `\(f_j(x_i)=0\)` if not -- * The `\(\beta_j\)` terms are the parameters the basis functions are being scaled by -- * The variance of the random effect is equal to `\(1/\lambda\)`, so the `\(S\)` matrix for a random effect is just a diagonal matrix with `\(1/\sigma^2\)` on the diagonal --- # How are the `\(\lambda\)` penalties fit? * By default, `mgcv` uses Generalized Cross-Validation, but this tends to work well only with really large data sets -- * We will use restricted maximum likelihood (REML) throughout this workshop for fitting GAMs -- * This is the same REML you may have used when fitting random effects models; again, smoothers in GAMs are basically a random effect in a different hat --- # To review: * GAMs are like GLMs: they use link functions and likelihoods to model different types of data -- * GAMs use linear combinations of basis functions to create nonlinear functions to predict data -- * GAMs use penalty parameters, `\(\lambda\)`, to prevent overfitting the data; this trades off between how wiggly the function is and how well it fits the data (measured by the likelihood) -- * the penalty matrix for a given smooth, `\(\textbf{S}\)`, encodes how the shape of the function translates into the total size of the penalty -- # But enough lecture; on to the live coding!


500 pages
500 pages are used to tell users that we [HMRC] have a problem that was not their fault.
They cover a range of situations when something has gone wrong with the server.
500 errors should only be displayed to users for a short time. The standard approach within HMRC is to shutter a service, if there is going to be a disruption to users for an extended period of time.
500 errors should be logged by services and fixed as a matter of priority.
There are a number of standard pages that fall into the category of 500 pages. We do not need different error pages to cover all of these situations.
Why users see 500 pages
For the purposes of HMRC services there are 3 scenarios when we would need to show users a 500 page:
- 500 Internal Server Error
- 503 Service Unavailable
- 504 Gateway Timeout
500 page design
When displaying a 500 page we should:
- use the standard template
- explain to users whats going on
- tell users what they can do, if anything to resolve the issue.
- If there is an alternative channel that they can use to continue their transaction this should be made available to them.


HIGH SCORES
Time Remaining: 0
JavaScript Coding Quiz!
Instructions:
You start with 100 seconds.
Correct answers will add 20 seconds.
Incorrect answers will deduct 20 seconds.
Final score is equal to number of seconds remaining.
START QUIZ
QUESTION
1)
2)
3)
4)
Quiz Complete!
Enter your name:
Submit Score


Portfolio
-
Hydraulic Tool Simscape Model Development
Contructed Multiple Simscape models for an unreleased hydraulic pressing tool at Milwaukee Tools. The models can virtually the actual outputs of the tool in seconds. Implemented Object Oriented Programming and designed an user-friendly interface to allow people from any background to use the model.
-
Robot Arm Control
Determined the forward and inverse kinematics of a 6 degree-of-freedom robot arm using MATLAB. Derived all the singularities of the given robot and desmonstrated with built-in software. Designed decentralized PD controllers for the robot.
-
Robot Tank Server & GUI
Programmed and designed web servers with Node, Python SSH, MQTT, and Firestore to achieve live communications among the tank, PC, and Raspberry Pi. Designed a customized GUI programs that controls the tank using MATLAB App Designer and Kivy. Implemented forward and inverse kinematics along with solid modeling to achieve synchronized movements of the tank both in the MATLAB GUI and reality
-
Remote Controlled Kart with Obstacle Bypass System
Modeled the chassis and designed the layout of all the components after detailed measurements of the selected parts. 3D Printed the chassis and assembled all the parts including DC motors, servo motors, shafts, wheels, and microcontroller. Compiled the microcontroller with Arduino and implemented IR remote to control the movement of the kart. Enabled obstacle detection and bypass with an ultrasonic sensor


String sql = "SELECT column" + "FROM table";
Use the checkbox below to have this inspection only report when both the left and right side of the concatenation are string literals.
New in 12, Powered by InspectionGadgets


-
This is how the “Shell Shock” bug imperils the whole internet
qz.com
It's a hacker's wet dream: a software bug discovered in the practically ubiquitous computer program known as "Bash" makes hundreds of millions of ...
-
Skeptical Football: Manning Redux, Ancient History And An Award For Tony ...
fivethirtyeight.com
Something marvelous has happened to me. I was transported to the seventh heaven. There sat all the gods assembled. As a special dispensation, I was ...
-
Find workspaces with wifi nearby and connect with other mobile workers.
cubefreeapp.com
Cubefree app will help you find reliable and free wifi nearby and also if place has electrical outlets, good level of noise, and easy parking
-
Connect your Marketo data with New Relic Insights – Marketo LaunchPoint
launchpoint.marketo.com
Leverage Marketo’s Webhooks to push data to New Relic Insights, and we'll show exactly how your marketing programs are doing in real-time.
-
Apple expands data encryption under iOS 8, making handover to cops moot
arstechnica.com
"Apple cannot bypass your passcode and therefore cannot access this data."
-
If net neutrality falls, what happens next? | Hacker News
news.ycombinator.com
Is a hacktivist group, deciding that the internet shouldn't be turned against it's users, going to DDoS the root DNS servers? Is everybody going to ...
-
Startup Wars: UC Santa Barbara Beats Wharton An...
www.scoop.it
Want to be an entrepreneur? Don't go to Wharton or Harvard.  According to a recent Forbes ...
-
The NSA's crazy fine threat against Yahoo put in perspective
www.dailydot.com
No wonder Yahoo gave into the pressure.
-
Visualizing Publicly Available US Government Data Online - information ...
infosthetics.com
Brightpoint Consulting recently released a small collection of interactive visualizations based on open, publicly available data from the US ...
-
Could Scotland’s currency be bitcoin?
qz.com
A central question in the Scottish independence campaign has centered on currency. The Bank of England has said repeatedly that an independent ...
-
Apple's "warrant canary" disappears, suggesting new Patriot Act demands
gigaom.com
Apple included language in its first Transparency Report to say that it had not been subject to a Section 215 Patriot Act request. That language is ...
-
Aubrey Plaza’s New Role: Grumpy Cat
blogs.wsj.com
The "Parks and Recreation" star will voice the world's favorite Internet feline
-
PSY - GANGNAM STYLE (강남스타일) M/V
www.youtube.com
▶ Watch HANGOVER feat. Snoop Dogg M/V @ http://youtu.be/HkMNOlYcpHg PSY - Gangnam Style (강남스타일) ▶ Available on iTunes: http://Smarturl.it/psygangnam ...
-
Countries can rescue the planet from meltdown and save money doing it
qz.com
The world is pumping carbon dioxide into the air at the fastest rate since 1984. Last month was the hottest August on record. The superlatives say it ...
-
7 videos from the inaugural MarTech of August 2014 - Chief Marketing ...
chiefmartec.com
Want to get a glimpse of what the inaugural MarTech conference was like? We recorded 7 of the sessions on video, and after a little editing, we’ve ...
-
Princeton Maintains No. 1 Spot in College Rankings
online.wsj.com
Princeton is No. 1, Dartmouth fell out of the top 10 and the three best public liberal arts colleges in America are all military academies, according ...
-
Sprint CEO Aims to Return Carrier to Its Roots: Unlimited Data Plans
online.wsj.com
In a recent interview, Sprint CEO Marcelo Claure talks about what's ahead for the wireless carrier and how he plans to turn the company around.
-
Google uses R to calculate ROI on advertising campaigns
www.r-bloggers.com
Google has just released a new package for R: CausalImpact. Amongst many other things, this package allows Google to resolve the classical conundrum: ...
-
Tips For Fixing The Nation’s Education System
www.theonion.com
Public schools throughout the nation continue to contend with budget shortfalls and insufficient classroom resources, while U.S.
-
Meet the Interns: Ali Gerrard
blog.newrelic.com
This New Relic intern gave up journalism for the world of marketing, including the “less-sexy” operations side.
-
The Feds Threatened To Fine Yahoo $250,000 A Day If It Didn't Hand Over ...
sfist.com
Yahoo will publish 1,500 pages of previously sealed documents from secret court hearings about the government's surveillance efforts.
-
Casino Reporting Steady Profits From Slot Machine That Promises Players ...
www.theonion.com
LAS VEGAS—Touting robust traffic on par with some of its most popular games, representatives from Las Vegas’ Bellagio resort said Thursday that the ...
 What was the last interesting thing you learned by listening rather ...
-
5 Million Online Passwords Leaked, Check Yours Now [Updated]
lifehacker.com
According to the Daily Dot, nearly 5 million usernames and passwords associated with Gmail accounts have been leaked on a Russian Bitcoin forum. ...
-
In the last 30 seconds there were 1,565,880 Facebook likes.
pennystocks.la
From tweets to likes, see how fast data is generated every second on the internet in this interactive visualization.
-
SomaFM: Listener Supported, Commercial Free Internet Radio
somafm.com
Independent, free internet radio with no commercials. Over 20 unique channels featuring underground electronica, chillout, ambient groove, downtempo, ...
-
Sounds and Playlists for the End of Summer—and Beyond
blog.newrelic.com
New Relic shares our favorite songs and playlists to keep help you have fun over the holidays—and stay focused at work.
-
Protein sources by calories, value and portion size [OC] (x-post from ...
www.reddit.com
2902 points and 409 comments so far on reddit


Want To Help Oaktown?
We're the Oakland Code for America Brigade,
a group of civic-minded geeks who volunteer our talents to projects that improve how our local governments and community organizations use the web.
Brigade is about action & you're here because you are someone who takes action.
See what kind of things brigades do, and stop by a Meetup to see if Brigade is right for you.
Still Not Sure? Watch This:


Submit Async Search APIedit
Requestedit
A SubmitAsyncSearchRequest
allows to submit an asynchronous search task to
the cluster. Required arguments are the SearchSourceBuilder
defining
the search and the target indices:
Optional argumentsedit
The following arguments can optionally be provided:
Synchronous Executionedit
Asynchronous Executionedit
The asynchronous execution of a SubmitAsyncSearchRequest
allows to use an
ActionListener
to be called back when the submit request returns. Note
that this is does not concern the execution of the submitted search request,
which always executes asynchronously. The listener, however, waits for the
submit request itself to come back:
The asynchronous method does not block and returns immediately. Once it is
completed the ActionListener
is called back using the onResponse
method
if the execution successfully completed or using the onFailure
method if
it failed.
A typical listener for AsyncSearchResponse
looks like:
Responseedit
The returned AsyncSearchResponse
allows to retrieve information about the executed
operation as follows:
response.getSearchResponse(); response.getId(); response.isPartial(); response.isRunning(); response.getStartTime(); response.getExpirationTime(); response.getFailure();
|
The |
|
|
The id of the async search request, |
|
|
|
|
|
|
|
|
The time the response was created (millis since epoch) |
|
|
The time the response expires (millis since epoch) |
|
|
Get failure reasons or |


|
A careful analysis of CAD model validity should employ thinking at several levels of abstraction:
The geometric validity checks are concerned with the mathematics of form. The input data for those checks are the equations of curves and surfaces while the verification methods usually employ some computationally expensive algorithms (intersection tests, sampling, evaluation of derivatives, etc.). The topological validity checks are concerned with the syntactical analysis of the model and perform verification of the data structure consistency. Finally, the analysis of the design intent requires the understanding of the function of the part, its manufacturing constraints and other reasoning which may often require human intervention. The following rule often works in practice: to fix the problem of a lower level, it is necessary to rise to the upper level of abstraction. E.g., to correctly fill a gap due to a missing face, it might be necessary to recognize and recover its containing feature (e.g., to extend and intersect surfaces rather than to patch a hole with a NURBS surface).
The reasoning on the validity of a CAD model should always be based on its application domain. E.g., self-intersection defects might be critical for mesh generation algorithms while they often have zero impact on specific modeling procedures such as unfolding of sheet metals.
From the application point of view, it is rarely needed to distinguish between pure geometric and topological invalidities. Such separation is done for better CAD kernel maintainability and exists only due to the separation between geometry and topology in B-Rep representation scheme. in practice, maintaining representation integrity is a direct function of a geometric modeling system whatever abstraction layers it uses under the cover.
The following table provides a checklist for a CAD model to verify its validity (both geometric and topological). These checks are relevant to a B-Rep representation scheme of OpenCascade kernel exclusively. The set of checks listed below is not full though the most frequently occurring defects are enumerated.
| Check | Tcl command | Issue description |
| Euler-Poincare property | check-euler | Checks if the Euler-Poincare property holds for the user-specified genus. |
| Orientation of vertex in edge | check-vertices-ori | Checks if the vertices of the part are distinguishable by their orientation flags. A valid edge should have one FORWARD vertex and one REVERSED vertex to properly signify its topological extremities. As a result of some poorly implemented modeling operators, this rule may appear to be violated. |
| Orientation of edge in wire | N/A | The edges should be oriented so that their owning contour is traversed in a determined order (clockwise or counterclockwise). |
| Orientation of wire in face | N/A | The wire should be oriented so that the material of its owning face is either enclosed (for the outer wires) or lies outside (for holes). |
| Orientation of face in solid | N/A | The faces of a solid model should be oriented so that to point outwards the bounded volume. This requirement is relaxed for surface modeling (shells). |
| Contour closeness | check-contours |
Checks if the contours of the part faces are closed (have no gaps). The optional
"tolerance" argument is used to tune the precision of coincidence test. You
can find more details in the corresponding chapter.
cad/anomalies/shading_wrongshape_031.brep
|
| Solid closeness (finiteness) | check-finite |
Checks if the solid body is finite. It should be noted that in some workflows
infinite volumes are perfectly valid.
cad/anomalies/shading_wrongshape_005.brep
|
| Open (naked) edges | check-open-edges |
The open edges (those owned by less than two faces) are valid for shells and prohibited for
solid models. To fix this problem, face stitching (sewing) algorithm might be necessary.
cad/anomalies/shading_wrongshape_015.brep
|
| Missing face (gap) | N/A | The gap filling algorithm is required to fix this anomaly. |
| Intersection and overlapping of surfaces | N/A | All surface intersections should be resolved by inserting the corresponding topological primitives (vertices, edges or patches in case of overlapping). If surfaces interact while having no topological resolution, the shape is considered locally faulty. Intersections or overlaps of the trimmed NURBS surfaces are a huge challenge for healing algorithms [Frischmann, 2011]. |
| Singular surface points | N/A | Surface degeneracies usually occur due to the coincidence of NURBS control points. Such surfaces are often used to represent triangular patches, e.g., in ship hull design. Even though the singularity points are usually allowed by a modeler, their existence may cause problems in subsequent operators (e.g., offsets). |
| Missing 3D curve | N/A | The 3D curve is a primary edge representation. If the 3D curve does not exist, it is clearly a problem. To fix the issue, the corresponding p-curves should be evaluated against their host surfaces. The obtained points are then reapproximated. |
| Missing p-curve | N/A | In OpenCascade kernel, the primary 3D curve should be followed by its images in all surface patches meeting at this curve. These p-curves can be recovered by projection of a 3D curve to each host surface. |
| Non-synchronous parameterization of curves | N/A | The 3D curves and the corresponding p-curves should be parameterized synchronously, so that they yield identical points for the same parameter value (with tolerance). |
| Missing seam | N/A | The seam edges correspond to a period value of a periodic surface. These edges are necessary to close the parametric domain of a face. Not all geometric kernels use the notion of seam edges, so it is necessary to recover them sometimes after data exchange. |
| Non-manifoldness | N/A |
A boundary surface is two-manifold if it is homeomorphic to a disk in the
neighborhood of every point (i.e., resembles a two-dimensional Euclidian
space near each point).
Non-manifold vertices, edges and faces might be perfectly valid if they
are modeled like this intentionally. Otherwise, the existence of non-manifold
boundary elements might be a problem for subsequent modeling operators
and manufacturing planning (such models are clearly non-manufacturable).
cad/anomalies/non-manifold/non-manifold-01.brep
|
| Unexpected shape type | N/A | It sometimes happens that the visually fine, closed models are defined as shells instead of being formal solids. Other examples include single faces defined as shells or compound parts wrapping a single result of a solid Boolean operation. These anomalies can be traced down using a topology graph representation of B-Rep model. The graph will contain excessive nodes and/or nodes of improper type. |
| Tolerance inclusion | N/A | A geometric tolerance of a vertex should not be less than a geometric tolerance of an edge. A geometric tolerance of an edge should not be less than a geometric tolerance of a face. |
There are two aspects which contribute to what we call shape "dirtiness" here:
The excessive shape description might lead to an increase of data volume or influence the processing time of geometry-based algorithms. Moreover, excessive shape representation and dirtiness might cause serious numeric problems within the downstream engineering workflows [Frischmann, 2011]. At the same time, all flaws enumerated below do not break the formal validity of a CAD model.
| Problem | Tcl command | Issue description |
| Non-canonic geometry | N/A |
Example: a geometrically planar surface represented with a NURBS surface or
a surface of revolution (like demonstrated by the example below).
cad/anomalies/occ26372_RP.brep
|
| Small edges | heal-small-edges |
Sometimes a CAD model contains excessive number of small (usually straight)
edges which are hard to treat numerically (e.g., when generating FEA meshes).
Such edges can be enlarged by reapproximation.
cad/anomalies/occ22778_square.brep
|
| Small faces | N/A | It is possible to merge small faces by reapproximating them. |
| Non-maximized boundary elements | N/A | Face/edge maximization is usually performed as a post-processing stage of a Boolean operation. |
| High geometric tolerances | check-toler | See the corresponding chapter for details. |
| C0 geometry | split-by-continuity |
The support of C0 geometric primitives is limited in all geometric kernels. It is
usually a good idea to split such entities with the relevant boundary elements (vertices or edges)
to enhance the smoothness of the geometry. Alternatively, for NURBS curves
and surfaces, it is possible to remove knots if the shape is geometrically continuous
though parameterized improperly. The knot insertion algorithm can also be applied
for non-G-smooth geometric elements if a certain deformation (within the prescribed
tolerance) is allowed.
cad/anomalies/from_sat/converted_brep_from_sat_37.brep
|
| Nested local transformations | check-internal-locations | In OpenCascade kernel, each topological element might be assigned with a local transformation to place it relative to its parent element. While this capacity of the modeler is convenient for representing assemblies as compounds, we discourage using the transformed boundary elements in a single solid representation. Formally speaking, a local transformation is a property of an arc in the topology graph. In Analysis Situs, it is possible to colorize the arcs for a visual check of internal transformations. It is Ok to have a local transformation for in-compound inclusions and not Ok to have them deeper in the graph. |
| Non-beautified model | N/A | A beautified geometric model is a modification of the input model that incorporates appropriate symmetries and regularities [González-Lluch et al, 2017]. Beautification-pending models usually emerge as a result of reverse engineering of a B-Rep model from a discrete dataset (point clouds, mesh). |
| Ill-defined surface extension | N/A | For some operations like removing face, push/pull, etc. surface extensions are used. It may easily happen that if parameter lines of a surface are converging, the surface extension starts to self-intersect. In such situations, any modeling operators which require surface extensions will likely fail. |
It is necessary to add a few words for the situations when we have a consistent & clean CAD model which is still not valid from the human's point of view. It is not a geometric kernel to blame in such situations. At the same time, a geometric kernel might still be helpful to discover some sorts of violated technological or functional requirements.
| Problem | Tcl command | Issue description |
| Too many details | N/A | The overcomplicated CAD parts may require simplification prior to the engineering analysis, manufacturing planning, data interoperability, visualization, etc. To simplify model, the defeaturing techniques should be employed. |
| Insufficient thickness | N/A | Thickness is a severe requirement, e.g., in die casting manufacturing. |
| Invalid sheet metal | N/A | Non-existing bends or non-constant sheet thickness is somewhat unexpected in sheet metal working. |
Since the Analysis Situs software is mostly focused on individual CAD parts, we do not speak of assembly-specific invalidities, such as collisions, lost instancing, etc.


zmv '(*).log' '$1.txt'- Preview the result of a move, without making any actual changes:
zmv -n '(*).log' '$1.txt'- Interactively move files, with a prompt before every change:
zmv -i '(*).log' '$1.txt'- Verbosely print each action as it's being executed:
zmv -v '(*).log' '$1.txt'


{% extends "base.html" %}
{% block body %}
Neuro FX Predictor
Predict FX next 1 bar in real time
• Select FX and timeframe
• Get predictions immediately!
• Sign up for as little as $1/month
Live monitoring
We monitor all currencies, so there is no need to wait for history download.
Latency
Fast predictions can be integrated into live trading system.
Stats
Keep track of your signals and overall prefomance.
Ease of use
Neuro FX Predictor is beautiful and easy to use.
OUR PARTNERS


Badges scale to match the size of the immediate parent element by using relative font sizing and em
units.
Add any of the below mentioned modifier classes to change the appearance of a badge.
Primary Secondary Success Danger Warning Info Light Dark
Use the .badge-pill
modifier class to make badges more rounded.
Using the contextual .badge-*
classes on an <a>
element quickly provide actionable
badges with hover and focus states.