pollen/doc/First_tutorial.html

13 lines
61 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><title>5&nbsp;First tutorial</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="racket.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-racket.css" title="default"/><script type="text/javascript" src="scribble-common.js"></script><script type="text/javascript" src="manual-racket.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_0&quot;);">&#9660;</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">Pollen:<span class="mywbr"> &nbsp;</span> the book is a program</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1&nbsp;</td><td><a href="Installation.html" class="tocviewlink" data-pltdoc="x">Installation</a></td></tr><tr><td align="right">2&nbsp;</td><td><a href="quick-tour.html" class="tocviewlink" data-pltdoc="x">Quick tour</a></td></tr><tr><td align="right">3&nbsp;</td><td><a href="Backstory.html" class="tocviewlink" data-pltdoc="x">Backstory</a></td></tr><tr><td align="right">4&nbsp;</td><td><a href="big-picture.html" class="tocviewlink" data-pltdoc="x">The big picture</a></td></tr><tr><td align="right">5&nbsp;</td><td><a href="First_tutorial.html" class="tocviewselflink" data-pltdoc="x">First tutorial</a></td></tr><tr><td align="right">6&nbsp;</td><td><a href="raco-pollen.html" class="tocviewlink" data-pltdoc="x">Using <span class="stt">raco pollen</span></a></td></tr><tr><td align="right">7&nbsp;</td><td><a href="File_formats.html" class="tocviewlink" data-pltdoc="x">File formats</a></td></tr><tr><td align="right">8&nbsp;</td><td><a href="reader.html" class="tocviewlink" data-pltdoc="x">&#9674; command overview</a></td></tr><tr><td align="right">9&nbsp;</td><td><a href="Module_reference.html" class="tocviewlink" data-pltdoc="x">Module reference</a></td></tr><tr><td align="right">10&nbsp;</td><td><a href="Acknowledgments.html" class="tocviewlink" data-pltdoc="x">Acknowledgments</a></td></tr><tr><td align="right">11&nbsp;</td><td><a href="License___source_code.html" class="tocviewlink" data-pltdoc="x">License &amp; source code</a></td></tr><tr><td align="right"></td><td><a href="doc-index.html" class="tocviewlink" data-pltdoc="x">Index</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_1&quot;);">&#9658;</a></td><td>5&nbsp;</td><td><a href="First_tutorial.html" class="tocviewselflink" data-pltdoc="x">First tutorial</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">5.1&nbsp;</td><td><a href="First_tutorial.html#%28part._.Prerequisites%29" class="tocviewlink" data-pltdoc="x">Prerequisites</a></td></tr><tr><td align="right">5.2&nbsp;</td><td><a href="First_tutorial.html#%28part._.The_relationship_of_.Racket___.Pollen%29" class="tocviewlink" data-pltdoc="x">The relationship of Racket &amp; Pollen</a></td></tr><tr><td align="right">5.3&nbsp;</td><td><a href="First_tutorial.html#%28part._.Starting_a_new_file_in_.Dr.Racket%29" class="tocviewlink" data-pltdoc="x">Starting a new file in Dr<span class="mywbr"> &nbsp;</span>Racket</a></td></tr><tr><td align="right">5.4&nbsp;</td><td><a href="First_tutorial.html#%28part._.Using_the_project_server%29" class="tocviewlink
<br/>standard-module-name-resolver: collection not found ...</span></p></td></tr></table></p><p>Why? Because there&rsquo;s no language called <span class="stt">pollenxyz</span>. Switch it back to <span class="stt">pollen</span> and let&rsquo;s move on.</p><h5>5.3.2<tt>&nbsp;</tt><a name="(part._.Putting_in_the_text_of_the_poem)"></a>Putting in the text of the poem</h5><p>Here&rsquo;s a short, bad poem I wrote about CSS.</p><p><table cellspacing="0"><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></p><p>Paste the text of this poem into your DrRacket editing window, below the <span class="stt">#lang</span> line, so it looks like this:</p><blockquote class="SCodeFlow"><table cellspacing="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote><p><span class="ssansserif">Run</span> the file again. In the interactions window, you&rsquo;ll see:</p><p><span class="RktVal">The margin is 8em.
<br/>The border is blue.
<br/>The padding is 2em.
<br/>The border is too.</span></p><p>This shows you something important: by default, any plain text in a Pollen source file is simply printed as written when you <span class="ssansserif">Run</span> the file (minus the <span class="stt">#lang</span> line, which is just for Racket&rsquo;s benefit). If you like, edit the text of the poem and click <span class="ssansserif">Run</span> again. You&rsquo;ll see the updated text printed in the interactions window.</p><h5>5.3.3<tt>&nbsp;</tt><a name="(part._.Saving___naming_your_source_file)"></a>Saving &amp; naming your source file</h5><p>File naming in Pollen is consequential.</p><p>Ultimately, every Pollen source file in your project will be <span style="font-style: italic">rendered</span> into an output file. Each Pollen source file corresponds to one output file. <span style="font-weight: bold">The name of this output file will be the name of the source file minus the Pollen source extension.</span> So a source file called <span class="stt">file.txt.pp</span> will become <span class="stt">file.txt</span>.</p><p>Thus, to build the name of a source file, we take the name we want for the output file and add the appropriate Pollen file extension. Different Pollen source files use different extensions &#8212; but more about that later. For now, the extension you&rsquo;ll use for your source is <span class="stt">.pp</span>.</p><p>In this case, let&rsquo;s say we want to end up with a file called <span class="stt">poem.html</span>. Therefore, the name of our source file needs to be:</p><p>the output name <span class="stt">poem.html</span> + the source extension <span class="stt">.pp</span> = <span class="stt">poem.html.pp</span></p><p>(If you want to name the file <span class="stt">something-else.html.pp</span>, be my guest. There&rsquo;s no magic associated with the prefix.)</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>You&rsquo;re welcome to change the name of your source files from the desktop. On Mac OS X and Windows, however, the desktop interface often hides file extensions, so check the properties of the file afterward to make sure you got the name you expected.</p></blockquote></blockquote></blockquote><p>In a convenient location (e.g., your home directory or the desktop) create a new directory for your project called <span class="stt">tutorial</span>. In this new directory, save your DrRacket file as <span class="stt">poem.html.pp</span>.</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote></blockquote><h4>5.4<tt>&nbsp;</tt><a name="(part._.Using_the_project_server)"></a>Using the project server</h4><p>The project server is a web server built into Pollen. Just as DrRacket lets you run individual files and see if they work as you expect, the project server lets you preview and test your project as a real website. While working on your Pollen project, you may find it convenient to have DrRacket open on half your screen, and on the other half, a web browser pointing at the project server.</p><p><img src="project-server.png" alt="" width="670" height="412"/></p><p>&ldquo;Why can&rsquo;t I just open the HTML files directly in my browser?&rdquo; If you want to keep making web pages the way we did in 1996, go ahead. But that approach has several shortcomings. First, when you open files directly in your browser, you&rsquo;re cruising the local filesystem, and absolute URLs (the kind that start with a <span class="RktInBG"><span class="hspace"></span><
</div><div class="SIntrapara"><ul><li><p>inserting <span class="stt">#lang pollen</span> as the first line,</p></li><li><p>adding the <span class="stt">.pp</span> file extension,</p></li><li><p>running it through Pollen.</p></li></ul></div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>For more about the Pollen processing modes and how to invoke them, see <a href="file-types.html" data-pltdoc="x">File</a>.</p></blockquote></blockquote></blockquote><p>&ldquo;The preprocessor be used with <span style="font-weight: bold">any</span> kind of text-based file?&rdquo; Right. &ldquo;But how?&rdquo; The preprocessor reads the source file, handles any Pollen commands it finds, and lets the rest of the content pass through untouched. To the preprocessor, it&rsquo;s all just text data. It doesn&rsquo;t care whether that text represents HTML, CSS, JavaScript, or even <a href="https://en.wikipedia.org/wiki/TI-BASIC">TI-BASIC</a>.</p><p>Because the preprocessor only deals in text, the Pollen commands you use in the preprocessor also have to produce text. Moreover, Pollen doesn&rsquo;t enforce the semantics of the underlying file &#8212; that&rsquo;s your responsibility. For instance, Pollen won&rsquo;t stop you from doing nonsensical things like this:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"bad-poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The cave is pitch black.</span></p></td></tr><tr><td><p><span class="stt">Look out for the grue.</span></p></td></tr><tr><td><p><span class="stt">&#9674;(insert-mp3-recording-of-scream)</span></p></td></tr></table></blockquote></blockquote><p>Here, the result is not going to be valid HTML, because you can&rsquo;t simply drop binary data in the middle of an HTML file. To paraphrase Mr. Babbage &#8212; garbage in, garbage out.</p><p>I&rsquo;ve encouraged you to mess with the source file, but let&rsquo;s return it to its original state:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote></blockquote><p>This file has <span class="stt">#lang pollen</span> as the first line, and <span class="stt">.pp</span> as the file extension, so it meets the minimum requirements for the preprocessor.</p><h5>5.5.2<tt>&nbsp;</tt><a name="(part._.Creating_valid_.H.T.M.L_output)"></a>Creating valid HTML output</h5><p>Let&rsquo;s update our source so it produces valid HTML. Edit the source as follows:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt">&lt;!DOCTYPE html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;pre&gt;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr><tr><td><p><span class="stt">&lt;/pre&gt;</spa
</span><br/><span class="stt">The border is red.</span><span class="stt">
</span><br/><span class="stt">The padding is 15em.</span><span class="stt">
</span><br/><span class="stt">The border is too.</span></p></blockquote><p>As before, because the source has changed, Pollen refreshes the output file. From the dashboard, you can use the <span class="stt">in</span> and <span class="stt">out</span> links to inspect the source and output.</p><p>This is now a valid HTML page.</p><h5>5.5.3<tt>&nbsp;</tt><a name="(part._.Adding_commands)"></a>Adding commands</h5><p>I mentioned that the preprocessor reads the file and handles any Pollen commands it finds. But our source file doesn&rsquo;t have any commands yet. Let&rsquo;s add some.</p><p>Pollen commands can be embedded in your source file using one of two modes: <span style="font-style: italic">Racket mode</span> or <span style="font-style: italic">text mode</span>. We&rsquo;ll try text mode in a later tutorial. For now, we&rsquo;ll use Racket mode.</p><p>To make a Racket-mode Pollen command, just take any Racket expression and put the lozenge character (<span class="RktInBG"><span class="hspace"></span><span class="RktIn">&#9674;</span><span class="hspace"></span></span>) in front of it. For instance, these are valid Racket expressions:</p><blockquote class="SCodeFlow"><table cellspacing="0"><tr><td><p><span class="stt">(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">(define color "blue")</span></p></td></tr></table></blockquote><p>And these are the equivalent commands in Pollen:</p><blockquote class="SCodeFlow"><table cellspacing="0"><tr><td><p><span class="stt">&#9674;(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define color "blue")</span></p></td></tr></table></blockquote><p>How to type a lozenge:
<br/><span style="font-weight: bold">Mac</span>: option + shift + V
<br/><span style="font-weight: bold">Windows</span>: holding down alt, type 9674 on the num pad
<br/><span style="font-weight: bold">Ubuntu</span>: ctrl + shift + U, then 25CA</p><h5>5.5.4<tt>&nbsp;</tt><a name="(part._.Racket_basics__if_you_re_not_familiar_)"></a>Racket basics (if you&rsquo;re not familiar)</h5><p>&ldquo;But how am I supposed to know Racket?&rdquo; You don&rsquo;t. So we&rsquo;ll start now. Here are the five basic rules of Racket:</p><ol><li><p>The core building block of Racket is the <span style="font-style: italic">expression</span>. An expression can be a value (like <span class="RktVal">2</span> or <span class="RktVal">"blue"</span>), a variable (like <span class="stt">edge</span>), or a function call (like <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>).</p></li><li><p>Every expression is <span style="font-style: italic">evaluated</span> to produce a value.</p></li><li><p>A variable evaluates to whatever value it holds (so <span class="stt">inner</span> would become <span class="RktVal">2</span>). A function call evaluates to its return value (so <span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> would become <span class="RktVal">2</span>).</p></li><li><p>Function calls go between parentheses. Unlike most languages, the function name comes <span style="font-style: italic">first</span>, followed by its arguments (so it&rsquo;s <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>, not <span class="RktPn">(</span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktSym">*</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>). This is called <span style="font-style: italic">prefix notation</span>.</p></li><li><p>Expressions can contain recursively nested expressions. Thus, <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span> could be written <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span> or <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span>.</p></li></ol><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Newcomers to Racket often gripe about prefix notation and the parentheses. If you need to get it out of your system, go ahead. Keep in mind, however, that it&rsquo;s not some peculiar affectation, but rather a necessary consequence of rule #1. As you&rsquo;ll come to learn, rule #1 is where the magic happens.</p></blockquote></blockquote></blockquote><p>That should tell you enough to infer what&rsquo;s going on in the Pollen commands above:</p><blockquote class="SCodeFlow"><table cellspacing="0"><tr><td><p><span class="stt">&#9674;(define inner 2)</span></p></td></tr><t