{"id":16100796,"url":"https://github.com/pannous/angle","last_synced_at":"2025-04-09T09:08:17.682Z","repository":{"id":33689314,"uuid":"37342096","full_name":"pannous/angle","owner":"pannous","description":"⦠ Angle: new speakable syntax for python 💡","archived":false,"fork":false,"pushed_at":"2024-02-19T11:24:42.000Z","size":2175,"stargazers_count":131,"open_issues_count":5,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-02T06:07:55.526Z","etag":null,"topics":["apple-script","compiler","programming-by-natural-language","programming-language","python","speech-recognition","speech-to-text"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pannous.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"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},"funding":{"github":["pannous"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"custom":null}},"created_at":"2015-06-12T20:06:12.000Z","updated_at":"2025-02-07T10:46:26.000Z","dependencies_parsed_at":"2024-02-25T10:31:44.708Z","dependency_job_id":null,"html_url":"https://github.com/pannous/angle","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pannous%2Fangle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pannous%2Fangle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pannous%2Fangle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pannous%2Fangle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pannous","download_url":"https://codeload.github.com/pannous/angle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248008630,"owners_count":21032556,"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":["apple-script","compiler","programming-by-natural-language","programming-language","python","speech-recognition","speech-to-text"],"created_at":"2024-10-09T18:48:14.483Z","updated_at":"2025-04-09T09:08:17.656Z","avatar_url":"https://github.com/pannous.png","language":"Python","funding_links":["https://github.com/sponsors/pannous"],"categories":[],"sub_categories":[],"readme":"![ENGLISH SCRIPT](English_script.png)\n\n**[Angle](https://github.com/pannous/angle/)** is the Python implementation of [English](https://github.com/pannous/english-script) as a programming language. Since Angle compiles to Python bytecode, it is can be used as a drop-in-replacement for classic Python and is fully debuggable, even in PyCharm. \nIt is currently in development to be run directly in WASM via [wasp](https://github.com/pannous/wasp).\n\nThe main purpose of this language is to facilitate programming computers via voice.\n**[Angle](https://github.com/pannous/angle/)** is the first speakable programing language and thus makes programing accessible to many more people.\n\nUpdate 2024\n-----------\nThis prototype has now been re-implemented in C++ as [wasp](https://github.com/pannous/wasp), in order to be compiled to WASM.\nA rust implementation is on it's way...\n\n🖥 INSTALL\n----------\n\n`pip install angle`\n\u003c!-- `pip install anglang` --\u003e\n`angle examples`\n\nOr from source:\n\n`git clone --recursive git@github.com:pannous/angle.git`\n\n`cd angle; ./install.sh`\n\nStart the shell : `./bin/angle` \n\n📓 Examples\n-----------\nHere are some of our favorite working examples from the [tests](tests):\n\n`assert two minus 1½ equals 0.5`\n\n`beep three times`\n(There will be a generation of programmers who will shake their heads that there ever was a programming language which did not interpret that sentence correctly.)\n\n`assert square of [1,2 and 3] equals 1,4,9`\n\n`assert 3rd word in 'hi my friend' is 'friend'`\n\n`x is 2; if all 0,2,4 are smaller 5 then increase x; assert x equals 3 `\n\n`beep every three seconds`\n\n`last item in 'hi','you' is equal to 'you'`\n\n\n```\nWhile Peter is online on Skype\n\tmake a beep\n\tsleep for 10 seconds\nDone\n```\nDespite being a *natural* language, **angle** has brevity and readabilty as its highest goals. Verbosity is optional, as are types and sigils.\n\n```\nTo check if person is online on Skype:\n\tSkype.checkStatus(person)\n\tif result is \"online\": return yes \n\telse return no\nEnd\n```\n\nFunction pointers and aliases\n`with class map: to merge is to update`\n\nStatus:\n-----------\n\nBeauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defence against complexity.\n\n        — David Gelernter\n\nALPHA, partly usable, some [tests](tests) not yet passing: \n[![Build Status](https://travis-ci.org/pannous/angle.png)](https://travis-ci.org/pannous/angle)\n\n### Operators:\n--------------\n* `|` pipe : output of last command as input for next command. `ls ~ | sort`\n* `,` list : turn two nodes into a list. Append if one is a list. 'cons' in lisp\n* `:` pair : turn two nodes into a pair, `a:3` (hashed+symbolic). almost identical to:\n* `=` value : turn two nodes into a variable pair, `a=3`\n* `;` list : end expressions/statements, list inside a block. if 1 : 0 ;\n* `., of, in` selection: garden of house == house.garden\n* ` ` space acts as comma in lists\n* ` ` newline, dedent: acts as comma in lists or closing 'bracket' if matching block start\n\nusual math operators `add` `plus` `times` `^` … and logical `and` `or` `xor` `not`\n\nbrackets: content of () is evaluated, {} is deferred (block/lambda)\n\nangle uses **mark** as data and code format:\n\n```\ncat{\n    size:3\n    color:{r=1 g=0 b=0}\n    form{\n        dimensions=(3,size*2)\n    }\n}\n```\nequivalent to\n```\na cat\n   size is 3\n   color is 1 for red, 0 for green and blue\n   a form\n     dimensions are 3 , size * 2\n   end\nend cat\n       \n```\nAll code is data and all data can be 'executed':\n```\ncat().dimensions returns (3,6) because last statement == return value\ncat(!) returns cat fully evaluated: cat{size:3,…,form:dimensions:{3,6}}\n\nprint(size) // prints value of size()\nprint{size} // prints function size\ncolors={red green blue}\ncolors=(red green blue)\n\nsort{.size} // ok\nsort{it.size} // ok\nsort{it's size} // ok\nsort(size) // warn unless value of size() returns lambda\nsort{size} // todo: read as it.size\nsort by size  // todo\n\n[] is evaluated as property index/match or deferred if assigned:\ncat[size] = 3\ncat[size:3] = true\npattern=[size:3]\ncat[pattern] = true\ndifference to cat.size : in cat[size], size can be a variable. to be sure use symbol or string cat[#size] cat['size']\n\nswitch takes a usual hash in which keys can be patterns:\nswitch :: a -\u003e { b -\u003e c } -\u003e c()\nswitch(time){\n    5pm: read\n    [hour\u003c5am]: sleep\n    [it.minute=0]: smoke\n    other: work\n}\nswitch(time,my_block)\nmy_block[time()]\n\nfallthrough must be forced with … if desired\n\nhow to force evaluation inside deferred block:\ncat{\n    born=time()  // instant\n    born:=time()  // deferred\n    born:time()  // deferred\n    \n}\n\nblocks can be given 'arguments' when evaluated:\ncat(time:5pm) == cat{born:5pm}\nsame rules apply: arguments can be values or blocks\ncat(time:calculate()) == cat{born:calculate()}\ncat(time=calculate()) == cat{born:5pm}\n\n\n```\n\n⏳ In progress\n--------------\n\n\u003c!-- `add one to every odd number in 1,2,3 == 2,2,4` --\u003e\n\nAngles implicit list filter '**that**' applies a selection criterion to all elements:\n\n`delete all files in my home folder that end with 'bak'` \n\ntranslates to ruby:\n\n`folder(:home).files.select{|that|that.end_with?(\"bak\")}.each{|file| file.delete}`\n\n\nImplicit lambda variable '**it**' \n\n`for all mails by peter: mark it as read if its subject contains 'SPAM'` \n\ntranslates to ruby:\n\n`mails(by: Peter).each{|it| it.mark(:read) if it.subject.match('SPAM')}`\n\n\nThe last example also illustrates what we call **matching by type name**.\n```\nTo delete mail:\n  move that mail to trash folder\nEnd\n```\n```\ncount char in \"שָלוֹם\" = 4\ncount byte in \"שָלוֹם\" = 12\ncount codepoints in \"שָלוֹם\" = 6\n```\nas loop:\n```\nfor char in \"שָׁלוֹם \": print char.clean\nשלום\n```\n\nHere 'mail' acts as argument name and argument type at once.\nNo more Java style Mail mail=new Mail().getMail();\n\n\n\u003c!-- Self documenting code is not about the \"how\", it's about the \"what\". Ex: A method name should be FilterOutOddNumbers(). Not MapModulo2Predicate(). --\u003e\n\n🐁 EXPERIMENT\n-------------\nRun it and see yourself!\n\n**experiment** by typing\n\n`angle \"6 plus six\"`\n\n`angle examples/test.e`\n\n`angle` (no args to start the shell)\n\n`⦠ 1/4`\n\n`⦠ 6 plus six`\n\n`⦠ beep three times`\n\n`⦠ x is 2; if all 0,2,4 are smaller 5 then increase x`\n\n`⦠ ls | item 2`\n\n📑 Language Specification\n-------------------------\nAngle is a multi-paradigm programming language with [gradual typing](https://en.m.wikipedia.org/wiki/Gradual_typing).\n\nRead the [DOSSIER](https://github.com/pannous/english-script/blob/master/DOSSIER.md) for a more complete [**language specification**](https://github.com/pannous/english-script/blob/master/DOSSIER.md), vision and some background. \n\nThe grammar is not meant to be linguistically complete, but [functionality complete](https://en.wikipedia.org/wiki/Functional_completeness) and easily extendable.\n\"Premature optimization is the root of all evil.\" Many programming languages 'optimize' on the syntax level in order to optimize the resulting applications. Maybe [this](http://www.cs.utexas.edu/~EWD/transcriptions/EWD06xx/EWD667.html) is a mistake.\n\nTo check out the current capabilities of English Script have a look at the [tests](https://github.com/pannous/angle/tree/master/tests),\n[keywords](https://github.com/pannous/angle/blob/master/core/english_tokens.py) and\n[grammar](https://github.com/pannous/angle/blob/master/core/english_parser.py)\n\n🕶 Future\n---------\nEnglish Script / Angle is currently running in the \n* [ruby](https://github.com/pannous/english-script) and [python](https://github.com/pannous/angle) environment, but will soon compile to the \n* WEB and **natively** thanks to [WebAssembly](https://github.com/WebAssembly/design)\n* Pure [JavaScript](https://github.com/pannous/angle.js) version as intermediate.\n\nHaving a [self-hosted \"bootstrapped\" compiler](https://en.wikipedia.org/wiki/Bootstrapping_%28compilers%29) is an important mid-term goal.\n\n\u003c!--\n**precedence**\nOne very hot idea is to allow modifying the language grammar on the fly, at least to a limited extend.\nThis goes beyond normal meta programming, macros and #defines\nOne first step would be to enable setting the precedence of functions.\nThis would yield very natural and sweet mathematical expressions, especially combined with Unicode names:\n```\nclass Complex alias ℂ (re, im)\n\tto add number x\n\t\tℂ(this.real+x.real, this.im+x.im)\n\tend\n\talias '+' = add\nend\t\nℂ.add.precedence=Number.add.precedence-1\nī := √-1\nī + 3ī == 4ī\n```\nThis would run against the goal to avoid sigil special chars though.\n--\u003e\n\n\nWhy the new implementation in python🐍?\n------------------------------------\nWe can **compile** English script / [Angle](https://github.com/pannous/angle/) directly to python byte-code:\nAs opposed to Ruby, Python(3) comes with a very nice and clean abstract syntax tree as well as byte code capabilities preinstalled.\nCompiling is so much nicer \u0026 faster than interpreted code.\nAlso the Python execution model is a bit more friendly than the Ruby VM, but both have their [advantages and drawbacks](https://github.com/pannous/cast/blob/master/ruby-vs-python.txt). The biggest advantage of Python is that objects can be given attributes at any time o.x='y'! However pythons limited block/lamda capabilities are a painful limitation. \n\n\n\"There should be one -- and preferably only one -- obvious way to do it\"\nBeautiful is better than ugly.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\t\t\t\n\nFor a background story/vision/philosophy/future of this project read the [DOSSIER](https://github.com/pannous/english-script/tree/master/DOSSIER.md)\n\nAlso check out: [Program Synthesis from Natural Language\nUsing Recurrent Neural Networks](https://github.com/TellinaTool/tellina)\n\n\n\u003c!-- \nTrying to express implicit and fuzzy relationships in ways that are explicit and sharp doesn’t clarify the meaning, it destroys it.\n\n        — Clay Shirky [http://www.shirky.com/writings/semantic_syllogism.html] \n\nHaving a language that almost looks like English is actually harder to program in than one that has a well defined strict syntax.\n\nIt falls into a sort of uncanny valley. Apple tried that sort of successfully with Hypertalk but really badly with Appkescript        --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpannous%2Fangle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpannous%2Fangle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpannous%2Fangle/lists"}