David Christiansen: David Christiansenurn:http-www-davidchristiansen-dk:-blog-index-html2014-12-03T05:00:00ZFilling out source locations in Idrisurn:http-www-davidchristiansen-dk:-2014-12-03-filling-out-source-locations-in-idris2014-12-03T05:00:00Z2014-12-03T05:00:00ZDavid Christiansen<html>
<p>The mainline branch of Idris now has support for source location reflection. This means that Idris code can be informed about which line and column of which file it occurs on. In this post, I&#8217;ll walk you through how this can be used for implementing programmer tools, such as a facility similar to Haskell&#8217;s <span class="stt">error</span> function. Then, I&#8217;ll briefly discuss how the feature is implemented and the implications for referential transparency and claims of purity.</p>
<p>Note that I&#8217;m not claiming any major innovation here &#8211; this blog post exists only to explain a feature that I took from <a href="http://lampwww.epfl.ch/~amin/pub/hosc2013.pdf">scala-virtualized</a> and implemented in Idris.</p>
<!--more-->
<h1><a name="(part._.Terminating_with_an_error)"></a>Terminating with an error</h1>
<p>The <span class="stt">error</span> function stops execution immediately, printing a user-supplied message. Because it will never return, it should inhabit every type, but it should most assuredly <span style="font-style: italic">not</span> pass the totality checker.</p>
<p>It is straightforward to implement <span class="stt">error</span> using Idris&#8217;s unsafe features. The C FFI can be used to call <span class="stt">exit</span>, terminating the program, and <span class="stt">unsafePerformIO</span> allows us to call arbitrary C functions in a pure context. The built-in primitive <span class="stt">believe_me</span> enables us to subvert the type checker. Combining these ingredients yields:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">||| Terminate the program after printing a user-specified error message.</span></p></td></tr>
<tr>
<td>
<p><span class="stt">|||</span></p></td></tr>
<tr>
<td>
<p><span class="stt">||| @ message The error to print</span></p></td></tr>
<tr>
<td>
<p><span class="stt">partial</span></p></td></tr>
<tr>
<td>
<p><span class="stt">error : (message : String) -&gt; a</span></p></td></tr>
<tr>
<td>
<p><span class="stt">error message =</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">believe_me . unsafePerformIO $</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">do putStrLn message</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">exit 1</span></p></td></tr></tbody></table>
<p>If this function is ever called, it means that something has gone wrong, and we have a bug in our program. However, the error itself may not be particularly helpful: there may be insufficient clues to determine why it occurred. Knowing where it occurred in the source code can make it much easier to debug the problem. Let&#8217;s extend <span class="stt">error</span> to display its call site along with the message.</p>
<h1><a name="(part._.Source_.Locations_for_.Dynamic_.Errors)"></a>Source Locations for Dynamic Errors</h1>
<p>Broadly speaking, Idris functions accept two kinds of arguments: <span style="font-style: italic">explicit</span> arguments, which the user directly provides, and <span style="font-style: italic">implicit</span> arguments, which the compiler is expected to work out for itself in most situations. An explicit argument can be provided implicitly by writing and underscore in its position, and an implicit argument can be provided explicitly by writing it in curly braces.</p>
<p>Implicit arguments are normally solved by <span style="font-style: italic">unification</span>. In other words, something else in the program will typically cause there to be precisely one possible value that would still type check, so the compiler is able to fill it out. When defining a function, you can specify an alternative way to fill out the implicit argument, such as by providing a default value or invoking the proof search system. Additionally, the default value need not be literal Idris code: it can also be a tactic script to be executed during <span style="font-style: italic">elaboration</span>, which is what we call the process of translating the high level Idris code that users write into the highly tedious, fully explicit core language that the compiler then proceeds to optimize and send off to the individual backends. Typical tactics include things like <span class="stt">refine</span>, which applies a name to the goal, generating subgoals as necessary for its arguments, and <span class="stt">try</span>, which attempts one tactic and falls back to another if the first fails.</p>
<p></p>
<div class="SIntrapara">As of a few days ago, Idris supports a new tactic called <span class="stt">sourceLocation</span> that fills out the argument using the source location at which it was invoked. This tactic can be used to improve the messages from <span class="stt">error</span>. Source locations are provided using the type <span class="stt">Language.Reflection.SourceLocation</span>, which is defined as follows:
</div>
<div class="SIntrapara">
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">data SourceLocation : Type where</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">FileLoc : String -&gt; (Int, Int) -&gt; (Int, Int) -&gt; SourceLocation</span></p></td></tr></tbody></table></div>
<p>The first argument to the constructor is the source file name, and the second and third are the line and column at the beginning and end of the relevant expression. Because not all of the parser has been updated to save source spans, the second and third arguments are often identical for now, but this will eventually be fixed.</p>
<p>To improve the messages provided by <span class="stt">error</span>, we need to arrange for the <span class="stt">sourceLocation</span> tactic to be used to fill out an implicit source context argument. Then, we can destructure this implicit argument using ordinary pattern matching to recover the filename, line number, and column number to report. The updated <span class="stt">error</span> function (which is in the Idris library in the <span class="stt">Debug.Error</span> package) is:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">||| Terminate the program after printing a user-specified error message.</span></p></td></tr>
<tr>
<td>
<p><span class="stt">|||</span></p></td></tr>
<tr>
<td>
<p><span class="stt">||| @ loc</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">The source location to display for the error</span></p></td></tr>
<tr>
<td>
<p><span class="stt">||| @ message The error to print</span></p></td></tr>
<tr>
<td>
<p><span class="stt">partial</span></p></td></tr>
<tr>
<td>
<p><span class="stt">error : {default tactics {sourceLocation} loc : SourceLocation} -&gt;</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(message : String) -&gt;</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">a</span></p></td></tr>
<tr>
<td>
<p><span class="stt">error {loc = FileLoc filename (line, col) _} message =</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">believe_me . unsafePerformIO $</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">do let place = filename ++ " line " ++ show line ++ " column " ++ show col</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">let message' = place ++ ": " ++ message</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">putStrLn message'</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">exit 1</span></p></td></tr></tbody></table>
<p>The same basic technique can also be used to report source locations for errors in deeply embedded langauges that aren&#8217;t easily encoded in the type system. Note that higher-level features, such as an assertions system built on top of <span class="stt">error</span>, can provide <span class="stt">loc</span> explicitly, enabling them to override the displayed source code location with their own. This straightforwardly allows a fine-grained control over the level at which errors should be displayed.</p>
<h1><a name="(part._.Implementation)"></a>Implementation</h1>
<p>Idris&#8217;s expression elaborator is a recursive traversal of the expression. Elaboration occurs within a monad that resembles a tactic-based interactive theorem prover, with a present goal and list of assumptions, a stack of remaining goals to be solved, and tactics that manipulate this state. Smaller tatics can be composed to create larger tactics. For details, check out <a href="http://eb.host.cs.st-andrews.ac.uk/drafts/impldtp.pdf">Edwin&#8217;s JFP paper from last year</a>.</p>
<p>The high-level Idris AST already contains source code information, which is used to report static error messages such as unification errors. To implement <span class="stt">sourceLocation</span>, the already-existing source locations are simply used to generate Idris-level source locations. Because not every term resulting from the parser contains a source location, the closest containing location is passed recursively in the elaborator.</p>
<h1><a name="(part._.Purity)"></a>Purity</h1>
<p>Does this change mean that Idris is no longer a pure language? After all, the following function will return a different value depending on where it is called:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">getLocation : {default tactics {sourceLocation} loc : SourceLocation} -&gt; SourceLocation</span></p></td></tr>
<tr>
<td>
<p><span class="stt">getLocation {loc} = loc</span></p></td></tr></tbody></table>
<p>Even mere changes to whitespace could cause a program that uses <span class="stt">getLoc</span> to compute a radically different value!</p>
<p>However, this does not affect the purity of the uderlying core language. From the perspective of the core, when you move a call to <span class="stt">getLoc</span> to a new location, the term itself changes, and the constant value of <span class="stt">loc</span> is simply changed. While this feature could most assuredly be abused, it is surely no worse than type class resolution or proof search when it comes to purity.</p>
<p>If you find a creative use for the <span class="stt">sourceLocation</span> tactic or if you use it in a serious manner, please let me know! I&#8217;d love to hear how it works for real-world users.</p></html>A Pretty-Printer That Says What it Meansurn:http-www-davidchristiansen-dk:-2014-09-06-a-pretty-printer-that-says-what-it-means2014-09-06T04:00:00Z2014-09-06T04:00:00ZDavid Christiansen<html>
<p>Idris supports <span style="font-style: italic">semantic</span> highlighting of compiler output. In this post, I&#8217;ll sketch what the feature brings users, why it&#8217;s interesting, what inspired it, and how it&#8217;s implemented in the Idris compiler. Rather than spending a bunch of time describing a series of screenshots, here&#8217;s <a href="http://www.youtube.com/watch?v=B5PRPzWZJ60">a quick video of it in action</a>, inside of <a href="https://github.com/idris-hackers/idris-mode">idris-mode</a> for Emacs:</p>
<!--more-->
<p>
<iframe class="youtube-player" frameborder="0" height="390" src="//www.youtube-nocookie.com/embed/B5PRPzWZJ60" title="YouTube video player" type="text/html" width="480"></iframe></p>
<p>Note that all the interesting features there are implemented in the Idris compiler (specifically, the pretty-printer), and that Emacs does very little work to use these features. They are available for any editor, and partially at the command line REPL, in a manner that can be incrementally implemented to get more and more features.</p>
<p>I showed Simon Peyton Jones a quick demo at the Haskell Implementors&#8217; Workshop in Gothenburg today, and he encouraged me to write it up, thinking that there might be more general interest. So here we go!</p>
<h1><a name="(part._.Context)"></a>Context</h1>
<p>The Idris compiler and REPL have two output modes: one intended for direct human interaction in a terminal, and one intended for integration into external tools. When in console mode, Idris emits ANSI codes in its output stream that place semantically relevant font information into the interpreter output. However, we&#8217;re limited by what terminals support. When working with more expressive output contexts, we can present much more than just fonts.</p>
<p>Output intended for other programs, when Idris is running in IDE mode, consists of S-expressions that represent the semantics of the output. Sometimes, the entire sense of the message can be a machine readable message, but other times annotated strings are sent. Examples of the first include a notification that a file was successfully type checked and a signal indicating that the user has completed a tactic proof, and examples of the second include error messages and REPL output. In this post, I&#8217;ll mostly focus on how annotated strings are generated, as it&#8217;s the most fun part. I&#8217;m focusing on the underlying ideas here, so I&#8217;m glossing over some details and type signatures may not match the real ones in the Idris code base.</p>
<p>Having colors in the output from the Idris interpreter was originally inspired by a demonstration of Julia at OPLSS 2013, by <a href="http://blog.leahhanson.us/">Leah Hanson</a>. I was really impressed by how the colored output from the REPL was helpful in understanding the results and distinguishing between program output and expression values. I was also feeling envious of Agda&#8217;s nice semantic coloring in Emacs buffers.</p>
<h1><a name="(part._.The_.Pretty-.Printer)"></a>The Pretty-Printer</h1>
<p>All output from the Idris compiler is generated by the Idris pretty-printer. In this pretty-printer, we need to do two things: (1) generate strings from compiler data structures, and (2) maintain the link between regions of these strings and semantically interesting information about them. For example, the compiler needs to know that the &#8220;Nat&#8221; in &#8220;Z : Nat&#8221; is a type constructor and that &#8220;Z&#8221; is a data constructor, and furthermore that both really occur in the namespace &#8220;Prelude.Nat&#8221;, but are being displayed in a truncated form. That way, the full disambiguated name can be used to do things like looking up documentation.</p>
<p>It is not possible, however, to maintain the link between regions of text and semantic annotations during pretty-printing, because the whole reason we have a pretty-printer is to free us from the burden of performing specific text formatting. The pretty-printing library combinators generate an abstract type <span class="stt">Doc</span>, which can later be rendered to specific output contexts, such as terminals of different widths.</p>
<p>The approach taken in Idris to bridge this gap is to replace the type <span class="stt">Doc</span> with a type constructor <span class="stt">Doc a</span>, where the type <span class="stt">a</span> represents the type of the semantic annotations in the document. Then, a single additional combinator <span class="stt">annotate :: a -&gt; Doc a -&gt; Doc a</span> can be used to attach elements of the semantic annotation type to the document.</p>
<p>The Idris pretty-printer is based on <a href="http://hackage.haskell.org/package/wl-pprint">wl-pprint</a>, and its available as a mostly-API-compatible library on Hackage called <a href="http://hackage.haskell.org/package/annotated-wl-pprint">annotated-wl-pprint</a>. Please refer to the original library documentation or to Phil Wadler&#8217;s paper "A Prettier Printer" for the basics of the approach. Rendering, in <span class="stt">wl-pprint</span>, converts a <span class="stt">Doc</span> to a <span class="stt">SimpleDoc</span>, which is specialized to a particular output width. Then, various functions are available to convert a <span class="stt">SimpleDoc</span> to a <span class="stt">String</span> and to write it to an output strea in <span class="stt">IO</span>. In <span class="stt">annotated-wl-pprint</span>, both <span class="stt">Doc</span> and <span class="stt">SimpleDoc</span> are parameterized over annotations, and additional <span class="stt">String</span>-rendering functions are available that can use the semantic information.</p>
<p>The original rendering functions are still available in <span class="stt">annotated-wl-pprint</span>: they merely discard the annotations. However, two new rendering functions are available. The first, called <span class="stt">displayDecorated</span>, take a decorator function with type <span class="stt">a -&gt; String -&gt; String</span> as an argument, and uses this to rewrite each substring as it is generated. This function is used in Idris to generated console output. The second, called <span class="stt">displaySpans</span>, generates a pair consisting of the ordinary string representation as well as a list of text spans and their corresponding annotations. This is used in Idris to generate machine-readable IDE output.</p>
<h1><a name="(part._.Doc_and_.Simple.Doc_are_.Functors)"></a>Doc and SimpleDoc are Functors</h1>
<p>The constructors of <span class="stt">Doc a</span> and <span class="stt">SimpleDoc a</span> are not exported, as they must maintain some invariants that the combinator language ensures. However, they have instances of <span class="stt">Functor</span>, which means that post-processing and rendering of user representations of the semantic annotations is just an <span class="stt">fmap</span> away. This is very useful in Idris, and I would like to thank <a href="http://www.flippac.org/">Philippa Cowderoy</a> for pointing out to me on IRC that pretty-printer documents are in fact functors.</p>
<p>For example, when the pretty-printer encounters a global name in a term, it simply saves its fully-qualified form in an annotation. Later, we can add the additional information (such as documentation summaries and type signatures) that is sent to IDEs. This enables the pretty-printer to be independent of the global definition context in Idris, enabling greater modularity. Additionally, the type system can be used to ensure that various processing steps have been carried out, although this could use some refactoring in Idris at the moment.</p>
<p>This structure enables a clean separation between the pretty-printing of textual output and the processing of semantic information. Additionally, the technique is also useful when displaying documentation, where parsed Markdown formatting information is inserted in the strings to be displayed, and to associate source locations in error messages with a declarative specification of the full filename and line and column numbers.</p>
<h1><a name="(part._.Active_.Terms_in_.Idris)"></a>Active Terms in Idris</h1>
<p>In the demo that I linked to at the top of this post, you can see editor commands to show the implicit arguments to already-printed terms and to normalize them on demand. This is implemented by annotating subterms in the output record with a serialized representation of their corresponding term in Idris&#8217;s core language, as well as some information about the names available in their scope. These terms are then attached as a semantic annotation. When these annotations are rendered for IDE clients, they are base64-encoded.</p>
<p>Idris&#8217;s IDE protocol has commands that can manipulate these encoded terms, pretty-printing them with various options, potentially after normalization. Naturally, these commands annotate their output with a serialized representation of the resulting term, allowing them to be used again.</p>
<h1><a name="(part._.Remaining)"></a>Remaining</h1>
<p>The current implementation of <span class="stt">annotated-wl-pprint</span> is lacking one important rendering function, which would allow actions in a monad to delimit output strings. This would enable the display of semantic colors on terminals in Windows, which don&#8217;t support ANSI color codes. Additionally, I&#8217;m quite sure that I can attach more information that would be useful.</p>
<p>Do you have any nifty ideas for <span class="stt">idris-mode</span>? Are you working on Idris support from another editor? Is there something in the above that should be done a better way? Do you need help using <span class="stt">annotated-wl-pprint</span> in your own project? Please don&#8217;t hesitate to get in touch!</p>
<p><span class="Larger"><span style="font-weight: bold">Update, 26 January, 2015</span></span></p>
<p>Trevor Elliott has implemented annotation support for the <a href="https://github.com/haskell/pretty">pretty</a> library, which has a Hughes-PJ-style interface, so if your project uses that API, you can more easily begin to use semantic annotations. See <a href="https://github.com/haskell/pretty/pull/19">pull request #19</a> for the gory details.</p>
<h1><a name="(part._.Comments)"></a>Comments</h1>
<p>
<article class="comment-body">
<footer class="comment-meta">
<div class="comment-author">
<div class="gravatar" style="width: 64px; height: 64px; background: url(http://www.gravatar.com/avatar/9f57a0b8bcfd77585fa2fd171455054e?d=identicon&amp;s=64);"></div>
<div class="comment-metadata"><span class="fn">carlos</span>
<time datetime="2014-09-07T22:32:00Z">2014-09-07 22:32</time></div></div></footer>
<div class="comment-content">Last time I needed coloured output from a Haskell program I defined some simple readable colour codes that were used throughout the code, something like "Text in !1red!7 and !4blue". Then I added a final step that output the text using System.Console.ANSI so it worked on both Windows and Linux without complicating the structure of your code.</div></article></p>
<p>
<article class="comment-body">
<footer class="comment-meta">
<div class="comment-author">
<div class="gravatar" style="width: 64px; height: 64px; background: url(http://www.gravatar.com/avatar/c7da8df7d8cb6a6d1b9ad052a20eb54d?d=identicon&amp;s=64);"></div>
<div class="comment-metadata"><span class="fn">Simon Peyton Jones</span>
<time datetime="2014-09-09T12:27:00Z">2014-09-09 12:27</time></div></div></footer>
<div class="comment-content">This is a very neat idea. I hope that someone implements something like it for GHC.
<br />
<br />
Simon</div></article></p></html>New paper submission: "Type-Directed Elaboration of Quasiquotations: A High-Level Syntax for Low-Level Reflection"urn:http-www-davidchristiansen-dk:-2014-08-20-new-paper-submission-type-directed-elaboration-of-quasiquotations-a-high-level-syntax-for-low-level-reflection2014-08-20T04:00:00Z2014-08-20T04:00:00ZDavid Christiansen<html>
<p>I just finished a submission to <a href="http://ifl2014.github.io/">IFL 2014</a>. It&#8217;s a paper about Idris&rsquo;s quasiquotations mechanism, which allow the use of high-level Idris syntax to describe low-level reflected terms, with the ability to escape from quotation in chosen areas and intentionally control the details of the representation. This is very much inspired by Lisp quasiquotation.</p>
<!--more-->
<p>You can find the paper on <a href="http://www.itu.dk/people/drc">my academic page</a>. Because of the IFL submission process, I have ample time to make changes, so if I&#8217;ve made a mistake or failed to explain something clearly, I&#8217;d love to hear about it!</p></html>New Podcast on Type Theoryurn:http-www-davidchristiansen-dk:-2014-08-13-new-podcast-on-type-theory2014-08-13T04:00:00Z2014-08-13T04:00:00ZDavid Christiansen<html>
<p>I&#8217;m a cohost of a new pocast on type theory, <a href="http://typetheorypodcast.com/">The Type Theory Podcast</a>. We just posted our first episode: <a href="http://typetheorypodcast.com/2014/08/episode-1-peter-dybjer-on-type-theory-and-testing/">an interview with Peter Dybjer</a> on types and testing.</p></html>Implementing an Emacs programming language mode: beyond the basicsurn:http-www-davidchristiansen-dk:-2014-07-16-implementing-an-emacs-programming-language-mode-beyond-the-basics2014-07-16T04:00:00Z2014-07-16T04:00:00ZDavid Christiansen<html>
<p>As one of the two primary authors of <a href="https://www.github.com/idris-hackers/idris-mode">idris-mode</a>, I&#8217;ve had to learn a fair bit about implementing Emacs modes. While I&#8217;m far from an expert on the subject, I do think that I&#8217;ve picked up a few ideas that are useful. There are already a number of good tutorials about the very basics, such as <span class="stt">define-derived-mode</span>, <span class="stt">font-lock</span>, and Emacs packages. What I haven&#8217;t been able to find is an answer to the question &#8220;what&#8217;s next?&#8221;. You can view this post as a kind of checklist for useful things to add to your mode.</p>
<p>I won&#8217;t go into great detail about how to do all of these things, because the documentation is typically quite good. The real problem is learning that there is documentation to be read!</p>
<!--more-->
<h1><a name="(part._.Imenu)"></a>Imenu</h1>
<p>While many Emacs users turn off the menu bar entirely, making Imenu not particularly attractive, it pays to support it anyway. This is because lots of other features in Emacs use Imenu as a data source. For example, speedbar will use it to show an index of your file and <span class="stt">which-func-mode</span> uses it to determine what to show in your mode line.</p>
<h1><a name="(part._.Completion)"></a>Completion</h1>
<p>These days, it is very straightforward to implement completion for your mode. Many older modes contain complicated code to show completion buffers, restoring window configurations afterwards. In Emacs 24, we have <span class="stt">completion-at-point</span>. Simply ensure that this is bound to something (often <span class="stt">M-TAB</span>), and then arrange for it to have enough information to present good completions</p>
<p>The variable <span class="stt">completion-at-point-functions</span> provides the raw data that completion-at-point will use to construct a completions buffer. The variable contains a list of 0-argument functions, each of which should return either nil or a collection of completion candidates. Emacs takes care of all the tedious organization of buffers. In <span class="stt">idris-mode</span>, we simply delegate to the compiler to provide completion candidates.</p>
<h1><a name="(part._.Eldoc)"></a>Eldoc</h1>
<p>Eldoc is a minor mode for showing documentation strings in the echo area. By default, it supports Emacs Lisp, but it&#8217;s quite straightfoward to make it work for your language. All you need is a function that returns either a docstring for the symbol at point or nil. In the case of Idris, we already had a command to ask the compiler for a type signature, so it was especially easy. Once you have this function, just set <span class="stt">eldoc-documentation-function</span> to its name and place <span class="stt">turn-on-eldoc-mode</span> in your default mode hook.</p>
<p></p>
<div class="SIntrapara">Here&#8217;s the function from idris-mode:
</div>
<div class="SIntrapara">
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">(defun idris-eldoc-lookup ()</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Support for showing type signatures in the modeline when there's a running Idris"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(let ((signature (ignore-errors (idris-eval (list :type-of (idris-name-at-point))))))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(when signature</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(with-temp-buffer</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(idris-propertize-spans (idris-repl-semantic-text-props (cdr signature))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(insert (car signature)))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(buffer-string)))))</span></p></td></tr></tbody></table></div>
<div class="SIntrapara">All of the <span class="stt">idris-propertize-spans</span> stuff is to apply font information from the compiler.</div>
<h1><a name="(part._.Flycheck)"></a>Flycheck</h1>
<p>Flycheck is a minor mode that runs quick external programs on the contents of your buffer, annotating the buffer with any warnings produced, without you needing to save the buffer. It is fairly straightforward to define a checker for Flycheck, and it can be added to your mode without disturbing users who don&#8217;t use Flycheck by wrapping it up in an <span class="stt">eval-after-load</span>. Here is the entire checker from <span class="stt">idris-mode</span>, written by Brian McKenna:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">;;;###autoload</span></p></td></tr>
<tr>
<td>
<p><span class="stt">(eval-after-load 'flycheck</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">'(progn</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(flycheck-define-checker idris</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">"An Idris syntax and type checker."</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">:command ("idris" "--check" "--nocolor" "--warnpartial" source)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">:error-patterns</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">((warning line-start (file-name) ":" line ":" column ":Warning - "</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(message (and (* nonl) (* "\n" (not (any "/" "~")) (* nonl)))))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(error line-start (file-name) ":" line ":" column ":"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(message (and (* nonl) (* "\n" (not (any "/" "~")) (* nonl))))))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">:modes idris-mode)</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"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(add-to-list 'flycheck-checkers 'idris)))</span></p></td></tr></tbody></table>
<h1><a name="(part._.Customize)"></a>Customize</h1>
<p>In my opinion, it&#8217;s important to have variables that control settings for a mode be separate from other variables, so that users can see what they&#8217;re intended to change and what they are not. A good way to indicate that a variable is intended for user customization is to make it available through customize. When thinking about how to customize features of your mode, consider how to organize them into groups so that they are easy to find.</p>
<p>If you define your mode as a derive mode (and you should), remember to pass the <span class="stt">:group</span> option to <span class="stt">define-derived-mode</span>. This makes the standard command <span class="stt">customize-mode</span> work.</p>
<p>Additionally, your mode should really avoid using built-in faces. Instead, define your own faces with <span class="stt">defface</span> and set them to inherit from the built-in faces that you were thinking of using. This lets your users decide how they want to see your mode. Good defaults are also important, to the extent that you can have them, so pay attention to built-in faces that you can inherit from, which will make your mode automatically conform to the user&#8217;s color theme. Perhaps the biggest source of complaints about <span class="stt">idris-mode</span> has come from default colors that don&#8217;t look good for users, where I was unable to find a built-in face to inherit from that makes sense. Surprisingly many Emacs users don&#8217;t know that they can easily customize a face.</p>
<h1><a name="(part._.Prog_mode)"></a>Prog mode</h1>
<p>Remember to derive your mode from <span class="stt">prog-mode</span>. If you don&#8217;t do that, at least make sure that you call <span class="stt">prog-mode-hook</span>. This allows Emacs users to set things up for every programming language mode, while not using these settings in other places. This is useful for things like showing trailing whitespace or turning on line numbering.</p>
<h1><a name="(part._.Common_.Lisp_features)"></a>Common Lisp features</h1>
<p>If you have experience writing Common Lisp code, you&#8217;re in for a disappointment when you write Emacs Lisp. There are many, many useful features, such as <span class="stt">destructuring-bind</span>, that Emacs Lisp just doesn&#8217;t support. Furthermore, when these features are available, you either have to use a compile-time-only macro package (<span class="stt">cl</span>) or an ugly prefixed version (<span class="stt">cl-lib</span>). I recommend the latter, as you avoid having to worry about which features are macros and which are functions. Unfortunately, you will probably end up with <span class="stt">cl</span> loaded by something in your initialization file, so Emacs will probably not complain if you accidentally use <span class="stt">cl</span> names instead of cl-lib names, which can lead to problems for your users. Consider using <span class="stt">cl-lib-highlight</span> to get warnings in your Lisp buffers when you use un-prefixed <span class="stt">cl</span> symbols.</p>
<h1><a name="(part._.All_the_rest)"></a>All the rest</h1>
<p>After you&#8217;ve got these things done, then it&#8217;s time to start attacking all the little things, like getting the parsing working for motion commands such as forward-sexp, implementing fill-paragraph for comments and docstrings, and so forth. I haven&#8217;t done all these things yet, but I&#8217;ll write it up if I find a nice strategy.</p>
<p>
<article class="comment-body">
<footer class="comment-meta">
<div class="comment-author">
<div class="gravatar" style="width: 64px; height: 64px; background: url(http://www.gravatar.com/avatar/da4b6e45576718c12386b1636497e3d0?d=identicon&amp;s=64);"></div>
<div class="comment-metadata"><span class="fn">David Christiansen</span>
<time datetime="2015-03-06T10:25:00Z">2015-03-06 10:25</time></div></div></footer>
<div class="comment-content">
There are some useful comments about this post in <a href="http://www.reddit.com/r/emacs/comments/2frtfr/implementing_an_emacs_programming_language_mode/">a Reddit discussion</a>.
<br />
<br />
First off, the candidates returned from a member of <span class="stt">completion-at-point-functions</span> need to have some additional information about string locations and can have some properties &#8211; make sure to read the documentation!
<br />
<br />
Also, <span class="stt">pcase-let</span> is a reasonable substitute for <span class="stt">destructuring-bind</span>.
<br />
<br />
Finally, make sure to have a test infrastructure set up that byte-compiles your mode in a clean Emacs. This will help catch <span class="stt">cl</span> errors along with all kinds of other issues. Additionally, use <span class="stt">flycheck-mode</span> while writing your package to catch more errors at that time.
</div></article></p></html>Techniques for using decision procedures in Idrisurn:http-www-davidchristiansen-dk:-2014-05-21-techniques-for-using-decision-procedures-in-idris2014-05-21T04:00:00Z2014-05-21T04:00:00ZDavid Christiansen<html><!--more-->
<p>This post is a literate Idris file, so first let&#8217;s get some bureaucracy out of the way:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">module LT</span></p></td></tr>
<tr>
<td>
<p><span class="stt">%default total</span></p></td></tr></tbody></table>
<p>When writing Idris code, we sometimes need a proof as an argument to a function. In many cases, these proofs can be constructed automatically by a decision procedure. Here, I&#8217;m using the term "decision procedure" for some property <span class="stt">p</span> to refer to a function that returns something in the type <span class="stt">Dec p</span>.</p>
<p>An instance of <span class="stt">Dec p</span> is either a proof of <span class="stt">p</span> or a proof that <span class="stt">p</span> is an absurdity. The datatype is defined as follows:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">data Dec : Type -&gt; Type where</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">Yes : p -&gt; Dec p</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">No : (p -&gt; _|_) -&gt; Dec p</span></p></td></tr></tbody></table>
<p>As an example, take the following type from the Idris library that represents a proof that one natural number is less than or equal to another:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">data LTE : Nat -&gt; Nat -&gt; Type where</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">lteZero : LTE 0 m</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">lteSucc : LTE n m -&gt; LTE (S n) (S m)</span></p></td></tr></tbody></table>
<p>The first constructor, <span class="stt">lteZero</span>, should be interpreted as an assertion that zero is less than or equal to any natural number. The second, <span class="stt">lteSucc</span>, is an assertion that if n&#8804;m, then n+1 &#8804; m+1. It happens to be the case that, for any two natural numbers, it is decidable whether the first is less than or equal to the second.</p>
<p>To prove this, we start with two simple lemmas. The first states that it is not the case that the successor of any number is less than or equal to zero:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">notLTESZ : LTE (S k) Z -&gt; _|_</span></p></td></tr>
<tr>
<td>
<p><span class="stt">notLTESZ lteZero impossible</span></p></td></tr></tbody></table>
<p>Additionally, we show that, if k&#8816;j, then k+1 &#8816; j+1:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">notLTE_S_S : (LTE k j -&gt; _|_) -&gt; LTE (S k) (S j) -&gt; _|_</span></p></td></tr>
<tr>
<td>
<p><span class="stt">notLTE_S_S nope (lteSucc x) = nope x</span></p></td></tr></tbody></table>
<p>We are now in a position to write the decision procedure, by examining each case and using our lemmas to produce the appropriate contents for the <span class="stt">No</span> constructor. If the details don&#8217;t make sense, then please fire up Idris, replace some right-hand sides with metavariables, and examine the proof context.</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">decLTE : (n,m : Nat) -&gt; Dec (n `LTE` m)</span></p></td></tr>
<tr>
<td>
<p><span class="stt">decLTE Z m = Yes lteZero</span></p></td></tr>
<tr>
<td>
<p><span class="stt">decLTE (S k) Z = No notLTESZ</span></p></td></tr>
<tr>
<td>
<p><span class="stt">decLTE (S k) (S j) with (decLTE k j)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">decLTE (S k) (S j) | (Yes prf) = Yes (lteSucc prf)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">decLTE (S k) (S j) | (No contra) = No $ notLTE_S_S contra</span></p></td></tr></tbody></table>
<p>Now that these details are out of the way, we can get to the main point of this blog post: demonstrating various techniques for getting Idris to fill out these proofs for us.</p>
<p>The most straightforward way is to use the interactive editing features to get Idris to construct the proof term directly. For example, if we want to show that 3 &#8804; 5, then we need only create a definition with type <span class="stt">3 </span><span class="stt">&lsquo;</span><span class="stt">LTE</span><span class="stt">&lsquo;</span><span class="stt"> 5</span>:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">ok : 3 `LTE` 5</span></p></td></tr></tbody></table>
<p>We can then use <span class="stt">C-c C-s</span> in <span class="stt">idris-mode</span> to cause it to become</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">ok : 3 `LTE` 5</span></p></td></tr>
<tr>
<td>
<p><span class="stt">ok = ?ok_rhs</span></p></td></tr></tbody></table>
<p>Using the proof search command <span class="stt">C-c C-a</span> on the metavariable gives us</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">ok : 3 `LTE` 5</span></p></td></tr>
<tr>
<td>
<p><span class="stt">ok = lteSucc (lteSucc (lteSucc lteZero))</span></p></td></tr></tbody></table>
<p>and the decision procedure simply isn&#8217;t necessary. This approach can make our programs ugly, but it is straightforward and direct. We need not actually show the resulting term, however. In Idris, tactic scripts are allowed as the right-hand side of definitions. So we can simply invoke the search tactic explicitly, rather than using it through the compiler&#8217;s editor interface, and the resulting term does not need to occur in the source file. This can also be more robust in the face of changes to the definition of <span class="stt">LTE</span>. The tactic-based definition is:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">okTactic : 3 `LTE` 5</span></p></td></tr>
<tr>
<td>
<p><span class="stt">okTactic = proof search</span></p></td></tr></tbody></table>
<p>Here, <span class="stt">proof</span> begins a tactic script, and search is the tactic to be invoked.</p>
<p></p>
<div class="SIntrapara">Using Idris&#8217;s built-in proof search has two major limitations:
</div>
<div class="SIntrapara">
<ol>
<li>
<p>It cannot solve more "interesting" goals, in which a simple recursive application of constructors is insufficient</p></li>
<li>
<p>It fails to find large goals, as the recursion depth is limited. For example, it cannot solve 103 &lsquo;LTE&lsquo; 105.</p></li></ol></div>
<div class="SIntrapara">What we really want to do is use <span class="stt">decLTE</span> to find the term.</div>
<p>One non-solution is to have the right-hand side of the definition perform a case analysis on the result of a call to <span class="stt">decLTE</span>, and then return the contents of the <span class="stt">Yes</span> case. Because we know that three is, in fact, less than five, we will never need the <span class="stt">No</span> case:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">okCase : 3 `LTE` 5</span></p></td></tr>
<tr>
<td>
<p><span class="stt">okCase = case decLTE 3 5 of</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">Yes prf =&gt; prf</span></p></td></tr></tbody></table>
<p>Unfortunately, the Idris compiler needs to be convinced of the fact that <span class="stt">No</span> cannot occur. We do this by showing that the <span class="stt">No</span> case could cause the empty type to be inhabited, and then use FalseElim. Unfortunately, doing this requires actually proving the property again:</p>
<p></p>
<div class="SIntrapara">
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">okCase : 3 `LTE` 5</span></p></td></tr>
<tr>
<td>
<p><span class="stt">okCase = case decLTE 3 5 of</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">Yes prf =&gt; prf</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">No nope =&gt; FalseElim . nope $ lteSucc (lteSucc (lteSucc lteZero))</span></p></td></tr></tbody></table></div>
<div class="SIntrapara">So this method is a non-starter.</div>
<p>The next method is to cause the solver for implicit arguments to execute the decision procedure while filling out an implicit argument for the proof, and then return this implicit argument. The definition <span class="stt">okImplicit</span> demonstrates this technique:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">okImplicit : 103 `LTE` 105</span></p></td></tr>
<tr>
<td>
<p><span class="stt">okImplicit</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">= getProof</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">where getProof : {prf : LTE 103 105} -&gt; {auto yep : decLTE 103 105 = Yes prf} -&gt; 103 `LTE` 105</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">getProof {prf} = prf</span></p></td></tr></tbody></table>
<p>All of the work happens in <span class="stt">getProof</span>, which is in a where block to keep the type signature of <span class="stt">okImplicit</span> clean. In the definition of <span class="stt">getProof</span>, the implicit argument <span class="stt">prf</span> is the one that will be filled out with the proof, and then returned. The argument <span class="stt">yep</span> is an implicit proof that the result of executing the decision procedure will be <span class="stt">Yes prf</span> &#8211; in other words, that it will succeed, and the thing it succeeds with will unify with <span class="stt">prf</span>. The <span class="stt">auto</span> keyword causes Idris to fill out the argument with <span class="stt">refl</span>, the constructor of proofs of equality.</p>
<p>While the <span class="stt">okImplici</span>t technique leads to noisy boilerplate in type signatures, it also tends to cause error messages that are easy to understand. I&#8217;ve had a lot of luck using it for embedded DSLs with some kind of side condition (like "these queries must have disjoint schemas").</p>
<p>The final technique that I&#8217;d like to demonstrate uses a dependently-typed extractor of proofs from Dec. The type of the function <span class="stt">getYes</span> does case-analysis on the result of a decision procedure. If the result was <span class="stt">Yes</span>, then <span class="stt">getYes</span> will return the contents &#8211; an instance of <span class="stt">p</span>. Otherwise, it returns unit, which contains no interesting information. Note that the result of the case expression is a type &#8212; either the type parameter to <span class="stt">Dec</span> or the unit type.</p>
<p>getYes : (res : Dec p) -&gt; case res of { Yes _ =&gt; p ; No _ =&gt; () }</p>
<p>The body of <span class="stt">getYes</span> performs a case analysis on the result of the decision, either returning a proof or a trivial value, in accordance with the type. Note that Idris&#8217;s interactive editing features were able to write this code entirely &#8211; the only thing I needed to do was tell it to case split on the argument. Agda, which has more advanced interactive editing features, could probably write the entire body by passing Agsy the -c option, which enables case splitting.</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">getYes (Yes prf) = prf</span></p></td></tr>
<tr>
<td>
<p><span class="stt">getYes (No contra) = ()</span></p></td></tr></tbody></table>
<p>Now, <span class="stt">getYes</span> can be used on the right-hand side of our definition to extract the proof:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">okYes :</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">3 `LTE` 5</span></p></td></tr>
<tr>
<td>
<p><span class="stt">okYes = getYes (decLTE 3 5)</span></p></td></tr></tbody></table>
<p>While this approach is clean, the error messages can be somewhat unpleasant if Idris is asked to prove a falsehood. The following code:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">oops :</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">5 `LTE` 3</span></p></td></tr>
<tr>
<td>
<p><span class="stt">oops = getYes (decLTE 5 3)</span></p></td></tr></tbody></table>
<p>results in this unification error:</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">When elaborating right hand side of oops:</span></p></td></tr>
<tr>
<td>
<p><span class="stt">Can't unify</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">case block in getYes (LTE (fromInteger 5) (fromInteger 3)) (decLTE (fromInteger 5) (fromInteger 3)) (decLTE (fromInteger 5) (fromInteger 3))</span></p></td></tr>
<tr>
<td>
<p><span class="stt">with</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">LTE 5 3</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">Specifically:</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">Can't unify</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">case block in getYes (LTE (fromInteger 5) (fromInteger 3)) (decLTE (fromInteger 5) (fromInteger 3)) (decLTE (fromInteger 5) (fromInteger 3))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">with</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">LTE 5 3</span></p></td></tr></tbody></table>
<p>whereas the error message from</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">badImplicit : 105 `LTE` 103</span></p></td></tr>
<tr>
<td>
<p><span class="stt">badImplicit</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">= getProof</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">where getProof : {prf : LTE 105 103} -&gt; {auto yep : decLTE 105 104 = Yes prf} -&gt; 105 `LTE` 103</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">getProof {prf} = prf</span></p></td></tr></tbody></table>
<p>was</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">When elaborating right hand side of badImplicit:</span></p></td></tr>
<tr>
<td>
<p><span class="stt">When elaborating argument yep to LT.badImplicit, getProof:</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">Can't solve goal</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">decLTE (fromInteger 105) (fromInteger 104) = Yes prf</span></p></td></tr></tbody></table>
<p>You have now seen a few ways of getting Idris to find proofs. Hopefully, you&#8217;ve also gotten a bit more understanding of how Idris works while compiling your source file.</p>
<p>This post sprang out of a discussion on a Github issue with Nicola Botta. The discussion of error messages is improved as the result of a suggestion from Anthony Cowley. Thanks, Nicola and Anthony!</p></html>New tutorial on bidirectional typing rulesurn:http-www-davidchristiansen-dk:-2013-10-16-new-tutorial-on-bidirectional-typing-rules2013-10-16T04:00:00Z2013-10-16T04:00:00ZDavid Christiansen<html>
<p>I&#8217;ve just written a new tutorial on bidirectional typing rules. It&#8217;s available from <a href="/tutorials">my tutorials page</a>. The PDF can also be <a href="/tutorials/bidirectional.pdf">downloaded directly</a>.</p></html>Tutorials on my ITU pageurn:http-www-davidchristiansen-dk:-2012-12-20-tutorials-on-my-itu-page2012-12-20T05:00:00Z2012-12-20T05:00:00ZDavid Christiansen<html>
<p>In case you&#8217;re interested in programming languages and you&#8217;re working from Peter Sestoft&#8217;s book <a href="http://www.itu.dk/people/sestoft/plc/">Programming Language Concepts</a>, I&#8217;ve just posted some supplementary materials to my ITU page. It consists of a tutorial for converting from regular expressions to discrete finite automata via NFAs and a tutorial on constructing typing derivations in the particular miniature ML-like language used in the book.</p>
<p>You can find them on my <a href="/tutorials">tutorials</a> page.</p></html>Using Scala libraries with new compiler versionsurn:http-www-davidchristiansen-dk:-2012-01-24-using-scala-libraries-with-new-compiler-versions2012-01-24T05:00:00Z2012-01-24T05:00:00ZDavid Christiansen<html>
<p>I recently needed to use Scalacheck with a milestone release of the compiler, and it took me a little while to wrap my head around the infrastructure. To preserve the steps for prosperity, I&#8217;m documenting them here, as I couldn&#8217;t find it described anywhere.</p>
<p></p>
<div class="SIntrapara">The first step is to understand the relationship between the various parts:
</div>
<div class="SIntrapara">
<ul>
<li>
<p>SBT is responsible for compiling your project, running tests, and generally performing the same role as make or ant. It also uses Ivy for retrieving library dependencies.</p></li>
<li>
<p>Apache Ivy provides an infrastructure for dependency management. Libraries exist in repositories, similar to Debian package repositories, and they are available in multiple versions.</p></li></ul></div>
<p>When you add library dependencies in your project&#8217;s SBT configuration, it will find the code by first looking in your local Ivy repository, then in any remote repositories that are configured. In other words, even if you don&#8217;t have access to the remote repositories, you can still put libraries in your local repository to be found by SBT.</p>
<p>Libraries such as Scalacheck that are intended to be used with multiple versions of Scala will typically use the <span class="stt">crossScalaVersions</span> setting to build against multiple compiler versions. The workflow to get a library working is, then:</p>
<ol>
<li>
<p>Get ahold of the source code to the library</p></li>
<li>
<p>In <span class="stt">build.sbt</span>, find the <span class="stt">crossScalaVersions</span> setting. Add the desired version of Scala.</p></li>
<li>
<p>Run <span class="stt">sbt</span>. At the command line, type <span class="stt">+ test</span>. This will compile the project for each configured version of Scala and run the tests.</p></li>
<li>
<p>Assuming the project passes, run <span class="stt">+ publish-local</span> to push the compiled version</p></li></ol>
<p>Now, the library will be available in your other projects.</p></html>Make Ensime work with newer versions of SBTurn:http-www-davidchristiansen-dk:-2011-12-20-make-ensime-work-with-newer-versions-of-sbt2011-12-20T05:00:00Z2011-12-20T05:00:00ZDavid Christiansen<html>
<p>If you try to use <a href="https://github.com/aemoncannon/ensime">Ensime</a> with newer versions of <a href="https://github.com/harrah/xsbt">SBT</a>, you&#8217;ll find that SBT grows to fill available memory and then crashes. This is because the latest released version of Ensime assumes the project format of an old version of SBT. To fix this, just add the following to your .emacs after you require Ensime:</p>
<!--more-->
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">(defun ensime-sbt-project-dir-p (path)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Does a build.sbt or a project/build.properties exists in the given path."</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(or (file-exists-p (concat path "/build.sbt"))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(file-exists-p (concat path "/project/build.properties"))))</span></p></td></tr></tbody></table>
<p>The problem occurs because Ensime looks for your project directory by recursively going to parent directories until it sees something that looks like an SBT project. Eventually, it ends up in root, and SBT crashes while trying to recursively enumerate all the files in the current directory. Redefining this function to also look for newer project formats fixes the issue.</p></html>Emacs code for fetching a bibliography in BibTeX form from CiteULikeurn:http-www-davidchristiansen-dk:-2011-12-12-emacs-code-for-fetching-a-bibliography-in-bibtex-form-from-citeulike2011-12-12T05:00:00Z2011-12-12T05:00:00ZDavid Christiansen<html>
<p>I typically manage my references with CiteULike. My typical workflow is to add the articles that I&#8217;m interested in, and then while writing, keep a complete copy of the exported BibTeX next to the LaTeX files. This gets tedious to maintain by hand, so I wrote this little chunk of elisp to download the file and name it the way I do.</p>
<!--more-->
<p>To use, simply place it in a file called <span class="stt">citeulike.el</span> on your <span class="stt">load-path</span> and add <span class="stt">(require &#8216;citeulike)</span> to your <span class="stt">.emacs</span>. Make sure to look at the customization options. Then, run <span class="stt">M-x citeulike-download-bibtex</span> in your LaTeX buffer.</p>
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">;;;; citeulike.el --- Getting things from CiteULike while working in AUCTeX</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;; Copyright (C) 2011 David Christiansen</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;; Author: David Christiansen</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; This program is free software: you can redistribute it and/or</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; modify it under the terms of the GNU General Public License as</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; published by the Free Software Foundation; either version 3 of the</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; License, or (at your option) any later version.</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; This program is distributed in the hope that it will be useful,</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; but WITHOUT ANY WARRANTY; without even the implied warranty of</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">See the GNU</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; General Public License for more details.</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; You should have received a copy of the GNU General Public License</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; along with GNU Emacs; see the file COPYING.</span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">If not, write to the</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; Boston, MA 02111-1307, USA.</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;; Commentary:</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; Purpose:</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;; To make downloading an updated copy of references from CiteULike easier.</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;</span></p></td></tr>
<tr>
<td>
<p><span class="stt">;;; Code:</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">(provide 'citeulike)</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">(defgroup citeulike nil</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Options for CiteULike support"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:prefix 'citeulike)</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">(defcustom citeulike-username ""</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"CiteULike username, used for downloading BibTeX exports."</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:type 'string</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:group 'citeulike)</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">(defcustom citeulike-export-username-prefix nil</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Whether to add a username prefix to keys"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:type '(choice (const :tag "Yes" t)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "No" nil))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:group 'citeulike)</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">(defcustom citeulike-export-key-type 0</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"What kind of keys to put in the exported BibTeX"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:type '(choice (const :tag "Prefer personal key; otherwise use numeric key" 0)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "Prefer personal key; otherwise use AuthorYearTitle key" 4)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "Prefer numeric keys" 1)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "Only export articles with a personal key" 2)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "Export both keys" 3))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:group 'citeulike)</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">(defcustom citeulike-export-include-amazon-link nil</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Include Amazon links for books in exported BibTeX"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:type '(choice (const :tag "Yes" t)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "No" nil))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:group 'citeulike)</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">(defcustom citeulike-export-clean-urls t</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Escape URLs for BibTeX?"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:type '(choice (const :tag "Escaped URLs" t)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "Don't escape URLs" nil))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:group 'citeulike)</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">(defcustom citeulike-export-smart-wrap 0</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Work around BibTeX capitalization"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:type '(choice (const :tag "Don't wrap" 0)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "Smart wrap whole field" 1)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(const :tag "Smart wrap individual words" 2))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">:group 'citeulike)</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">(defun citeulike-export-url ()</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(concat "http://www.citeulike.org/bibtex/user/"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">citeulike-username "?"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">"do_username_prefix=" (if citeulike-export-username-prefix "1" "0") "&amp;"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">"key_type=" (number-to-string citeulike-export-key-type) "&amp;"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">"incl_amazon=" (if citeulike-export-include-amazon-link "1" "0") "&amp;"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">"clean-urls=" (if citeulike-export-clean-urls "1" "0") "&amp;"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">"smart_wrap=" (number-to-string citeulike-export-smart-wrap)))</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">(defun citeulike-download-bibtex ()</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(interactive)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(let* ((extension (file-name-extension buffer-file-name))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(rest (file-name-sans-extension buffer-file-name))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(target (if (equal extension "tex")</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(concat rest ".bib")</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(read-file-name "Filename to save: "))))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(if (or (equal citeulike-username "") (not (stringp citeulike-username)))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(error "No valid CiteULike username is configured")</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(let* ((command (concat "wget \"" (citeulike-export-url) "\""</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">" -O " target))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(final-command (read-string "Command: " command)))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(shell-command final-command)))))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr></tbody></table></html>Loading the current buffer in F#urn:http-www-davidchristiansen-dk:-2011-11-11-loading-the-current-buffer-in-f2011-11-11T05:00:00Z2011-11-11T05:00:00ZDavid Christiansen<html>
<p>My primary editor for use with F# is Emacs. One feature that I missed in F# mode was the ability to load the file corresponding to the current buffer. Here&#8217;s some elisp to do it. Put this in your <span class="stt">.emacs</span> file, and then when you are editing an F# module you can load it at the toplevel by pressing <span class="stt">C-c C-f</span>.</p>
<!--more-->
<p></p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><span class="stt">(defun fsharp-load-buffer-file ()</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">"Load the filename corresponding to the present buffer in F# with #load"</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(interactive)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(require 'inf-fsharp)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">(let* ((name buffer-file-name)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(command (concat "#load \"" name "\"")))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(when (buffer-modified-p)</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(when (y-or-n-p (concat "Do you want to save \"" name "\" before loading it? "))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(save-buffer)))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(save-excursion (fsharp-run-process-if-needed))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(save-excursion (fsharp-simple-send inferior-fsharp-buffer-name command))))</span></p></td></tr>
<tr>
<td>
<p><span class="stt">(add-hook 'fsharp-mode-hook</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(lambda ()</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(define-key fsharp-mode-map "\C-c\C-f" 'fsharp-load-buffer-file)))</span></p></td></tr>
<tr>
<td>
<p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr></tbody></table></html>