{"action":"created","comment":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/28540071","id":28540071,"diff_hunk":"@@ -872,3 +872,203 @@ entirely in Julia. You can read their source and see precisely what they\n do — and all they do is construct expression objects to be inserted into\n your program's syntax tree.\n \n+Staged functions\n+----------------\n+\n+*Staged functions* play a similar role as macros, but at a later stage\n+between parsing and run-time. Staged functions give the capability to\n+generate specialized code depending on the types of their arguments.\n+While macros work with expressions at parsing-time and cannot access the\n+types of their inputs, a staged function gets expanded at a time when\n+the types of the arguments are known, but the function is not yet compiled.\n+\n+Depending on the types of the arguments, a staged function returns a quoted\n+expression which then forms the function body of the specialized function.\n+Thus, staged functions provide a flexible framework to move work from\n+run-time to compile-time.\n+\n+When defining staged functions, there are three main differences to\n+ordinary functions:\n+\n+1. You use the keyword ``stagedfunction`` instead of ``function``\n+\n+2. In the body of the ``stagedfunction`` you only have access to the\n+   *types* of the arguments, not their values.\n+\n+3. Instead of calculating something or performing some action, you return\n+   from the staged function a *quoted expression* which, when evaluated,\n+   does what you want.\n+\n+It's easiest to illustrate this with an example. We can declare a staged\n+function ``foo`` as\n+\n+.. doctest::\n+\n+    julia> stagedfunction foo(x)\n+               println(x)\n+               :(x*x)\n+           end\n+    foo (generic function with 1 method)\n+\n+Note that the body returns a quoted expression, namely ``x*x``.\n+\n+From the callers perspective, they are very similar to regular functions;\n+in fact, you don't have to know if you're calling a ``function`` or a\n+``stagedfunction`` - the syntax and result of the call is just the same.\n+Let's see how ``foo`` behaves:\n+\n+.. doctest::\n+\n+    julia> x = foo(2); # note: not printing the result\n+    Int64              # this is the println() statement in the body\n+    julia> x           # now we print x\n+    4\n+\n+    julia> y = foo(\"bar\");\n+    ASCIIString\n+    julia> y\n+    \"barbar\"\n+\n+So, we see that in the body of the ``stagedfunction``, ``x`` is the\n+*type* of the passed argument, and the value returned by the ``stagedfunction``,\n+is the result of evaluating the quoted expression we returned from the\n+definition, now with the *value* of ``x``.\n+\n+What happens if we evaluate ``foo`` again with a type that we have already\n+used?\n+\n+.. doctest::\n+\n+    julia> foo(4)\n+    16\n+\n+Note that there is no printout of ``Int64``. The body of the ``stagedfunction``\n+is only executed *once* (not entirely true, see note below) when the method\n+for that specific set of argument types is compiled. After that, the\n+expression returned from the ``stagedfunction`` on the first invocation\n+is re-used as the method body.\n+\n+The reason for the disclaimer above is that the number of times a staged\n+function is staged is really an implementation detail; it *might* be only\n+once, but it *might* also be more often. As a consequence, you should \n+*never* write a staged function with side effects - when, and how often,\n+the side effects occur is undefined.\n+\n+The example staged function ``foo`` above did not do anything a normal\n+function ``foo(x)=x*x`` could not do, except printing the the type on the\n+first invocation. However, the power of a staged function lies in its\n+ability to compute different quoted expression depending on the types\n+passed to it:\n+\n+.. doctest::\n+\n+   julia> stagedfunction bar(x)\n+              if x <: Integer\n+                  return :(x^2)\n+              else\n+                  return :(x)\n+              end\n+          end\n+    bar (generic function with 1 method)\n+\n+    julia> bar(4)\n+    16\n+    julia> bar(\"baz\")\n+    \"baz\"","path":"doc/manual/metaprogramming.rst","position":106,"original_position":106,"commit_id":"0d66a8878baffb6986b95a3dfbc197d57e25bf1d","original_commit_id":"0d66a8878baffb6986b95a3dfbc197d57e25bf1d","user":{"login":"vtjnash","id":330950,"avatar_url":"https://avatars.githubusercontent.com/u/330950?v=3","gravatar_id":"","url":"https://api.github.com/users/vtjnash","html_url":"https://github.com/vtjnash","followers_url":"https://api.github.com/users/vtjnash/followers","following_url":"https://api.github.com/users/vtjnash/following{/other_user}","gists_url":"https://api.github.com/users/vtjnash/gists{/gist_id}","starred_url":"https://api.github.com/users/vtjnash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vtjnash/subscriptions","organizations_url":"https://api.github.com/users/vtjnash/orgs","repos_url":"https://api.github.com/users/vtjnash/repos","events_url":"https://api.github.com/users/vtjnash/events{/privacy}","received_events_url":"https://api.github.com/users/vtjnash/received_events","type":"User","site_admin":false},"body":"it's perhaps worth noting that, while this example is correct, it should not be copied, since the correct formulation for this code would be to use dispatch directly (`bar(x::Integer) = x^2; bar(x) = x`) for optimal performance and behavior","created_at":"2015-04-16T19:09:39Z","updated_at":"2015-04-16T19:09:39Z","html_url":"https://github.com/JuliaLang/julia/pull/10673#discussion_r28540071","pull_request_url":"https://api.github.com/repos/JuliaLang/julia/pulls/10673","_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/28540071"},"html":{"href":"https://github.com/JuliaLang/julia/pull/10673#discussion_r28540071"},"pull_request":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/10673"}}},"pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/10673","id":32186993,"html_url":"https://github.com/JuliaLang/julia/pull/10673","diff_url":"https://github.com/JuliaLang/julia/pull/10673.diff","patch_url":"https://github.com/JuliaLang/julia/pull/10673.patch","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/10673","number":10673,"state":"open","locked":false,"title":"WIP: Document stagedfunctions","user":{"login":"tlycken","id":1550920,"avatar_url":"https://avatars.githubusercontent.com/u/1550920?v=3","gravatar_id":"","url":"https://api.github.com/users/tlycken","html_url":"https://github.com/tlycken","followers_url":"https://api.github.com/users/tlycken/followers","following_url":"https://api.github.com/users/tlycken/following{/other_user}","gists_url":"https://api.github.com/users/tlycken/gists{/gist_id}","starred_url":"https://api.github.com/users/tlycken/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tlycken/subscriptions","organizations_url":"https://api.github.com/users/tlycken/orgs","repos_url":"https://api.github.com/users/tlycken/repos","events_url":"https://api.github.com/users/tlycken/events{/privacy}","received_events_url":"https://api.github.com/users/tlycken/received_events","type":"User","site_admin":false},"body":"`stagedfunction`s have been around for a while now, and we've successfully used them in Interpolations.jl, but they are sadly without documentation. I know @timholy wants to help with it, but he has more important stuff on his plate, so I figured I'd help out. I don't claim to be an expert in the inner workings of this black magic in any way, but as an \"outsider\" I might even be more suitable to write these docs than someone who knows all the gory details, since can't go into them ;) However, this also means that these docs need to be extra carefully fact-checked; I've tested all the examples locally, but I can't guarantee that I've understood *why* they work the way they do.\r\n\r\nThis is still just WIP - as indicated toward the end, I want to add another section with a more advanced example that demonstrate `stagedfunction`s doing something in a way that's more convenient than doing it with macros and/or regular functions, but I couldn't come up with a good case that didn't require a lot of background. Any suggestions are welcome.\r\n\r\nAlso, I couldn't figure out how to run the doc tests locally. I know I knew how to do this once, but I've forgotten and couldn't find the info anywhere I looked (`README.md` in both project root and under `doc`, `CONTRIBUTING.md` and at `docs.julialang.org`). If it's not just me being illiterate, maybe that too needs to be documented...","created_at":"2015-03-29T20:07:29Z","updated_at":"2015-04-16T19:09:39Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2c6d95189874d08f25d59d6dbfee641287696a0a","assignee":null,"milestone":{"url":"https://api.github.com/repos/JuliaLang/julia/milestones/11","html_url":"https://github.com/JuliaLang/julia/milestones/0.4.0","labels_url":"https://api.github.com/repos/JuliaLang/julia/milestones/11/labels","id":748886,"number":11,"title":"0.4.0","description":"For tracking release-defining items for 0.4: important new features, breaking changes, and blocking bugs.\r\n\r\nAfter a brief period for deciding scope, adding issues to this milestone is not allowed. Once the items in this milestone are done, 0.4 will enter its stabilizing period and a release candidate can be made soon after.","creator":{"login":"JeffBezanson","id":744556,"avatar_url":"https://avatars.githubusercontent.com/u/744556?v=3","gravatar_id":"","url":"https://api.github.com/users/JeffBezanson","html_url":"https://github.com/JeffBezanson","followers_url":"https://api.github.com/users/JeffBezanson/followers","following_url":"https://api.github.com/users/JeffBezanson/following{/other_user}","gists_url":"https://api.github.com/users/JeffBezanson/gists{/gist_id}","starred_url":"https://api.github.com/users/JeffBezanson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JeffBezanson/subscriptions","organizations_url":"https://api.github.com/users/JeffBezanson/orgs","repos_url":"https://api.github.com/users/JeffBezanson/repos","events_url":"https://api.github.com/users/JeffBezanson/events{/privacy}","received_events_url":"https://api.github.com/users/JeffBezanson/received_events","type":"User","site_admin":false},"open_issues":28,"closed_issues":30,"state":"open","created_at":"2014-08-10T18:13:46Z","updated_at":"2015-04-16T09:13:24Z","due_on":"2015-06-20T18:30:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/JuliaLang/julia/pulls/10673/commits","review_comments_url":"https://api.github.com/repos/JuliaLang/julia/pulls/10673/comments","review_comment_url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/10673/comments","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/0d66a8878baffb6986b95a3dfbc197d57e25bf1d","head":{"label":"tlycken:doc-stagedfunctions","ref":"doc-stagedfunctions","sha":"0d66a8878baffb6986b95a3dfbc197d57e25bf1d","user":{"login":"tlycken","id":1550920,"avatar_url":"https://avatars.githubusercontent.com/u/1550920?v=3","gravatar_id":"","url":"https://api.github.com/users/tlycken","html_url":"https://github.com/tlycken","followers_url":"https://api.github.com/users/tlycken/followers","following_url":"https://api.github.com/users/tlycken/following{/other_user}","gists_url":"https://api.github.com/users/tlycken/gists{/gist_id}","starred_url":"https://api.github.com/users/tlycken/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tlycken/subscriptions","organizations_url":"https://api.github.com/users/tlycken/orgs","repos_url":"https://api.github.com/users/tlycken/repos","events_url":"https://api.github.com/users/tlycken/events{/privacy}","received_events_url":"https://api.github.com/users/tlycken/received_events","type":"User","site_admin":false},"repo":{"id":9855421,"name":"julia","full_name":"tlycken/julia","owner":{"login":"tlycken","id":1550920,"avatar_url":"https://avatars.githubusercontent.com/u/1550920?v=3","gravatar_id":"","url":"https://api.github.com/users/tlycken","html_url":"https://github.com/tlycken","followers_url":"https://api.github.com/users/tlycken/followers","following_url":"https://api.github.com/users/tlycken/following{/other_user}","gists_url":"https://api.github.com/users/tlycken/gists{/gist_id}","starred_url":"https://api.github.com/users/tlycken/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tlycken/subscriptions","organizations_url":"https://api.github.com/users/tlycken/orgs","repos_url":"https://api.github.com/users/tlycken/repos","events_url":"https://api.github.com/users/tlycken/events{/privacy}","received_events_url":"https://api.github.com/users/tlycken/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tlycken/julia","description":"The Julia Language: A fresh approach to technical computing.","fork":true,"url":"https://api.github.com/repos/tlycken/julia","forks_url":"https://api.github.com/repos/tlycken/julia/forks","keys_url":"https://api.github.com/repos/tlycken/julia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tlycken/julia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tlycken/julia/teams","hooks_url":"https://api.github.com/repos/tlycken/julia/hooks","issue_events_url":"https://api.github.com/repos/tlycken/julia/issues/events{/number}","events_url":"https://api.github.com/repos/tlycken/julia/events","assignees_url":"https://api.github.com/repos/tlycken/julia/assignees{/user}","branches_url":"https://api.github.com/repos/tlycken/julia/branches{/branch}","tags_url":"https://api.github.com/repos/tlycken/julia/tags","blobs_url":"https://api.github.com/repos/tlycken/julia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tlycken/julia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tlycken/julia/git/refs{/sha}","trees_url":"https://api.github.com/repos/tlycken/julia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tlycken/julia/statuses/{sha}","languages_url":"https://api.github.com/repos/tlycken/julia/languages","stargazers_url":"https://api.github.com/repos/tlycken/julia/stargazers","contributors_url":"https://api.github.com/repos/tlycken/julia/contributors","subscribers_url":"https://api.github.com/repos/tlycken/julia/subscribers","subscription_url":"https://api.github.com/repos/tlycken/julia/subscription","commits_url":"https://api.github.com/repos/tlycken/julia/commits{/sha}","git_commits_url":"https://api.github.com/repos/tlycken/julia/git/commits{/sha}","comments_url":"https://api.github.com/repos/tlycken/julia/comments{/number}","issue_comment_url":"https://api.github.com/repos/tlycken/julia/issues/comments{/number}","contents_url":"https://api.github.com/repos/tlycken/julia/contents/{+path}","compare_url":"https://api.github.com/repos/tlycken/julia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tlycken/julia/merges","archive_url":"https://api.github.com/repos/tlycken/julia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tlycken/julia/downloads","issues_url":"https://api.github.com/repos/tlycken/julia/issues{/number}","pulls_url":"https://api.github.com/repos/tlycken/julia/pulls{/number}","milestones_url":"https://api.github.com/repos/tlycken/julia/milestones{/number}","notifications_url":"https://api.github.com/repos/tlycken/julia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tlycken/julia/labels{/name}","releases_url":"https://api.github.com/repos/tlycken/julia/releases{/id}","created_at":"2013-05-04T14:53:01Z","updated_at":"2015-04-07T15:26:20Z","pushed_at":"2015-04-14T06:48:48Z","git_url":"git://github.com/tlycken/julia.git","ssh_url":"git@github.com:tlycken/julia.git","clone_url":"https://github.com/tlycken/julia.git","svn_url":"https://github.com/tlycken/julia","homepage":"http://julialang.org/","size":62486,"stargazers_count":0,"watchers_count":0,"language":"Julia","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"JuliaLang:master","ref":"master","sha":"c8c967c761f0463fad6b84ca36d18832cefa5092","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-04-16T18:04:36Z","pushed_at":"2015-04-16T18:04:35Z","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":190386,"stargazers_count":5374,"watchers_count":5374,"language":"Julia","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1131,"mirror_url":null,"open_issues_count":1234,"forks":1131,"open_issues":1234,"watchers":5374,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/10673"},"html":{"href":"https://github.com/JuliaLang/julia/pull/10673"},"issue":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/10673"},"comments":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/10673/comments"},"review_comments":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/10673/comments"},"review_comment":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/10673/commits"},"statuses":{"href":"https://api.github.com/repos/JuliaLang/julia/statuses/0d66a8878baffb6986b95a3dfbc197d57e25bf1d"}}}}