{"id":27121962,"url":"https://github.com/osiris-team/a-lang","last_synced_at":"2025-04-07T11:17:21.475Z","repository":{"id":110532623,"uuid":"475858170","full_name":"Osiris-Team/A-Lang","owner":"Osiris-Team","description":"A language is my idea of a perfect programming language.","archived":false,"fork":false,"pushed_at":"2025-02-24T02:02:01.000Z","size":537,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-07T11:17:15.373Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Osiris-Team.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-30T11:59:13.000Z","updated_at":"2025-02-24T02:02:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"87707a5d-eda5-4932-a4fa-d99d8bd6e8ad","html_url":"https://github.com/Osiris-Team/A-Lang","commit_stats":null,"previous_names":["osiris-team/a-lang"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osiris-Team%2FA-Lang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osiris-Team%2FA-Lang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osiris-Team%2FA-Lang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osiris-Team%2FA-Lang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Osiris-Team","download_url":"https://codeload.github.com/Osiris-Team/A-Lang/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247640475,"owners_count":20971558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-07T11:17:20.583Z","updated_at":"2025-04-07T11:17:21.463Z","avatar_url":"https://github.com/Osiris-Team.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A-Lang\nA language is my idea of a perfect programming language, which was\nborn from the frustration and joy of using languages like Java, C, C++ and JavaScript.\n\nThere is an actual compiler written in Java that compiles A =\u003e C =\u003e binary.\nThus A achieves the same cross-platform performance as C.\n\nIts main aim is to make programming fun and provide higher-level concepts without sacrificing performance.\nFunctions are variables for example. To be exact, everything in this language is a variable and\nyou can learn the whole language by reading this file.\n\nIf you want to get started right away, download the [A-Sample](https://github.com/Osiris-Team/A-Sample) repo,\nopen a terminal in that folder and\nexecute `./a/a` on Linux or `.\\a\\a.exe` if you are on Windows (this starts the A compiler command-line interface).\n\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eCore Ideas, Highlights and Status\u003c/b\u003e\u003c/summary\u003e\n\n ## Core Ideas\n - Tiny standard library, to keep the focus on language development. This will change once the language is more mature.\n - Allow easy use of GPU / hardware acceleration, instead of only writing CPU code.\n - Provide cross-platform methods for all input and output devices, like (touch-)screens, keyboards, files, etc.\n - Include a dependency management system and provide an online repository.\n - Include a build-tool and make compilation frictionless.\n - Performance, fast writability, and readability have the same importance.\n - Encourage the use of event listeners.\n - Garbage collected via [bdwgc](https://github.com/ivmai/bdwgc), can be [disabled](#TODO).\n - Library developers should benefit the same amount as their users, in terms of language features.\n - Language patterns/features should be simple, consistent, logical, and similar to each other.\n\n## Highlights\n - Modular Object Oriented Programming (MOOP) via [object parts](#object-blocks--parts).\n - Compiles to C and [allows embedding raw C code](#TODO).\n - Everything is a variable and [primitives functionality can be extended](#Extending-functionality).\n\n## Status\n- No release yet, still in early development (spec- and implementation-wise). Once the basics are done 1.0 will get released.\n- This repository contains the A compiler which is written in Java and misses a bunch of the features mentioned in this file.\nHowever it more or less lays the groundwork and style for the compiler.\n\u003c/details\u003e\n\n\n\n## Statements\nMultiple statements on a single line must be separated by a semicolon `;` otherwise\nthe semicolon is optional.\n```java\na = 10\nb = 20; c = 30\n```\n\n⚠️ All variables behave similarly to the variables for Java objects. Thus keep in mind that something like `a = b` does **not** copy/clone the value of b into a, instead it copies the b ref as value (preventing linking of these variables). Still look out when dealing with primitives especially, you might want something like this `a = b.clone()` instead. That's because primitives behave like objects, thus without clone `a.substract(1)` would change the value for the original variable b too.\n\u003cdetails\u003e\n \u003csummary\u003eHow is this still typesafe?\u003c/summary\u003e\n\nBecause null values are not allowed, every variable has a default value from which we determine the type.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n \u003csummary\u003eIssues with readability?\u003c/summary\u003e\n\nWith this Python-like approach, we do not know if it's the initial usage / declaration of the variable or updating/setting the variable, and would need to rely on IDEs to make that difference clear.\nWhich I do not really like because of github PRs for example where the code is basically in its raw text form and only has some syntax highlighting.\n\nThus maybe instead something like this?\n```java\nnew a = 10\nnew b = 20; new c = 30\n```\nI think in this case we could directly just insert the type name instead of \"new\", to increase readability, however for longer types + if we some day get generics\nthis can also decrease readability.\n\nAnother problem with this is that it might seem we also create a \"new\" object with this keyword even though we only create a new variable/pointer, for example: \n```java\nnew a = 10\nnew b = a\n```\n\u003c/details\u003e\n\n\n\n## Comments\nEverything inside a comment is ignored. \n`//` marks the start of a comment and goes until the end of the line.\n```java\na = 1 // Single line comment\n```\n\n\n\n## Values, Variables and Types\n- A variable is a value with a name/reference. It's a particular set of bits or type of data located in the RAM that can be modified.\n- Primitive types (listed below) are available in all your code without the need of importing something.\n- Providing the type before the variable name is optional, meaning both `int x = 10` and `x = 10` are valid, since types are inferred.\n\n### Numbers\n| Usage                 | Name    | Description                                                                                                         |\n|-----------------------|--------|---------------------------------------------------------------------------------------------------------------------|\n| `v = true` or `v = false` | boolean | Has only two possible values: true (1) and false (0). Represents one bit of information.                            |\n| `v = 1b`              | byte    | 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive).       |\n| `v = 1s`              | short   | 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive) |\n| `v = 1`               | int     | 32-bit signed two's complement integer, which has a minimum value of -2^31 and a maximum value of 2^31 -1.          |\n| `v = 1l`              | long    | 64-bit two's complement integer. The signed long has a minimum value of -2^63 and a maximum value of 2^63 -1.       |\n| `v = 1f`              | float   | Single-precision 32-bit IEEE 754 floating point.                                                                    |\n| `v = 1d` or `v = 1.0`     | double  | Double-precision 64-bit IEEE 754 floating point.                                                                    |\n\n### Text\n| Usage          | Name   | Description                                                                                                                       |\n|---------------|--------|-----------------------------------------------------------------------------------------------------------------------------------|\n| `v = \"a\"`     | char   | Single 16-bit Unicode character. It has a minimum value of '\\u0000' (or 0) and a maximum value of '\\uffff' (or 65,535 inclusive). |\n| `v = \"aa\"`    | string | String of characters, or more accurately: an array of char with variable length.                                                  |\n\n### Special \n| Usage              | Name       | Description                                                                                       |\n|--------------------|------------|---------------------------------------------------------------------------------------------------|\n| `{}`               | code       | Single code block.                                                                                |\n| `v = {}` or `v = (){}`  | function   | Function without arguments and empty body. As you can see you can \"promote\" any code block into a function easily by giving it a name/variable. |\n| `v = ObjectName()` | ObjectName | Comes from the ObjectName.a file you created. If in another folder requires an import to be used. ObjectName is a placeholder for anything you might come up with. |\n| `v = (0, 1, 2)` | `[int*3]` | Fixed size array of elements. Inspired by the function arguments syntax. Supports different types per index/element. If defining the type you must provide the type of its elements and their amounts. |\n\n### Attributes\nVariables can have additional/optional attributes which get added \nat the start: `hidden final a = 10`\n - `hidden` hides the variable from other files. \nYou can disable this by adding `show hidden` to the start of your file.\n - `final` makes the variable unchangeable after first value assignment.\n - `global` makes the variable globally accessible in the format `ObjectName.myGlobalVariable` and thus the variable lives the whole runtime of the program.\n\n### Arrays/Tuples\nAdditional features of arrays/tuples and some syntax clarification if you need to write down the type of an array:\n```java\n[int] array = (10, 11, 12) // Type error, max size is not given, more accurately its wrong 1 != 3\n[int] array = (10) // Valid, correct max size: 1\n[int*1] array = (10) // Same as above\n[int*3] array = (10, 11, 12) // Valid: max size info given, in this case its 3\n\nvalueAtIndex0 = array[0] // 10, use brackets to access the value at an index\nvalueAtIndex1 = array[1] // 11\n\n[int, string] array = (10, \"hello\") // You can use any amount of different types\n\n[int*100] array = (0...*100) // Fill with 0 values\n[int*50, string*50] array = (0...*50, \"hello\"...*50) // Works with any types\nsize = array.length // 100\n// Note that .length is not a real variable, instead its a placeholder. The compiler replaces it with the actual numeric value.\n\n// switch supports arrays\narray = (1, 2, 3)\ntxt = \"\"\nswitch x {\n  if (1, a, b) { txt = \"Contains a 1 at first position!\" }\n  if (a, 1, b) { txt = \"Contains a 1 at second position!\" }\n  else { txt = \"Unknown number pattern!\" }\n}\n```\n\n### Extending functionality\nPrimitives are strictly speaking not really primitives but objects located in `./a`, thus you can also extend their functionality by using the object parts feature explained further below. \n\nNote that primitives must not be imported because the compiler adds a hidden import statement to import everything from `./a`.\n\n\u003cdetails\u003e\n\u003csummary\u003eWhy is there no public/private?\u003c/summary\u003e\n \nAll variables are public by default (except inside functions/scopes of course, those are not accessible from outside). \nIf you are a library developer, you can use the variable modifier `hidden` to hide\nvariables from the developer. Note that the developer can show them again though. Thus `hidden` should mean \"better not touch unless you know what you are doing,\nthis is used internally, not part of the public API and subject to change\".\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eWhere is null?\u003c/summary\u003e\n\nGone! Due to the countless runtime errors arising from it and because otherwise\nwe would need to name the type when defining a variable. This way its ensured all variables\nhave a default value which lets us determine the type at compile time and gives us the same\nbenefits as statically typed languages.\n\u003c/details\u003e\n\n\n## Code/Scopes\nA scope is code within brackets `{}`. \nVariables created within a scope are not accessible from outside:\n```java\na = 3\n{\n  b = 0\n  // a can be used here\n}\n// a can be used here\n// b cannot be used here\n```\n\nLet's say the code above is located in the `Utils` file and we want to access \nit in our `Main` file:\n```java\nUtils utils = Utils()\nutils.a // Can be accessed\nutils.b // Error: Cannot be accessed\n```\n\u003c/details\u003e\n\n⚠️ Note that a code block executes directly, but you can promote it to a function by naming it. Thus do not forget\nto call the function to actually execute your code if you did so.\n\n## Functions\nFunctions are special code blocks that are held by the `function` variable.\nNote that functions are `final` by default due to the limitations by the underlying C language and\nwe must provide type information for the arguments and return type.\n```java\nb = 0;\nsetNumber = {\n  b = 9\n}\nsetNumber // Does nothing\nsetNumber() // Executes the code\n\ngetNumber = returns int {\n  return b\n}\nresult = getNumber() // Executes the code and returns b\n```\nParameters can be passed over too like so:\n```java\nmultiply = returns int (int a, int b) {\n  return a * b\n}\nmultiply(10, 20)\n```\nNote that changing a parameter's value in a function,\naffects the original variables value:\n```java\nsetTo10 = (int a) {\n  a = 10\n}\nmyVariable = 27\nsetTo10(myVariable)\n// myVariable is now 10\n```\n\n\n### Side effect-free functions and clone\nThe compiler enforces the usage of double parenthesis when defining and using a function that has no side effects,\nmeaning that it doesn't update its arguments or other variables/fields of the object (except global fields). For this to work you either only read the argument or clone it and update its clone only.\n\nSo we can modify the previous example, which removes the whole purpose of the setTo10 function, however it should clarify the idea:\n```java\nsetTo10 = ((clone int a)) {\n  a = 10\n}\nmyVariable = 27\nsetTo10((myVariable))\n// myVariable is still 27, because the operation is performed on a clone/copy\n```\n\nThe `clone` keyword in a function parameter simply is a quality of life addition to reduce code, the previous example would look much worse without it:\n```java\nsetTo10 = ((int a)) {\n  a1 = a.clone()\n  a1 = 10\n}\nmyVariable = 27\nsetTo10((myVariable))\n// myVariable is still 27, because the operation is performed on a clone/copy\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eTODO How to reduce code duplication for libraries?\u003c/summary\u003e\n \n Let's say we have a string object and we want to provide a `str.replace(\"x\", \"y\")` function with replaces all x characters with y in this case,\n we would know that it affects the string directly / itself. Now we also want to provide `str1 = str.replace((\"x\", \"y\"))` function which does the same,\n however returns a new string with the changes. Does the library developer really need to define the function twice and code the logic twice?\n\u003c/details\u003e\n\n\n### Function overloading\nFunction overloading is allowed, however is written in a more concise way to avoid writing duplicate functions and documentation. \n```java\nmyFunction = (void a or int a) {\n  // You can use the variable \"a\" outside the if blocks below, however note the lowest common type is void.\n  // If it was string for example the lowest common type would be obj.\n  if a.type == void{ // The compiler will require these if statements\n  }\n  else if a.type == int{\n    // Automatic casting to the int type will happen inside this block\n  }\n}\nmyFunction() // Valid\nmyFunction(1) // Valid\n```\nThis ensures that less duplicate documentation is written\nand related code is inside the same function.\n\nOptional function parameters should help you out if you allow multiple different types of inputs in your function for example.\n\n\n## Null safety and optional parameters\nAll variables must have a starting/default value when defined, which means\nthat code like this: `a;` will not work. Thus there is no `null` type in A.\n\nOptional function parameters must have a default value.\n\nYou can make parameters optional by writing `optional: var1, var2, etc...`.\nHere is an example:\n```java\nmultiply = returns int (int a, int b, optional: int c = 1, int d = 1){ \n  return a * b * c * d\n}\nmultiply(10, 20) // Valid\nmultiply(10, 20, 30, 40) // Not valid, optional parameters must have the variable name\nmultiply(10, 20, c:30, d:40); // Valid\nmultiply(10, 20, c:30) // Valid\nmultiply(10, 20, d:40) // Valid\n```\n\n\n\n### Return multiple values\nSometimes you want to return multiple values from a single function.\nIn most languages you would need to create a new class or a new datatype which can be annoying.\nA however has a built in solution for this to make it easier:\n```java\nmyFunction = returns [int*2] {\n  return (10, 20)\n}\narray = myFunction()\na = array[0] // == 10\nb = array[1] // == 20\n// or simpler:\na, b = myFunction() // a == 10, b == 20\n```\n\n### Special functions\nThere are different types of functions / code blocks, which all extend the `code` type: `function, if, if else, else if, switch, for, for each, while`.\nThese will be explained further below. \n\n\u003cdetails\u003e\n \u003csummary\u003e\u003ch4\u003eLogic: if, if else, else if, switch\u003c/h4\u003e\u003c/summary\u003e\n \n```java\na = true\nb = true\nif a { // short version for: if a == true\n  a = false // do something if a is true, set it to false for example\n} else { // else is optional\n  a = false\n}\n\n// inline example\nif a do a = false \nelse do a = false // else is optional\n\nif a \u003e b do a = false\nelse if b do b = false // elseIf example, also optional\n\n// you can easily make it a variable/function\nmyLogic = if a do a = false\nmyLogic()\n\n// do not confuse the above with this:\nresult = if a use false\n// result is now false and not a function because of the \"use\" keyword\n\n// note that switch also supports arrays/tuples (see that section for details)\nx = 10\ntxt = \"Its a 10!\"\nswitch x {\n  if 10 { txt = \"Its a 10!\" }\n  if 3 { txt = \"Its a 3!\" }\n  else { txt = \"Its another number!\" }\n}\n\n// inline example\nswitch x \n  if 10 do txt = \"Its a 10!\"\n  if 3 do txt = \"Its a 3!\"\n  else do txt = \"Its another number!\"\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n \u003csummary\u003e\u003ch4\u003eLoops: for, for each, while\u003c/h4\u003e\u003c/summary\u003e\n \n```java\nnumbers = (1, 2, 3, 4)\ncurrent = 0\nfor index i = 0; i \u003e numbers.length; i++ {\n  current = numbers[i] // access number at index position in numbers array\n}\n\n// inline example\nfor index i = 0; i \u003e numbers.length; i++ do current = numbers[i] \n\nfor each x in numbers {\n  current = x\n}\n\n// inline example\nfor each x in numbers do current = x \n\nfor each x in numbers and index i { // for each with optional index\n  current = x\n}\n\n// inline example\nfor each x in numbers and index i do current = x\n\ni = 0\nwhile i \u003c numbers.length {\n  current = numbers[i]\n  i++\n}\n\n// inline example\ni = 0\nwhile i \u003c numbers.length do current = numbers[i]; i++\n```\n\u003c/details\u003e\n\nSince everything is a variable you can convert a `for index` loop into a variable.\n\n⚠️ Keep in mind that this converts the code block that executed directly, into a function that only executes when you call it, for example:\n```java\nnumbers = (1, 2, 3, 4)\ncurrent = 0\nmyLoop = for index i = 0; i \u003e numbers.length; i++ {\n  current = numbers[i] // access number at index position in numbers array\n}\nmyLoop() // Only executed once you call it\n```\n\n\n\n## The `constructor` keyword\nThe main paradigm is modular object oriented programming.\nObjects get initialized by using the `ObjectName()`\nlike so:\n\n`Main`\n```java\njohn = Person(63)\npeter = Person(35)\n\njohn.age // == 63\njohn.id // == 1\n\npeter.age // == 35\npeter.id // == 2\n\nPerson.count // == 2\n```\n`Person`\n```java\nglobal count = 0\n\nconstructor = (int age) {\n    count++\n    id = count\n}\n```\nThe constructor is the function called to initialize an object:\n- There can only be one in a file/object.\n- It is similar to a regular function, which means that it can also have parameters,\n  but no return type (note that the parameters will be available to the instantiated object if not set to private).\n- It gets added by the compiler automatically if not existing (with no parameters).\n- Variables defined inside the constructor are only available to the instantiated object.\n\nNote that everything you write outside the constructor will only be executed once, specifically at the first time the file/object is used somewhere else.\n\n\n\n## Files/Objects\nEach file represents one object.\n```\nproject\n - Main.a\n - MathLib.a\n - folder\n    - MathLib.a\n    - AnotherLib.a\n```\n`MathLib` can be used in `Main` like so:\n```java\nmath = MathLib()\n```\n`MathLib` from /folder can be used in `Main` like so:\nThis must be done like this, since MathLib exists twice, in the\ncurrent folder and in /folder.\n```\nmath = MathLib()\nmath1 = ./folder/MathLib()\n```\nNormally you just enter the files'/folders' relative path on the top:\n```java\n./folder/AnotherLib\n\n// Otherwise you can import the whole folder:\n./folder\n\nanotherLib = AnotherLib()\n```\n\n\n\n## Object\nThe default object all other objects automatically extend from contains following functions:\n- `obj.free()` for optional manual memory management, after calling this the memory for this object is cleared and referencing it is not allowed anymore.\n- `obj.clone()` returns a deep copy of the object.\n\n\n## Object Blocks / Parts\n```\n/Main.a\n/Person.a\n/Brain.a\n/Hand.a\n```\nObject Blocks make it possible to break down\nan otherwise very large file into multiple smaller files, since an Object Block has access to the code\nof all the other related blocks (except for optional Object Blocks).\n\nBesides that it allows \"true\" functionality extension of existing Objects (for example from an Object of another library, or even primitive types)\nwith no need of code refactoring.\n\nBrain:\n```\npart of Person\n```\n\nHand:\n```\noptional part of Person\n```\n\nUsage in Main.a:\n```\n// How do I use the Person class with its Object Blocks?\np = Person()\n\n// How do I make sure Person gets loaded with all Object Blocks, even optional ones?\np = Person+*()\n\n// How do I only use specific optional Object Blocks?\np = Person+Hand()\n```\n\n\n\n## Inheritance\nThere are two ways of inheriting another objects' functionality, namely\nvia the `inherits` and `implements` keywords.\n\n`inherits \u003cobj1\u003e, \u003cobj2\u003e, ...` lets you use the methods and fields of the inherited object in your current object.\n- Their constructors are called in the order they were listed.\n- If there are overlapping top-level variables (for example functions with equal names),\nyou also need to specify the variable name behind the object like so (myVariableName exists inside AnotherObject and AnotherObject2 in this example): `inherits AnotherObject, AnotherObject2+myVariableName`.\n\n`implements \u003cobj1\u003e, \u003cobj2\u003e, ...` lets you use the methods and fields of the implemented object in your current object, but you\nmust provide your own implementation for all of them.\n- Their constructors must also be implemented, and are called in the order they were listed.\n\n```java\ninherits AnotherObject, AnotherObject2\nimplements AnotherObject3, /path/to/AnotherObject4\n```\n\n\n\n## Object Semantic Versioning\nThis is more relevant for library developers since it forces you at compile time to update your objects' version if you\ndid either a major/breaking change, an addition like adding a new function or variable, or minor code changes / bug fixes.\nTo enable this feature simply add something like `version 1.0.0` to the top of your file.\n\nIts usage is optional, but it's recommended for any objects you expect your users to touch, if you are a library developer.\n\nIf a user uses your library and wants to ensure the final executable contains no duplicate dependencies\nand the user has another library (lets call it XTremeLib) that uses your library too, but an older version, now the compiler can check\nfor version conflicts that would otherwise only be visible through bugs at runtime, since the user has to choose\na specific version of your library, which may break XTremeLib.\n\n\n\n## Project structure and dependencies/libraries\nThe project root directory is located where your `a` directory is in.\nIn your code, you can only use/import code that is within that folder.\nTo reference it in code use `./`.\n\nThe A compiler has a dependency management system (DMS) built in.\nCurrently, it supports A projects hosted and released on GitHub.\nWith the command `add lib github_repo_url/github_repo_name`, the DMS\nwill fetch the `src.zip` of the projects' latest release and extract its\ncontents into `./libs/lib_author/lib_name/lib_version`.\n\nTo use that lib in your code, you would simply import it by entering\nits path at the top of your file.\n```java\n./libs/lib_author/lib_name/lib_version/SomeObject\n```\n\nUpdating libs can be done with the DMS too: `update libs` to update all, or\n`update lib github_repo_url/github_repo_name` to update a specific lib.\nThe DMS will take care of renaming/updating your imports in your code too.\n\n## TODO\n- Implement most of the mentioned features.\n- Spec for multithreading\n  - maybe even event-loop based (javascript)\n  - and where sleeping does not block the actual thread, but instead yields like in java virtual threads?\n- Spec for errors/exceptions.\n- Spec for GPU / hardware acceleration, or no spec if code can be fully auto-generated by the compiler at the needed places.\n- Spec for all mathematical primitive operations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosiris-team%2Fa-lang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosiris-team%2Fa-lang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosiris-team%2Fa-lang/lists"}