-
Function Definition:
- Begin with the keyword
funcfollowed by the function name. - Inside parentheses, list the arguments with their names followed by a colon and their types.
- Define the function body within curly braces
{}.
- Begin with the keyword
-
Function Call:
- Call functions by their name followed by parentheses.
- Inside the parentheses, specify argument names followed by a colon and the values. Arguments can be provided in any order due to the named argument feature.
-
Prototype Definition:
- Use the keyword
prototypefollowed by the prototype name to define a new prototype. - Inside curly braces
{}, define properties with thevarkeyword, and methods with thefunckeyword. - Method definition within prototypes follows the same pattern as standalone function definition.
- Use the keyword
-
Prototype Inheritance:
- Use the keyword
extendsfollowed by the name of the existing prototype to create a new prototype that inherits properties and methods of the existing one.
- Use the keyword
-
Method Call:
- Methods are called on objects using the dot (
.) operator, followed by the method name and arguments within parentheses. - Like function calls, method arguments are specified with their names followed by a colon and the values.
- Methods are called on objects using the dot (
-
Default Argument Values:
- While defining functions or methods, default values for arguments can be specified by using the equals sign (
=) followed by the default value after the type.
- While defining functions or methods, default values for arguments can be specified by using the equals sign (
-
String Interpolation:
- Strings prefixed with a dollar sign (
$) followed by double quotes ("") allow for interpolation. - Variables and expressions to be interpolated are enclosed in curly braces (
{}) within the string.
- Strings prefixed with a dollar sign (
-
Object Creation and Property Access:
- Create new objects using the
newkeyword followed by the prototype name. - Set and access properties using the dot (
.) operator.
- Create new objects using the
-
Keyword for Fiber Definition:
- Introduce a keyword
fiberto denote a coroutine. Thefiberkeyword precedes the function name and follows the same syntax as function definition but is used to declare a coroutine instead.
- Introduce a keyword
-
Fiber Body:
- The body of the fiber is enclosed within curly braces
{}. Inside the body, define the operations the coroutine should perform.
- The body of the fiber is enclosed within curly braces
-
Await Keyword:
- Introduce an
awaitkeyword within the fiber body to indicate points where the coroutine can be paused, waiting for some asynchronous operation to complete. When anawaitexpression is encountered, the fiber is paused until the awaited operation is finished, at which point the fiber is resumed.
- Introduce an
-
Creating a Fiber Instance:
- Create instances of a fiber by calling the fiber function, similar to how you'd call a regular function. This returns a fiber object.
-
Resuming a Fiber:
- Define a method
resume()on the fiber object which, when called, resumes the execution of the fiber from the point where it was last paused.
- Define a method
-
Example Code:
// Define a fiber using the 'fiber' keyword
fiber fetchData(url: String) {
// Simulate a non-blocking I/O operation
var data = await io.get(url); // Assume 'await' pauses the fiber and resumes when data is available
process(data); // Process the data
}
// Create a new fiber instance
var dataFiber = fetchData("https://example.com/data");
// Resume the fiber to start its execution
dataFiber.resume();
// Later in the code...
// Resume the fiber again, if needed (e.g., after an await)
dataFiber.resume();
In this example:
- A fiber named
fetchDatais defined with thefiberkeyword. - The
fetchDatafiber is designed to perform a simulated non-blocking I/O operation using anawaitkeyword. - A new fiber instance
dataFiberis created by callingfetchData. - The
resume()method is used to start or continue the execution of thedataFiberinstance.
- Importing Entire Modules: Users can import an entire module, bringing all of its exported items into scope.
import Math; // Import everything from the Math module
- Importing Specific Items: Users can import specific items from a module, which can help to reduce name conflicts and improve clarity.
import { sqrt, pow } from Math; // Import specific items from the Math module
- Aliasing: Users can give imported items an alias to avoid name conflicts or for convenience.
import { sqrt as squareRoot } from Math; // Import sqrt as squareRoot
- Explicit Exports:
Items (functions, prototypes, variables, etc.) are exported explicitly with an
exportkeyword, making it clear what is part of the module's public interface.
export func square(x: Int): Int {
return x * x;
}
- Default Exports: Each module can have one default export, which is the primary exported value for the module. This is useful for modules that export a single item.
export default func square(x: Int): Int {
return x * x;
}
- Export Lists: Alternatively, at the end of the module, an export list can specify all the items to be exported.
func square(x: Int): Int {
return x * x;
}
func cube(x: Int): Int {
return x * x * x;
}
export { square, cube }; // Export list
-
File-based Modules: Modules could correspond to files in the filesystem, with the module name matching the file name.
-
Folder-based Modules: If a folder is specified instead of a file, the system could look for an
indexfile in that folder as the module. -
Path Resolution: A system of path resolution for finding modules, possibly with configurable paths and support for relative and absolute paths.
-
Package Management: A package management system could be developed to download and manage third-party modules, similar to npm or pip.
-
Cyclic Dependencies: The system should handle cyclic dependencies gracefully, possibly with an error or warning.
There should be an "unsafe mode" which would be able to turn off different parts of the language such as:
- The garbage collector, letting you use your own memory management
- More will be planned soon