{"action":"created","issue":{"url":"https://api.github.com/repos/gkz/LiveScript/issues/1011","repository_url":"https://api.github.com/repos/gkz/LiveScript","labels_url":"https://api.github.com/repos/gkz/LiveScript/issues/1011/labels{/name}","comments_url":"https://api.github.com/repos/gkz/LiveScript/issues/1011/comments","events_url":"https://api.github.com/repos/gkz/LiveScript/issues/1011/events","html_url":"https://github.com/gkz/LiveScript/issues/1011","id":300469106,"number":1011,"title":"Make LiveScript pluggable and backward compatible to backward incompatible changes","user":{"login":"bartosz-m","id":11303115,"avatar_url":"https://avatars2.githubusercontent.com/u/11303115?v=4","gravatar_id":"","url":"https://api.github.com/users/bartosz-m","html_url":"https://github.com/bartosz-m","followers_url":"https://api.github.com/users/bartosz-m/followers","following_url":"https://api.github.com/users/bartosz-m/following{/other_user}","gists_url":"https://api.github.com/users/bartosz-m/gists{/gist_id}","starred_url":"https://api.github.com/users/bartosz-m/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartosz-m/subscriptions","organizations_url":"https://api.github.com/users/bartosz-m/orgs","repos_url":"https://api.github.com/users/bartosz-m/repos","events_url":"https://api.github.com/users/bartosz-m/events{/privacy}","received_events_url":"https://api.github.com/users/bartosz-m/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-27T02:17:47Z","updated_at":"2018-02-27T21:54:57Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"I have proposition for first steps to make LiveScript pluggable and backward compatible to backward incompatible changes.\r\n\r\nI will try to explain why LiveScript would benefit from plugins, what already I've done in that matter and what more is to do. It'll be a little longish and although I'm totally sober I'm extremely tired, so bear with me and my whim to express my thought in this peculiar way. (But if You can't then go directly to [todo](#todo) section)\r\n\r\n\r\nLets start with some boring stuff to calm some fears:\r\n\r\n**Terminology**:  \r\n\r\n* **core** - what you get out of the box by installing LiveScript from main repo.\r\n* **plugin** - some module that can at runtime extend/modify functionality of the **core**\r\n* **system** - **core** combine with installed **plugins** \r\n\r\n**Requirements**:  \r\n\r\n* no backward incompatible modification inside **core**\r\n* only incremental changes\r\n* **plugins** are developed outside main repo\r\n\r\nAs You can see it won't be so scary, no revolution. You can stop holding your breath now.\r\n\r\n\r\n# But why?\r\n\r\nLets lean over crystal ball and see if future holds the answer:  \r\n\r\nuser `A` wants feature `F` but it is backward incompatible, so maintainers decide to not implement it in the **core**. User `B` has to much free time and implements **plugin** `P0` for `F`.  \r\n`A` is happy because he can install **plugin** `P0` and use `F` in his projects, maintainers are happy because **core** is unpolluted by rarely used functionality, unicorns dance on the rainbows and whole world is a happy place.\r\n\r\nThen comes the day when `A` decides that in order to build the most awesome app in entire universe he will need to use another **plugin** `P1`. But installing `P1` alongside `P0` breaks his **system** and he is screwed.  \r\nMeanwhile unicorns continue to dance, maintainers and rest of LiveScript users continue their work uninterrupted.\r\nPoor `A` `B` and maintainer of `P1` will need  to resolve `A`'s problem on their own.  \r\n\r\n[VISION ENDS]\r\n\r\nWe can learn from it that plugin system would accomplished five goals:  \r\n* ensure **core** is stable and well tested\r\n* introduce bleeding edge innovations\r\n* increase level of diversity across whole **system**\r\n* give people freedom to choose their own \"LiveScript\"\r\n* make unicors really happy\r\n\r\n\r\n# Where? \r\n\r\nI like what I've seen it that crystall ball. So I gathered couple of my little frieds one of them was plugin that could convert any function with await inside into async-one (very handy fellow) and together we went on a journey to find that \"plugin heaven\" from the vision...  \r\nOk.Ok. I'll keep it short.  \r\nOur party grew bigger - now we travel with a big dude that puts livescript files in a hat and pulls out of it es6 modules - and after many adventures we finally get to place which we call now home. Its not \"plugin heaven\" but still we like it and we work only here. Going back to **core** or making expedition to **js** wastelands is no an option for us. \r\nFor future generation of explorer We would like to share a map, that contains usefull landmarks we visited which may help you find \"plugin heaven\":\r\n\r\n* **core** - LiveScript freshly served from main repo without any modification\r\n* compiler - wrapper for **core** that allows for augmenting of compiling and lexing process by exposing internal parts to plugins.\r\n* system - configures compiler based on individual project requirements and feeds compiler with files and writes transpiled one to disk. I hoped to extend it in future to become central point for serving LiveScript related services e.g. transpilation, linting, preview, autocompletion (right now this functionality is duplicated across many editor specific extensions)\r\n* **plugins** - few small and one big module for extending and modify core e.g. es6 module, top level await \r\n\r\n# How\r\nWhen I and my little plugin friends set of on a journey to \"pluggable heaven\", We didn't anticipate how many obstacle would we need to overcome. So here's list of things you better prepare here in **core**  before You venture forth\r\n\r\n## Todo\r\n\r\nFirst step - making LiveScript plugin friendly:  \r\n\r\nExpose:\r\n  * ast:  \r\n    - [ ] `Node` for creating new kind of nodes\r\n    - [ ] `UTILS` for custom implementation of utility functions\r\n    - [ ] `Scope`\r\n  * lexer:\r\n    - [ ] tokens\r\n    - [ ] regular expressions\r\n    - [ ] keywords\r\n- [ ] Use properties instead of using modules directly e.g assign `lexer` to `compiler.lexer` and use it `this.lexer.tokenize some-stuff`\r\n\r\nNext steps - making LiveScript plugin aware\r\n  - [ ] - add hooks/point that multiple plugins could use at same time\r\n  - [ ] - load plugins defined in config\r\n\r\nDistant future:\r\n  - [ ] move as much functionality from core to plugins\r\n\r\n\r\n# Boring summary\r\n\r\n* plugin system is beneficial to LiveScript\r\n* it doesn't have to be implemented inside core LiveScript\r\n* only little backward compatible changes would need to be done\r\n* it is doable - I've created something that could be called proof-of-concept and I'm using it for my personal projects\r\n"},"comment":{"url":"https://api.github.com/repos/gkz/LiveScript/issues/comments/369040148","html_url":"https://github.com/gkz/LiveScript/issues/1011#issuecomment-369040148","issue_url":"https://api.github.com/repos/gkz/LiveScript/issues/1011","id":369040148,"user":{"login":"rhendric","id":1570964,"avatar_url":"https://avatars0.githubusercontent.com/u/1570964?v=4","gravatar_id":"","url":"https://api.github.com/users/rhendric","html_url":"https://github.com/rhendric","followers_url":"https://api.github.com/users/rhendric/followers","following_url":"https://api.github.com/users/rhendric/following{/other_user}","gists_url":"https://api.github.com/users/rhendric/gists{/gist_id}","starred_url":"https://api.github.com/users/rhendric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rhendric/subscriptions","organizations_url":"https://api.github.com/users/rhendric/orgs","repos_url":"https://api.github.com/users/rhendric/repos","events_url":"https://api.github.com/users/rhendric/events{/privacy}","received_events_url":"https://api.github.com/users/rhendric/received_events","type":"User","site_admin":false},"created_at":"2018-02-27T21:54:57Z","updated_at":"2018-02-27T21:54:57Z","author_association":"COLLABORATOR","body":"The LiveScript grammar is non-modular, since it would have to be fully regenerated any time you want to add elements of syntax, and that grammar generator currently isn't even shipped with LiveScript. So I think that would mean you can't add new AST node types, at least types that would be created by syntax. You could, I suppose, monkey-patch existing methods to insert new node types in appropriate places. I don't know how far that would get you with your goals.\r\n\r\nIn general, I don't think there's anything wrong with unofficial, aftermarket modifications to LS that add custom functionality on a may-break-whenever basis, and to the extent that plugins are simply a formalization (but still officially unsupported) of that, I'm all for them. However, exposing more compiler internals in a supported way would constrain maintainers and therefore need to be thought through carefully, which should include making sure you can actually do what you want if those things are exposed. Exposing the lexer's lists of keywords and token types for extension, for example, doesn't help unless the grammar can recognize those tokens.\r\n\r\nI would be interested in seeing your proofs of concept. I'd also be very happy to be proven wrong about my pessimism, for the record; I've been doing a lot of thinking about modular language design, particularly in the context of LiveScript, and my conclusion has been that modularity pretty much needs to be a first-order consideration from the language's beginning to be viable. If you do have a viable way to make LiveScript modular without redoing the whole thing, I'd be delighted. But also very, very surprised."}}
{"actor":{"display_login":"rhendric"}}