on master help sign in
add some AtomFunctionBody script documentation
commit97524b40b4a662175d8165da1c1a591298bb5480 authorAgentM <agentm@themactionfaction.com> dateWed 24 Aug 2016, 18:21 (10 years ago) parent4dd599b
2 files changed+52−3
README.markdown+12−3 docs/atomfunctions.markdown+40
README.markdown+12−3
@@ -22,21 +22,30 @@ Project:M36 supports multiple frontends which target different audiences.
2222
2323## Documentation
2424
25+### Introductory Materials
26+
25271. [Installation and Introduction to Project:M36](docs/introduction_to_projectm36.markdown)
26281. [Introduction to the Relational Algebra](docs/introduction_to_the_relational_algebra.markdown)
27291. [TutorialD Tutorial](docs/tutd_tutorial.markdown)
28301. [15 Minute Tutorial](docs/15_minute_tutorial.markdown)
29−1. [Transaction Graph Operators](docs/transaction_graph_operators.markdown)
31+
32+### Database Comparisons
33+
34+1. [ACID Database Properties](docs/acid_assessment.markdown)
30351. [On NULL (in SQL)](docs/on_null.markdown)
36+1. [Reaching "Out of the Tarpit" with Project:M36](docs/reaching_out_of_the_tarpit.markdown)
37+
38+### Advanced Features
39+
40+1. [Transaction Graph Operators](docs/transaction_graph_operators.markdown)
31411. [Persistent Library Driver](docs/persistent_library_driver.markdown)
32421. [ProjectM36.Client Library](docs/projectm36_client_library.markdown)
33431. [Adding New Data Types](docs/new_datatypes.markdown)
34−1. [ACID Database Properties](docs/acid_assessment.markdown)
35441. [Serving Remote ProjectM36 Databases](docs/server_mode.markdown)
36451. [Using Notifications](docs/using_notifications.markdown)
37461. [Merge Transactions](docs/merge_transactions.markdown)
38−1. [Reaching "Out of the Tarpit" with Project:M36](docs/reaching_out_of_the_tarpit.markdown)
39471. [WebSocket Server](docs/websocket_server.markdown)
48+1. [Atom (Value) Functions](docs/atomfunctions.markdown)
4049
4150## Development
4251
docs/atomfunctions.markdownnew file+40
@@ -0,0 +1,40 @@
1+# Project:M36 Extendable Atom Functions
2+
3+## Introduction
4+
5+While Project:M36 includes a set of basic function which operate on relational values (atoms in Project:M36 parlance), users may find it useful to write functions which operate on these atoms in the database context. For example, if a value represents a temperature in Celsius units, an atom function could be implemented to convert the value to Fahrenheit units.
6+
7+Other DBMSes also include this feature by way of stored functions such as with PL/pgsql, T-SQL, or PL/SQL.
8+
9+Project:M36 allows users to implement strongly-typed and pure atom functions in the Haskell language at runtime. This facility makes use of GHC, the Haskell compiler, as a runtime service.
10+
11+## Atom Function Example
12+
13+In this example, we install an atom function to convert between Fahrenheit and Celsius temperatures where the temperatures are represented as integers of type ```Int```.
14+
15+We write the function giving it the name "celsiusToFahrenheit" with type ```Int -> Int``` which indicates to the compiler that the function take one ```Int``` argument value and returns one ```Int``` value. Finally, the body of the function is implemented in quotes or triple-quotes. Note that the function makes use of the "[ProjectM36.Base](/src/lib/ProjectM36/Base.hs)" module to handle the Atom type. The function must take a list of Atoms as arguments and return an Atom. The standard GHC Prelude is available in this AtomFunctionBody context.
16+
17+```
18+TutorialD (master): addatomfunction "celsiusToFahrenheit" Int -> Int """\((IntAtom c):_) -> IntAtom ( (c * 9 `div` 5) + 32)"""
19+```
20+
21+Using triple-quotes allows quotes to be used inside the string without backslash escaping, which can become tedious.
22+
23+## Advanced Atom Function Example
24+
25+Project:M36 also supports runtime-created new data types represented as algebraic data types. Internally, these are represented as ```ConstructedAtom```s, so the atom function script must use appropriate constructors.
26+
27+In the following example, splitting the temperature values into two types make sense because it prevents accidental use of operators between the two domains. For example, a ```CelsiusTemperature``` could never be accidentially added to a ```FahrenheitTemperature``` or otherwise compared without a conversion function in between. Thus, the separation of types increases our confidence in the database results when compared to the raw ```Int``` representation above.
28+
29+```
30+data CelsiusTemperature = CelsiusTemperature Int
31+data FahrenheitTemperature = FahrenheitTemperature Int
32+
33+addatomfunction "celsiusToFahrenheit" CelsiusTemperature -> FahrenheitTemperature """\(ConstructedAtom _ _ (IntAtom celsius:_):_) -> ConstructedAtom "Fahrenheit" (ConstructedAtomType "Fahrenheit" empty) [IntAtom (celsius * (9 `div` 5) + 32)] """
34+```
35+
36+First, we define our new types and use these types in the function's type definition. Next, we deconstruct the incoming ```ConstructedAtom``` argument to extract its ```Int``` value. Finally, we perform the calculation and wrap the value in a new Fahrenheit-based ```ConstructedAtom```.
37+
38+## Differences when compared to other DBMSes
39+
40+Project:M36 enforces strongly-typed atom functions. Specifically, atom functions must be pure (free of any side effects) and cannot operate on any variables other than the atoms passed in. This certainly sets stricter limits on what can be accomplished in an atom function when compared to stored functions in other DBMS products. For example, an atom function in Project:M36 would never be able to retrieve stock information from an external website because such a function cannot be pure and thus would be rejected by the atom function compiler. This restriction maintains the mathematical cohesiveness of the database and allows the DBMS to make performance-enhancing inferences it would not otherwise be able to make.