{"action":"created","comment":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/22446355","id":22446355,"diff_hunk":"@@ -9,106 +9,120 @@\n The strongest legacy of Lisp in the Julia language is its metaprogramming\n support. Like Lisp, Julia represents its own code as a data structure of\n the language itself.\n+Because all data types and code in Julia are represented by Julia data structures,\n+powerful reflection capabilities are available to explore the internals of a\n+program and its types just like any other data.\n Since code is represented by objects that can be created and manipulated\n from within the language, it is possible for a program to transform and\n generate its own code. This allows sophisticated code generation without\n-extra build steps, and also allows true Lisp-style macros, as compared\n-to preprocessor \"macro\" systems, like that of C and C++, that perform\n-superficial textual manipulation as a separate pass before any real\n-parsing or interpretation occurs. Another aspect of metaprogramming is\n-reflection: the ability of a running program to dynamically discover\n-properties of itself. Reflection emerges naturally from the fact that\n-all data types and code are represented by normal Julia data structures,\n-so the structure of the program and its types can be explored\n-programmatically just like any other data.\n-\n-Expressions and :func:`eval`\n-----------------------------\n-\n-Julia code is represented as a syntax tree built out of Julia data\n-structures of type :obj:`Expr`. This makes it easy to construct and\n-manipulate Julia code from within Julia, without generating or parsing\n-source text. Here is the definition of the :obj:`Expr` type::\n-\n-    type Expr\n-      head::Symbol\n-      args::Array{Any,1}\n-      typ\n-    end\n+extra build steps, and also allows true Lisp-style macros operating at\n+the level of abstract syntax. In contrast, preprocessor \"macro\" systems,\n+like that of C and C++, perform textual manipulation and substitution\n+before any actual parsing or interpretation occurs.\n \n-The ``head`` is a symbol identifying the kind of expression, and\n-``args`` is an array of subexpressions, which may be symbols referencing\n-the values of variables at evaluation time, may be nested :obj:`Expr`\n-objects, or may be actual values of objects. The ``typ`` field is used\n-by type inference to store type annotations, and can generally be\n-ignored.\n+Program representation\n+----------------------\n \n-There is special syntax for \"quoting\" code (analogous to quoting\n-strings) that makes it easy to create expression objects without\n-explicitly constructing :obj:`Expr` objects. There are two forms: a short\n-form for inline expressions using ``:`` followed by a single expression,\n-and a long form for blocks of code, enclosed in ``quote ... end``. Here\n-is an example of the short form used to quote an arithmetic expression:\n+Every Julia program starts life as a string:\n \n .. doctest::\n \n-    julia> ex = :(a+b*c+1)\n-    :(a + b * c + 1)\n+    julia> prog = \"1 + 1\"\n+    \"1 + 1\"\n+\n+**What happens next?**\n+\n+The next step is to `parse <http://en.wikipedia.org/wiki/Parsing#Computer_languages>`_\n+each string into an object called an expression, represented by the Julia type\n+:obj:`Expr`:\n+\n+.. doctest::\n+\n+    julia> ex1 = parse(prog)\n+    :(1 + 1)\n \n     julia> typeof(ex)\n     Expr\n \n-    julia> ex.head\n+Expressions may also be constructed directly in\n+`prefix notation <http://en.wikipedia.org/wiki/Polish_notation>`_:\n+\n+.. doctest::\n+\n+    julia> ex2 = Expr(:call, :+, 1, 1)\n+    true\n+\n+The two expressions constructed above -- by parsing and by direct\n+construction -- are equivalent:\n+\n+.. doctest::\n+\n+    julia> ex1 == ex2\n+    true\n+\n+**The key point here is that Julia code is internally represented\n+as a data structure that is accessible from the language itself.**\n+\n+:obj:`Expr` objects contain three parts:\n+\n+- a Symbol identifying the action represented by the expression:\n+\n+.. doctest::\n+\n+    julia> ex1.head\n     :call\n \n-    julia> typeof(ans)\n-    Symbol\n+- the expression arguments, which may be symbols, other expressions, or literal values:\n+\n+.. doctest::\n \n-    julia> ex.args\n-    4-element Array{Any,1}:\n+    julia> ex1.args\n+    3-element Array{Any,1}:\n       :+\n-      :a\n-      :(b * c)\n+     1\n      1\n \n-    julia> typeof(ex.args[1])\n-    Symbol\n+- finally, the expression result type, which may be annotated by the user or inferred\n+  by the compiler (and may be ignored completely for the purposes of this chapter):\n \n-    julia> typeof(ex.args[2])\n-    Symbol\n+.. doctest::\n \n-    julia> typeof(ex.args[3])\n-    Expr\n+    julia> ex1.typ\n+    Any\n \n-    julia> typeof(ex.args[4])\n-    Int64\n+The :func:`dump` function provides indented and annotated display of :obj:`Expr`\n+objects:\n \n-Expressions provided by the parser generally only have symbols, other\n-expressions, and literal values as their args, whereas expressions\n-constructed by Julia code can easily have arbitrary run-time values\n-without literal forms as args. In this specific example, ``+`` and ``a``\n-are symbols, ``*(b,c)`` is a subexpression, and ``1`` is a literal\n-64-bit signed integer. Here's an example of the longer expression\n-quoting form:\n+.. doctest::\n+\n+    julia> dump(ex2)\n+    Expr\n+      head: Symbol call\n+      args: Array(Any,(3,))\n+\t1: Symbol +\n+\t2: Int64 1\n+\t3: Int64 1\n+      typ: Any\n+\n+:obj:`Expr` objects may also be nested:\n \n .. doctest::\n \n-    julia> quote\n-             x = 1\n-             y = 2\n-             x + y\n-           end\n-    quote  # none, line 2:\n-        x = 1 # line 3:\n-        y = 2 # line 4:\n-        x + y\n-    end\n+    julia> ex3 = parse(\"(4 + 4) / 2\")\n+    :((4 + 4) / 2)\n+\n+    julia> Base.Meta.show_sexpr(ex3)","path":"doc/manual/metaprogramming.rst","position":175,"original_position":175,"commit_id":"0fad74deda8ce8380bbae05a9db19fdd4bef3ffd","original_commit_id":"0fad74deda8ce8380bbae05a9db19fdd4bef3ffd","user":{"login":"ihnorton","id":327706,"avatar_url":"https://avatars.githubusercontent.com/u/327706?v=3","gravatar_id":"","url":"https://api.github.com/users/ihnorton","html_url":"https://github.com/ihnorton","followers_url":"https://api.github.com/users/ihnorton/followers","following_url":"https://api.github.com/users/ihnorton/following{/other_user}","gists_url":"https://api.github.com/users/ihnorton/gists{/gist_id}","starred_url":"https://api.github.com/users/ihnorton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ihnorton/subscriptions","organizations_url":"https://api.github.com/users/ihnorton/orgs","repos_url":"https://api.github.com/users/ihnorton/repos","events_url":"https://api.github.com/users/ihnorton/events{/privacy}","received_events_url":"https://api.github.com/users/ihnorton/received_events","type":"User","site_admin":false},"body":"done and done","created_at":"2015-01-05T03:00:06Z","updated_at":"2015-01-05T03:00:06Z","html_url":"https://github.com/JuliaLang/julia/pull/9594#discussion_r22446355","pull_request_url":"https://api.github.com/repos/JuliaLang/julia/pulls/9594","_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/22446355"},"html":{"href":"https://github.com/JuliaLang/julia/pull/9594#discussion_r22446355"},"pull_request":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/9594"}}},"pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/9594","id":26790809,"html_url":"https://github.com/JuliaLang/julia/pull/9594","diff_url":"https://github.com/JuliaLang/julia/pull/9594.diff","patch_url":"https://github.com/JuliaLang/julia/pull/9594.patch","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/9594","number":9594,"state":"open","locked":false,"title":"doc: refactor metaprogramming section","user":{"login":"ihnorton","id":327706,"avatar_url":"https://avatars.githubusercontent.com/u/327706?v=3","gravatar_id":"","url":"https://api.github.com/users/ihnorton","html_url":"https://github.com/ihnorton","followers_url":"https://api.github.com/users/ihnorton/followers","following_url":"https://api.github.com/users/ihnorton/following{/other_user}","gists_url":"https://api.github.com/users/ihnorton/gists{/gist_id}","starred_url":"https://api.github.com/users/ihnorton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ihnorton/subscriptions","organizations_url":"https://api.github.com/users/ihnorton/orgs","repos_url":"https://api.github.com/users/ihnorton/repos","events_url":"https://api.github.com/users/ihnorton/events{/privacy}","received_events_url":"https://api.github.com/users/ihnorton/received_events","type":"User","site_admin":false},"body":"This is a fairly substantial reworking of parts of the Metaprogramming section of the manual, inspired by [this email chain](https://groups.google.com/d/msg/julia-users/bLDuSI1MkVA/vPOo7pPrwO0J) (among many others).\r\n\r\nOne of the main goals here is to introduce and work with directly-constructed Expr objects first, and separately from quoted expressions. This seems to be the way that many users end up using macros anyway, and I hope that decoupling expression structure will make both expressions and quoting easier to understand.\r\n\r\nI've also tried to explicitly ask and answer the question \"why are macros necessary\", but that section may need some more work.\r\n\r\nThis PR does make the chapter longer, but hopefully breaks some of it into explicit and digestible chunks. I'll try to figure out how to add an internal TOC to the top of the page. Any comments very much appreciated.\r\n\r\ncc: @tlycken @ismael-vc @jiahao","created_at":"2015-01-04T04:36:55Z","updated_at":"2015-01-05T03:00:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f8a986e708981cbe2cea0459e1ce7b11e0330e3b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/JuliaLang/julia/pulls/9594/commits","review_comments_url":"https://api.github.com/repos/JuliaLang/julia/pulls/9594/comments","review_comment_url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/{number}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/9594/comments","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/0fad74deda8ce8380bbae05a9db19fdd4bef3ffd","head":{"label":"JuliaLang:doc_mp_upd","ref":"doc_mp_upd","sha":"0fad74deda8ce8380bbae05a9db19fdd4bef3ffd","user":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"repo":{"id":1644196,"name":"julia","full_name":"JuliaLang/julia","owner":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/JuliaLang/julia","description":"The Julia Language: A fresh approach to technical computing.","fork":false,"url":"https://api.github.com/repos/JuliaLang/julia","forks_url":"https://api.github.com/repos/JuliaLang/julia/forks","keys_url":"https://api.github.com/repos/JuliaLang/julia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JuliaLang/julia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JuliaLang/julia/teams","hooks_url":"https://api.github.com/repos/JuliaLang/julia/hooks","issue_events_url":"https://api.github.com/repos/JuliaLang/julia/issues/events{/number}","events_url":"https://api.github.com/repos/JuliaLang/julia/events","assignees_url":"https://api.github.com/repos/JuliaLang/julia/assignees{/user}","branches_url":"https://api.github.com/repos/JuliaLang/julia/branches{/branch}","tags_url":"https://api.github.com/repos/JuliaLang/julia/tags","blobs_url":"https://api.github.com/repos/JuliaLang/julia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JuliaLang/julia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JuliaLang/julia/git/refs{/sha}","trees_url":"https://api.github.com/repos/JuliaLang/julia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/{sha}","languages_url":"https://api.github.com/repos/JuliaLang/julia/languages","stargazers_url":"https://api.github.com/repos/JuliaLang/julia/stargazers","contributors_url":"https://api.github.com/repos/JuliaLang/julia/contributors","subscribers_url":"https://api.github.com/repos/JuliaLang/julia/subscribers","subscription_url":"https://api.github.com/repos/JuliaLang/julia/subscription","commits_url":"https://api.github.com/repos/JuliaLang/julia/commits{/sha}","git_commits_url":"https://api.github.com/repos/JuliaLang/julia/git/commits{/sha}","comments_url":"https://api.github.com/repos/JuliaLang/julia/comments{/number}","issue_comment_url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/{number}","contents_url":"https://api.github.com/repos/JuliaLang/julia/contents/{+path}","compare_url":"https://api.github.com/repos/JuliaLang/julia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JuliaLang/julia/merges","archive_url":"https://api.github.com/repos/JuliaLang/julia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JuliaLang/julia/downloads","issues_url":"https://api.github.com/repos/JuliaLang/julia/issues{/number}","pulls_url":"https://api.github.com/repos/JuliaLang/julia/pulls{/number}","milestones_url":"https://api.github.com/repos/JuliaLang/julia/milestones{/number}","notifications_url":"https://api.github.com/repos/JuliaLang/julia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JuliaLang/julia/labels{/name}","releases_url":"https://api.github.com/repos/JuliaLang/julia/releases{/id}","created_at":"2011-04-21T07:01:50Z","updated_at":"2015-01-05T01:46:04Z","pushed_at":"2015-01-05T00:09:31Z","git_url":"git://github.com/JuliaLang/julia.git","ssh_url":"git@github.com:JuliaLang/julia.git","clone_url":"https://github.com/JuliaLang/julia.git","svn_url":"https://github.com/JuliaLang/julia","homepage":"http://julialang.org/","size":153357,"stargazers_count":4880,"watchers_count":4880,"language":"Julia","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1008,"mirror_url":null,"open_issues_count":1058,"forks":1008,"open_issues":1058,"watchers":4880,"default_branch":"master"}},"base":{"label":"JuliaLang:master","ref":"master","sha":"3b350f114d2a6065c45565b379a3b58d440bd135","user":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"repo":{"id":1644196,"name":"julia","full_name":"JuliaLang/julia","owner":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/JuliaLang/julia","description":"The Julia Language: A fresh approach to technical computing.","fork":false,"url":"https://api.github.com/repos/JuliaLang/julia","forks_url":"https://api.github.com/repos/JuliaLang/julia/forks","keys_url":"https://api.github.com/repos/JuliaLang/julia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JuliaLang/julia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JuliaLang/julia/teams","hooks_url":"https://api.github.com/repos/JuliaLang/julia/hooks","issue_events_url":"https://api.github.com/repos/JuliaLang/julia/issues/events{/number}","events_url":"https://api.github.com/repos/JuliaLang/julia/events","assignees_url":"https://api.github.com/repos/JuliaLang/julia/assignees{/user}","branches_url":"https://api.github.com/repos/JuliaLang/julia/branches{/branch}","tags_url":"https://api.github.com/repos/JuliaLang/julia/tags","blobs_url":"https://api.github.com/repos/JuliaLang/julia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JuliaLang/julia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JuliaLang/julia/git/refs{/sha}","trees_url":"https://api.github.com/repos/JuliaLang/julia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/{sha}","languages_url":"https://api.github.com/repos/JuliaLang/julia/languages","stargazers_url":"https://api.github.com/repos/JuliaLang/julia/stargazers","contributors_url":"https://api.github.com/repos/JuliaLang/julia/contributors","subscribers_url":"https://api.github.com/repos/JuliaLang/julia/subscribers","subscription_url":"https://api.github.com/repos/JuliaLang/julia/subscription","commits_url":"https://api.github.com/repos/JuliaLang/julia/commits{/sha}","git_commits_url":"https://api.github.com/repos/JuliaLang/julia/git/commits{/sha}","comments_url":"https://api.github.com/repos/JuliaLang/julia/comments{/number}","issue_comment_url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/{number}","contents_url":"https://api.github.com/repos/JuliaLang/julia/contents/{+path}","compare_url":"https://api.github.com/repos/JuliaLang/julia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JuliaLang/julia/merges","archive_url":"https://api.github.com/repos/JuliaLang/julia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JuliaLang/julia/downloads","issues_url":"https://api.github.com/repos/JuliaLang/julia/issues{/number}","pulls_url":"https://api.github.com/repos/JuliaLang/julia/pulls{/number}","milestones_url":"https://api.github.com/repos/JuliaLang/julia/milestones{/number}","notifications_url":"https://api.github.com/repos/JuliaLang/julia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JuliaLang/julia/labels{/name}","releases_url":"https://api.github.com/repos/JuliaLang/julia/releases{/id}","created_at":"2011-04-21T07:01:50Z","updated_at":"2015-01-05T01:46:04Z","pushed_at":"2015-01-05T00:09:31Z","git_url":"git://github.com/JuliaLang/julia.git","ssh_url":"git@github.com:JuliaLang/julia.git","clone_url":"https://github.com/JuliaLang/julia.git","svn_url":"https://github.com/JuliaLang/julia","homepage":"http://julialang.org/","size":153357,"stargazers_count":4880,"watchers_count":4880,"language":"Julia","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1008,"mirror_url":null,"open_issues_count":1058,"forks":1008,"open_issues":1058,"watchers":4880,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/9594"},"html":{"href":"https://github.com/JuliaLang/julia/pull/9594"},"issue":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/9594"},"comments":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/9594/comments"},"review_comments":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/9594/comments"},"review_comment":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/9594/commits"},"statuses":{"href":"https://api.github.com/repos/JuliaLang/julia/statuses/0fad74deda8ce8380bbae05a9db19fdd4bef3ffd"}}}}