-
Boo: A New CLR Language
Lambda the Ultimate has a story on a new CLR (.NET) language named Boo. Ian Bicking’s comparison of Boo vs Python is a nice, succinct summary of it. Looks quite interesting: type inference, duck typing, macros, and string interpolation. Seems that the CLR does seem to be breeding all sorts of new languages …
-
Imperative Code as Streams
In imperative languages, you usually get a new random number by calling a function (such as C’s
rand(3)
) when you need a new one. You can do this in a functional language like Haskell too, but then you’re forced into an imperative style, which isn’t very functional. (An imperative style would be required because generating a new random number depends on the current state of the random number generator.) You can keep a functional programming style by having a random number generator produce a (lazy) list of numbers, rather than a single number: any code which wants a random numbers simply pulls the next one out of the list. I posted some example code to the haskell-cafe mailing list recently to demonstrate this, in answer to a Haskell newcomer’s post. Lazy lists are often also called streams.Normally, monads are used to encapsulate state changes in Haskell in a purely functional manner, but you can use streams too: any state changes which occur can be represented with new list elements. It’s no coincidence that streams are monads: they’re powerful enough to sequence non-deterministic operations. The Haskell Ports Library gives you even more convenience when working with streams by modelling time as a list, and the awesome iHaskell and Fudgets libraries for Haskell manage to model an entire GUI in a purely functional manner. Just to show that this is also has a practical benefit, the Fudgets code examples show how succinct writing GUI code can be. The Fudgets thesis is a great introduction and explanation to how it all works.
Closely related is the newer concept of arrows, which provide a formal framework to reason about stream-based (and also various other non-stream-based) computations. Anyone up for writing a Haskell library to interface to the gstreamer media framework as an arrow?
-
Me on Xoltar on Static Typing
Bryn Keller (a.k.a. Xoltar) takes on Bruce Eckel’s comments about Python and static typing, and does a pretty good job at poking all the holes in Eckel’s arguments while remaining objective. Worth a read, especially if you’re wondering what all the hoopla is about Haskell and O’Caml’s type systems.
My Comments
Bryn comments toward the end of his article about how duck typing can lead to ‘dangerous’ situations. He uses the example of a method named
draw
, which has different semantics for theGunslinger
class (wheredraw
means ‘Bang!’) vs aArtist
class (wheredraw
means ‘paint’). While it’s possible to have such name clashes with different semantics, in reality I don’t think it’s a big problem: certainly one not worth spending a few paragraphs on in an article. (When would this situation ever crop up, for example?)He points out that in the Nice language, you can write a class, and make them part of the interface later. In his words: “We also got additional power in the bargain, because now we can selectively bless any class we like into the Speaker interface, without including classes we don’t want - we can ensure that our Artist doesn’t end up in a gunfight by mistake!”. In languages such as Java or C++, you must declare that a class implements an interface when you write the class: you cannot write a class and declare later that it implements the interface. It is very cool to program in a language which enables you to separate the code you write, from declaring how that code is used as part of your whole system design. Some other examples of this feature in other languages are:
- Haskell, which enables you to declare a type class to capture common functionality provided by different functions. So, you could write a Haskell module which provides a new Hashtable data type, and another Haskell module to provide a new balanced tree data type. You can then later write a type class to capture operations common to such colletion/aggregate types, by writing a new type class that declare type signatures for functions such as inserting objects into the collection, or retrieving objects from the collection. Note that you could have completely different interfaces to the hashtable/tree classes with completely different type signatures: the type class performs the ‘glue’ code necessary to provide one clean, consistent interface to both of them. (Plus, the very small glue code required to do that will be optimised away by any optimising Haskell compiler, such as GHC.) This is the same idea as Nice’s separation of code declaration vs interface declaration, though type classes are a far more powerful and generic concept.
- Objective-C’s categories, which enable you to add new methods to existing classes. You don’t like it how the
NSFileHandle
class doesn’t have a method to create a new temporary file and return you a file descriptor for it? No problem, just add your own method to do that to the class — no subclassing necessary. Categories are possibly the greatest thing I miss about Objective-C when I use any other language (Haskell included: it would be really cool to be able to extend type classes by adding new methods to them!). C# has a similar feature named partial types, although it’s nowhere near as elegant as categories. Perl 6 takes this idea even further than Objective-C does: it differentiates between open classes, which can have methods added to them, and closed classes, which can’t. The clever bit is that all classes are open by default, but any users of that class will close the class unless it’s specifically declared open. This is really smart because it means that you can have the same flexibility that open classes give you, but you gain all the optimisation opportunities that come with closed classes, such as performing static dispatch rather than dynamic dispatch on a function call, which opens up a whole new set of optimisations that weren’t previously possible, such as inlining.
One of the points of Bryn’s article seems to be that static typing detects different errors from unit tests: while this is true, I’d phrase this a different way. One benefit of unit testing is that it helps you develop your code faster because unit tests enable your code to be more robust as you develop it, saving you from hunting down those stupid bugs later on. Modern static type systems give you different test coverage, and I think they speed up your development even more, because they often pick up a lot more errors than unit tests do. If you’re a Perl programmer, the
use strict;
pragma that Perl has basically turns on static type checking. Think about how many bugs you’ve found thanks to its warnings and errors, and imagine how much of a nightmare it’d be if you didn’t have that facility at all. Now think about extending Perl’s simple type system (which is limited to only type checking of scalars/arrays/hashes), so that types are pervasive in your program design that enable far better coverage by the type checker, and you’ll hopefully have some idea of what I’m talking about.He remarks right at the end of his article that “We need both strong testing and strong typing” — I think he means static typing, not strong typing, considering that was what his entire article was about :). Mind you, static and strong typing seems to be confused quite easily: even Guido van Rossum confuses strong typing with static typing. I personally find it a bit worrying that the designer of such a popular (and great!) language gets it wrong, but hey, nobody’s perfect.
Bryn, I think, doesn’t point out the biggest benefit of modern static typing systems: it saves you time because so often, when that anal type checker finally does let your program compile, it just works a really surprisingly large amount of the time. (This is closely related to the increase in productivity that I discussed above, but it’s not quite the same thing.) It’s downright unnerving just how many times your program performs correctly: one thread on the cvs-ghc mailing list gives an anecdote, where most of the Glasgow Haskell Compiler back-end was ripped out and re-written (14000 lines of code!), and the PowerPC code generator worked first-go. I’m yet to nail down whether this phenomenon is only due to the advanced type systems alone, or whether it’s a combination of the powerful type system and a (purely?) functional programming style; I suspect it’s the combination of the two. Programs are much easier to reason about when state changes are made explicit.
-
6-Star Smart Playlists in iTunes
iTunes is nice and all, but I wish you could rank a song between 0-6 stars rather than 0-5 stars. That way, you can classify 0-star songs as unrated, and have 5 stars leftover for your own classification, rather than 4, which may be a bit too restrictive. Well, you can do this pretty easily for purposes of including it in a smart playlist, which is all I wanted to do.
How to do it? Easy:
- Rate all your 6-star songs as 5-star, so they’ll be included in any matches that would normally include 5-star songs.
- Add the text “6-star” to the comment of any of the songs you want to rate as 6-star.
- Make a new Smart Playlist, and include the “6-star” text as part of the criteria for the playlist.
That’s it. You can obviously expand the scheme to 69 stars if you want, but 6 is enough for me.
-
Beyond C, C++, Perl and Python
Abstract
As a Linux user or developer, you probably know a few programming and scripting languages: shell scripting, Perl perhaps, Python, C or C++, and maybe Java or XSLT. Once you’ve learnt one systems language or one scripting language, you’ve learnt them all, right? Especially because of that “Turing-complete” thing …
In this talk, I’ll explore the research and developments that have happened outside of mainstream programming languages in the past decade, in languages such as Objective-C, Haskell, O’Caml, and Nemerle. The scope of the talk is broad: I’ll touch on many topics, such as meta-programming, generics, type systems, and proof-carrying code, without going too in-depth into any of them. (Believe me, you don’t want to hear me talk for seventeen hours about type systems.) Most of the topics covered (such as meta-programming) are not language-specific, and can be directly applied to your own work, increasing your own programming expertise and repertoire of techniques.
Download
Slides: Adobe Acrobat PDF
-
WWDC 2004 Cuteness
I like Apple’s sense of humour :)
- In one screenshot of the Stock Ticker dashboard app, Microsoft (MSFT) was the only company in the shot which had their stock price going down.
- The calculator app in this Dashboard demonstration shows the number 1.337.
- And, of course, the most excellent Introducing Longhorn poster!
-
Plugging Haskell In
AndrÈ Pang, Don Stewart, Sean Seefried, and Manuel M. T. Chakravarty.
Submitted to the 2004 Haskell Workshop.
Abstract
Extension languages enable users to expand the functionality of an application without touching its source code. Commonly, these languages are dynamically typed languages, such as Lisp, Python, or domain-specific languages, which support runtime plugins via dynamic loading of components. We show that Haskell can be comfortably used as a statically typed extension language, and that it can support type-safe dynamic loading of plugins using dynamic types. Moreover, we discuss how plugin support is especially useful to applications where Haskell is used as an embedded domain-specific language (EDSL). We explain how to realise type-safe plugins using dynamic types, runtime compilation, and dynamic linking, exploiting infrastructure provided by the Glasgow Haskell Compiler. We demonstrate the practicability of our approach with several applications that serve as running examples.
Download
The paper’s official website, where you can download the hs-plugins library and example programs, is at http://www.cse.unsw.edu.au/~dons/hs-plugins/paper/.
12 pages: Postscript (.ps.gz), Adobe Acrobat PDF. The copyright for the papers is held by the authors or by the publisher. The papers are provided for personal use only; other use requires the explicit permission of the copyright holder.
BibTeX Entry
@inproceedings{PSSC04, author = {Andr{\'e} Pang and Don Stewart and Sean Seefried and Manuel M. T. Chakravarty}, title = {Plugging Haskell in}, booktitle = {Proceedings of the ACM SIGPLAN workshop on Haskell}, year = {2004}, isbn = {1-58113-850-4}, pages = {10--21}, location = {Snowbird, Utah, USA}, doi = {http://doi.acm.org/10.1145/1017472.1017478}, publisher = {ACM Press}, }
Related Webpages
-
Embedding Frameworks in Applications
If your Mac OS X application uses a framework, you can embed it in your application even after you’ve built and linked the application against a framework which you’ve installed privately to
/Library/Frameworks
.The secret is to use the obscure
install_name_tool
command. You’ll need to do two things:- Change the identification name of the framework itself from
Foo.framework/...
to@executable_path/../Frameworks/Foo.framework/...
- Change the application’s main executable dependent shared library list, from
Foo.framework/...
to@executable_path/../Frameworks/Foo.framework/...
Here’s how to do it:
- Copy your existing framework first and work on that: the
install_name_tool
command directly modifies the framework, so you’ll probably want be operating on a copy of it. - Run
install_name_tool -id '@executable_path/../Frameworks/Foo.framework/...' Foo.framework/Foo
- Run
install_name_tool -change 'Foo.framework/...' '@executable_path/../Frameworks/Foo.framework/...' MyApplication.app/Contents/MacOS/MyApplication
To find out what to put in the
...
bit of the commands above, run theotool -L
command on the executable or shared library to see the full pathname. It should look something likeVersions/A/Foo
.It’s a bit of a pain in the arse, but at least it works. Until I figured this out, it was really a bit of a pain to embed frameworks into applications properly!
- Change the identification name of the framework itself from
-
Subversion Tips
Here’s a few tips that I’ve discovered to ease working with Subversion.
Long URLs
Tired of those long URLs, like
svn+ssh://foo@bar.com/long/directory/hierarchy/to/svn/repo/trunk
? Use a shell alias, function or shell script which simply prints the URL. e.g.#!/bin/sh echo "svn+ssh://foo@bar.com/long/directory/hierarchy/to/svn/repo/$@"
Save the shell script as, say,
FooSVN
. Now, instead of typing those long URLs on the commandline, you can just writesvn co `FooSVN trunk`
instead. -
Subversion for Mac OS X
Note: I don’t support this package anymore: Martin Ott of TheCodingMonkeys provides his own statically-linked Subversion binaries, and Darwinports also supplies their own subversion package. The main reason I made this package was because I wanted an easy way to install Subversion without going through Fink, which wants to install Apache 2 at the same time. Both the above two places enable you to do that. I’m only keeping this around for posterity’s sake :).
Subversion Package
Detailed Dependency Build Information
Subversion has quite a number of dependencies, which make building it not a lot of fun. My binary distribution puts all of Subversion’s dependencies into the
/usr/local/libexec/subversion
directory, so if you have any of its required libraries installed yourself or via Fink, none of these versions will conflict. The downside is that you use a bit more disk space, but hey, who’s complaning about a few megabytes these days?The APR (the Apache Portable Runtime) 0.9 branch was used, checked out on 15 March 2003 3:20pm (UTC +10), with the following
./configure
line:./configure --prefix=/usr/local/libexec/subversion/apr
apr-util
./configure
line:./configure --prefix=/usr/local/libexec/subversion/apr-util --with-dbm=db42 --with-berkeley-db=/usr/local/libexec/subversion/berkeley-db --with-apr=/usr/local/libexec/subversion/apr
Berkeley DB 4.2.52 with the 4.2.52.1 and 4.2.52 patches applied. The following
./configure
line was used to compile it:../dist/configure --prefix=/usr/local/libexec/subversion/berkeley-db
The version of OpenSSL that is distributed with Mac OS X Panther 10.3.2 (0.9.7, I believe) was used.
Neon. Note:
./autogen.sh
was run for Neon, so that a newer version of libtool and the auto{conf,make} utilities would be installed which understands how to build shared libraries on Mac OS X../configure --prefix=/usr/local/libexec/subversion/neon --with-ssl --enable-shared
SWIG:
./configure --prefix=/usr/local/libexec/subversion/swig
Subversion itself was ./
configure
d with (note also ./autogen.sh was run):./configure --with-ssl --with-apr=/usr/local/libexec/subversion/apr --with-apr-util=/usr/local/libexec/subversion/apr-util --with-neon=/usr/local/libexec/subversion/neon --with-apxs=/Library/Apache2/bin/apxs --prefix=/usr/local/libexec/subversion
-
Mail.app Pictures
You know those cute little pictures which pop up if you receive an email from somebody with a Mac.com account? It turns out that you can set that picture with an email header: no Mac.com account needed.
Simply add a
X-Image-Url
header to your email, with the contents being a URL that contains the picture, e.g.X-Image-Url: http://www.algorithm.com.au/albums/ozone/Me.jpg
.Credit where credit is due: I found out about this tip from the following two links:
-
USB Numeric Keypad
If you didn’t know, you can use the numeric keypad to select options that appear on the radial menu (that appears when you, for example, right-click on your character). Of course, the numeric keypad is in an inconvenient spot: most gamers have their left hand resting on the left-hand side of the keyboard on the Quake-inspired
W/A/S/D
keys, not on the right-hand side where the numeric keypad is. On laptops, it’s in an even more inconvenient spot—like, it doesn’t exist and stuff. D’oh.If you’re willing to fork out a bit of dough for a game, drop $50 on a USB numeric keypad, and put that to the left of your keyboard. Your enjoyment of Neverwinter will go up dramatically. It’s also useful for Alpha Centauri if you’re a laptop person :-).
-
VideoLAN Annodex patches
Here are some patches for the VideoLAN cross-platform multimedia player, to enable support for Annodex bitstreams.
- Annodex support for the Ogg demuxer (
modules/demux/ogg.c
): vlc_modules_demux_ogg.c.diff (MERGED) - A modification to the
vout_ShowTextAbsolute
function insrc/video_output/video_text.c
, so that it returns thesubpicture_t
created. This is required for the upcoming CMML support: vout_STA_returns_subpicture_t.diff (MERGED)
VLC now supports playback of Annodex files and CMML tracks as of version 0.7.2. Woo!
- Annodex support for the Ogg demuxer (
-
Disable the Splash Screens (Introduction Movies)
Add the line:
Disable Intro Movie=1
to the
[Display Options]
section of thenwn.ini
file in your Neverwinter Nights directory. (This tip’s fairly widely known: it’s described in the NWVault FAQ, and it’s also a topic in the BioWare NWN forums. I mostly have it here for my own reference.) -
Suggested Neverwinter Nights Additions
Hakpacks
Note that all hakpacks can be used in any modules—including the standard BioWare campaigns—by extracting the data in them and putting their data files into NWN’s
override\
directory. In fact, that’s what I do with all the hakpacks listed below. -
Interfacing Haskell to Object-Oriented Languages
AndrÈ T. H. Pang and Manuel M. T. Chakravarty
In Greg Michaelson and Phil Trinder, editors, IFL 2003 - 15th International Workshop on the Implementation of Functional Languages, LNCS, Springer-Verlag, 2004.
Abstract
The interfacing of object-oriented languages with functional languages, in general, and with Haskell, in particular, has received a considerable amount of attention. Previous work, including Lambada, a Haskell to Java bridge, showed how an object-oriented class hierarchy can be modeled using Haskell type classes, such that Java libraries can be used conveniently from Haskell.
The present paper extends this previous work in two major directions. Firstly, we describe a new implementation of object-oriented style method calls and overloading in Haskell, using multi-parameter type classes and functional dependencies. This enables calling of a foreign object’s methods in a syntactically convenient, type-safe manner. Secondly, we sketch an approach to automating the generation of library bindings using compile-time meta-programming for object-oriented frameworks featuring reflection. We have evaluated the practicality of our approach by implementing a Haskell binding to the Objective-C language on the Mac OS X platform.
Download
16 pages: Postscript (.ps.gz), Adobe Acrobat PDF. The copyright for the papers is held by the authors or by the publisher. The papers are provided for personal use only; other use requires the explicit permission of the copyright holder.
Related Webpages
-
Use HakPaks in the Standard Campaigns
If you extract the files from a
.hak
pack and place those extracted files in Neverwinter Night’soverride
directory, you can use that hakpack in any of the standard BioWare campaigns (with the usual disclaimer that hakpacks may break stuff, you will actually need to put in new merchants to use any of the new items, etc.) This is very useful for non-intrusive hak-pack changes, like thejigglyhi-poly human torsos models.You can use tools like NWN Explorer or NWN Viewer to extract the files from a
.hak
pack. -
NWScript Dissassembly
After Neverwinter Nights just came out, I started dissembling the NWScript bytecode that it uses internally for its game engine, with the intention of writing a command-line script compiler some day. I since stopped work on it since I had a few other things to do. It seems that the great Torlack (who now works at BioWare) beat me to it, but I thought I’d put up my results for download anyway. For budding dissasemblers (like myself :-), I’ve also put up all the scripts I used to try to figure out the bytecode, which may be more important than the bytecode itself for some people.
Note that BioWare provides their own command-line compiler now anyway, if you have a version more recent than 1.40 or something like that—see
utils\clcompile.exe
.I find it interesting that BioWare chose their own scripting format for NWN considering that they used the very flexible and extensible Lua for Baldur’s Gate I/II (which is also used in a number of other games; in fact, one of the Monkey Island games had a bar named Lua as a dedication to the Lua community for their great efforts). While NWScript is OK as a language, I certainly wonder why they didn’t stick with Lua …
Anyhoo, feel free to download the results of my peeking and poking.
-
Auto-Save Every 5 Minutes!
Play in multiplayer all the time, even if you’re just playing single-player mode—and turn on the auto-save option and set it to save every 5 minutes or so. That’s saved my arse a few times now!
-
Amusement on #haskell
14:48 < Pseudonym> Riastradh: With a mind like that… ever considered a career as a C++ luminary?
14:48 * Riastradh throws a pointy template at Pseudonym.
14:49 * Pseudonym carefully places it in a smart pointer container
14:49 * SyntaxLaptop frees it
14:49 * Riastradh dereferences Pseudonym.
14:50 < SyntaxLaptop> sorry, delete
14:50 < Pseudonym> Why do I feel like I’ve suddenly accessed some of my uninitialised memory?
14:50 * Riastradh unsafePerformIOs Pseudonym.
14:51 < DeezNuts> just trying to run the prebuilt version of ghc 5.04.3 it bitches that it can’t find “libgmp.so.3:”
14:51 * Pseudonym FFIs Riastradh
14:51 < DeezNuts> err thats “libgmp.so.3”
14:51 < Pseudonym> Do you have GMP installed?
14:51 * Riastradh DEFINE-FOREIGNs Pseudonym.
14:52 * Pseudonym reinterpret_cast<>()s Riastradh
14:52 * Riastradh Obj.magics Pseudonym.
14:52 * Pseudonym GOTOs Riastradh
14:52 < Pseudonym> Riastradh considered harmful.
14:52 * Riastradh reflects Pseudonym.
14:53 * Pseudonym reifies Riastradh
14:53 * Riastradh shifts Pseudonym with no reset in place to delimit the shift.
14:53 < Pseudonym> Careful with all my bits.
14:53 * Riastradh converts Pseudonym to base three!
14:54 * Pseudonym pushbacks Riastradh
14:54 < DeezNuts> blah
14:54 < DeezNuts> could u explain?
14:54 < Pseudonym> Careful with my trits!s
14:54 * Riastradh throws Pseudonym.
14:54 * Pseudonym raises Riastradh
14:54 * Riastradh signals Pseudonym.
14:54 < DeezNuts> fine! linux-ppc won’t be getting a build
14:55 * Pseudonym kills Riastradh
14:55 < jameson> This is getting just a bit surreal… at least no one has used pointer arithmetics or ‘memfrob()’ yet…
14:55 < jameson> DeezNuts: Well, you have to install libgmp.
14:55!monotonom [trebla@130.63.90.200] has quit [“Do not join the channels joined by all who join all channels you join.”]
14:55 < jameson> It should be a dependency for the ghc package.
14:55 < Pseudonym> jameson: How dare you suggest such a thing.
14:55 * Riastradh throws himself and unsafely kills Pseudonym’s thread.
14:55 < Pseudonym> memfrob() is banned by the Geneva Convention
14:56 * Pseudonym cancels Riastradh’s thread and reaps his zombie children
14:56 * Riastradh throws across a process boundary and terminates Pseudonym’s process with a SIGSEGV.
14:56 * jameson makes sure that his lambda lifter and CPS converter are fully charged, just in case
14:57 * Pseudonym marshals Riastradh down a pipe and maps him to anonymous memory
14:57 * Riastradh incrementally lambda-lifts jameson before he gets to put his inferiour lambda-lifter into action.
14:57 * Riastradh comes out the other end of the pipe in yet another process and ANF-transforms Pseudonym.
14:57 < jameson> Keep playing guys, but keep in mind: No side effects on my memory!
14:57 * Pseudonym unsafeCasts jameson
14:58 * Riastradh throws into the kernel and twiddles jameson’s memory carefully.
14:58 * Pseudonym transfers Riastradh’s control over a superblock boundary
14:58 * Riastradh traps Pseudonym into one process, having full access to the kernel, and patches the scheduler so it doesn’t transfer control to that process ever.
14:59 < Etaoin> pwned
14:59 * Riastradh jumps down into the firmware, off into a firewire cable, emerges from a nearby hard drive, and unplugs the firewire cable, causing a kernel panic.
14:59 < Riastradh> HAH!
14:59 * Pseudonym loads a modular scheduler from flash and disables all interrupt threads
15:00 < Pseudonym> You forgot I was running Solaris, didn’t you?
15:00 * Riastradh picks up a sledgehammer and blowtorch and turns the computer upon which Pseudonym is barely staying alive into a pile of beaten slag.
15:01 * Pseudonym transfers himself to a different NUMA node to recover before disabling Riastradh’s processor set
15:01 * Pseudonym severs the backplane connection just in case
15:01 * Riastradh was reified, so he is no longer constrained to the internals of a computer.
15:02 * Pseudonym insert a nonassociative morphism into Riastradh’s category
15:02 < Riastradh> AAAAAGH!
15:02 < Riastradh> NOT THE NONASSOCIATIVE MORPHISM!
15:02 < Pseudonym> Now you’re inconsistent!
15:02 * Riastradh helplessly slumps to the floor…
15:02 < Pseudonym> Haha!
15:02 * Riastradh paws about for any weapon with which to retaliate…
15:02 < Pseudonym> You thought being abstract would save you.
15:02 * Riastradh picks up a monad and a comonad…hmmm…I wonder what happens when I cross the, er, duals.
15:03 < Pseudonym> No! DON’T CROSS THE DUALS!
15:03 * SyntaxLaptop tosses Riastradh an arrow
15:03 < Pseudonym> That comonad is unsafe!
15:03 < SyntaxLaptop> s/tosses/throws
15:04 * Riastradh straps the comonad onto one side of the arrow and the monad onto the other, and throws it at Pseudonym.
15:04 * Riastradh homomorphisizes Pseudonym!
15:04 * Riastradh uhohs as he realizes that that attack wasn’t sufficient.
15:04 * Pseudonym left-cancels the arrow
15:05 * Riastradh hides under a catamorphic syntamorphism.
15:05 * Pseudonym retracts the monad, but realises too late that it’s idempotent
15:05 * Riastradh plots coalgebraically while Pseudonym cannot find him.
15:06 * Pseudonym searches for Riastradh on an endomap
15:07 * Pseudonym flips off the safety on a terminal object
15:07 * Riastradh whets an eslupherum as he monofunctorializes his handy exomorph.
15:08 * SyntaxLaptop eats some syntactic sugar
15:08 * Riastradh watches with revulsion as SyntaxLaptop gets semicolon cancer.
15:11 * Riastradh qopas Pseudonym and stuffs him into a monadic canister, sealed tightly with a polyfunctorialism disguised as a monofunctorialized exomorph!
15:11 * Pseudonym claims this channel in the name of Free Constructions
15:12 * Riastradh forces coalgebra upon Pseudonym so that his constructor fails.
15:12 * Pseudonym gets out through a safe destructor
15:12 * Riastradh duals Pseudonym so both his constructor and destructor fail.
15:13 * Pseudonym hops on a natural transformation into a free functor
15:14 * Riastradh impales that free functor with an extrintolphoric arrow.
15:15 * Pseudonym stops the arrow with a terminal object
15:15 * Riastradh terminates Pseudonym’s terminal object and lets the arrow continue.
15:16 * Pseudonym turns it around with a contravariant functor
15:16 * Riastradh cocontravaries Pseudonym’s functor, negating the effect completely.
15:16 < sam-> oh god make it stop
15:16 * Pseudonym adjuncts it into the Herbrand universe
15:17 * Riastradh discojuncts Pseudonym hyperbolically.
15:17 < Pseudonym> Ooh, kinky.
15:18 < Riastradh> An irrelevant statement! I win!
15:18 * Pseudonym traps Riastradh under a cocone
15:18 * Riastradh treaps Pseudonym in a cacao bean.
15:18 < Pseudonym> Never! Irrelevancy is always part of the game.
15:19 * Riastradh catamorphs Pseudonym into a simple seed!
15:21 * Pseudonym notes the seed is isomorphic to a human, so what’s the big deal?
15:21 * Riastradh squishes it and ends the big deal, having triumphed.
15:22 * Pseudonym notes the gooey mess is isomorphic to a large cauldron of boiling oil
15:23 * Riastradh takes it off of the burner and then dips chips in it to enhance their flavour.