### Starting a Hobbes Server Source: https://github.com/morganstanley/hobbes/blob/main/README.md Starts a Hobbes server process that listens on a specified port for incoming network requests. ```Shell $ hi -s -p 8080 > ``` -------------------------------- ### Hog Consumer Output Example Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates the expected output from the 'hog' consumer program when it starts and begins consuming data from a specified storage group. ```APIDOC $ hog -g WeatherMonitor [2018-01-01T09:00:00.867323]: hog running in mode : |local={ dir="./", groups={"WeatherMonitor"} }| [2018-01-01T09:00:00.867536]: polling for creation of memory regions [2018-01-01T09:00:00.873862]: group 'WeatherMonitor' ready, preparing to consume its data [2018-01-01T09:00:01.637614]: ==> carPassed :: ([char]) (#1) [2018-01-01T09:00:01.733374]: ==> sensor :: ([char] * { temp:double, humidity:double }) (#0) ``` -------------------------------- ### Start hi Server Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/networking/hi.rst Starts the 'hi' tool as a server, listening for network connections on a specified port. This is the first step in establishing remote communication. ```C++ $ hi -p 8080 [...] running a repl server at myhost:8080 > ``` -------------------------------- ### Build and Install Hobbes Source: https://github.com/morganstanley/hobbes/blob/main/README.md Instructions for building and installing Hobbes using CMake. Requires LLVM 3.3+, CMake 3.4+, GCC 4.8+, and Linux kernel 2.5+. ```Shell cmake . make make install ``` -------------------------------- ### Hi REPL Queries for Hobbes Log Data Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/raindrop_logger.rst Examples of querying logged data using the 'hi' REPL. Demonstrates how to load log files, inspect data types, calculate sums, and filter data based on conditions. ```hi > raindrops = inputFile :: (LoadFile "log_file_name" w) => w > size(raindrops.FirstBucket) 51 ``` ```hi > sum(raindrops.ThirdBucket[:0]) 614 ``` ```hi > :t raindrops.ThirdBucket[1:2] [int] ``` ```hi > size([x | x <- raindrops.FirstBucket[0:] ++ raindrops.SecondBucket[0:] ++ raindrops.ThirdBucket[0:] ++ raindrops.FourthBucket[0:], x > 5]) 193 ``` ```hi > raindrops.transactions ``` -------------------------------- ### Installation Rules Source: https://github.com/morganstanley/hobbes/blob/main/CMakeLists.txt Specifies rules for installing targets (libraries and executables) and directories (include files and scripts) to their respective destinations. ```cmake install(TARGETS hobbes hobbes-pic DESTINATION "lib") install(TARGETS hi hog hobbes-test DESTINATION "bin") install(DIRECTORY "include/hobbes" DESTINATION "include") install(DIRECTORY "scripts" DESTINATION "scripts") ``` -------------------------------- ### Simple Hobbes Logging Example Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/logging/HLOG.rst A basic example demonstrating a log producer with drop and auto-commit semantics. It initializes a logger and then logs a few messages using the HLOG macro. ```c++ #include #include #include using namespace std; using namespace std::chrono; ``` -------------------------------- ### Hobbes C++ Main Function Example Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst The `main` function initializes a `hobbes::cc` instance, binds several functions to it, and then enters a loop to accept user input, compile, and execute Hobbes expressions. It includes error handling and memory pool resetting. ```C++ int main() { hobbes::cc c; c.bind("addTwo", &addTwo); c.bind("getWriters", &getWriters); c.bind("getWriter", &getWriter); c.bind("classify", &classify); c.bind("binaryIntFn", &binaryIntFn); while (std::cin) { std::cout << "> " << std::flush; std::string line; std::getline(std::cin, line); if (line == ":q") break; try { c.compileFn(std::string("print(") + line + ")")(); } catch (std::exception& ex) { std::cout << "*** " << ex.what(); } std::cout << std::endl; hobbes::resetMemoryPool(); } return 0; } ``` -------------------------------- ### Hobbes Slice Notation Examples Source: https://github.com/morganstanley/hobbes/blob/main/README.md Provides examples of Hobbes's slice notation for extracting subsequences. It covers positive, negative, reversed, and full-sequence slicing. ```Hobbes > "foobar"[0:3] "foo" ``` ```Hobbes > "foobar"[3:0] "oof" ``` ```Hobbes > "foobar"[-3:] "bar" ``` ```Hobbes > "foobar"[:-3] "rab" ``` ```Hobbes > "foobar"[0:] "foobar" ``` ```Hobbes > "foobar"[:0] "raboof" ``` -------------------------------- ### Hobbes REPL Example Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/embedding/compiler.rst Demonstrates the basic usage of the Hobbes REPL, including compiling and executing Hobbes code line by line. It shows how to interact with the compiler and handle exceptions. ```c++ int main() { hobbes::cc c; while (std::cin) { std::cout << "> " << std::flush; std::string line; std::getline(std::cin, line); try { c.compileFn(std::string("print(") + line + ")")(); } catch (std::exception& ex) { std::cout << "*** " << ex.what(); } std::cout << std::endl; hobbes::resetMemoryPool(); } } ``` -------------------------------- ### Addable Instance for Integers Source: https://github.com/morganstanley/hobbes/blob/main/README.md An example of an 'Addable' instance for integers. It assumes the existence of a function 'iadd' for integer addition and maps the overloaded '+' operator to it. ```hobbes instance Addable int int int where (+) = iadd ``` -------------------------------- ### Hobbes Rewriting Process Example (:u command) Source: https://github.com/morganstanley/hobbes/blob/main/README.md Illustrates Hobbes's rewriting mechanism, showing how a constrained expression like 'show(42)' is transformed into a concrete function call 'showInt(42)' using the ':u' command. ```Haskell-like > :u show(42) showInt(42) ``` -------------------------------- ### Simple C++ Function Binding Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst Demonstrates binding a basic C++ function `addTwo` to the Hobbes environment. This function takes an integer and returns the integer plus two. ```c++ int addTwo(int i){ return 2 + i; } ``` -------------------------------- ### C++ Function Pointer Binding for Hobbes Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst Presents a C++ function `binaryIntFn` that accepts a function pointer as an argument. This demonstrates how function pointers can be passed and used within the Hobbes environment. ```c++ int binaryIntFn(int (*pf)(int, int), int x){ return pf(x, x); } ``` -------------------------------- ### Hobbes Basic Pattern Matching Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/controlflow.rst Shows a simple pattern matching example using a 'match' expression, similar to a switch statement. It includes a wildcard '_' for the default case. ```Hobbes match 3 with | 1 -> show("hello") | 2 -> show("hobbes") | _ -> show("oops!") ``` -------------------------------- ### C++ Switch Statement Example Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates a basic C++ switch statement for conditional execution based on integer values. ```C++ switch (x) { case 0: return "foo"; case 1: return "bar"; case 2: return "chicken"; default: return "beats me"; } ``` -------------------------------- ### Hobbes Header Inclusion Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst Includes the necessary Hobbes header file for using the Hobbes interpreter and its functionalities in a C++ program. ```c++ #include ``` -------------------------------- ### Logging to Disk with Hog Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/logging/hog.rst Demonstrates how to use 'hog' to consume logs and write them to local disk. It shows the command to start 'hog' for a specific log group and the expected output indicating local mode operation and file writing. ```bash $ hog -g SimpleLogger [2018-01-01T09:00:00.867323]: hog running in mode : |local={ dir="./$GROUP/$DATE/data", serverDir="/var/tmp" groups={"SimpleLogger"} }| [2018-01-01T09:00:00.867536]: install a monitor for the SimpleLogger group [2018-01-01T09:00:01.637614]: new connection for 'SimpleLogger' [2018-01-01T09:00:01.733374]: queue registered for group 'SimpleLogger' from 3817:3817, cmd 0 [2018-01-01T09:00:01.912325]: ==> FirstEvent :: () (#0) [2018-01-01T09:00:01.969274]: ==> SecondEvent :: [:char|10L:] (#1) [2018-01-01T09:00:02.009241]: ==> log :: [2018-01-01T09:00:02.129401]: finished preparing statements, writing data to './SimpleLogger/2018.01.01/data.log' ``` -------------------------------- ### Using the Hobbes Network Client (C++) Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/networking/cpp.rst This example shows how to instantiate the generated Connection class, establish a connection to a Hobbes process, and invoke a remote function ('mul'). It includes basic error handling for the connection and remote call. ```C++ int main(int, char**) { try { Connection c("localhost:8080"); std::cout << "c.mul(1,2) = " << c.mul(1,2) << std::endl; } catch (std::exception& e) { std::cout << "*** " << e.what() << std::endl; } return 0; } ``` -------------------------------- ### Hobbes Networking API Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/networking/hi.rst Provides an overview of the core Hobbes networking functionalities, including connection setup, remote function invocation, and type negotiation mechanisms. ```APIDOC Hobbes Networking: Connect unqualifier: Connect "host:port" p - Establishes a connection to a Hobbes server at the specified host and port. - 'p' is a placeholder for the connection object. invoke(connection, function_name, arguments): - Invokes a function on a remote Hobbes process. - connection: The connection object to the remote server. - function_name: The name of the function to invoke (quoted form). - arguments: The arguments to pass to the remote function. - Returns a serialized representation of the function call. receive(serialized_data): - Deserializes and processes data received from a remote Hobbes process. - Handles type negotiation and returns the result of the remote operation. printConnection(connection): - Displays details about an established connection, including assigned IDs for remote functions and their inferred types. Remote Function Definition: - Functions can be defined on the server (e.g., `addOne = \x.x+1`). - These functions can be made available remotely via the `invoke` mechanism. Delayed Invocation and Type Inference: - Hobbes can query type information from the server before invoking a method. - This is achieved by specifying input types (e.g., `x::int`) in the remote function call. - The server process performs type inference, returning structured type data. Error Handling: - Errors occurring on the server (e.g., undefined variables, type mismatches) are propagated back to the client. - The `receive` function will surface these server-side errors. ``` -------------------------------- ### C++ Nested Switch Statement Example Source: https://github.com/morganstanley/hobbes/blob/main/README.md Presents a C++ implementation using nested switch statements to handle multi-value conditions, highlighting the verbosity compared to Hobbes. ```C++ switch (x) { case 0: switch (y) { case 0: return "foo"; case 1: return "foobar"; default: return "beats me"; } case 1: switch (y) { case 0: return "bar"; case 1: return "barbar"; default: return "beats me"; } case 2: switch (y) { case 0: return "chicken"; case 1: return "chicken bar!"; default: return "beats me"; } default: return "beats me"; } ``` -------------------------------- ### Hobbes REPL Implementation in C++ Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst The main function sets up the Hobbes interpreter context, binds various C++ functions (including custom types, arrays, and variants) to the interpreter, and then enters a loop to read user input, compile and execute Hobbes code, and print results. It includes error handling for compilation and execution, and a mechanism to exit the loop. ```c++ #include #include #include int addTwo(int i){ return 2 + i; } DEFINE_STRUCT( Writer, (size_t, age), (const hobbes::array*, name) ); typedef std::pair*> Writer; Writer* getWriter(){ return hobbes::make(34, hobbes::makeString("Sam")); } hobbes::array* getWriters(){ auto writers = hobbes::makeArray(4); writers->data[0].age = 21; writers->data[0].name = hobbes::makeString("John"); writers->data[1].age = 22; writers->data[1].name = hobbes::makeString("Paul"); writers->data[2].age = 22; writers->data[2].name = hobbes::makeString("George"); writers->data[3].age = 42; writers->data[3].name = hobbes::makeString("Sam"); return writers; } typedef hobbes::variant*> CountOrMessage; CountOrMessage* classify(int i){ if(i < 22){ return hobbes::make(i); }else{ return hobbes::make(hobbes::makeString("haha!")); } } int binaryIntFn(int (*pf)(int, int), int x){ return pf(x, x); } int main() { hobbes::cc c; c.bind("addTwo", &addTwo); c.bind("getWriters", &getWriters); c.bind("getWriter", &getWriter); c.bind("classify", &classify); c.bind("binaryIntFn", &binaryIntFn); while (std::cin) { std::cout << "> " << std::flush; std::string line; std::getline(std::cin, line); if (line == ":q") break; try { c.compileFn(std::string("print(") + line + ")")(); } catch (std::exception& ex) { std::cout << "*** " << ex.what(); } std::cout << std::endl; hobbes::resetMemoryPool(); } return 0; } ``` -------------------------------- ### Hobbes Array Handling in C++ Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst Illustrates the use of `hobbes::makeArray` to create and populate an array of custom `Writer` types. Each element in the array is initialized with specific age and name values, demonstrating Hobbes' interaction with collections. ```c++ hobbes::array* getWriters(){ auto writers = hobbes::makeArray(4); writers->data[0].age = 21; writers->data[0].name = hobbes::makeString("John"); writers->data[1].age = 22; writers->data[1].name = hobbes::makeString("Paul"); writers->data[2].age = 22; writers->data[2].name = hobbes::makeString("George"); writers->data[3].age = 42; writers->data[3].name = hobbes::makeString("Sam"); return writers; } ``` -------------------------------- ### Binding Custom Datatypes with Hobbes Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst Shows how to define a custom C++ struct `Writer` using the `DEFINE_STRUCT` macro, making it known to Hobbes. It also demonstrates creating instances of this custom type and `std::string` using Hobbes' memory management functions (`hobbes::make` and `hobbes::makeString`). ```c++ DEFINE_STRUCT( Writer, (size_t, age), (const hobbes::array*, name) ); typedef std::pair*> Writer; Writer* getWriter(){ return hobbes::make(34, hobbes::makeString("Sam")); } ``` -------------------------------- ### Hobbes Pattern Matching with Arrays Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/controlflow.rst Illustrates pattern matching on arrays in Hobbes, specifically focusing on extracting elements and matching against specific array structures. The example shows how to use wildcards to ignore elements. ```Hobbes match [("sam", 2013), ("james", 2012), ("stephen", 2010)] with | [_, (n, 2012), _] -> show(n) | _ -> show("none") ``` -------------------------------- ### Specializing hobbes::lift for Custom Type Descriptions Source: https://github.com/morganstanley/hobbes/blob/main/README.md Explains how to specialize the `hobbes::lift` type to provide custom descriptions for C++ types when the default lifting logic is insufficient. References `hobbes/lang/tylift.H` for examples. ```C++ If the default logic for lifting your C++ type is insufficient, the `hobbes::lift` type can be specialized to determine a more useful description (the code in `hobbes/lang/tylift.H` has many examples of this; this is where the default set of lift definitions are made). ``` -------------------------------- ### Hobbes GroupBy and Comprehension for Summarization Source: https://github.com/morganstanley/hobbes/blob/main/README.md Shows how to use the `groupBy` function in Hobbes to categorize elements of a sequence, followed by a comprehension to process the grouped results. This example sums numbers based on their divisibility by 3. ```Hobbes > [(k, sum(vs)) | (k, vs) <- groupBy(x.x % 3, [0..20])] 0 63 1 70 2 77 ``` -------------------------------- ### Hobbes Variant Usage in C++ Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/simplerepl.rst Demonstrates the use of `hobbes::variant` to create a type that can hold either an integer or a string. The `classify` function shows how to conditionally initialize the variant with different types based on input. ```c++ typedef hobbes::variant*> CountOrMessage; CountOrMessage* classify(int i){ if(i < 22){ return hobbes::make(i); }else{ return hobbes::make(hobbes::makeString("haha!")); } } ``` -------------------------------- ### Hobbes Haskell Code Snippets Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/index.rst Examples of Hobbes code demonstrating functional programming constructs like nil and cons, written in Haskell syntax. These snippets illustrate basic data structure definitions within the Hobbes environment. ```haskell nil :: () -> (^x.(()+(a*x))) nil _ = roll(|0=()|) cons :: (a, ^x.(()+(a*x))) -> (^x.(()+(a*x))) cons x xs = roll(|1=(x,xs)|) ``` -------------------------------- ### Hobbes Maybe Type and Utilities Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/appendix/stdlib.rst Explains the Hobbes 'Maybe' type, used for handling cases where a value might not exist. It shows the type's definition, constructors ('just', 'nothing'), and utility functions like 'dropNulls', 'map', and 'fromMaybe' with examples. ```Hobbes (()+a) maybenums = [just(1), just(2), nothing, just(3)] dropNulls(maybenums) map((\x.x+2), maybenums) fromMaybe(0, maybenums[1]) fromMaybe(0, maybenums[2]) ``` -------------------------------- ### Interactive Data Querying with 'hi' Shell Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates how to use the 'hi' shell to load and query data from a log file. It shows how to access specific fields like 'sensor' and 'carPassed' and how to view live data updates. ```Hobbes > wm = inputFile :: (LoadFile "./WeatherMonitor/data-2018.01.01-0.log" w) => w > wm.sensor AZ {temp=44.572017, humidity=44.582017} AZ {temp=3.575808, humidity=3.585808} HI {temp=39.150116, humidity=39.160116} ... > wm.carPassed AZ AZ CO AZ ... ``` -------------------------------- ### C++ Hobbes Logger Example Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/examples/raindrop_logger.rst A C++ program that logs data using the Hobbes storage system. It defines a storage group 'RaindropLogger' with unreliable manual-commit semantics and simulates logging raindrops of varying sizes into different buckets. ```c++ #include #include #include DEFINE_STORAGE_GROUP( RaindropLogger, 1, Unreliable, ManualCommit ); int main(){ while(true){ auto raindrop_size { rand () % 10 }; switch( rand() % 5){ case 0: HSTORE(RaindropLogger, FirstBucket, size); break; case 1: HSTORE(RaindropLogger, SecondBucket, size); break; case 2: HSTORE(RaindropLogger, ThirdBucket, size); break; case 4: HSTORE(RaindropLogger, FourthBucket, size); break; } RaindropLogger.commit(); cout << "." << flush; this_thread::sleep_for(milliseconds(500)); } } ``` -------------------------------- ### Hobbes Parser with Ambiguous Grammar Example Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates a Hobbes parser definition that introduces ambiguous choice, which is treated as an error in Hobbes to ensure predictable O(n) parse times. This example highlights a scenario where a parser might have multiple valid interpretations. ```hobbes err = parse { S := "a" { 1 } | z:Z { z } Z := "a" { 2 } } ``` -------------------------------- ### Building the Hobbes C++ Program Source: https://github.com/morganstanley/hobbes/blob/main/README.md Provides the command-line instructions to compile a C++ program that embeds Hobbes. It specifies necessary include paths, libraries for Hobbes and LLVM, and compiler flags. ```Shell $ g++ -pthread -std=c++11 -I -I test.cpp -o test -L -lhobbes -ldl -lrt -ltinfo -lz -L `llvm-config --libs x86asmparser x86codegen x86 mcjit passes` ``` -------------------------------- ### Show Instance for Tuples Source: https://github.com/morganstanley/hobbes/blob/main/README.md Provides a 'Show' instance for any type 'p' that has a 'ShowTuple' instance. It formats the tuple representation by joining the string representations of its elements with commas and enclosing them in parentheses. ```hobbes instance (ShowTuple p) => Show p where show p = "(" ++ cdelim(showTuple(p), ", ") ++ ")" ``` -------------------------------- ### Mock Cheeseburger Order Management Application Source: https://github.com/morganstanley/hobbes/blob/main/README.md A C++ program demonstrating transactional data recording for a mock cheeseburger order system. It uses HSTORE to record customer actions like entering the store, ordering products, and payment, with manual commit for transaction correlation. ```C++ int main() { while (true) { // a customer enters the store const char* names[] = { "Harv", "Beatrice", "Pat" }; const char* name = names[rand() % 3]; HSTORE(Orders, customerEntered, name); // he/she orders a cheeseburger const char* products[] = { "BBQ Attack", "Cheese Quake", "Bacon Salad" }; const char* product = products[rand() % 3]; HSTORE(Orders, productOrdered, product); // perhaps he/she decides to add a drink if (rand() % 5 == 0) { const char* drinks[] = { "Soda", "Lemonade", "Water" }; const char* drink = drinks[rand() % 3]; HSTORE(Orders, drinkOrdered, drink); } // sometimes the customer has a change of heart, else they pay up and go if (rand() % 10 == 0) { HSTORE(Orders, orderCanceled); } else { HSTORE(Orders, paymentReceived, 10.0 * ((double)(rand() % 100)) / 100.0); } // now that the order is finished, end the transaction Orders.commit(); } return 0; } ``` -------------------------------- ### Establishing Compile-Time Connection (Hobbes) Source: https://github.com/morganstanley/hobbes/blob/main/README.md Establishes a network connection to a remote Hobbes process at compile-time using the `connection` function and a provided signature. ```Hobbes > c = connection :: (Connect "localhost:8080" p) => p > ``` -------------------------------- ### Hobbes Type Inference Failure Example Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates a scenario in Hobbes where type inference fails due to unresolved type constraints when the result type of an addition is not explicitly provided. ```Haskell-like > 1 + 2 stdin:1,1-5: Failed to compile expression due to unresolved type constraints: Addable int int a Print a > ``` -------------------------------- ### Bind C++ Function to Hobbes Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates how to bind a C++ function to a Hobbes instance, making it callable from Hobbes expressions. The example shows a simple integer multiplication function. ```C++ int applyDiscreteWeighting(int x, int y) { return x * y; } // ... c.bind("applyDiscreteWeighting", &applyDiscreteWeighting); ``` ```Hobbes > applyDiscreteWeighting(3, 4) 12 > applyDiscreteWeighting(3, "pizza") *** stdin:1,1-22: Cannot unify types: int != [char] ``` -------------------------------- ### Live Data Updates with Signals Source: https://github.com/morganstanley/hobbes/blob/main/README.md Shows how to register a function to receive updates for specific data fields, enabling real-time monitoring and processing of data as it changes. ```Hobbes > signals(wm).sensor <- (\_.do { putStrLn("sensor batch updated"); return true }) sensor batch updated sensor batch updated sensor batch updated sensor batch updated ``` -------------------------------- ### Hobbes Type Class Constraint Example Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/polymorphism.rst Demonstrates how Hobbes infers type class constraints for functions, showing the 'Add' type class for a function involving addition. ```Hobbes > :t \x.x.Name ``` -------------------------------- ### Querying Transactional Data with 'hi' Source: https://github.com/morganstanley/hobbes/blob/main/README.md Illustrates how to load and query the 'transactions' sequence from a log file generated by the 'Orders' storage group. It shows the structure of transaction data, including timestamps and arrays of recorded storage statements. ```Hobbes > orders = inputFile :: (LoadFile "./Orders/data-2018.01.01-0.log" w) => w > orders.transactions time entries -------------------------- -------------------------------------------------------------------------------------------------------------------- 2018-01-01T12:19:03.244206 [|customerEntered=("Pat")|, |productOrdered=("Bacon Salad")|, |orderCanceled|] ``` -------------------------------- ### Receiving Logs from Remote Hog Instance Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/logging/hog.rst Shows the command to start a 'hog' instance to receive log messages from a remote 'hog' process. It specifies the port on which the receiving instance will listen. ```bash $ hog -g SimpleLogger -s $p ``` -------------------------------- ### Hobbes Qualified Types and Type Inference Source: https://github.com/morganstanley/hobbes/blob/main/README.md Illustrates the use of qualified types and type classes in Hobbes, enabling mixed-type arithmetic and type inference. Includes an example of a lambda function for addition. ```hobbes > 0X01+2+3.0+4L+5S 15 > (\x y z u v.x+y+z+u+v)(0X01,2,3S,4L,5.0) 15 ``` -------------------------------- ### Hobbes Interactive Shell (hi) - Type Queries for Qualified Types Source: https://github.com/morganstanley/hobbes/blob/main/README.md Illustrates how to use the 'hi' shell to view type constraints for qualified types in Hobbes. ```hobbes > :t \x.x.foo (a.foo::b) => (a) -> b > :t .foo (a.foo::b) => (a) -> b ``` -------------------------------- ### Hobbes Interactive Shell (hi) - Type Queries for Primitives Source: https://github.com/morganstanley/hobbes/blob/main/README.md Shows how to use the 'hi' interactive shell in Hobbes to query the types of primitive values. ```hobbes $ hi hi : an interactive shell for hobbes type ':h' for help on commands > :t () () > :t false bool > :t 'c' char > :t 0Xff byte > :t 42S short > :t 42 int > :t 42L long > :t 42.0f float > :t 42.0 double ``` -------------------------------- ### Hobbes Match Expression Syntax Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates the general form of match expressions in Hobbes, including multiple inputs, patterns, conditions, and result expressions. ```Hobbes match I0 I1 ... IN with | p00 p10 ... pN0 where C0 -> E0 | p01 p11 ... pN1 where C1 -> E1 | ... | p0R p1R ... pNR -> ER ``` -------------------------------- ### Hobbes Type Unification Error in Match Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/controlflow.rst Provides an example of a type error in Hobbes when different branches of a match expression return incompatible types. This demonstrates the importance of type consistency. ```Hobbes > match 1 with | 0 -> "hello" | _ -> 1 Cannot unify types: [char] != int ``` -------------------------------- ### Hobbes Language Design Rationale Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/introduction/domain.rst Explains why a custom language like Hobbes is necessary for low-latency trading systems, contrasting it with alternatives like Python and C++. ```APIDOC Why a custom language? It's a great question. The domain (dynamic, non-developer-driven changes to execution behaviour of processes which can't be restarted, and which come with a *tight* latency budget) is specialised enough to quickly exhaust most existing solutions: * Hosting a python environment would be user-friendly but not fast enough. * Dynamically-compiled C++ would be fast but ugly, brittle, and complex. * Marshalling runtime execution decisions to another process, perhaps one which enjoyed more natural dynamic mapping to natural language, would quickly blow latency away. In addition, a custom *type system* allows for tight bindings with existing data in hosting applications, along with low-latency custom serialisation for binary logging. ``` -------------------------------- ### Hobbes Recursive Type Definition for Lists Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/types.rst Demonstrates how to define recursive types in Hobbes, using the canonical example of a list. It shows the syntax for denoting recursion with a caret ('^') to define a type that refers to itself. ```Hobbes ^x.(()+([char]*x)) ``` -------------------------------- ### Hobbes Interpreter Loading Files Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/appendix/hi.rst Shows how to load and execute code from a Hobbes file using the 'hi' interpreter, making symbols from the file available in the session. ```hobbes bin/hobbes $ cat match.hob foo = match 3 with | 1 -> "hello" | 2 -> "hobbes" | _ -> "oops" bin/hobbes $ hi match.hob hi : an interactive shell for hobbes type ':h' for help on commands loaded module 'match.hob' > foo "oops" ``` -------------------------------- ### Defining and Binding C++ Structs in Hobbes Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/embedding/compiler.rst Shows how to expose C++ structs to Hobbes using the DEFINE_STRUCT macro and how to bind functions that return arrays of these structs. It includes examples of initializing struct members. ```c++ DEFINE_STRUCT(Writer, (size_t, age), (const hobbes::array*, name) ); hobbes::array* getWriters(){ auto writers = hobbes::makeArray(2); writers->data[0].age = 21; writers->data[0].name = hobbes::makeString("John"); writers->data[1].age = 22; writers->data[1].name = hobbes::makeString("Paul"); return writers; } ``` -------------------------------- ### Transactional Data Storage Group Definition Source: https://github.com/morganstanley/hobbes/blob/main/README.md Defines a storage group named 'Orders' with specific reliability and commit policies. This setup is used for tracking all orders reliably and correlating events within an order transactionally. ```C++ #include #include DEFINE_STORAGE_GROUP( Orders, 3000, hobbes::storage::Reliable, /* we _must_ track all orders */ hobbes::storage::ManualCommit /* we need to correlate all events in an order */ ); ``` -------------------------------- ### Hobbes Multi-Value Pattern Matching Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/controlflow.rst Demonstrates pattern matching with multiple values and the use of wildcards. It highlights the top-down matching order and the requirement for matching all potential options or providing a default. ```Hobbes match 1 2 with | 2 _ -> show("first!") | 1 2 -> show("second!") | _ _ -> show("default!") ``` ```Hobbes match 1 2 with | _ 2 -> show("matched!") | 1 2 -> show("didn't match!") | _ _ -> show("didn't even get here!") ``` ```Hobbes match 1 2 with | _ 2 -> show("matched!") | 1 2 -> show("didn't match!") | _ _ -> show("didn't even get here!") ``` -------------------------------- ### Executable and Test Targets Source: https://github.com/morganstanley/hobbes/blob/main/CMakeLists.txt Defines executables for mock processes and tests, links the main Hobbes library to the test executable, and adds the test executable as a CMake test. ```cmake add_executable(mock-proc test/mocks/proc.C) add_executable(hobbes-test ${test_files}) target_link_libraries(hobbes-test PRIVATE hobbes) add_test(hobbes-test hobbes-test) ``` -------------------------------- ### Hobbes Library and Executable Definitions (CMake) Source: https://github.com/morganstanley/hobbes/blob/main/CMakeLists.txt Defines the static libraries 'hobbes' and 'hobbes-pic', and executables 'hi' and 'hog'. It specifies source files using `file(GLOB_RECURSE ...)` and links necessary libraries including LLVM, ZLIB, Curses, Readline, and system libraries. ```cmake file(GLOB_RECURSE lib_headers lib/*.H) file(GLOB_RECURSE lib_source lib/*.C) set(lib_files ${lib_headers} ${lib_source}) include_directories(include) file(GLOB test_files test/*.C) file(GLOB hi_files bin/hi/*.C) file(GLOB_RECURSE hog_files bin/hog/*.C) add_library(hobbes STATIC ${lib_files}) target_link_libraries(hobbes PUBLIC ${llvm_ldflags} ${llvm_libs} ${ZLIB_LIBRARIES} ${CURSES_LIBRARIES} ${sys_libs}) add_library(hobbes-pic STATIC ${lib_files}) target_link_libraries(hobbes-pic PUBLIC ${llvm_ldflags} ${llvm_libs} ${ZLIB_LIBRARIES} ${CURSES_LIBRARIES} ${sys_libs}) set_property(TARGET hobbes-pic PROPERTY POSITION_INDEPENDENT_CODE TRUE) add_executable(hi ${hi_files}) target_link_libraries(hi PUBLIC "-rdynamic" PRIVATE hobbes ${Readline_LIBRARIES}) add_executable(hog ${hog_files}) target_link_libraries(hog PRIVATE hobbes) enable_testing() ``` -------------------------------- ### Show Instance for Integer Source: https://github.com/morganstanley/hobbes/blob/main/README.md Provides a 'Show' instance for the 'int' type. It associates the 'show' function with 'showInt', a default Hobbes function for converting integers to strings. ```hobbes instance Show int where show = showInt ``` -------------------------------- ### Connect to hi Server Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/networking/hi.rst Establishes a connection from a client 'hi' instance to a running server. It uses the 'Connect' unqualifier to specify the server's host and port. ```C++ > c = connection :: (Connect "myhost:8080" p) => p ``` -------------------------------- ### Hobbes Sum Type Usage Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/types.rst Illustrates the creation and typing of sum types in Hobbes, which are variants without names. It shows using indices to specify the type (int or char array) and provides examples of instantiating these sum types. ```Hobbes > |1="hello"| :: (int+[char]) |1="hello"| > |0=3| :: (int+[char]) |0=3| ``` -------------------------------- ### Hog Consumer Program Usage Source: https://github.com/morganstanley/hobbes/blob/main/README.md Provides the command-line usage for the 'hog' program, which consumes and stores data produced by Hobbes. It details various options for data storage, routing, and configuration. ```APIDOC hog : record structured data locally or to a remote process usage: hog [-d ] [-g group+] [-p t s host:port+] [-s port] [-c] [-m ] [-z] where -d : decides where structured data (or temporary data) is stored -g group+ : decides which data to record from memory on this machine -p t s host:port+ : decides to send data to remote process(es) every t time units or every s uncompressed bytes written -s port : decides to receive data on the given port -c : decides to store equally-typed data across processes in a single file -m : decides where to place the domain socket for producer registration (default: /var/tmp) -z : store data compressed ``` -------------------------------- ### Log Structured Data with HSTORE Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/logging/HLOG.rst Logs structured data to a specified LogGroup with an event name. Supports various Hobbes primitive types, std::string, char*, and collections like arrays, vectors, and tuples. This example logs an integer. ```c++ HSTORE( MyGroupName, EventName, 12 ); ``` -------------------------------- ### Hobbes Pattern Matching with Tuples Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/language/controlflow.rst Demonstrates matching against tuple elements in Hobbes for conditional execution based on environment variables and associated values. It shows how to unpack tuple values for use in function calls. ```Hobbes match env getHostPort(env) with | "dev" (host, port) -> connect(host, port) | "qa" (host, port) -> connectqa(host, port, qadb) | "prod" (host, _) -> connectkrb(host) | _ _ -> ... ``` -------------------------------- ### Hobbes Type Classes for Arithmetic Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/appendix/stdlib.rst Demonstrates Hobbes Type Classes for polymorphic arithmetic operations like addition. It shows the definition of the Add type class and its instances for 'int' and 'long', along with an example of defining a custom instance for a 'counter' type. ```Hobbes class Add a b c | a b -> c where (+) :: (a,b) -> c instance Add int int int where (+) = iadd instance Add long long long where (+) = ladd type counter = { count: int} counterAdd = (\x y. { count = iadd(x.count,y.count)}) instance Add counter counter counter where (+) = counterAdd ``` -------------------------------- ### C++ Variant Type and Hobbes Interaction Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/embedding/compiler.rst This example defines a C++ variant type `CountOrMessage` that can hold either an integer or a C-style string. It demonstrates creating instances of this variant based on conditions and interacting with the bound C++ function `classify` from the Hobbes REPL. ```c++ typedef hobbes::variant*> CountOrMessage; CountOrMessage* classify(int i){ if(i<22){ return hobbes::make(i); }else{ return hobbes::make classify(12) |0=12| > classify(42) |1="haha!"| ``` -------------------------------- ### Print Connection Details Source: https://github.com/morganstanley/hobbes/blob/main/doc/en/networking/hi.rst Displays the current state and details of an established network connection, including its ID, expression, input type, and output type. ```C++ > printConnection(c) id expr input output -- ---- ----- ------ > ``` -------------------------------- ### Hobbes Arrays of Records/Tuples Source: https://github.com/morganstanley/hobbes/blob/main/README.md Demonstrates how Hobbes displays arrays of records or tuples, formatting them as tables for better readability. ```hobbes > [{name="Jimmy", age=45, job="programmer"}, {name="Chicken", age=40, job="programmer"}] name age job ------- --- ---------- Jimmy 45 programmer Chicken 40 programmer > [("Jimmy", 45, "programmer"),("Chicken", 40, "programmer")] Jimmy 45 programmer Chicken 40 programmer ```