<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7913334388303599270</id><updated>2012-02-02T07:45:14.519-08:00</updated><category term='flash'/><category term='Technical'/><category term='postgres'/><category term='nicknames'/><category term='light guide'/><category term='screentime'/><category term='as3'/><category term='macros'/><category term='perl'/><category term='Non Technical'/><category term='lisp macros'/><category term='experiment'/><category term='eeepc'/><category term='Lisp'/><category term='fiber optics'/><category term='evtouch'/><category term='as2'/><category term='debian'/><category term='performance'/><category term='QR Code'/><category term='Lisp Example'/><category term='Web development'/><category term='Common Lisp'/><category term='usbtouchscreen'/><category term='HTML5'/><title type='text'>(+ 1 1)</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-3821878167398015518</id><published>2011-11-17T03:45:00.001-08:00</published><updated>2011-11-17T04:19:30.122-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Non Technical'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='Web development'/><title type='text'>HTML5 - for non technical folk</title><content type='html'>&lt;br /&gt;TAKEHOME: HTML5 is coming - prepare for it.&lt;br /&gt;&lt;br /&gt;With Adobe abandoning mobile Flash development, it looks like the age of HTML5 is upon us.&lt;br /&gt;&lt;br /&gt;This is the non-technical version. For a bit more detail, &lt;a href="http://ryan-white.blogspot.com/2011/11/html5.html" target="_blank"&gt;click here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* What it is&lt;/b&gt;&lt;br /&gt;&amp;nbsp; HTML5 is the next step in the evolution of the web. A host of technical changes that should clear the way for really great work.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* What it isn't&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Mostly, HTML5 isn't ready yet!&lt;br /&gt;&lt;br /&gt;&amp;nbsp; It's still being argued over and agreed upon. It'll be ready anywhere between 2013 and 2022, depending on who you ask. &lt;a href="http://en.wikipedia.org/wiki/HTML5"&gt;http://en.wikipedia.org/wiki/HTML5&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; It also isn't:&lt;br /&gt;&amp;nbsp; - Animations&lt;br /&gt;&amp;nbsp; - Faster Javascript&lt;br /&gt;&amp;nbsp; - Gorgeous CSS (styling)&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Confused? So is everybody else. And when confusion is out there, snake-oil salesmen are always in the wings, ready to take some poor suckers for a ride. So be careful out there.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* The FUD&lt;/b&gt;&lt;br /&gt;&amp;nbsp; HTML5 is set to become the new Flash, AJAX and Web 2.0 combined. Understandably, people are worried that they'll get left behind. That no one will use their sites. That if they don't get "the HTML5", their businesses will crash and burn. Not likely.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* Why it's good&lt;/b&gt;&lt;br /&gt;&amp;nbsp; If it plays out how folks are intending, it's going to simplify the development of really fantastic web apps. Things like video and audio come baked in. Styling is taken care of by enhanced CSS. Machines will be able to understand the structure of pages more easily.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* When to use it&lt;/b&gt;&lt;br /&gt;&amp;nbsp; At every opportunity :) Seriously though: you'd be wise to start getting things ready as soon as possible.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* When not to use it&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Don't try and do serious Flash-style animations. Also: remember that Flash and HTML are fundamentally different technologies, so trying to make one into the other is not a good strategy.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* How to prepare for it&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Start off small. Build content so it'd just as easily work on iPads, iPhones and regular browsers. Slowly, everything will converge, and you'll be ahead of the curve.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* Links&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blogs.adobe.com/conversations/2011/11/flash-focus.html"&gt;http://blogs.adobe.com/conversations/2011/11/flash-focus.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/TR/html5-diff/"&gt;http://www.w3.org/TR/html5-diff/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://mashable.com/2011/11/11/flash-mobile-dead-adobe/"&gt;http://mashable.com/2011/11/11/flash-mobile-dead-adobe/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/HTML5"&gt;http://en.wikipedia.org/wiki/HTML5&lt;/a&gt;&lt;br /&gt;&lt;a href="https://developer.mozilla.org/en/HTML/HTML5#Technologies_often_called_part_of_HTML5_that_aren%27t"&gt;https://developer.mozilla.org/en/HTML/HTML5#Technologies_often_called_part_of_HTML5_that_aren%27t&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-3821878167398015518?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/3821878167398015518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=3821878167398015518' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/3821878167398015518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/3821878167398015518'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2011/11/html5-for-non-technical-folk.html' title='HTML5 - for non technical folk'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-9166985788280006759</id><published>2011-11-16T11:08:00.001-08:00</published><updated>2011-11-17T04:04:56.149-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technical'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='Web development'/><title type='text'>HTML5 - for technical folk</title><content type='html'>&lt;b&gt;TAKEHOME:&lt;/b&gt; HTML5 is coming - know what your options are.&lt;br /&gt;&lt;br /&gt;This post is targeted at a more technical audience. &lt;a href="http://ryan-white.blogspot.com/2011/11/html5-for-non-technical-folk.html" target="_blank"&gt;Click here&lt;/a&gt; for the ideas without all the detail.&lt;br /&gt;&lt;br /&gt;Sometimes a technology goes mainstream, and everyone suddenly wants to show that they're at that cutting edge, so they MUST have the new thing. With Adobe basically jumping ship on Flash - HTML5 is that new thing.&lt;br /&gt;&lt;br /&gt;Nothing new or groundbreaking here - just my thoughts on it, all in one place, as quickly as possible.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* What it is&lt;/b&gt;&lt;br /&gt;&amp;nbsp; HTML5 is the next step in the evolution of the web. That's all. It's the specification for HTML - how it will look, and how browsers will deal with it. It separates concerns - making styling information the domain of CSS for instance. It defines things that are relevent and likely to be important in future - how to have audio and video, how to deal with email addresses and such in forms, things to make your site behave a bit more like applications (with their own little databases and things like that) and how to "semantically" construct your pages. A host of tweaks and imrovements that, on their own, wouldn't amount to much, but together are going to open the web up for vast improvements over time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* What it isn't&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Mostly, HTML5 isn't ready yet! &lt;br /&gt;&lt;br /&gt;&amp;nbsp; It's still being argued over and agreed upon. It'll be ready anywhere between 2013 and 2022, depending on who you ask. &lt;a href="http://en.wikipedia.org/wiki/HTML5"&gt;http://en.wikipedia.org/wiki/HTML5&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; It also isn't:&lt;br /&gt;&amp;nbsp; - Animations&lt;br /&gt;&amp;nbsp; - Faster Javascript&lt;br /&gt;&amp;nbsp; - Advanced CSS&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Confused? So is everybody else. Be prepared for lots of requests for "HTML 5" - without clear direction on what people are expecting.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* The FUD&lt;/b&gt;&lt;br /&gt;&amp;nbsp; HTML5 is set to become the new Flash, AJAX and Web 2.0 combined. Understandably, people are worried that they'll get left behind. That no one will use their sites. That if they don't get "the HTML5", their businesses will crash and burn. It is your job to offset their fears. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;* Why it's good&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Hopefully, websites will be easier for machines to read - making SEO easier to do and more honest. It'll hopefully do away with the need for third party plugins like Flash. It'll hopefully specify not only what browsers should do, but exactly how they should behave, even when failing - so web design should become more consistent, with less custom styling to get a site working in different browsers. Also - it should create an environment in which browser and website are able to behave in a more app-like manner.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* When to use it&lt;/b&gt;&lt;br /&gt;&amp;nbsp; You can start using it right away. The secret here is to remember that most browsers only support parts of it. Building for complete cross-browser compatability with all the bells and whistles is difficult, if not impossible right now. &lt;a href="http://www.webresourcesdepot.com/html5-and-css3-browser-compatibility-chart/" target="_blank"&gt;http://www.webresourcesdepot.com/html5-and-css3-browser-compatibility-chart/ &lt;/a&gt;&lt;a href="http://www.findmebyip.com/litmus/"&gt;http://www.findmebyip.com/litmus/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* When not to use it&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Freaky animations - the high end stuff you'd do in Flash - rather keep those in flash. That said, you'll want to start avoiding doing that sort of thing - people with tablets and smartphones (iOS) won't be able to see your site anyway.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* How to prepare for it&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;Start getting used to having to take the animations down a notch.&lt;br /&gt;&lt;br /&gt;Right now, having the best features of HTML5 available to you on all platforms is pretty much impossible, or possible, but with large amounts of dev work and duplication of functionality over multiple platforms.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Use good Javascript and CSS to get most things done. Tweening libraries and CSS resetting frameworks will give you a lot of room to play. That said, you should still be aiming for a "progressive enhancement" approach - just to cover all your bases. Fundamentally, you want clean html, with nice, consistent and logical CSS and Javascript. Preparing your content for mobile and tablet devices is part of the battle anyway, so there's a good place to start. Either build an alternate version of your site for such devices or create them from the start to work on them as well as browsers.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Right now, things are just beginning, so, for a while, it's going to feel like a ridiculous amount of work to get the most basic stuff done. You can expect things to get better shortly - even Adobe is spending a lot of time and effort in making HTML5 easier for everyone.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;* Links&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blogs.adobe.com/conversations/2011/11/flash-focus.html"&gt;http://blogs.adobe.com/conversations/2011/11/flash-focus.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/TR/html5-diff/"&gt;http://www.w3.org/TR/html5-diff/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://mashable.com/2011/11/11/flash-mobile-dead-adobe/"&gt;http://mashable.com/2011/11/11/flash-mobile-dead-adobe/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/HTML5"&gt;http://en.wikipedia.org/wiki/HTML5&lt;/a&gt;&lt;br /&gt;&lt;a href="https://developer.mozilla.org/en/HTML/HTML5#Technologies_often_called_part_of_HTML5_that_aren%27t"&gt;https://developer.mozilla.org/en/HTML/HTML5#Technologies_often_called_part_of_HTML5_that_aren%27t&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-9166985788280006759?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/9166985788280006759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=9166985788280006759' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/9166985788280006759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/9166985788280006759'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2011/11/html5.html' title='HTML5 - for technical folk'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-4869531219555787396</id><published>2011-11-08T10:46:00.000-08:00</published><updated>2012-01-23T02:04:32.867-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Non Technical'/><category scheme='http://www.blogger.com/atom/ns#' term='QR Code'/><title type='text'>QR Codes - for non technical folk</title><content type='html'>By the end of this post, I hope to pass on a little bit of information about QR codes - just some things I've picked up over time in dealing with them.&lt;br /&gt;This post is aimed at non-technical folk, keeping all the gory details to a minimum. For a tech-centric post, &lt;a href="http://ryan-white.blogspot.com/2011/11/qr-codes.html" target="_blank"&gt;go here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What are they?&lt;/b&gt;&lt;br /&gt;QR codes are hyperlinks that bridge the real and digital worlds. They allow a piece of print media to take the user to a website, usually on their mobile. The codes themselves are 2D barcodes, and can actually contain text or v-cards to name a few, but mostly they contain hyperlinks.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Where are they from, aren't they just a fad?&lt;/b&gt;&lt;br /&gt;They originated in Japan - a subsidiary of Toyota invented them to keep track of car parts. From there, they spread into marketing. Because of their plain, utilitarian nature, I think they will fade as a cutesy novelty, to become ubiquitous, in the same way that hyperlinks are on the web.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Where can one get them?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.qrstuff.com/"&gt;http://www.qrstuff.com/&lt;/a&gt; is a good place to start, but if you google "QR Code generator", you'll find plenty of tools.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;Creative executions?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://designerqrcodes.wordpress.com/designer-qr-code-art-gallery/"&gt;http://designerqrcodes.wordpress.com/designer-qr-code-art-gallery/&lt;/a&gt; shows many good examples.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What are the legal requirements?&lt;/b&gt;&lt;br /&gt;The term "QR Code" is owned by Denso Wave (a subsidiary of Toyota), and their only requirements are listed here:&lt;br /&gt;&lt;a href="http://www.denso-wave.com/qrcode/faqpatent-e.html"&gt;http://www.denso-wave.com/qrcode/faqpatent-e.html&lt;/a&gt;&lt;br /&gt;Basically, you can get away with using the actual code in any way you want, but if you use the term "QR Code", you should note that QR Code is a registered trademark of Denso Wave.&lt;br /&gt;&lt;br /&gt;More info?&lt;br /&gt;For more info and links, &lt;a href="http://ryan-white.blogspot.com/2011/11/qr-codes.html" target="_blank"&gt;go to the techie version&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;QR Codes, explained by commoncraft&lt;br /&gt;&lt;a href="http://www.commoncraft.com/video/qr-codes"&gt;http://www.commoncraft.com/video/qr-codes&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-4869531219555787396?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/4869531219555787396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=4869531219555787396' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/4869531219555787396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/4869531219555787396'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2011/11/qr-codes-for-non-technical-folk.html' title='QR Codes - for non technical folk'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-8977708124695808160</id><published>2011-11-08T10:40:00.000-08:00</published><updated>2012-02-02T07:45:14.547-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technical'/><category scheme='http://www.blogger.com/atom/ns#' term='QR Code'/><title type='text'>QR Codes - for technical folk</title><content type='html'>By the end of this post, I hope to pass on a little bit of information about QR codes - just some things I've picked up over time in dealing with them.&lt;br /&gt;&lt;br /&gt;This post is targeted at technical folk. For the non-technical version, &lt;a href="http://ryan-white.blogspot.com/2011/11/qr-codes-for-non-technical-folk.html" target="_blank"&gt;go here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Where are they from?&lt;/b&gt;&lt;br /&gt;Denso Wave, a subsidiary of Toyota, first created them to track motor vehicle parts, and it wasn't too long before someone thought they'd be useful in the wild.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What do they do?&lt;/b&gt;&lt;br /&gt;QR codes themselves just encode text, with varying degrees of capacity and redundancy. Often, the text is a link off to a web site, but it can also be plain text or a v-card or something like that. So QR codes are basically just hyperlinks in the physical world, enabling users to go to content quickly and easily.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Where does one get them?&lt;/b&gt;&lt;br /&gt;The easiest way to get started is to google "QR Code generator" and go from there.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do they have to be black and white?&lt;/b&gt;&lt;br /&gt;Not at all - there are many ways to play with them - just as long as the contrast is maintained. Many deployments use a small logo or picture in the middle of the code or as part of the design. This is possible because the codes have a certain amount of error correction.&lt;br /&gt;&lt;a href="http://designerqrcodes.wordpress.com/designer-qr-code-art-gallery/"&gt;http://designerqrcodes.wordpress.com/designer-qr-code-art-gallery/&lt;/a&gt; has good examples of interestingly crafted codes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What are the legal requirements?&lt;/b&gt;&lt;br /&gt;The term "QR Code" is owned by Denso Wave (a subsidiary of Toyota), and their only requirements are listed here:&lt;br /&gt;&lt;a href="http://www.denso-wave.com/qrcode/faqpatent-e.html"&gt;http://www.denso-wave.com/qrcode/faqpatent-e.html&lt;/a&gt;&lt;br /&gt;The requirements are extremely lenient - basically the codes themselves can just be used, and using the phrase "QR Code" needs a mention of Denso Wave as the owners of the term. Somewhere :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Any tips?&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create different codes for each execution of your campaign, so you'll know which codes led users to the target URL.&lt;/li&gt;&lt;li&gt;Ideal size is 20x20mm, or the "pixels" to be 0.7x0.7mm, whichever is *bigger* (encoding more text will lead to more intricate patterns). Of course, this is for printed media within arm's reach of the user. Billboards and such will need special treatment.&lt;/li&gt;&lt;li&gt;Make sure the content the user is going to is mobile friendly. Users will almost exclusively use mobile phones to scan the codes, and will probably use the same to actually visit the destination.&lt;/li&gt;&lt;li&gt;QR codes are not a silver bullet. They're not a call to action in themselves, so don't expect addition of QR codes to printed media to suddenly and drastically increase visits.&lt;/li&gt;&lt;li&gt;Accept no substitutes. QR codes are the most widely used mobile codes - there are competitors out there, but they don't have the ubiquity of QR Codes - and&amp;nbsp; the companies peddling proprietary formats often charge to create them.&lt;/li&gt;&lt;li&gt;Stats and analytics are important - but beware of companies offering "free" analytics. Such operators still make money, potentially by selling details about visitors to your site. Rather go with a company that will charge you for analytics - your data will be safer this way. If you don't want to spend all that money, using Google Analytics on the destination page, combined ith some GET data will give you a fair amount of information. http://www.gloo.co.za?qr=001 and http://www.gloo.co.za?qr=002 are examples of what I'm talking about - they go to the same place, but indicate different entry points.&lt;/li&gt;&lt;li&gt;When generating codes, it's best to save them as a vector based format (like SVG) - your print people will thank you, because they can be scaled to suit whatever media they're designing for.&lt;/li&gt;&lt;/ul&gt;For more info, Wikipedia has an article:&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/QR_code"&gt;http://en.wikipedia.org/wiki/QR_code&lt;/a&gt;&lt;br /&gt;QR Codes, explained by commoncraft&lt;br /&gt;&lt;a href="http://www.commoncraft.com/video/qr-codes"&gt;http://www.commoncraft.com/video/qr-codes&lt;/a&gt;&lt;br /&gt;QR code generator:&lt;br /&gt;&lt;a href="http://beqrious.com/generator"&gt;http://beqrious.com/generator&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-8977708124695808160?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/8977708124695808160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=8977708124695808160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/8977708124695808160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/8977708124695808160'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2011/11/qr-codes.html' title='QR Codes - for technical folk'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-9025289505709826036</id><published>2011-10-29T05:14:00.000-07:00</published><updated>2011-10-29T05:14:32.536-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='light guide'/><category scheme='http://www.blogger.com/atom/ns#' term='fiber optics'/><category scheme='http://www.blogger.com/atom/ns#' term='experiment'/><title type='text'>Transmitting light, via liquid, down a plastic tube</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-cuAyhnvmlCU/TqvrxS9IyzI/AAAAAAAAAMk/Zsz6hcfdIvA/s1600/2011-10-17+20.09.11.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="480" src="http://2.bp.blogspot.com/-cuAyhnvmlCU/TqvrxS9IyzI/AAAAAAAAAMk/Zsz6hcfdIvA/s640/2011-10-17+20.09.11.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I've always been curious about fiber optics. And recently found out about &lt;a href="http://www.lumatec.de/"&gt;liquid lightguides&lt;/a&gt;.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;In a nutshell: you need a transmission medium with a&amp;nbsp;high &lt;a href="http://refractiveindex.info/"&gt;refractive index&lt;/a&gt;, clad in a medium with a low refractive index. The greater the difference, the easier you can get light to bounce around nicely.&lt;br /&gt;&lt;br /&gt;I ended up using &lt;a href="http://en.wikipedia.org/wiki/Glycerol"&gt;glycerine/glycerol&lt;/a&gt; as the transmission medium, &lt;a href="http://www.tygon.com/chemfluor-367-tubing.aspx"&gt;Chemfluor 367&lt;/a&gt; as the cladding.&lt;br /&gt;&lt;br /&gt;Pictures below: - bit more of an intense light burst, and one of my boys having fun shining the light in one end of a tube, and getting it out the other side :)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-JgkNNogwsus/Tqvr1ZQyU6I/AAAAAAAAAMs/oZhQNX5NRVY/s1600/2011-10-17+20.08.48.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="480" src="http://4.bp.blogspot.com/-JgkNNogwsus/Tqvr1ZQyU6I/AAAAAAAAAMs/oZhQNX5NRVY/s640/2011-10-17+20.08.48.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-fA466831vDs/Tqvrt8n9HHI/AAAAAAAAAMc/WFwTz1Wm04o/s1600/2011-10-17+20.10.00.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="480" src="http://3.bp.blogspot.com/-fA466831vDs/Tqvrt8n9HHI/AAAAAAAAAMc/WFwTz1Wm04o/s640/2011-10-17+20.10.00.jpg" width="640" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-9025289505709826036?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/9025289505709826036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=9025289505709826036' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/9025289505709826036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/9025289505709826036'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2011/10/transmitting-light-via-liquid-down.html' title='Transmitting light, via liquid, down a plastic tube'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-cuAyhnvmlCU/TqvrxS9IyzI/AAAAAAAAAMk/Zsz6hcfdIvA/s72-c/2011-10-17+20.09.11.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-993486839940602700</id><published>2010-07-01T00:27:00.000-07:00</published><updated>2010-07-01T00:27:09.958-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nicknames'/><title type='text'>Creepy old man.</title><content type='html'>I have an evil laugh. It's not my fault, I picked it up when I was a kid. And I was born in 1975 - so I don't reckon I'm that old. I mean, it was after man landed on the moon fer cryin' out loud.&lt;br /&gt;&lt;br /&gt;But when you work in a studio where the average age is, like 22 or something, I guess you're old.&lt;br /&gt;&lt;br /&gt;Frighteningly, I've been given the nickname "Creepy Old Man". I'm told it's affectionate, but who knows?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-993486839940602700?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/993486839940602700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=993486839940602700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/993486839940602700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/993486839940602700'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2010/07/creepy-old-man.html' title='Creepy old man.'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-7858843143827562842</id><published>2010-05-26T03:01:00.000-07:00</published><updated>2010-05-26T03:01:29.642-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='as3'/><category scheme='http://www.blogger.com/atom/ns#' term='screentime'/><category scheme='http://www.blogger.com/atom/ns#' term='as2'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Screentime Gotchas</title><content type='html'>Screentime is the de-facto standard for turning flash content into screensavers. It was painful 7 years ago, and it's still painful now.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Screentime's AS3 support is broken right now. Specifically, checking existence of files and/or copying files always returns true, regardless of what actually happened. AS2 works fine though.&lt;/li&gt;&lt;li&gt;When using stringWrite, on OSX, you must supply the full path to the file being written.&lt;/li&gt;&lt;li&gt;Permissions behave a bit weirdly. When including, say, a config file, the Windows installation won't allow you to write to the file, but the OSX version will. You can get around this by supplying a default config, reading from that, and then writing it in the Win version - the newly created file then has all the permissions you'd want.&lt;/li&gt;&lt;li&gt; Opening a URL from a Win screensaver creates a security loophole. If the user has checked the "on resume, display the logon screen"(or whatever), the box should basically be locked, but if you open a page in the browser, you're able to browse the machine. Using getSecurityMode() clears this up - it can tell you whether the box is checked or not, and you can behave accordingly.&lt;/li&gt;&lt;li&gt;Screentime have drunk some sort of asynchrony cool-aid. I'm pretty sure this is implemented with speed and all that in mind, but having to use registerCallBack() for everything - even detecting the security mode means that I have to chain stuff together, which is brittle.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-7858843143827562842?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/7858843143827562842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=7858843143827562842' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/7858843143827562842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/7858843143827562842'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2010/05/screentime-gotchas.html' title='Screentime Gotchas'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-5414493559959911799</id><published>2010-03-23T02:58:00.000-07:00</published><updated>2010-03-23T03:00:11.286-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><category scheme='http://www.blogger.com/atom/ns#' term='postgres'/><title type='text'>Postgres and Fsync</title><content type='html'>After an upgrade to a server I sometimes help out with, the perl script responsible for importing about 300 000 records into a Postgres database went from taking 2.5 to 6 hours.&lt;br /&gt;&lt;br /&gt;Not overly fond of reworking things that aren't broken, I decided not to tweak the scripts to use COPY instead of the usual massive, bulky number of INSERTs... There had to be some bottle-neck somewhere...&lt;br /&gt;&lt;br /&gt;Ultimately, checking out the warning logs pointed me to setting the fsync setting in postgres to "off"&amp;nbsp; - which made things tons better. Sure things won't work nicely if there's an OS or hardware freak-out, but if that happens, the state of the database will pretty much be the least of my problems.&lt;br /&gt;&lt;br /&gt;Time taken to import those records now: 1.5 hours. I'm pretty convinced I'm missing something else subtle out here, but such a performance gain for so little effort is worth a few words here. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/8.1/interactive/runtime-config-wal.html"&gt;http://www.postgresql.org/docs/8.1/interactive/runtime-config-wal.html&lt;/a&gt; provides some more info.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-5414493559959911799?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/5414493559959911799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=5414493559959911799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/5414493559959911799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/5414493559959911799'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2010/03/postgres-and-fsync.html' title='Postgres and Fsync'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-565797434846199554</id><published>2008-12-20T09:16:00.000-08:00</published><updated>2009-01-08T22:20:02.954-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usbtouchscreen'/><category scheme='http://www.blogger.com/atom/ns#' term='debian'/><category scheme='http://www.blogger.com/atom/ns#' term='evtouch'/><category scheme='http://www.blogger.com/atom/ns#' term='eeepc'/><title type='text'>eeepc, touchscreen and evtouch</title><content type='html'>I've got an eeepc 701. It seems that part of the process of owning one means that you're obliged to pimp it in some way. A buddy of mine added a blue tooth module, but I thought it'd be cool to add a touch screen.&lt;br /&gt;&lt;br /&gt;Scratching around on Ebay, I managed to find one from VirtualVillage, ordered, waited, received, experimented and installed. It ran on WinXP after a quick install, so I thought it'd be easy enough to run under Debian. After ruining my install of Debian through a combination of ignorance and clumsy attempts to compile and install the eGalax driver provided, I reinstalled and started again. Ultimately, a stock standard install of the evtouch driver, with a few pretty much undocumented options in my xorg.conf file made everything okay. &lt;br /&gt;&lt;br /&gt;Getting there was a bit of a pain though. I found an obscure URL &lt;a href="http://www.postnuklear.de/xorg-patches/"&gt;http://www.postnuklear.de/xorg-patches/&lt;/a&gt; after googling a bit, saw that it was an unofficial patch, googled a bit more, and it seemed like the patch had been rolled into the evtouch driver. I just added a few extra options to xorg.conf, and they seemed to work. So we basically have undocumented features in the evtouch driver. Great.&lt;br /&gt;&lt;br /&gt;Here's the /etc/X11/xorg.conf file for future reference:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;xorg.conf (X.Org X Window System server configuration file)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;This file was generated by dexconf, the Debian X Configuration tool, using&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;values from the debconf database.&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;Edit this file with caution, and see the xorg.conf manual page.&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;(Type &amp;quot;man xorg.conf&amp;quot; at the shell prompt.)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;This file is automatically updated on xserver-xorg package upgrades *only*&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;if it has not been modified since the last upgrade of the xserver-xorg&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;package.&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;If you have edited this file but would like it to be automatically updated&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;again, run the following command:&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;#   &lt;/span&gt;&lt;span class="comment"&gt;sudo dpkg-reconfigure -phigh xserver-xorg&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;InputDevice&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Generic Keyboard&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Driver&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;kbd&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;XkbRules&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;xorg&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;XkbModel&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;pc104&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;XkbLayout&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;us&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;XkbVariant&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;dvorak&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;InputDevice&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Configured Mouse&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Driver&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;mouse&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Device&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Configured Video Device&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Monitor&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Configured Monitor&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Screen&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Default Screen&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Monitor&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;Configured Monitor&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;InputDevice&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;touchscreen&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Driver&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;evtouch&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Device&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;/dev/input/event3&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;DeviceName&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;touchscreen&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;ReportingMode&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Raw&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;SendCoreEvents&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;On&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Rotate&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;CCW&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="comment-delimiter"&gt;#&lt;/span&gt;&lt;span class="comment"&gt;Option &amp;quot;Calibrate&amp;quot; &amp;quot;1&amp;quot;&lt;br /&gt;&lt;/span&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;MinX&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;266&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;MinY&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;95&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;MaxX&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;1889&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;MaxY&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;1957&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x0&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;20&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y0&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-3&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x1&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;10&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y1&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-5&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x2&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-4&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y2&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-8&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x3&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;10&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y3&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x4&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;5&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y4&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-3&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x5&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-5&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y5&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-5&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x6&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y6&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;8&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x7&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y7&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;4&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;x8&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;-10&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="variable-name"&gt;Option&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;y8&amp;quot;&lt;/span&gt;        &lt;span class="string"&gt;&amp;quot;5&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt;       &lt;span class="string"&gt;&amp;quot;MoveLimit&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;touched_drag&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;longtouched_action&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;down&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;longtouched_button&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;maybetapped_action&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;maybetapped_button&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;touched_drag&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;oneandahalftap_button&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;TapTimer&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;30&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;LongtouchTimer&amp;quot;&lt;/span&gt;  &lt;span class="string"&gt;&amp;quot;500&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;InputDevice&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;dummy&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Driver&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;void&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Option&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Device&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;/dev/input/mice&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;Section&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;ServerLayout&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Identifier&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Default Layout&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;Screen&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Default Screen&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="variable-name"&gt;InputDevice&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;touchscreen&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;CorePointer&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;# &lt;/span&gt;&lt;span class="comment"&gt;InputDevice &amp;quot;dummy&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="variable-name"&gt;EndSection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-565797434846199554?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/565797434846199554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=565797434846199554' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/565797434846199554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/565797434846199554'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2008/12/eeepc-touchscreen-and-evtouch.html' title='eeepc, touchscreen and evtouch'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-5623514385078835459</id><published>2008-10-31T07:02:00.000-07:00</published><updated>2008-11-08T12:48:03.195-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Common Lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='lisp macros'/><category scheme='http://www.blogger.com/atom/ns#' term='macros'/><title type='text'>Macros.</title><content type='html'>Macros - grasped. Kind of.&lt;br /&gt;When you're dealing with lisp, sooner or later, you're going to hear about macros, and how utterly, astoundingly fantastic they are.&lt;br /&gt;&lt;b&gt;Macros are for:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Creating new operators and saving you a gang of time by "extending the language"&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Um, that's all I can think of. There is probably a lot more to it than that, but if you're in desperate need of a starting point, that would probably be quite a goody.&lt;br /&gt;&lt;br /&gt;Of course, when you're a total monkey like me, you very quickly pick up on the &lt;i&gt;emotional&lt;/i&gt; content of any &lt;a href="http://paulgraham.com/diff.html"&gt;essays&lt;/a&gt;,&lt;a href="http://smuglispweeny.blogspot.com/2008/02/macro-ro-ro-your-code-gently-down-page.html"&gt;blogs&lt;/a&gt; or &lt;a href="http://gigamonkeys.com/book/"&gt;books&lt;/a&gt;, but the logic escapes you for a bit.&lt;br /&gt;&lt;br /&gt;Even when you think you've wrapped your brain around the issue, you still have this nagging feeling that you're not getting something vital.&lt;br /&gt;&lt;br /&gt;A few things fell nicely into place when I was reading about anaphoric macros. I think they should be used to introduce the idea of lisp macros, rather than being interesting items you only get to see after a while...&lt;br /&gt;&lt;br /&gt;So let's look at AIF. AIF is the anaphoric version of if. Anaphoric meaning something like "referring to itself". You can define and test it like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defmacro&lt;/span&gt; &lt;span class="function-name"&gt;aif&lt;/span&gt; (test-form then-form &lt;span class="type"&gt;&amp;amp;optional&lt;/span&gt; else-form)&lt;br /&gt; `(&lt;span class="keyword"&gt;let&lt;/span&gt; ((it ,test-form))&lt;br /&gt;    (&lt;span class="keyword"&gt;if&lt;/span&gt; it ,then-form ,else-form)))&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defun&lt;/span&gt; &lt;span class="function-name"&gt;big-long-calculation&lt;/span&gt; ()&lt;br /&gt; t)&lt;br /&gt;&lt;br /&gt;(aif (big-long-calculation)&lt;br /&gt;    (format t &lt;span class="string"&gt;"hello"&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;;running the above will give you "hello" in the repl. &lt;br /&gt;;changing big-long-calculation to return nil will result&lt;br /&gt;;in the aif test doing nothing.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Which allows you to avoid this:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;let&lt;/span&gt; ((result (big-long-calculation)))&lt;br /&gt; (&lt;span class="keyword"&gt;if&lt;/span&gt; result&lt;br /&gt;     (foo result)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;... and use this instead:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(aif (big-long-calculation)&lt;br /&gt;    (foo it))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;(all this stuff stolen from Paul Graham's &lt;a href="http://paulgraham.com/books.html"&gt;"On Lisp"&lt;/a&gt; - fantastic book that I've not finished reading, because it's too advanced, or I'm too much of a monkey)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;... so you've "extended" the language by adding a new operator, as elemental as, say, "+" or "format" (I think).&lt;br /&gt;&lt;br /&gt;Which is pretty powerful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-5623514385078835459?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/5623514385078835459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=5623514385078835459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/5623514385078835459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/5623514385078835459'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2008/10/first-useful-macro-and-its-in-emacs.html' title='Macros.'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-1972079898642037896</id><published>2008-09-20T14:33:00.000-07:00</published><updated>2008-09-24T01:23:28.944-07:00</updated><title type='text'>Emacs Modes - some notes</title><content type='html'>I've been playing with creating a couple of useful functions in Emacs, and started thinking about packaging a couple of them into some sort of useful grouping.&lt;br /&gt;&lt;br /&gt;So I'd need to define either Major, derived or minor modes.&lt;br /&gt;&lt;br /&gt;Deciding which was pretty much half of the hassle. Eventually, I ended up going with a half-baked combination of the three, believe it or not. My little bit of usefulness is only handy for people connecting to Microsoft SQLServer databases, wanting to trawl through stored procs, looking for tables, trying to figure out how everything interconnects. Maybe the stuff will be ready for release someday, but I found some stuff pretty interesting.&lt;br /&gt;&lt;br /&gt;In the meantime, I couldn't find templates for creating modes, so I wrote some.&lt;br /&gt;&lt;br /&gt;Go visit the link below for the Elisp code:&lt;br /&gt;modes-atomic.el at:&lt;br /&gt;&lt;a href="http://ryan-white-lisp.googlecode.com/files/modes-atomic.el"&gt;http://ryan-white-lisp.googlecode.com/files/modes-atomic.el&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Some interesting links to look up:&lt;br /&gt;&lt;a href="http://sachachua.com/"&gt;http://sachachua.com&lt;/a&gt;  - Sacha is an Emacs nut/guru&lt;br /&gt;&lt;a href="http://www.gnu.org/software/emacs/manual/elisp.html"&gt;http://www.gnu.org/software/emacs/manual/elisp.html&lt;/a&gt; The really dense, not too easy to understand, but still good Elisp manual&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-1972079898642037896?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/1972079898642037896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=1972079898642037896' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/1972079898642037896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/1972079898642037896'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2008/09/emacs-modes-some-notes.html' title='Emacs Modes - some notes'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-2524554317620949412</id><published>2008-09-09T13:08:00.000-07:00</published><updated>2009-08-10T12:23:59.785-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Common Lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='Lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='Lisp Example'/><title type='text'>Lisp conditions - atomic example</title><content type='html'>Lisp allows you to use restarts - magical stuff that allows your app to recover from errors, instead of vomiting everything at you.&lt;br /&gt;&lt;br /&gt;Lisp gives you options. Hopefully. One day, I might even be able to use them somewhat.&lt;br /&gt;&lt;br /&gt;Here's my grossly simplified, probably wrong internal model of conditions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Something goes wrong&lt;/li&gt;&lt;li&gt;A continuation is created, or maybe several are. Conditions are mystical "pause" buttons in the app, or something.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The debugger appears, offering you the options&lt;/li&gt;&lt;li&gt;When you pick one, lisp magicaly re-injects you where the condition was created.&lt;/li&gt;&lt;li&gt;Things hopefully work a bit better.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Pretty sure this will be totally embarrasing in future.&lt;br /&gt;&lt;br /&gt;Any way. From what I can gather, the CL condition system is implemented in terms of objects, and a 'condition' is a parent of an 'error'. 'Conditions' allow for signalling of diferent states within your app, but that's quite a fancy-pants subject, for when I know what the heck I'm doing. Typically, you'd define your error condition like this:&lt;br /&gt;&lt;br /&gt;(define-condition slave-not-happy (error) ... other code ...)&lt;br /&gt;&lt;br /&gt;So you're basically creating your little error as a sub-class of error, which is a subclass of condition.&lt;br /&gt;&lt;br /&gt;In your code, you can then enable all sorts of mystical getting-out-of-jail stuff like this:&lt;br /&gt;&lt;br /&gt;... other code ... (restart-case (error 'slave-not-happy :useable-key-name useable-key-value&lt;br /&gt;(this-option ... some code)&lt;br /&gt;(that-option ... some other code))&lt;br /&gt;&lt;br /&gt;...So when you have a problem, and lisp kicks into the debugger, you'll have something like&lt;br /&gt;..blah blah blah - THERE'S A PROBLEM:&lt;br /&gt;0 - this-option&lt;br /&gt;1 - that-option&lt;br /&gt;2 - abort&lt;br /&gt;3 - maybe  some more options&lt;br /&gt;&lt;br /&gt;Your stuff appears RIGHT THERE with the system's restarts, and you feel all powerful and stuff. So, basically, you're giving yourself more options for getting out of trouble.&lt;br /&gt;&lt;br /&gt;Deciding what to do with the signalled conditions is up to you, but you can start getting really fancy-cool stuff done:&lt;br /&gt;&lt;br /&gt;...code&lt;br /&gt;(handler-bind ((slave-not-happy #'(lambda (c) (invoke-restart 'this-option)))&lt;br /&gt;... other code&lt;br /&gt;&lt;br /&gt;Of course, you can conditionally decide which restart to invoke, based on some other internal logic. Really spiffy.&lt;br /&gt;&lt;br /&gt;here's a complete, working example you can put in a file and play around with:&lt;br /&gt;Also available at&lt;a href="http://code.google.com/p/ryan-white-lisp/downloads/list"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://ryan-white-lisp.googlecode.com/files/conditions-atomic.lisp"&gt;http://ryan-white-lisp.googlecode.com/files/conditions-atomic.lisp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Update:&lt;/div&gt;&lt;div&gt;Nikodemus Siivola (major contributor to SBCL) posted a style guide on conditions and errors:&lt;/div&gt;&lt;div&gt;&lt;a href="http://random-state.net/log/3453016738.html"&gt;http://random-state.net/log/3453016738.html&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: -webkit-sans-serif; "&gt;"Learn the difference between &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_handle.htm" style="color: maroon; "&gt;&lt;tt&gt;HANDLER-BIND&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_hand_1.htm" style="color: maroon; "&gt;&lt;tt&gt;HANDLER-CASE&lt;/tt&gt;&lt;/a&gt;. Short version: &lt;tt&gt;HANDLER-CASE&lt;/tt&gt; always unwinds, with &lt;tt&gt;HANDLER-BIND&lt;/tt&gt; you can eg. log the condition without handling it, or decide whether to unwind or not after inspecting the condition in more detail."&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Fantastic resources:&lt;a href="http://www.nhplace.com/kent/Papers/Condition-Handling-2001.html"&gt;&lt;br /&gt;http://www.nhplace.com/kent/Papers/Condition-Handling-2001.html&lt;/a&gt; (Kent Pitman)&lt;br /&gt;&lt;a href="http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html"&gt;http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html&lt;/a&gt; (Peter Siebel)&lt;br /&gt;enjoy.&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="comment"&gt;#|&lt;br /&gt;Copyright (c) 2008 Ryan White&lt;br /&gt;&lt;br /&gt;Permission is hereby granted, free of charge, to any person&lt;br /&gt;obtaining a copy of this software and associated documentation&lt;br /&gt;files (the "Software"), to deal in the Software without&lt;br /&gt;restriction, including without limitation the rights to use,&lt;br /&gt;copy, modify, merge, publish, distribute, sublicense, and/or sell&lt;br /&gt;copies of the Software, and to permit persons to whom the&lt;br /&gt;Software is furnished to do so, subject to the following&lt;br /&gt;conditions:&lt;br /&gt;&lt;br /&gt;The above copyright notice and this permission notice shall be&lt;br /&gt;included in all copies or substantial portions of the Software.&lt;br /&gt;&lt;br /&gt;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,&lt;br /&gt;EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES&lt;br /&gt;OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND&lt;br /&gt;NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT&lt;br /&gt;HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,&lt;br /&gt;WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING&lt;br /&gt;FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR&lt;br /&gt;OTHER DEALINGS IN THE SOFTWARE.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CONDITIONS - quick and dirty intro/reminder&lt;br /&gt;Originally set up on&lt;br /&gt;&lt;br /&gt;Fire up lisp and enter&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;load "path-to-this-file")&lt;br /&gt;You should then be able to call&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;slave 10)&lt;br /&gt;which will return 10&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;slave "foo")&lt;br /&gt;which will give you a set of restarts.&lt;br /&gt;Calling&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;master '(1 2 3 "foo"))&lt;br /&gt;will return just (1 2 3)&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;master '(1 2 3 "foo") :on-error "change" :chage-value 111)&lt;br /&gt;will return (1 2 3 111)&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;emperor '(1 2 3 "foo"))&lt;br /&gt;will return (1 2 3)&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;careless-master '(1 2 3 "foo"))&lt;br /&gt;will give a set of restarts&lt;br /&gt;&lt;/span&gt;&lt;span class="warning"&gt;(&lt;/span&gt;&lt;span class="comment"&gt;micromanaging-emperor '(1 2 3 "foo"))&lt;br /&gt;will return (1 2 3 1000000)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;Extend.Document.Publish.&lt;br /&gt;|#&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#|&lt;br /&gt;Define a condition - an indicator that something isn't&lt;br /&gt;totally and fantastically 100% right&lt;br /&gt;|#&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;define-condition&lt;/span&gt; &lt;span class="function-name"&gt;slave-not-happy&lt;/span&gt; (&lt;span class="warning"&gt;error&lt;/span&gt;)&lt;br /&gt;((given-value &lt;span class="builtin"&gt;:initarg&lt;/span&gt; &lt;span class="builtin"&gt;:given-value&lt;/span&gt; &lt;span class="builtin"&gt;:reader&lt;/span&gt; given-value-read))&lt;br /&gt;(&lt;span class="builtin"&gt;:report&lt;/span&gt; (&lt;span class="keyword"&gt;lambda&lt;/span&gt; (condition stream)&lt;br /&gt;   (format stream &lt;span class="string"&gt;"~A is not a number, dammit!"&lt;/span&gt; (given-value-read condition)))))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#|&lt;br /&gt;This is the function at the bottom of the chain of events.&lt;br /&gt;When its unhappy, it uses the condition to let everyone know&lt;br /&gt;|#&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defun&lt;/span&gt; &lt;span class="function-name"&gt;slave&lt;/span&gt; (item)&lt;br /&gt;(&lt;span class="keyword"&gt;if&lt;/span&gt; (numberp item)  &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;the test&lt;br /&gt;&lt;/span&gt;      item   &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;if everything's good, just return the number&lt;br /&gt;&lt;/span&gt;      (&lt;span class="keyword"&gt;restart-case&lt;/span&gt; (&lt;span class="warning"&gt;error&lt;/span&gt; 'slave-not-happy &lt;span class="builtin"&gt;:given-value&lt;/span&gt; item) &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;or start this whole error handling trip&lt;br /&gt;&lt;/span&gt; (use-nil () &lt;span class="builtin"&gt;:report&lt;/span&gt; &lt;span class="string"&gt;"Use nil value."&lt;/span&gt; nil)&lt;br /&gt;(replace-item (new-value) &lt;span class="builtin"&gt;:report&lt;/span&gt; &lt;span class="string"&gt;"Replace the value"&lt;/span&gt; new-value)&lt;br /&gt;(replace-item-interactively (new-value)&lt;br /&gt;&lt;span class="builtin"&gt;:report&lt;/span&gt; &lt;span class="string"&gt;"Provide a value yourself."&lt;/span&gt;&lt;br /&gt;&lt;span class="builtin"&gt;:interactive&lt;/span&gt; (&lt;span class="keyword"&gt;lambda&lt;/span&gt; ()&lt;br /&gt; (format t &lt;span class="string"&gt;"~&amp;amp;Value to use: "&lt;/span&gt;)&lt;br /&gt; (list (eval (read))))&lt;br /&gt;(slave new-value))))) &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;finally - a potentially recursive call...&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment"&gt;#|&lt;br /&gt;This is a function up the chain of events. It handles the error spit out&lt;br /&gt;|#&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defun&lt;/span&gt; &lt;span class="function-name"&gt;master&lt;/span&gt; (mylist &lt;span class="type"&gt;&amp;amp;key&lt;/span&gt; (on-error &lt;span class="string"&gt;"ignore"&lt;/span&gt;) (change-value 0))&lt;br /&gt;(&lt;span class="keyword"&gt;handler-bind&lt;/span&gt; ((slave-not-happy &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;figuring out what to do with the slave-not-happy error&lt;br /&gt;&lt;/span&gt;    (&lt;span class="keyword"&gt;if&lt;/span&gt; (equal  on-error &lt;span class="string"&gt;"change"&lt;/span&gt;)&lt;br /&gt;     #'(&lt;span class="keyword"&gt;lambda&lt;/span&gt; (c) (invoke-restart 'replace-item change-value)) &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;we either do a substitution&lt;br /&gt;&lt;/span&gt;        #'(&lt;span class="keyword"&gt;lambda&lt;/span&gt; (c) (invoke-restart 'use-nil)) &lt;span class="comment-delimiter"&gt;; &lt;/span&gt;&lt;span class="comment"&gt;or we use nil&lt;br /&gt;&lt;/span&gt;        )))&lt;br /&gt; (&lt;span class="keyword"&gt;let&lt;/span&gt; ((output '()) (tst &lt;span class="string"&gt;""&lt;/span&gt;))&lt;br /&gt;   (&lt;span class="keyword"&gt;loop&lt;/span&gt; for item in mylist do&lt;br /&gt; (setf tst (slave item))&lt;br /&gt; (&lt;span class="keyword"&gt;if&lt;/span&gt; (eq nil tst)&lt;br /&gt;     ()&lt;br /&gt;     (push tst output)))&lt;br /&gt;   (reverse output))))&lt;br /&gt;&lt;span class="comment"&gt;#|&lt;br /&gt;This function just orders stuff done, and doesn't want to know&lt;br /&gt;about the details&lt;br /&gt;|#&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defun&lt;/span&gt; &lt;span class="function-name"&gt;emperor&lt;/span&gt; (list)&lt;br /&gt;(master list))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#|&lt;br /&gt;This version of master doesn't worry about errors at all.&lt;br /&gt;Basically, it just doesn't cater for the error&lt;br /&gt;|#&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defun&lt;/span&gt; &lt;span class="function-name"&gt;careless-master&lt;/span&gt; (mylist &lt;span class="type"&gt;&amp;amp;key&lt;/span&gt;)&lt;br /&gt;(&lt;span class="keyword"&gt;let&lt;/span&gt; ((output '()) (tst nil))&lt;br /&gt; (&lt;span class="keyword"&gt;loop&lt;/span&gt; for item in mylist do&lt;br /&gt;(setf tst (slave item))&lt;br /&gt;(&lt;span class="keyword"&gt;if&lt;/span&gt; (eq nil tst)&lt;br /&gt;   ()&lt;br /&gt;   (push tst output)))&lt;br /&gt; (reverse output)))&lt;br /&gt;&lt;span class="comment"&gt;#|&lt;br /&gt;If the emperor wishes, he can do the managing of&lt;br /&gt;the unhappy slave. In a typically self-serving manner&lt;br /&gt;|#&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defun&lt;/span&gt; &lt;span class="function-name"&gt;micromanaging-emperor&lt;/span&gt; (list)&lt;br /&gt;(&lt;span class="keyword"&gt;handler-bind&lt;/span&gt;&lt;br /&gt;   ((slave-not-happy #'(&lt;span class="keyword"&gt;lambda&lt;/span&gt; (c) (invoke-restart 'replace-item 1000000))))&lt;br /&gt; (careless-master list)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-2524554317620949412?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/2524554317620949412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=2524554317620949412' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/2524554317620949412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/2524554317620949412'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2008/09/lisp-conditions-atomic-example.html' title='Lisp conditions - atomic example'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7913334388303599270.post-3438754574742474828</id><published>2008-09-09T12:58:00.000-07:00</published><updated>2011-11-11T02:13:50.793-08:00</updated><title type='text'>Why, what, how</title><content type='html'>(("Place to store snippets")(emacs common-lisp miscellanea) (short-descriptions-and-examples))&lt;br /&gt;&lt;br /&gt;------ Random testing here ------&lt;br /&gt;&lt;a href="https://docs.google.com/document/d/1dmhher5C61Tjj1gmobnYikUeBamEN0-5x7PrVFJ1K7Y/edit"&gt;click here to view a shared document online&lt;/a&gt;&lt;br /&gt;&lt;a href="mailto:ryan@gloo.co.za?subject=Please%20send%20me%20the%20test%20doc"&gt;click here to request the shared document via email&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.linkedin.com/profile/view?id=6433964" target="_blank"&gt;click here to visit a linkedin profile&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7913334388303599270-3438754574742474828?l=ryan-white.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-white.blogspot.com/feeds/3438754574742474828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7913334388303599270&amp;postID=3438754574742474828' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/3438754574742474828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7913334388303599270/posts/default/3438754574742474828'/><link rel='alternate' type='text/html' href='http://ryan-white.blogspot.com/2008/09/why-what-how.html' title='Why, what, how'/><author><name>R. James White</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
