<?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-5652096800386218209</id><updated>2012-02-17T03:13:54.644Z</updated><category term='parallelism'/><category term='dsl'/><category term='funding'/><category term='flash'/><category term='constraints'/><category term='ypnos'/><category term='type classes'/><category term='compilers'/><category term='haskell'/><category term='languages'/><category term='types'/><title type='text'>The Cambridge Programming Research Group Blog</title><subtitle type='html'>Authored by members of the Cambridge Programming Research Group in the Computer Lab at the University of Cambridge, this blog contains posts related to the research of the CPRG and relevant research from elsewhere.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dominic Orchard</name><uri>http://www.blogger.com/profile/00356502943141121461</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_RIjA3spQtI0/S86fFEGtyfI/AAAAAAAAAAM/Z5SRr63-7kU/S220/n61300853_4317.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5652096800386218209.post-3880349585746013845</id><published>2010-05-03T09:38:00.004+01:00</published><updated>2010-05-03T09:44:59.983+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='types'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='constraints'/><category scheme='http://www.blogger.com/atom/ns#' term='languages'/><title type='text'>Video Talk: Haskell Type Constraints Unleashed</title><content type='html'>Unfortunately, due to the &lt;a href='http://en.wikipedia.org/wiki/Air_travel_disruption_after_the_2010_Eyjafjallaj%C3%B6kull_eruption'&gt;air travel disruption in Europe in April&lt;/a&gt; I was unable to fly to Japan to attend &lt;a href='http://www.kb.ecei.tohoku.ac.jp/flops2010/wiki/'&gt;FLOPS 2010&lt;/a&gt; to present my paper on extensions to Haskell's type constraints system. Fortunately my inability to attend provided  motivation to record a video talk. See below for links to the video and to the paper.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.kb.ecei.tohoku.ac.jp/~sumii/tmp/19434274.m4v"&gt;High quality (470.3MB &lt;sc&gt;&lt;small&gt;MPEG4&lt;/small&gt;&lt;/sc&gt;)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.cl.cam.ac.uk/~dao29/dorchard-flops10-talk-medium.m4v"&gt;Medium quality (277.6MB &lt;sc&gt;&lt;small&gt;MPEG4&lt;/small&gt;&lt;/sc&gt;)&lt;/a&gt;&lt;br /&gt;&lt;small&gt;(If you have any problems playing the video files, I recommend &lt;a href='http://www.videolan.org/vlc/'&gt;VLC&lt;/a&gt; a great, cross-platform media player that plays almost everything.)&lt;/small&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.cl.cam.ac.uk/~dao29/talks/type-constraints-unleashed-flops-2010.pdf"&gt;Presentation Slides&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://vimeo.com/11081622"&gt;Streaming version @ Vimeo&lt;/a&gt;&lt;br /&gt;&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=11081622&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=11081622&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/11081622"&gt;Haskell Type Constraints Unleashed&lt;/a&gt; from &lt;a href="http://vimeo.com/user3635302"&gt;Dominic Orchard&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href='http://www.cl.cam.ac.uk/~dao29/publ/constraint-families.pdf'&gt;Paper&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href='http://www.cs.kuleuven.be/publicaties/rapporten/cw/CW574.abs.html'&gt;Technical Report&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href='http://github.com/dorchard/constraintTermExtensions'&gt;Prototype Implementation&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5652096800386218209-3880349585746013845?l=cprg-research.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/3880349585746013845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cprg-research.blogspot.com/2010/05/video-talk-haskell-type-constraints.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/3880349585746013845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/3880349585746013845'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/2010/05/video-talk-haskell-type-constraints.html' title='Video Talk: Haskell Type Constraints Unleashed'/><author><name>Dominic Orchard</name><uri>http://www.blogger.com/profile/00356502943141121461</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_RIjA3spQtI0/S86fFEGtyfI/AAAAAAAAAAM/Z5SRr63-7kU/S220/n61300853_4317.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5652096800386218209.post-8383981889465409712</id><published>2010-02-09T09:42:00.007Z</published><updated>2010-02-11T10:44:04.000Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><title type='text'>A domain specific language for binary file formats</title><content type='html'>I recently wrote a parser for the &lt;a href="http://en.wikipedia.org/wiki/Adobe_Flash"&gt;Flash&lt;/a&gt; file format &lt;a href="http://www.adobe.com/devnet/swf/"&gt;specification&lt;/a&gt;, in Haskell. I managed to build support for reading and writing all the Flash 10 specification (apart from the embedded multimedia formats, such as h.264 and MP3) in only three days of committed coding.&lt;br /&gt;&lt;br /&gt;How did I implement this 250+ page specification in such a short amount of time? Simple - I took the specification and made it &lt;strong&gt;executable&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;The specification is full of tables describing the on-disk format that look like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Ozi79bjVETI/S3E0G0hhmLI/AAAAAAAAABc/6YxlCiJKDMU/s1600-h/rgb.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 122px;" src="http://4.bp.blogspot.com/_Ozi79bjVETI/S3E0G0hhmLI/AAAAAAAAABc/6YxlCiJKDMU/s320/rgb.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5436183516996016306" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;At first, I began by manually coding up my library from these tables. Unfortunately, each table corresponds to no less than three bits of Haskell:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;A data type definition for the record (called &lt;code&gt;FOCALGRADIENT&lt;/code&gt; in this case)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A function for reading that record from the file (of type &lt;code&gt;SwfGet FOCALGRADIENT&lt;/code&gt;: &lt;code&gt;SwfGet&lt;/code&gt; is a state monad encapsulating a &lt;code&gt;ByteString&lt;/code&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A function for writing that thing back (of type &lt;code&gt;FOCALGRADIENT -&amp;gt; SwfPut ()&lt;/code&gt;, where &lt;code&gt;SwfPut&lt;/code&gt; is another monad)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;It quickly became obvious that writing this code (and keeping the three versions in sync!) was &lt;strong&gt;totally&lt;/strong&gt; untenable.&lt;br /&gt;&lt;br /&gt;My solution was to turn my parser into a Literate Haskell file which can contain sections like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;   p18: RGB color record&lt;br /&gt;   \begin{record}&lt;br /&gt;   RGB&lt;br /&gt;   Field Type Comment&lt;br /&gt;   Red   UI8  Red color value&lt;br /&gt;   Green UI8  Green color value&lt;br /&gt;   Blue  UI8  Blue color value&lt;br /&gt;   \end{record}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I then have a preprocessor which replaces these wholesale with code implementing the data type, reader and writer. For our running example, we get this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;   data RGB = RGB{rGB_red :: UI8, rGB_green :: UI8, rGB_blue :: UI8}&lt;br /&gt;            deriving (Eq, Show, Typeable, Data)&lt;br /&gt;   getRGB&lt;br /&gt;     = do rGB_red &amp;lt;- getUI8&lt;br /&gt;          rGB_green &amp;lt;- getUI8&lt;br /&gt;          rGB_blue &amp;lt;- getUI8&lt;br /&gt;          return (RGB{..})&lt;br /&gt;   putRGB RGB{..}&lt;br /&gt;     = do putUI8 rGB_red&lt;br /&gt;          putUI8 rGB_green&lt;br /&gt;          putUI8 rGB_blue&lt;br /&gt;          return ()&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Choice and Repetition&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Frequently, some part of the record is repeated a number of times that depends on an earlier part of the record. In other cases, the exact shape a field takes can depend on an earlier one. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    p96: ActionConstantPool&lt;br /&gt;    \begin{record}&lt;br /&gt;    ActionConstantPool&lt;br /&gt;    Field              Type               Comment&lt;br /&gt;    ActionConstantPool ACTIONRECORDHEADER ActionCode = 0x88&lt;br /&gt;    Count              UI16               Number of constants to follow&lt;br /&gt;    ConstantPool       STRING[Count]      String constants&lt;br /&gt;    \end{record}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This record contains a field-controlled repetition count. My generator is smart enough to:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Generate a Haskell expression from the repetition count within the square brackets. In this case it is just &lt;code&gt;Count&lt;/code&gt;, but in general this can contain arithmetic and references to several fields.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Omit the &lt;code&gt;Count&lt;/code&gt; field from the generated data type, and infer it from the length of the &lt;code&gt;ConstantPool&lt;/code&gt; when we come to put this record back&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;There is similar support for choice. For example, look at the &lt;code&gt;CodeTable&lt;/code&gt; field in &lt;code&gt;DefineFontInfo&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    p177: DefineFontInfo&lt;br /&gt;    \begin{record}&lt;br /&gt;    DefineFontInfo&lt;br /&gt;    Field              Type                                           Comment&lt;br /&gt;    Header             RECORDHEADER                                   Tag type = 13&lt;br /&gt;    FontID             UI16                                           Font ID this information is for.&lt;br /&gt;    FontNameLen        UI8                                            Length of font name.&lt;br /&gt;    FontName           UI8[FontNameLen]                               Name of the font (see following).&lt;br /&gt;    FontFlagsReserved  UB[2]                                          Reserved bit fields.&lt;br /&gt;    FontFlagsSmallText UB[1]                                          SWF 7 file format or later: Font is small. Character glyphs are aligned on pixel boundaries for dynamic and input text.&lt;br /&gt;    FontFlagsShiftJIS  UB[1]                                          ShiftJIS character codes.&lt;br /&gt;    FontFlagsANSI      UB[1]                                          ANSI character codes.&lt;br /&gt;    FontFlagsItalic    UB[1]                                          Font is italic.&lt;br /&gt;    FontFlagsBold      UB[1]                                          Font is bold.&lt;br /&gt;    FontFlagsWideCodes UB[1]                                          If 1, CodeTable is UI16 array; otherwise, CodeTable is UI8 array.&lt;br /&gt;    CodeTable          If FontFlagsWideCodes, UI16[] Otherwise, UI8[] Glyph to code table, sorted in ascending order.&lt;br /&gt;    \end{record}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The field changes representation based on &lt;code&gt;FontFlagWideCodes&lt;/code&gt; - this is represented in the corresponding Haskell record as an &lt;code&gt;Either&lt;/code&gt; type, and the &lt;code&gt;FontFlagsWideCodes&lt;/code&gt; flag is not put in the record at all, as it can be unambiguously inferred from whether we are &lt;code&gt;Left&lt;/code&gt; or &lt;code&gt;Right&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Bit Fields&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;The fields we saw in &lt;code&gt;DefineFontInfo&lt;/code&gt; with the name &lt;code&gt;UB&lt;/code&gt; were actually bit fields. &lt;code&gt;UB[n]&lt;/code&gt; is actually an unsigned number with &lt;code&gt;n&lt;/code&gt; bits in it. Here is another example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    \begin{record}&lt;br /&gt;    BLURFILTER&lt;br /&gt;    Field    Type  Comment&lt;br /&gt;    BlurX    FIXED Horizontal blur amount&lt;br /&gt;    BlurY    FIXED Vertical blur amount&lt;br /&gt;    Passes   UB[5] Number of blur passes&lt;br /&gt;    Reserved UB[3] Must be 0&lt;br /&gt;    \end{record}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Bit fields pose a problem - how should they be represented in Haskell? If I know the number of bits statically, there might be a suitable type I can choose. For example, my generator will use &lt;code&gt;Bool&lt;/code&gt; for &lt;code&gt;UB[1]&lt;/code&gt; fields. Unfortunately, in general I'll have to choose a Haskell type which is large enough to hold the maximum possible number of bits I might encounter.&lt;br /&gt;&lt;br /&gt;What I have chosen to do is represent any &lt;code&gt;UB[n]&lt;/code&gt; field (where &lt;code&gt;n&lt;/code&gt; is not 1) with a &lt;code&gt;Word32&lt;/code&gt; (32 bits seems to be the upper limit on any variable-length bitfields I've encountered in practice, though this isn't part of the specification). What this means, however, is that my generator must produce runtime assertions in the writing code to ensure that we won't lose any information by truncating the &lt;code&gt;Word32&lt;/code&gt; to the number of bits we actually have available.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Abstraction&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Sometimes, the structure of a record varies depending on the context in which it is used. For example, the &lt;code&gt;GLYPHENTRY&lt;/code&gt; record can only be read and written if we know the number of bits used for its two fields. This is encoded as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    p192: Glyph entry&lt;br /&gt;    \begin{record}&lt;br /&gt;    GLYPHENTRY(GlyphBits, AdvanceBits)&lt;br /&gt;    Field        Type            Comment&lt;br /&gt;    GlyphIndex   UB[GlyphBits]   Glyph index into current font.&lt;br /&gt;    GlyphAdvance SB[AdvanceBits] x advance value for glyph.&lt;br /&gt;    \end{record}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The "parameter list" after &lt;code&gt;GLYPHENTRY&lt;/code&gt; in the header must be filled out with concrete arguments by any user of &lt;code&gt;GLYPHENTRY&lt;/code&gt;, such as in the &lt;code&gt;GlyphEntries&lt;/code&gt; field of the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    \begin{record}&lt;br /&gt;    TEXTRECORD(TextVer, GlyphBits, AdvanceBits)&lt;br /&gt;    Field                Type                                                      Comment&lt;br /&gt;    TextRecordType       UB[1]                                                     Always 1.&lt;br /&gt;    StyleFlagsReserved   UB[3]                                                     Always 0.&lt;br /&gt;    StyleFlagsHasFont    UB[1]                                                     1 if text font specified.&lt;br /&gt;    StyleFlagsHasColor   UB[1]                                                     1 if text color specified.&lt;br /&gt;    StyleFlagsHasYOffset UB[1]                                                     1 if y offset specified.&lt;br /&gt;    StyleFlagsHasXOffset UB[1]                                                     1 if x offset specified.&lt;br /&gt;    FontID               If StyleFlagsHasFont, UI16                                Font ID for following text.&lt;br /&gt;    TextColor            If StyleFlagsHasColor, If TextVer = 2, RGBA Otherwise RGB Font color for following text.&lt;br /&gt;    XOffset              If StyleFlagsHasXOffset, SI16                             x offset for following text.&lt;br /&gt;    YOffset              If StyleFlagsHasYOffset, SI16                             y offset for following text.&lt;br /&gt;    TextHeight           If StyleFlagsHasFont, UI16                                Font height for following text.&lt;br /&gt;    GlyphCount           UI8                                                       Number of glyphs in record.&lt;br /&gt;    GlyphEntries         GLYPHENTRY(GlyphBits, AdvanceBits)[GlyphCount]            Glyph entry (see following).&lt;br /&gt;    Padding              PADDING8                                                  Padding to byte boundary&lt;br /&gt;    \end{record}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Records abstracted over parameters generate Haskell reading and writing code which is lambda-abstracted over those same paramaters, just as you might expect. Likewise, occurrences of argument lists correspond to applications of arguments to a nested reading or writing function.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Having a declarative description of the contents of SWF files helped &lt;strong&gt;enormously&lt;/strong&gt;. It had the following benefits:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Very rapid development. I essentially just pasted in the contents of the specification for each record. This also led to a very low rate of bugs in the code (though I found some specification bugs, I can hardly be blamed for those :-)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Easy post-hoc changes when adding new features.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I only added assertions to check bit fields lengths quite late on in development, and it was a painless generator change. If I had handwritten everything I would have had to do a lot of tedious and error-prone programming to add a small feature like this.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I could make use of the declarative information to generate reasonable error messages for showing to the user when they try to write back an invalid SWF. Again, this is something I decided to do &lt;strong&gt;after&lt;/strong&gt; transcribing the specification.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Very easy to read and spot bugs. Legibility was a goal when designing the DSL.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;It's relatively easy to change to using custom Haskell code for dealing with those records that can't be expressed in the DSL - you can copy and paste the unsatisfactory generated Haskell and then mold it to fit your needs.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Using custom code (as per the last bullet point) is sometimes indispensable for making the Haskell records look nicer. For example, you might need to write it so you can stop generating this sort of record:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    data RECT = RECT { rECT_nbits :: UI8, rECT_xmin :: SB, rECT_xmax :: SB, rECT_ymin :: SB, rECT_ymax :: SB }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And, by observing that you can compute &lt;code&gt;nbits&lt;/code&gt; by the maximum of the base-2 logarithms of the 4 &lt;code&gt;SB&lt;/code&gt; fields, generate this one instead:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    data RECT = RECT { rECT_xmin :: SB, rECT_xmax :: SB, rECT_ymin :: SB, rECT_ymax :: SB } &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The fact that you have to use copy and paste to get this done is something which I'm not totally happy with. I've been looking at approaches to turn my DSL into &lt;br /&gt;much more of a combinator library (i.e. taking the focus away from using an external code generator).&lt;br /&gt;&lt;br /&gt;A combinator based approach would make it easy to add extra primitive combinators that know about special cases like one - but more on that another time!&lt;br /&gt;&lt;br /&gt;Interested souls can get the code for my SWF library on &lt;a href="http://github.com/batterseapower/hswf/tree/master/Data/SWF/"&gt;GitHub&lt;/a&gt;. It can successfully roundtrip all of the example files that I could gather from the &lt;a href="http://www.gnu.org/software/gnash/"&gt;Gnash&lt;/a&gt; and &lt;a href="http://github.com/tobeytailor/gordon"&gt;Flash Gordon&lt;/a&gt; projects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5652096800386218209-8383981889465409712?l=cprg-research.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/8383981889465409712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cprg-research.blogspot.com/2010/02/domain-specific-language-for-binary.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/8383981889465409712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/8383981889465409712'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/2010/02/domain-specific-language-for-binary.html' title='A domain specific language for binary file formats'/><author><name>Max Bolingbroke</name><uri>http://www.blogger.com/profile/05003540528496327090</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Ozi79bjVETI/SeBQmmATNHI/AAAAAAAAAAM/FsCgTGPScAE/s1600-R/de6812ad9760ee68ee10830ffc364b19%3Fs%3D100'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Ozi79bjVETI/S3E0G0hhmLI/AAAAAAAAABc/6YxlCiJKDMU/s72-c/rgb.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5652096800386218209.post-4462369226937857610</id><published>2009-11-23T12:24:00.005Z</published><updated>2010-02-11T10:51:27.226Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ypnos'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='parallelism'/><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><title type='text'>Slides from talk: Ypnos: Declarative, Parallel Structured Grid Programming</title><content type='html'>Slides from this talk, given on Friday 20th November at the CPRG weekly seminar, can be found &lt;a href="http://www.cl.cam.ac.uk/%7Edao29/talks/ypnos-cprg-09.pdf"&gt;here&lt;/a&gt;. The paper accompanying the talk can be found &lt;a href="http://www.cl.cam.ac.uk/%7Edao29/publ/ypnos1.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Talk abstract:&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;A fully automatic, compiler-driven approach to parallelisation can result in unpredictable time and space costs for compiled code. On the other hand, a fully manual approach to parallelisation can be long, tedious, prone to errors, hard to debug, and often architecture-specific. This talk presents a declarative domain-specific language, Ypnos, for expressing structured grid computations which encourages manual specification of causally sequential operations but then allows a simple, predictable, static analysis to generate optimised, parallel implementations. Ypnos is sufficiently restricted such that optimisation and parallelisation is guaranteed.&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5652096800386218209-4462369226937857610?l=cprg-research.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/4462369226937857610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cprg-research.blogspot.com/2009/11/slides-from-talk-ypnos-declarative.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/4462369226937857610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/4462369226937857610'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/2009/11/slides-from-talk-ypnos-declarative.html' title='Slides from talk: Ypnos: Declarative, Parallel Structured Grid Programming'/><author><name>Dominic Orchard</name><uri>http://www.blogger.com/profile/00356502943141121461</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_RIjA3spQtI0/S86fFEGtyfI/AAAAAAAAAAM/Z5SRr63-7kU/S220/n61300853_4317.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5652096800386218209.post-6205232974924498154</id><published>2009-07-31T13:55:00.011+01:00</published><updated>2009-07-31T16:54:52.999+01:00</updated><title type='text'>Message Relays, Parrot Fashion</title><content type='html'>Lately I have been thinking a lot about pirates. Pirates are ubiquitous in programming language design but they've had a bad press. This post hopes to redress the balance a little.&lt;br /&gt;&lt;br /&gt;I was recently chatting to my pirate buddy Elfonso, and he related to me a problem that he'd recently encountered concerning his four crewmates: Albert, Blackbeard, Cuthbert and Dread. The five of them had taken to living on the desert islands shown on the delightful map below. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/__D23IsOHCC4/SnMTY2HZbyI/AAAAAAAAAA0/v62tchqVamU/s1600-h/treasure.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 400px;" src="http://2.bp.blogspot.com/__D23IsOHCC4/SnMTY2HZbyI/AAAAAAAAAA0/v62tchqVamU/s400/treasure.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5364652898692722466" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The pirates like their privacy and each insists on having one island to himself. Following a dispute over some buried treasure, Elfonso only really talks to Dread; the other four all talk to each other, except Dread and Blackbeard who've never really seen eye to eye (they both have patches). Even when chillaxing on their private islands, the pirates like to send messages to each other, and do so by the classic medium of string and tin cans. Due to a shortage of string, the islands are now wired together somewhat haphazardly, as the map shows. The pirates will forward messages for each other if no direct route is available between the two islands, but they'd really rather not. Elfonso's question was, "Where should each pirate live so that they can all send messages to their friends with the minimum amount of forwarding?"&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__D23IsOHCC4/SnMQ7KQONUI/AAAAAAAAAAs/jwX-G2hJPn0/s1600-h/treasure_random.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://4.bp.blogspot.com/__D23IsOHCC4/SnMQ7KQONUI/AAAAAAAAAAs/jwX-G2hJPn0/s320/treasure_random.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5364650189679113538" /&gt;&lt;/a&gt; Let's try a simple arrangement (see left) and see what happens. Let's say Elfonso takes the middle island, and the other four pirates take the four islands that have a direct connection with him. Now when Elfonso and Dread want to exchange messages, they can do it directly; each of the other pairings (Albert with Blackbeard, Cuthbert, and Dread; Dread with Cuthbert and Cuthbert with Blackbeard) will require Elfonso to forward the message. So if each pair of pirates who are on speaking terms exchange one message, that will require five forwards in total. We'll say that this arrangement has a score of 5, remembering of course that a lower score is better. Is it possible to improve on this arrangement?&lt;br /&gt;&lt;br /&gt;There is a simple but very time-consuming way to find the best possible arrangement; we simply try every possible combination of pirates and islands, and work out the score for each one, then take the best of the bunch. This is quite feasible for five pirates and eight islands, but (planning ahead) we'd like a method that works for thousands of islands and hundreds of pirates! Even the fastest computer would take hours to solve a problem that large with this "brute force" method, and pirates are notoriously technophobic in any case. Clearly we need something different.&lt;br /&gt;&lt;br /&gt;One solution is to use a method which will hopefully find a "fairly good" arrangement very quickly. This allows us to trade off the quality of the arrangement with how long we are willing to spend looking for it. This is where I felt the CPRG could maybe help Elfonso out.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__D23IsOHCC4/SnL2kOkyLgI/AAAAAAAAAAc/328HavQcmOM/s1600-h/treasure_reams1.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://3.bp.blogspot.com/__D23IsOHCC4/SnL2kOkyLgI/AAAAAAAAAAc/328HavQcmOM/s320/treasure_reams1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5364621208399785474" /&gt;&lt;/a&gt;&lt;br /&gt;A simple approximate method is to put the pirate with the most friends on the island with the most wires, the second most popular on the second best-connected island, and so on. In this case this leads us to the arrangement on the left. The real weakness in this case is that Dread and Elfonso are at opposite ends of the map, so every message between them will need to be forwarded by Albert and Blackbeard (or Albert and Cuthbert). But overall this isn't too bad; it has a "score" of 6, which is clearly not ideal, but it was quick to work out and in some contexts that would be good enough. &lt;br /&gt;&lt;br /&gt;My current work is in finding a method somewhere between these two; still fast enough to solve examples involving large numbers of pirates and islands, but producing better solutions than the naive method of giving the chattiest pirates the best-connected islands. How can we do this? There are many possible approaches. One of the weaknesses of the simple approach above is that it ignores the structure of the islands and the pirate's communications; even if two pirates talk to each other a lot, they won't necessarily be given nearby islands. I am investigating methods which take this structure into account. Early results suggest that it's often possible to get within 10% - 20% of optimal with approaches that run 10 or 20 thousand times faster than brute force.&lt;br /&gt;&lt;br /&gt;Having read this far, you may now be scratching your head and wondering how on Earth this could pass for computer science. Maybe you figured it out already. The islands are analogous to computers, joined together in a network; or maybe, processors joined together on a chip. The pirates are particular programs which need to run, and maybe communicate with each other. At this point the simple model of "communicate or don't communicate" breaks down; instead we need to know &lt;i&gt;how often&lt;/i&gt; each program needs to send or receive data to each other program, and how fast the links between the computers can provide that data. But in fact this extra structure usually makes it easy to find a "reasonably good" solution, even if it complicates finding optimal solutions.&lt;br /&gt;&lt;br /&gt;The final task, of finding an optimal solution for Elfonso and his piratical buddies, is left as an exercise to the reader.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5652096800386218209-6205232974924498154?l=cprg-research.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/6205232974924498154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cprg-research.blogspot.com/2009/07/pirate-telegraphy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/6205232974924498154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/6205232974924498154'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/2009/07/pirate-telegraphy.html' title='Message Relays, Parrot Fashion'/><author><name>Charlie Reams</name><uri>http://www.blogger.com/profile/02227769914654330512</uri><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/__D23IsOHCC4/SnMTY2HZbyI/AAAAAAAAAA0/v62tchqVamU/s72-c/treasure.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5652096800386218209.post-6245410357872849354</id><published>2009-05-19T10:47:00.001+01:00</published><updated>2010-02-11T10:45:58.054Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='types'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='type classes'/><title type='text'>Dictionaries: lazy or eager type class witnesses</title><content type='html'>I gave a talk at the Cambridge computer lab on May 15, 2009:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Type classes are Haskell’s acclaimed solution to ad-hoc overloading. This talk gives an introductory overview of type classes and their   runtime witnesses, dictionaries. It asks the questions whether dictionaries should abide by Haskell’s default lazy evaluation strategy.&lt;br /&gt;&lt;br /&gt;Conceptually, a type class is a type-level predicate: a type is an                                                                                                                                                                                                             &lt;br /&gt;instance of a type class iff it type provides an implementation for                                                                                                                                                                                                            &lt;br /&gt;overloaded functions. For instance, `Eq a’ declares that type `a’                                                                                                                                                                                                              &lt;br /&gt;implements a function `(==) :: a → a → Bool’ for checking equality.                                                                                                                                                                                                            &lt;br /&gt;                                                                                                                                                                                                                                                                            &lt;br /&gt;Type classes are used as constraints on type variables, in so-called                                                                                                                                                                                                           &lt;br /&gt;constrained polymorphic functions. E.g. `sort :: Ord a =&gt; [a] → [a]’                                                                                                                                                                                                           &lt;br /&gt;sorts a list with any type of elements `a’ that are an instance of the                                                                                                                                                                                                         &lt;br /&gt;Ord type class, i.e. provide implementations for comparison.                                                                                                                                                                                                                   &lt;br /&gt;                                                                                                                                                                                                                                                                            &lt;br /&gt;Witnesses for type class constraints are necessary to select the appropriate implementation for the overloaded functions at runtime. For instance, if `sort’ is called with Int elements, the Int comparison must be used, versus say Float comparison for Float elements.&lt;br /&gt;                                                                                                                                                                                                                                                                            &lt;br /&gt;Two forms of witnesses have been considered in the literature, runtime type representations and so-called dictionaries, of which the latter are the most most commonly implementation, e.g. in GHC . Haskell implementations treat dictionaries just like all other data, as lazy values that may potentially consists of non-terminating computations. This way part of the type checker’s work, who has made sure that the dictionaries do exist, is simply forgotten. Is this really necessary? Can performance be gained by exploiting the strict nature of dictionaries? &lt;/blockquote&gt;  &lt;br /&gt;You can get the slides &lt;a href="http://www.cs.kuleuven.be/%7Etoms/Research/talks/eagerdictionaries.pdf"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5652096800386218209-6245410357872849354?l=cprg-research.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/6245410357872849354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cprg-research.blogspot.com/2009/05/dictionaries-lazy-or-eager-type-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/6245410357872849354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/6245410357872849354'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/2009/05/dictionaries-lazy-or-eager-type-class.html' title='Dictionaries: lazy or eager type class witnesses'/><author><name>Tom Schrijvers</name><uri>http://www.blogger.com/profile/05575578560152022579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://2.bp.blogspot.com/_Sh235RGes-w/SwBIn8B85VI/AAAAAAAADiE/MhmbNdrFPKw/S220/tom3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5652096800386218209.post-9155984404554828516</id><published>2009-04-08T14:11:00.008+01:00</published><updated>2009-04-08T22:54:09.071+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='compilers'/><category scheme='http://www.blogger.com/atom/ns#' term='funding'/><title type='text'>Compiler research centres</title><content type='html'>As Mary Hall, David &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Padua&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Keshav&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Pingali&lt;/span&gt; observed in a February 2009  &lt;a href="http://portal.acm.org/citation.cfm?id=1461928.1461946"&gt;&lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Commun&lt;/span&gt;. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;ACM&lt;/span&gt; &lt;/span&gt;article&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;There are few large compiler research groups anywhere in the world today.  At universities, such groups typically consist of a senior researcher and a few students, and their projects tend to be short term, usually only as long as a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Ph&lt;/span&gt;.D. project.&lt;/blockquote&gt;This is certainly the case in the UK. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Imperial's&lt;/span&gt; &lt;a href="http://spo.doc.ic.ac.uk"&gt;Software Performance Optimisation&lt;/a&gt; group is a blueprint of that (OK, with a post-doc sandwiched between the senior researcher and students).  Whilst other research groups in the UK may &lt;span style="font-style: italic;"&gt;appear&lt;/span&gt; to be larger, compiler researchers typically represent a smaller subset of researchers working on programming languages or computer architecture.  For example, in Cambridge the &lt;a href="http://www.cl.cam.ac.uk/research/cprg/"&gt;Programming&lt;/a&gt; group is part of the &lt;a href="http://www.cl.cam.ac.uk/research/pls/"&gt;Programming, Logic, and Semantics&lt;/a&gt; group (and a recent article in the &lt;a href="http://kn.theiet.org/magazine/"&gt;IET magazine&lt;/a&gt; suggests that a senior member of the Programming group also belongs to the &lt;a href="http://www.cl.cam.ac.uk/research/comparch/"&gt;Computer Architecture&lt;/a&gt; group); in Oxford the &lt;a href="http://web.comlab.ox.ac.uk/activities/tools/"&gt;Programming Tools&lt;/a&gt; group is part of the &lt;a href="http://web.comlab.ox.ac.uk/research/pl/"&gt;Programming Languages&lt;/a&gt; group; in Manchester and Edinburgh compiler researchers work in the &lt;a href="http://intranet.cs.man.ac.uk/apt/"&gt;Advanced Processor Technologies&lt;/a&gt; group and the &lt;a href="http://www.icsa.informatics.ed.ac.uk/compilers/"&gt;Compiler and Architecture Design&lt;/a&gt; group, respectively. Note that only the Edinburgh group prides themselves as compiler researchers (at least if one judges by the group name). &lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the same   &lt;a href="http://portal.acm.org/citation.cfm?id=1461928.1461946"&gt;&lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Commun&lt;/span&gt;. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ACM&lt;/span&gt; &lt;/span&gt;article&lt;/a&gt; we read the following recommendation:&lt;blockquote&gt;...researchers must attempt radical new solutions that are likely to be lengthy and involved.  The compiler research community (university and industry) must work together to develop a few large centers where long-term research projects with the support of a stable staff are carried out.  Industry and funding agencies must work together to stimulate and create opportunities for the initiation of these centers.&lt;/blockquote&gt;The situation is definitely getting better in the US.  In April 2009, The Defense Advanced Research Projects Agency (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;DARPA&lt;/span&gt;) awarded &lt;a href="http://www.rice.edu/nationalmedia/news2009-04-07-darpa.shtml"&gt;$16 million to the Platform-Aware  Compilation Environment (PACE) project at Rice University&lt;/a&gt;, as part of its &lt;a href="http://www.darpa.mil/ipto/programs/aace/aace.asp"&gt;Architecture Aware Compiler Environment&lt;/a&gt; (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;AACE&lt;/span&gt;) programme.  In March 2007, &lt;a href="http://www.microsoft.com/presspass/press/2008/mar08/03-18UPCRCPR.mspx"&gt;Intel and Microsoft announced&lt;/a&gt; awarding a combined $20 million grant to the &lt;a href="http://parlab.eecs.berkeley.edu/"&gt;Parallel Computing Laboratory at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;UC&lt;/span&gt; Berkeley&lt;/a&gt; and to the &lt;a href="http://www.upcrc.uiuc.edu/"&gt;Universal Parallel Computing Research Centre at Illinois&lt;/a&gt; (with the universities reportedly applying to additional funding of $7 and $8 million, respectively, to match the industry grant). No doubt, these parallel computing centres will spend big on compiler projects (e.g. PACE is explicitly focused on compilers).&lt;br /&gt;&lt;br /&gt;What about compiler funding the UK? From what I see (by looking at the number of PhD studentships, post-doctoral fellowships and permanent positions), the UK spending on compiler research seems to have been monotonically increasing over the past couple of years.  However, this growth does not have as much support as in the US, so the UK risks losing its competitiveness in this field.&lt;/div&gt;&lt;div&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/5652096800386218209-9155984404554828516?l=cprg-research.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/9155984404554828516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cprg-research.blogspot.com/2009/04/research-centres-in-compilers.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/9155984404554828516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/9155984404554828516'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/2009/04/research-centres-in-compilers.html' title='Compiler research centres'/><author><name>Anton Lokhmotov</name><uri>http://www.blogger.com/profile/17818727442450712038</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_G9lwqxizJUQ/SZQTgDdO8UI/AAAAAAAABIY/95sDDO3wq5g/s1600-R/02580c9.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5652096800386218209.post-8647365847021371139</id><published>2009-02-12T11:24:00.001Z</published><updated>2009-02-12T11:24:29.051Z</updated><title type='text'>First Post</title><content type='html'>Welcome to the Cambridge Programming Research Group's blog. The &lt;a href="http://www.cl.cam.ac.uk/research/cprg/"&gt;CPRG&lt;/a&gt; is a research group in the &lt;a href="http://www.cl.cam.ac.uk/"&gt;Computer Laboratory&lt;/a&gt; at the &lt;a href='http://www.cam.ac.uk'&gt;University of Cambridge&lt;/a&gt;. The group is also part of a larger group at the Computer Lab known as &lt;a href="http://www.cl.cam.ac.uk/research/pls/"&gt;PLS, or Programming, Logic, and Semantics&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This blog is authored by members of the CPRG containing posts related to the research of the CPRG and interesting, relevant research from elsewhere. This includes research relating to: programming language design, compilers, interpreters, virtual machines, portable target codes, program analysis, program transformations, and optimisation. Other related topics include: fast typical-case solutions to NP problems, algebraic manipulation by computer, and compiler/hardware trade-offs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5652096800386218209-8647365847021371139?l=cprg-research.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cprg-research.blogspot.com/feeds/8647365847021371139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cprg-research.blogspot.com/2009/02/first-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/8647365847021371139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5652096800386218209/posts/default/8647365847021371139'/><link rel='alternate' type='text/html' href='http://cprg-research.blogspot.com/2009/02/first-post.html' title='First Post'/><author><name>Dominic Orchard</name><uri>http://www.blogger.com/profile/00356502943141121461</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_RIjA3spQtI0/S86fFEGtyfI/AAAAAAAAAAM/Z5SRr63-7kU/S220/n61300853_4317.jpg'/></author><thr:total>0</thr:total></entry></feed>
