"Sputnik" help  
Sputnik Help
Context

Description

The function context in Sputnik allows for type-specific operations or behaviors based on the desired type when casting a function or evaluating its return value. It provides a way to specify the expected type for the function or its return value, enabling different actions or processing based on the desired type.

When using the function context, you can indicate the desired type using various annotations such as (array), (string), (int64), (double), and so on. This allows you to perform type-specific operations or handle the return value accordingly.

For example, if you have a function Func() that can return different types of values, you can utilize the function context to handle each type appropriately. Here are some examples:

When using (array)Func(), the function context ensures that the return value is treated as an array. You can perform array-specific operations or access individual array elements.
Similarly, (string)Func() specifies that the return value should be treated as a string. This enables string-specific operations like string concatenation or string manipulation.
(int64)Func() indicates that the return value is expected to be an int64 (64-bit integer). You can perform integer-specific operations or handle the value as a large integer.
(double)Func() denotes that the return value should be treated as a double-precision floating-point number. This allows for floating-point operations or precise numerical calculations.
By utilizing the function context, you can tailor your code based on the desired type, ensuring type safety and enabling appropriate handling of function return values.

Additionally, certain types can be used as function-like constructs, such as integer($value) or integer(func()). These constructs trigger the function context, similar to the casting syntax, and enable type-specific operations or behaviors based on the desired type.

For example, if you have a variable $value and you want to treat it as an integer, you can use integer($value) to trigger the function context and ensure the value is handled as an integer. Similarly, integer(func()) allows you to evaluate the return value of the function func() and treat it as an integer.

By utilizing these function-like constructs and the function context, you can tailor your code based on the desired type, ensuring type safety and enabling appropriate handling of function return values or other expressions.

Please note that the function context applies to the function as a whole or the return value specifically, depending on how it is used in the code.

Remarks

The function context in Sputnik provides a way to specify the desired type for a function or its return value, allowing for type-specific operations or behaviors. By using annotations like (array), (string), (int64), (double), and others, you can indicate the expected type and handle the return value accordingly.

When using the function context, it is crucial to save the @Want context before performing any additional operations or function calls within the function. Calling other functions or performing certain operations can inadvertently modify the @Want context, leading to unexpected results.

Saving the @Want context at the beginning of the function ensures that subsequent checks accurately reflect the intended context. By preserving the original context, you can safely perform operations and function calls without risking unintended modifications or errors in the returned values.

The function-like constructs, such as integer($value) or integer(func()), also trigger the function context, allowing for type-specific operations or behaviors based on the desired type. These constructs enable the evaluation of expressions or return values as the desired type, enhancing flexibility in handling different types.

By understanding and utilizing the function context effectively, you can tailor your code to handle specific types, ensuring type safety and enabling appropriate processing of function return values or other expressions.

In addition, it's important to note that not all functions require or utilize the function context for specifying a specific type of return value. While the function context provides flexibility for handling type-specific operations or behaviors, many functions may not explicitly request or require a particular context.

The function context becomes particularly useful in scenarios where a function's behavior or return value needs to vary based on the desired type. However, it's not a mandatory aspect of all function calls, and its usage depends on the specific requirements and design of the function itself.

When working with functions in Sputnik, it's essential to understand the purpose and intended usage of the function context, and apply it judiciously when necessary. This ensures that the function context enhances the code's readability, maintainability, and type safety, while avoiding unnecessary complexity or overhead in cases where it may not be needed.

Note: The examples provided demonstrate the usage of the function context and its practical applications.

Related

User Functions

Example

Example of usage:

printr (array)Cat();
say (string)Cat();
say (int64)Cat();
say (double)Cat();

Function Cat()
{
    if (@WantArray)
        return array("Cat", "Dog");
    if (@WantString)
        return "Hello world";
    if (@WantInt64)
        return 777;
    if (@WantDouble)
        return 13.37;
    return "oh";
}

// PRINTS

// Array
// (
//     [0] => Cat
//     [1] => Dog
// )
// Hello world
// 777
// 13.37

In the given example, we have a function called Cat() that returns different values based on the desired type specified through the function context. The function is invoked using different type annotations: (array), (string), (int64), and (double).

When the function is called with the (array) context, it checks if the function context is requesting an array. If so, it returns an array containing the elements "Cat" and "Dog".

Similarly, when the function is called with the (string) context, it checks if the function context is requesting a string. If true, it returns the string "Hello world".

For the (int64) context, the function returns the integer value 777 if the function context is requesting an int64 value.

Lastly, for the (double) context, the function returns the double value 13.37 if the function context is requesting a double value.

The resulting output shows the values returned by the function when invoked with the corresponding function contexts. Each invocation prints the expected output based on the desired type.

This example demonstrates how the function context allows for type-specific behavior, enabling the function to return different values based on the desired type. It provides flexibility in handling function return values and ensures appropriate processing based on the expected type.

Using a Switch statement in a more practical example:

printr (array)GetPoint();
say (string)GetPoint();
say (double)GetPoint();

Function GetPoint()
{
    my $x = 5;
    my $y = 10;
    switch (@Want)
    {
        case @WantTypeArray:
            return array($x, $y);
        case @WantTypeString:
            return "$x, $y";
        case @WantTypeDouble:
            return (Double)$x * (Double)$y;
    }
    return null;
}

// PRINTS
// Array
// (
//     [0] => 5
//     [1] => 10
// )
// 5, 10
// 50

In this practical example, the GetPoint() function demonstrates the power of context-based operations. Depending on the desired context, the function returns different representations of a point in a two-dimensional space.

When the context is an array ((array)GetPoint()), the function returns an array containing the x and y coordinates of the point, allowing for easy access to the individual components.

In the case of a string context ((string)GetPoint()), the function returns a string representation of the point, where the x and y coordinates are concatenated together with a comma, providing a human-readable format.

Lastly, in a double context ((double)GetPoint()), the function calculates and returns the product of the x and y coordinates as a double value, representing the area of a rectangle with sides defined by the coordinates.

This example showcases the flexibility and versatility of context-based operations. By tailoring the return value based on the desired context, the GetPoint() function provides different representations of a point, allowing for seamless integration into various scenarios. It can be particularly useful in applications involving vectors, mouse coordinates, graphics, or any situation where different representations of a point are required based on the context of its usage.

Same as above but using a Select statement instead:

printr (array)GetPoint();
say (string)GetPoint();
say (double)GetPoint();

Function GetPoint()
{
    my $x = 5;
    my $y = 10;
    select
    {
        case @WantArray:
            return array($x, $y);
        case @WantString:
            return "$x, $y";
        case @WantDouble:
            return (Double)$x * (Double)$y;
    }
    return null;
}

// PRINTS
// Array
// (
//     [0] => 5
//     [1] => 10
// )
// 5, 10
// 50

Saving the context:

printr (array)Cat();
say (string)Cat();
say (int64)Cat();
say (double)Cat();
say (float)Cat();

Function Cat()
{
    my $w = @Want;
    if ($w == @WantTypeArray)
        return array("Cat", "Dog");
    if ($w == @WantTypeString)
        return "Hello world";
    if ($w == @WantTypeInt64)
        return 777;
    if ($w == @WantTypeDouble)
        return 13.37;
    return 6;
}

// PRINTS

// Array
// (
//     [0] => Cat
//     [1] => Dog
// )
// Hello world
// 777
// 13.37
// 6


In this updated example, we have the same function Cat() with the addition of a new line my $w = @Want;. This line stores the current function context in a variable $w.

Instead of directly checking the function context using @WantArray, @WantString, etc., we compare the value of $w with the corresponding function context types, such as @WantTypeArray, @WantTypeString, etc.

This approach allows us to perform additional operations or call other functions within the Cat() function without altering the original function context. By saving the function context in a variable, we can safely use the value of $w in different comparisons and logic without losing or modifying the initial function context.

The resulting output remains the same as the previous example, displaying the values returned by the Cat() function based on the corresponding function contexts. The ability to save and use the function context in this manner provides flexibility and control over the behavior of the function.

This style is particularly useful when we want to perform complex operations or conditionals based on the function context, ensuring that we maintain the original context throughout the function execution. It allows us to safely manipulate the function's behavior without risking unintended modifications to the function context.

Overall, this approach enhances the flexibility and versatility of the function by preserving the function context while enabling more complex logic based on the saved context value.

Here is what happens if the context is not saved:

printr (array)Cat();
say (string)Cat();
say (int64)Cat();
say (double)Cat();

Function Cat()
{
    my $a = substr("cat", 1);
    if (@WantArray)
        return array("Cat", "Dog");
    if (@WantString)
        return "Hello world";
    if (@WantInt64)
        return 777;
    if (@WantDouble)
        return 13.37;
    return $a;
}

// PRINTS

// Array
// (
//     [0] => at
// )
// at
// 0
// 0

In this updated example, we have the function Cat() with an additional line of code my $a = substr("cat", 1);. This line of code extracts a substring from the string "cat" starting from index 1, resulting in the value "at".

The purpose of this example is to illustrate why it is important to save the @Want context before performing any additional operations or function calls within the function.

When we call a function or perform certain operations, it can modify or overwrite the current function context, potentially causing unexpected results. In the case of this example, calling substr() modifies the string but also inadvertently modifies the @Want context.

As a result, when we subsequently check the @WantArray, @WantString, @WantInt64, and @WantDouble contexts, they no longer match the original function context. Therefore, the function returns unexpected values: an array with only one element, the substring "at", and the default values of 0 for @WantInt64 and @WantDouble.

By saving the @Want context at the beginning of the function, as we did in the previous examples, we can safely perform operations and function calls without affecting the original function context. This allows us to accurately determine the desired type and return the expected values based on the saved context.

In summary, saving the @Want context before any potential context-modifying operations or function calls ensures that the subsequent checks accurately reflect the intended context and prevent unintended modifications or errors in the returned values.

Here is an example of using the want context system with the generic statement to achieve an interesting result:

my $a = array("testy");
my $b = "testy";
my $c = 100;
my $d = 100.0;
printr generic($a, array: array("Cat", "Dog"), string: "Hello world", int64: 777, double: 13.37);
printr generic($b, array: array("Cat", "Dog"), string: "Hello world", int64: 777, double: 13.37);
printr generic($c, array: array("Cat", "Dog"), string: "Hello world", int64: 777, double: 13.37);
printr generic($d, array: array("Cat", "Dog"), string: "Hello world", int64: 777, double: 13.37);

Function Cat()
{
    if (@WantArray)
        return array("Cat", "Dog");
    if (@WantString)
        return "Hello world";
    if (@WantInt64)
        return 777;
    if (@WantDouble)
        return 13.37;
    return "oh";
}

// PRINTS
// Array
// (
//     [0] => Cat
//     [1] => Dog
// )
// Hello world
// 777
// 13.37

The combination of the Want context and the Generic function in Sputnik allows for powerful and flexible type-based evaluations and behavior. By utilizing these features together, you can create code that adapts dynamically to different types and contexts, enhancing code reusability and maintainability.

In the provided example, the code demonstrates how the Want context is used within the Generic function to handle different types of input values. The Generic function evaluates the input value based on the provided type-expression pairs and returns the corresponding expression that matches the Want context.

The Function Cat() showcases the usage of the Want context within an if-else logic structure. Depending on the value of the Want context, the function returns different values, including an array, a string, an int64 value, or a double value. This dynamic behavior allows the code to adapt its output based on the desired type specified in the Want context.

The resulting output from the printr statements demonstrates the flexibility of combining the Want context and the Generic function. Each printr statement returns the expected output based on the provided input and the matching type-expression pairs defined within the Generic function.

This combination of features in Sputnik opens up a wide range of possibilities for creating flexible and type-aware code. It enables you to handle different data types and contexts seamlessly, making your code more adaptable and versatile.

By leveraging the Want context and the Generic function, you can achieve type-specific operations, handle different return values, and customize the behavior of your code based on the desired type. This capability enhances the overall functionality and effectiveness of your Sputnik programs, allowing for more efficient and expressive code.

Overall, the ability to combine the Want context and the Generic function in Sputnik showcases the language's versatility and provides a powerful toolset for type-based evaluations and dynamic behavior.


Contact
Cheryl (uberfox@hotmail.com)
Homepage
http://ubersoft.org