<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Drinkable Chicken &#187; awk</title>
	<atom:link href="http://4.flowsnake.org/archives/tag/awk/feed" rel="self" type="application/rss+xml" />
	<link>http://4.flowsnake.org</link>
	<description>A Pythoneer's adventures with Scheme, Clojure and a whole lot more. ^_^</description>
	<lastBuildDate>Sat, 10 Jul 2010 14:39:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Macro trial balloons</title>
		<link>http://4.flowsnake.org/archives/66</link>
		<comments>http://4.flowsnake.org/archives/66#comments</comments>
		<pubDate>Sat, 16 Feb 2008 04:36:20 +0000</pubDate>
		<dc:creator>Hans Nowak</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[chicken]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[s1]]></category>
		<category><![CDATA[scheme]]></category>

		<guid isPermaLink="false">http://4.flowsnake.org/archives/66</guid>
		<description><![CDATA[I&#8217;ve been hacking on and off on s1, my vaporware Awk-like tool that uses Scheme for scripting. The &#8220;language&#8221; defined by s1 includes a few macros. Strictly speaking, these are redundant, but they do make things shorter, which is important for writing one-liners. Anyway, I am still kind of new to macros&#8230; so I&#8217;m wondering [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been hacking on and off on <a href="/archives/58">s1</a>, my <s>vaporware</s> Awk-like tool that uses Scheme for scripting.  The &#8220;language&#8221; defined by <em>s1</em> includes a few macros. Strictly speaking, these are redundant, but they do make things shorter, which is important for writing one-liners.</p>
<p>Anyway, I am still kind of new to macros&#8230; so I&#8217;m wondering if the code I wrote is sound. I&#8217;m offering the definitions here for review. (Comments from experienced Schemers are welcome.)</p>
<p>1. <em>inc!</em> is used to easily increase variables. It can take any number of arguments; if none are given, 1 is added by default. For example:</p>
<ul>
<li><em>(inc! x)</em> adds 1 to <em>x</em></li>
<li><em>(inc! x 33)</em> adds 33 to <em>x</em></li>
<li><em>(inc! x 1 2 3 4 5)</em> adds <em>(+ 1 2 3 4 5)</em> to <em>x</em></li>
</ul>
<p>As the exclamation mark indicates, <em>inc!</em> changes the variable in-place. Here&#8217;s its current definition:</p>
<pre>(define-macro (inc! name . args)
  (let ((total (gensym)))
    `(let ((,total
             (if (null? (list ,@args))
                 1
                 (apply + (list ,@args)))))
       (set! ,name (+ ,name ,total)))))</pre>
<p>2. Defining multiple variables does not mix well with one-liners. So I added a macro <em>def</em> that allows one to define them quickly and concisely. Like <em>inc!</em>, <em>def</em> takes any number of arguments. If an argument is a list <em>(name value)</em>, then a variable is created with the given name and value. If an argument is a symbol, then a variable is created with that name and a value of 0. (Awk is often used to add numbers, so zero seems the most sensible default, IMHO.)</p>
<p>Examples:</p>
<ul>
<li><em>(def x)</em> &#8212; same as <em>(define x 0)</em></li>
<li><em>(def x y)</em> &#8212; same as <em>(define x 0) (define y 0)</em></li>
<li><em>(def (a 1) (b &#8220;hello&#8221;))</em> &#8212; same as <em>(define a 1) (define b &#8220;hello&#8221;)</em></li>
<li><em>(def q (w 3))</em> &#8212; same as <em>(define q 0) (define w 3) </em></li>
</ul>
<p>Here&#8217;s the current definition:</p>
<pre>(define-macro (def . args)
  (if (null? args)
      #f
      (let* ((a (car args))
             (rest-args (cdr args))
             (name (if (list? a) (car a) a))
             (value (if (list? a) (cadr a) 0)))
        `(begin
           (define ,name ,value)
           (def ,@rest-args)))))</pre>
<p>(I&#8217;m not sure about the <em>#f</em>; it&#8217;s not supposed to return a value anyway.)</p>
<p>In any case, <em>s1</em>&#8216;s auxiliary functions and macros allow for concise code. (Some of it is sloppy, but useful for &#8220;scripting&#8221;, especially one-liners. Naturally, it&#8217;s always possible to write longer scripts using &#8220;cleaner&#8221; code.)</p>
<p>For example, here&#8217;s a one-liner that takes the last words on the given lines and adds them up (assuming they are numbers):</p>
<pre>s1 '(B (def s)) (inc! s &amp;$nf) (A (out s))'</pre>
<p>(I&#8217;m not sure about the <em>&amp;</em> syntax yet; it&#8217;s used here as a shortcut for the <em>as-number</em> function, which attempts to convert a string to a number, returning 0 by default.)</p>
<p><em>B</em> and <em>A</em> are shorthands for <em>BEFORE</em> and <em>AFTER</em>, blocks that are executed before and after the main code (which is executed for each line in the given text). The actual order in which these appear doesn&#8217;t matter, but it&#8217;s probably more intuitive to do before-main-after.</p>
<p>Print the number of lines, words and characters (like <em>wc</em>):</p>
<pre>s1 '(B (def c w)) (inc! w nf) (inc! c (len $0) 1) (A (out nl w c))'</pre>
<p>Print names starting with &#8220;Ga&#8221;:</p>
<pre>s1 '(if (~ #/^Ga/) (print $0))' /usr/share/dict/propernames</pre>
<p>(I&#8217;m using <a href="http://chicken.wiki.br/regex-literals">regex literals</a>, and <em>~</em> is the same as <em>string-search</em>, except it matches against <em>$0</em> (the whole line) by default.)</p>
<p>These are just teasers. Actual code is subject to change. I will release this when the &#8220;API&#8221; is somewhat stable. It&#8217;s still mostly a toy, though&#8230; :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://4.flowsnake.org/archives/66/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Interlude: Scheme command-line tool idea</title>
		<link>http://4.flowsnake.org/archives/48</link>
		<comments>http://4.flowsnake.org/archives/48#comments</comments>
		<pubDate>Sat, 26 Jan 2008 04:36:40 +0000</pubDate>
		<dc:creator>Hans Nowak</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[idea]]></category>
		<category><![CDATA[scheme]]></category>

		<guid isPermaLink="false">http://4.flowsnake.org/archives/48</guid>
		<description><![CDATA[While I&#8217;m preparing a long Python-vs-Scheme post, here&#8217;s a bit of filler. :-) Check this. No, not the part about Common Lisp; what I&#8217;m interested in right now, is the snippet of Awk code, and the question whether a similar tool can be written in Scheme. To put it more precisely, would it be possible [...]]]></description>
			<content:encoded><![CDATA[<p>While I&#8217;m preparing a long Python-vs-Scheme post, here&#8217;s a bit of filler. :-)</p>
<p>Check <a href="http://perl.plover.com/yak/12views/samples/notes.html#sl-39">this</a>. No, not the part about Common Lisp; what I&#8217;m interested in right now, is the snippet of <a href="http://en.wikipedia.org/wiki/AWK">Awk</a> code, and the question whether a similar tool can be written in Scheme.</p>
<p>To put it more precisely, would it be possible to have a command-line tool, using Scheme as its language (and probably written in Scheme as well), that lets users write one-line queries like that?</p>
<p>It would be a cool thing to have, although I&#8217;m not sure if nested parentheses mix so well with the command line. Writing Scheme code in an editor is different from writing it at a shell prompt.</p>
<p>The Awk example could look something like this:</p>
<pre>&lt;name&gt; '(begin (set-fs! ":")) (if (equal? $6 "/sbin/nologin") (print $1))' /etc/passwd</pre>
<p>(It would have to use some reader manipulation to allow for expressions like <em>$6</em> meaning <em>(field 6)</em>, or something like that. Chicken already uses the $, so maybe a different syntax would be preferable.)</p>
<p>In any case, I am pondering this. The idea is to have a tool that is powerful, relatively easy to use, and still Scheme-y. Of course, the world probably doesn&#8217;t need a new Awk, but I am exploring this idea as a coding/design exercise.</p>
]]></content:encoded>
			<wfw:commentRss>http://4.flowsnake.org/archives/48/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
