{"action":"created","issue":{"url":"https://api.github.com/repos/masak/007/issues/159","repository_url":"https://api.github.com/repos/masak/007","labels_url":"https://api.github.com/repos/masak/007/issues/159/labels{/name}","comments_url":"https://api.github.com/repos/masak/007/issues/159/comments","events_url":"https://api.github.com/repos/masak/007/issues/159/events","html_url":"https://github.com/masak/007/issues/159","id":164702476,"node_id":"MDU6SXNzdWUxNjQ3MDI0NzY=","number":159,"title":"Have a mechanism to allow arbitrary (undeclared) identifiers in expressions","user":{"login":"masak","id":20627,"node_id":"MDQ6VXNlcjIwNjI3","avatar_url":"https://avatars1.githubusercontent.com/u/20627?v=4","gravatar_id":"","url":"https://api.github.com/users/masak","html_url":"https://github.com/masak","followers_url":"https://api.github.com/users/masak/followers","following_url":"https://api.github.com/users/masak/following{/other_user}","gists_url":"https://api.github.com/users/masak/gists{/gist_id}","starred_url":"https://api.github.com/users/masak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masak/subscriptions","organizations_url":"https://api.github.com/users/masak/orgs","repos_url":"https://api.github.com/users/masak/repos","events_url":"https://api.github.com/users/masak/events{/privacy}","received_events_url":"https://api.github.com/users/masak/received_events","type":"User","site_admin":false},"labels":[{"id":401035438,"node_id":"MDU6TGFiZWw0MDEwMzU0Mzg=","url":"https://api.github.com/repos/masak/007/labels/macro-idea","name":"macro-idea","color":"bb0000","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":14,"created_at":"2016-07-10T06:39:39Z","updated_at":"2018-08-08T20:53:21Z","closed_at":null,"author_association":"OWNER","body":"In the action method `term:identifier`, there's this wonderful piece of code:\n\n```\nmy $name = $<identifier>.Str;\nif !$*runtime.declared($name) {\n    my $frame = $*runtime.current-frame;\n    $*parser.postpone: sub checking-postdeclared {\n        my $value = $*runtime.maybe-get-var($name, $frame);\n        die X::Macro::Postdeclared.new(:$name)\n            if $value ~~ Val::Macro;\n        die X::Undeclared.new(:symbol($name))\n            unless $value ~~ Val::Sub;\n    };\n}\n```\n\nActually, for the purposes of this issue we can ignore the postponement logic and the check for postdeclared macros; the code then becomes much simpler:\n\n```\nif !$*runtime.declared($name) {\n    die X::Undeclared.new(:symbol($name));\n}\n```\n\nIn other words, undeclared variables cause the compiler to abort with `X::Undeclared`.\n\nWhat if we could selectively turn off this check? Or, even better, what if we could selectively let some identifiers through? I think that would make a big difference for DSLs, to enable stuff like this:\n\n```\nmyfor [1, 2, 3] { say(it); }    # 'it' supplied by the `myfor` macro\n\nsay(each([1, 2, 3]);          # 'each' supplied by the `each` pragma, see #158 \n```\n\nThe details are not clear to me, but it just occurred to me that we can do this. And we probably should.\n\nIt's funny, I've used \"Perl 6 has a very particular intertwining between parser and static checks\" as an argument many times, but I've never considered doing the above, which seems like it'd solve quite a few problems.\n"},"comment":{"url":"https://api.github.com/repos/masak/007/issues/comments/411548561","html_url":"https://github.com/masak/007/issues/159#issuecomment-411548561","issue_url":"https://api.github.com/repos/masak/007/issues/159","id":411548561,"node_id":"MDEyOklzc3VlQ29tbWVudDQxMTU0ODU2MQ==","user":{"login":"masak","id":20627,"node_id":"MDQ6VXNlcjIwNjI3","avatar_url":"https://avatars1.githubusercontent.com/u/20627?v=4","gravatar_id":"","url":"https://api.github.com/users/masak","html_url":"https://github.com/masak","followers_url":"https://api.github.com/users/masak/followers","following_url":"https://api.github.com/users/masak/following{/other_user}","gists_url":"https://api.github.com/users/masak/gists{/gist_id}","starred_url":"https://api.github.com/users/masak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masak/subscriptions","organizations_url":"https://api.github.com/users/masak/orgs","repos_url":"https://api.github.com/users/masak/repos","events_url":"https://api.github.com/users/masak/events{/privacy}","received_events_url":"https://api.github.com/users/masak/received_events","type":"User","site_admin":false},"created_at":"2018-08-08T20:53:21Z","updated_at":"2018-08-08T20:53:21Z","author_association":"OWNER","body":"I was thinking about this one today. Here's a possible mechanism:\r\n\r\n```\r\nimport parser;\r\n\r\n# meanwhile, later, in an `is parsed`\r\n\r\n/ { parser.declare(\"_\") } <block> / # the `_` variable will be available in the `<block>`\r\n```\r\n\r\nI was also thinking a `parser.newBlock()` could declare a block until current block's end. Something like #13 could use that."}}
{"actor":{"display_login":"masak"}}