{"id":17162099,"url":"https://github.com/thysultan/ally","last_synced_at":"2025-04-13T14:12:09.140Z","repository":{"id":93022002,"uuid":"136180016","full_name":"thysultan/Ally","owner":"thysultan","description":"Pronounced L-I, Ally is a programming language with semi-optional types.","archived":false,"fork":false,"pushed_at":"2023-09-04T21:57:34.000Z","size":260,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T07:21:48.620Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thysultan.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}},"created_at":"2018-06-05T13:16:12.000Z","updated_at":"2023-09-20T23:55:10.000Z","dependencies_parsed_at":"2023-03-08T11:00:33.534Z","dependency_job_id":null,"html_url":"https://github.com/thysultan/Ally","commit_stats":{"total_commits":123,"total_committers":2,"mean_commits":61.5,"dds":"0.016260162601625994","last_synced_commit":"d1210f9c0bf4b39bba24437b1782aade634ad78b"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thysultan%2FAlly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thysultan%2FAlly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thysultan%2FAlly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thysultan%2FAlly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thysultan","download_url":"https://codeload.github.com/thysultan/Ally/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248724629,"owners_count":21151561,"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":"2024-10-14T22:44:43.187Z","updated_at":"2025-04-13T14:12:09.118Z","avatar_url":"https://github.com/thysultan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ally\n\nPronounced L-I, Ally is a static programming language with semi-optional types. The language draws inspiration from C, JavaScript, Swift and PHP.\n\n## Reserved\n\n```\nint, flt, str, obj, def, fun, var,\ntrue, false, null,\nimport, export, as,\ncontinue, break, return, throw, keyof, typeof, sizeof, instanceof,\ntry, catch, finally, if, else, for, in, switch, case, default,\nsuper, extends, await, yield\n```\n\n## Comments\n\nLine comments start with `//` and end at the end of the line.\n\n```\n// This is a comment.\n```\n\nBlock comments can nest and span multiple lines, starting with `/*` and ending with `*/`.\n\n```\n/* multi-line\n   comment. */\n```\n\nIdentifiers\n\nSimilar to other programming languages. Identifiers start with a letter or underscore and may contain letters, digits, and underscores. Case is sensitive.\n\n```\nnocase\ncamelCase\nPascalCase\n_under_score\nabc123\nALL_CAPS\n```\n\n---\n\n## Boolean\n\nBooleans values are identified by either `true` or `false`, or `!0` or `0`. Boolean operations include:\n\n1. \u0026\u0026 logical and\n1. || logical or\n1. ! logical not\n1. \u003c=, \u003e=, \u003c, \u003e\n1. \u003c\u003c=, \u003e\u003e=, \u003c\u003c, \u003e\u003e, \u003c\u003c\u003c, \u003e\u003e\u003e\n1. ?. ?? ?=\n1. == equal\n1. != unequal\n1. === deep equal\n1. !== deep unequal\n\n## Number\n\n```\nint number = 64_000 // 32/64 bit integer\nflt number = 64.000 // 64 bit floating point number\nint binary = 0b0101 // also included is octal and hexadecimal notation\n```\n\nProvides the usual operations: `+`, `-`, `*`, `/`, `++`, `--` etc.\n\n```\nflt a = ( 1 + 2.9 \u003e\u003e 2 / 1e6 + - 1 - 70e2 * 4 ) + 100\n```\n\nBoth `.4` and `1.` are not valid, and must be pre/post-fixed with a zero.\n\n```\n1.0\n0.4\n```\n\nUnderscores and appended letters are ignored.\n\n```\n10_000_000km\n```\n\n## String\n\nStrings are delimited with either double quotes \", or single ' quotes. String can span multiple lines.\n\n```\nstr a = '\n\tHello\n\tWorld\n'\n```\n\nString concatenation uses `+`.\n\n```\nstr a = 'Hello' + ' ' + 'World'\n```\n\n## Control\n\nControl flow operators do not use parenthesis in contrast to function invocations. These share a common pattern of `keyword arguments {}`.\n\n### Switch\n\n```\nswitch condition {\n\tcase a, b {\n\t}\n\tcase c =\u003e 'return'\n\tcase {\n\t\tprint('default')\n\t}\n}\n```\n\n### If..Else\n```\nif condition {\n} else if condtion {\n} else {\n}\n```\n\n### Try..Catch\n\n```\ntry {\n} catch e {\n} finally {\n}\n```\n\n### For\n\n```\nfor step \u003c 100 {\n}\n\nfor int step = 0, step \u003c 100, step++ {\n}\n```\n\n### For..Of\n\n```\nfor step of children {\n}\n\nfor step of 0...10 {\n}\n```\n\n## Function\n\nFunctions are first class values that have the type `function`. These share the form of `fun name arguments body`.\n\n```\nfun name {\n}\n\nfun name var a, var b {\n}\n\nfun name var ...args {\n}\n\nfun name var ...args, var a {\n}\n\nfun name var a, ...args {\n}\n\nfun name var a = 1 {\n}\n\nfun name var a = 1, var b = 2 {\n}\n\nfun name var {ref, age = 1}, var b {\n}\n\nfun name\n\tvar {type, age = 1},\n\tint b {\n}\n```\n\n## Lambdas\n\nLambdas are identical to functions and share the same type of `function`. The expression immediatly after '=\u003e' is the return value of a lambda function.\n\n```\n(var a) =\u003e 'return'\n\n(var a, var b) =\u003e 'return'\n\n() =\u003e 'return'\n\n(var ...args) =\u003e 'return'\n\n(var ...args, var a) =\u003e 'return'\n\n(var a, var ...args) =\u003e 'return'\n\n(var {ref, age}) =\u003e 'return'\n\n({ref, age = 1}) =\u003e 'return'\n\na = 1 =\u003e 'return'\n\n(a = 1, var b = 2) =\u003e 'return'\n\n({ref, age = 1}, int b) =\u003e 'return'\n```\n\n## Invocations\n\n```\nprint('Hello')\n\nprint('Hello', 'World')\n\nprint(print(print('Hello', 'World'))\n\nprint(\n\tprint('Hello')\n\t\tprint('World'))\n\nprint('Hello', fun name {\n})\n\nprint(fun name =\u003e print(''))\n\nprint(fun name =\u003e\n\tprint(''))\n```\n\n## Types\n\nTypes are semi-optional(inferred where possible), you can attach them to function arguments, variable bindings and class bodies. The following primitive types exist.\n\n```\nnumber - numbers, denoted as 'int', 'flt'\nstring - strings, denoted as 'str'\ndefinition - types, denoted as 'def'\n\nfunction - functions, denoted as 'fun'\nobject - objects, denoted as 'obj'\narray - arrays, also denoted as 'obj'\n```\n\nIn the form of examples this includes.\n\n```\nchr number = 8_000\n\nint number = 64_000\nflt number = 64.000\ndec number = 128.000\n\nobj object = {int len = 0, str str = ''}\nstr string = 'hello'\n\nobj array = ['hello']\nobj array = ['hello', 'world']\n\nobj array = [['hello'], ['world']]\nobj array = [[vec()], [vec()]]\n```\n\nThe use of types follow the pattern `type binding`.\n\n```\nint age = 1\n\nfun name int age, obj subjects, obj person {\n\treturn 'return'\n}\n\nfun name int age, obj subjects, obj person =\u003e 'return'\n```\n\n## Class\n\nClasses are created using the def keyword that follow the pattern `def Name ...args? {}`.\n\n```\ndef Person {\n\tobj object = {}\n\tobj dictionary = {['key', 'value']}\n\tvar variable = var(1024)\n\tvar integer = int(1024)\n\tvar object = obj(1024)\n\n\tfun create (var name, var age) {}\n\tfun assign (var key, var value) {}\n\tfun destroy (var id) {}\n\tfun generic (def type, var value) {}\n}\n```\n\nClass optional parameters resemble function parameters.\n\n```\ndef Person ({var key}, var b = 1, obj c) {\n\tint age = key\n}\n```\n\nFields are created statitically or through referenced named parameters.\n\n```\ndef Person (var age, var year, {name}) {\n\tint x = 0\n\tint y = 0\n\tfun print =\u003e print('Hello' + 'World' + '!')\n\tfun write =\u003e x = value\n}\n\nobj person = Person('23', '1989', {name: 'Sultan'})\n\nprint('Name: ' + person.name 'Age: ' + person.age + ', Born In: ' + person.year)\n```\n\nClass instances are created when invoked. Parameters are passed to classes like functions.\n\n```\nobj person = Person(10, 1989, {name: 'Sultan'})\n```\n\nAll named arguments in the class are assigned to a corrosponding field.\n\n```\ndef Element (var type, {var ref, var key}, children) {\n  fun handleEvent (obj event) {\n    dispatchEvent(event, =\u003e print('dispatchEvent'))\n  }\n  fun dispatchEvent (obj event, fun callback) {\n    try {\n      callback(event)\n    } catch e {\n      throw e\n    }\n  }\n}\n\nfun createElement (var type, obj props, var ...children) {\n  return Element(type, props, children)\n}\n\nobj person = Person('h1', {}, '')\n\nprint(person.type == 'h1')\n```\n\nClasses can extend other class.\n\n```\ndef Person {\n\tfun getter (var key) {\n\t\treturn super[key]\n\t}\n}\n\ndef Student extends Person {\n\tfun get (var key) {\n\t\tsuper.getter(key)\n\t}\n}\n\nobj student = Student()\n```\n\n## Object\n\nPlain objects are created using the `{}` (curly braces). Objects are immutable(size). Objects are created in two flavours, plain objects and dictionary objects.\n\n```\nobj plain = {\n\tint age = 27\n\tint year = 1989\n\tfun name var value =\u003e print(value)\n\tfun name var key, var value {\n\t\treturn super[key] = value\n\t}\n}\n\nobj dictionary = {\n\t['age', 27],\n\t['year', 1989]\n}\n```\n\nWhile Dictionary objects can hold any key including objects plain objects can only hold string keys.\n\n```\nobj plain = {\n\tvar age = 27,\n\tvar year = 1989\n}\n\nobj dictionary = {\n\t[{}, 27],\n\t['year', 1989]\n}\n```\n\n## In\n\nThe `in` operator returns whether a given key is present in an `object`.\n\n```\n'foo' in {var foo = 1} == true\n```\n\n## Sizeof\n\nThe `sizeof` operator returns the size of a given array/object/string and `nan` for invalid values.\n\n```\nprint(sizeof [1, 2, 3])       // 3\nprint(sizeof {a: 1, b: 2})    // 2\nprint(sizeof 'Hello')         // 5\nprint(sizeof fun var a, var b {})     // 2\nprint(sizeof {[1, '1']})      // 1\n```\n\n## Typeof\n\nThe `typeof` operator returns the type of a given value in string form.\n\n```\nprint(typeof [1, 2, 3])       // 'array'\nprint(typeof {a: 1, b: 2})    // 'object'\nprint(typeof \"Hello\")         // 'string'\nprint(typeof 2)               // 'number'\nprint(typeof fun {})          // 'function'\nprint(typeof true)            // 'boolean'\nprint(typeof {[1, '1']})      // 'object'\n\nprint(switch typeof 100 {\n\tcase 'object' =\u003e 'object'\n\tcase 'number' =\u003e 'number'\n})\n```\n\n## Instanceof\n\nThe `instanceof` operator returns the class that value is an instance of.\n\n```\ndef Person {}\ndef Student extends Person {}\n\nvar persons = Person()\nvar student = Student()\n\npersons instanceof Person == true\nstudent instanceof Student === true\nstudent instanceof Person !== true\n```\n\n## Keyof\n\nThe `keyof` operator retrieves the corresponding keys from an `object`.\n\n```\nkeyof {var foo, var bar} === ['foo', 'bar']\nkeyof [1...4] === [1, 2, 3, 4]\n```\n\n\n## Spread\n\nThe `...` operator is a generic operator that spreads it's contents onto the context of its binding. The different contexts include function arguments `fun (...arg)`, objects `{...a}` and arrays `[...a]`.\n\n```\nint arr = [1, 2]\nobj foo = {var foo = 1}\n\n{...foo, var bar = 2} === {var foo = 1, var bar = 2}\n\n[0, ...arr] === [0, 1, 2]\n\nfun name var ...args {\n\tprint(typeof args === 'array')\n}\n```\n\n## Range\n\nThe `..` operator is a generic range that generates an array with the contents made of the range of values of its binding.\n\n```\n1..3 === [1, 2, 3]\n```\n\n## Array\n\nArray literals are delimited with brackets `[`, `]` and share the form `[1, 2, 3]`.\n\n```\n// create\nint arr[] = [0, 2, 3, 4...6]\n\n// assigment\narr[0] = 1\n\n// deep compare\narr === [1, 2, 3, 4, 5, 6]\n\n// length\nsizeof arr == 6\n```\n\n## Standard Library\n\n### Network\n\n```\nimport net as {stringify}\n\nstringify(obj target) str\n```\n\n## System\n\n```\nimport sys as {console}\n\nconsole.print(...arguments)\nconsole.write(...arguments)\nconsole.clear(...arguments)\nconsole.yield(...arguments)\n```\n\n### Math\n\n```\nimport math as math\n\nmath.random() flt\nmath.abs(flt target) flt\nmath.ceil(flt target) flt\nmath.floor(flt target) flt\nmath.round(flt target) flt\nmath.sign(flt target) flt\nmath.trunc(flt target) flt\nmath.sqrt(flt target) flt\nmath.cbrt(flt target) flt\nmath.log(flt target) flt\nmath.cos(flt target) flt\nmath.cosh(flt target) flt\nmath.sin(flt target) flt\nmath.tan(flt target) flt\nmath.max(flt ...arguments) flt\nmath.min(flt ...arguments) flt\nmath.hypot(flt ...arguments) flt\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthysultan%2Fally","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthysultan%2Fally","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthysultan%2Fally/lists"}