<?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-16943816</id><updated>2012-01-02T18:07:51.847-07:00</updated><title type='text'>Qwertie's Scribblings</title><subtitle type='html'>You can ignore this blog.  It's just a place for me to put miscellaneous notes, snippets, and incomplete ideas.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>59</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-16943816.post-7768307274811092958</id><published>2011-04-11T10:08:00.006-06:00</published><updated>2011-04-11T10:22:08.143-06:00</updated><title type='text'>Complicated SWIG polymorphic return</title><content type='html'>&lt;a href="http://www.voom.net/swig-csharp-java-downcast"&gt;A simpler solution&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;// TODO: make this macro compatible with .NET Compact Framework, in which you&lt;br /&gt;// can't return a structure over PInvoke.&lt;br /&gt;//&lt;br /&gt;// There is a problem in case you want to wrap a function that returns a pointer &lt;br /&gt;// to a base class in SWIG, if that base class could refer to some derived &lt;br /&gt;// class. For example suppose these classes are defined:&lt;br /&gt;//   class Actor { virtual ~Actor(); ... };&lt;br /&gt;//   class HumanActor : public Actor { ... };&lt;br /&gt;//   class RobotActor : public Actor { ... };&lt;br /&gt;//   class DogActor   : public Actor { ... };&lt;br /&gt;// &lt;br /&gt;// And there is this function that could return any of the above:&lt;br /&gt;//   Actor* GetActor() { ... }&lt;br /&gt;//&lt;br /&gt;// The problem is that on the C# side, GetActor() will always return a new&lt;br /&gt;// base class object (Actor), instead of the derived class (such as HumanActor).&lt;br /&gt;// There is no easy way to deal with this, but I've written a macro that can&lt;br /&gt;// help if you really need it. To use it, first, invoke the macro:&lt;br /&gt;//&lt;br /&gt;// %cs_return_derived_proxy_by_code(Actor, ActorOrDerivedClass, 0)&lt;br /&gt;// &lt;br /&gt;// The second name is a special typedef name that tells SWIG when to use the&lt;br /&gt;// macro's special behavior. In order to make the macro apply to GetActor(), &lt;br /&gt;// change the function declaration to this:&lt;br /&gt;//&lt;br /&gt;// typedef Actor ActorOrDerivedClass;&lt;br /&gt;// ActorOrDerivedClass* GetActor() { ... }&lt;br /&gt;//&lt;br /&gt;// Next, you have to write a global function that obtains a code that will&lt;br /&gt;// be put in a "SwigPtrAndTypeCode" structure to represent the derived type:&lt;br /&gt;//&lt;br /&gt;// %{&lt;br /&gt;//   int GetSwigTypeCode(Actor* a) &lt;br /&gt;//   {&lt;br /&gt;//   if (dynamic_cast&amp;lt;HumanActor*&gt;(a) != NULL) return 1;&lt;br /&gt;//   if (dynamic_cast&amp;lt;RobotActor*&gt;(a) != NULL) return 2;&lt;br /&gt;//   if (dynamic_cast&amp;lt;DogActor*&gt;  (a) != NULL) return 3;&lt;br /&gt;//   return 0;&lt;br /&gt;//   }&lt;br /&gt;// %}&lt;br /&gt;// &lt;br /&gt;// Now, when you call GetActor() from C#, the C-side wrapper will return&lt;br /&gt;// SwigPtrAndTypeCode, a special 8-byte structure, instead of Actor*. &lt;br /&gt;// SwigPtrAndTypeCode contains the pointer to the Actor together with the&lt;br /&gt;// type code returned from your function.&lt;br /&gt;//&lt;br /&gt;// Finally, the C# side will call a function that you must write called &lt;br /&gt;// NewActorProxy() inside the P/Invoke class. Define it by inserting something&lt;br /&gt;// like the following into your main .i file:&lt;br /&gt;//&lt;br /&gt;//  %pragma(csharp) imclasscode=%{&lt;br /&gt;//   internal static Actor NewActorProxy(SwigPtrAndTypeCode p, bool memoryOwn)&lt;br /&gt;//   {&lt;br /&gt;//    switch(p.TypeCode) {&lt;br /&gt;//    case 1:  return new HumanActor(p.Ptr, memoryOwn);&lt;br /&gt;//    case 2:  return new RobotActor(p.Ptr, memoryOwn);&lt;br /&gt;//    case 3:  return new   DogActor(p.Ptr, memoryOwn);&lt;br /&gt;//    default: return new      Actor(p.Ptr, memoryOwn);&lt;br /&gt;//    }&lt;br /&gt;//   }&lt;br /&gt;//  %}&lt;br /&gt;//&lt;br /&gt;// The third argument is an integer flag saying whether the object is reference-&lt;br /&gt;// counted via %counted_obj. If you use %counted_obj for this type, then set&lt;br /&gt;// IsCountedObj=1. They both change csout, so they are not compatible without this&lt;br /&gt;// little hack.&lt;br /&gt;//&lt;br /&gt;// Note: this macro assumes IntPtr is used instead of HandleRef, but it only&lt;br /&gt;// makes a difference if BaseClassPtrType is used as an input argument type.&lt;br /&gt;//&lt;br /&gt;// Finally, sometimes you may want to return more information to C++ than just&lt;br /&gt;// a type code. In that case you use your own structure in place of struct&lt;br /&gt;// SwigPtrAndTypeCode, and use %cs_return_derived_proxy_by_code2() to specify&lt;br /&gt;// two extra arguments: the name of your structure on the C++ side, then the&lt;br /&gt;// name of the structure on the C# side. Use SwigPtrAndTypeCode as an example.&lt;br /&gt;%define %cs_return_derived_proxy_by_code(BaseClass, BaseClassPtrType, IsCountedObj)&lt;br /&gt; %cs_return_derived_proxy_by_code2(BaseClass, BaseClassPtrType, IsCountedObj, SwigPtrAndTypeCode, $imclassname.SwigPtrAndTypeCode)&lt;br /&gt;%enddef&lt;br /&gt;%define %cs_return_derived_proxy_by_code2(BaseClass, BaseClassPtrType, IsCountedObj, CppPtrAndTypeCode, CsPtrAndTypeCode)&lt;br /&gt; typedef BaseClass BaseClassPtrType;&lt;br /&gt; %typemap(ctype, fragment="CppPtrAndTypeCode", out="CppPtrAndTypeCode") BaseClassPtrType* %{ BaseClassPtrType* %}&lt;br /&gt; %typemap(in)       BaseClassPtrType* %{ $1 = (BaseClassPtrType*)$input; %}&lt;br /&gt; %typemap(varin)    BaseClassPtrType* %{ $1 = (BaseClassPtrType*)$input; %}&lt;br /&gt; //%typemap(memberin) BaseClassPtrType* %{ $1 = (BaseClassPtrType*)$input; %}&lt;br /&gt; &lt;br /&gt; %typemap(imtype, out="CsPtrAndTypeCode") BaseClassPtrType* "IntPtr"&lt;br /&gt; %typemap(cstype) BaseClassPtrType* "$csclassname"&lt;br /&gt; %typemap(csin)   BaseClassPtrType* "$csclassname.getCPtr($csinput)"&lt;br /&gt; %typemap(csout, excode=SWIGEXCODE) BaseClassPtrType* {&lt;br /&gt;  CsPtrAndTypeCode p = $imcall;$excode&lt;br /&gt;  #if IsCountedObj&lt;br /&gt;  return $imclassname.New ## %mangle(BaseClass) ## Proxy(p, true);&lt;br /&gt;  #else&lt;br /&gt;  return $imclassname.New ## %mangle(BaseClass) ## Proxy(p, $owner);&lt;br /&gt;  #endif&lt;br /&gt; }&lt;br /&gt;%enddef&lt;br /&gt;&lt;br /&gt;// REAL LIFE EXAMPLE (redacted for simplicity)&lt;br /&gt;&lt;br /&gt;// Allow Element* to be returned using the correct proxy class.&lt;br /&gt;// Not Compact Framework compatible.&lt;br /&gt;%cs_return_derived_proxy_by_code2(Element, ElementOrDerived, 1, ElementPtrEtc, $imclassname.ElementPtrEtc)&lt;br /&gt;%fragment("ElementPtrEtc","header") {&lt;br /&gt; struct ElementPtrEtc&lt;br /&gt; {&lt;br /&gt;  ElementPtrEtc() {}&lt;br /&gt;  ElementPtrEtc(Element* p) { *this = p; }&lt;br /&gt;&lt;br /&gt;  void* ptr;&lt;br /&gt;  ElemType elemType;&lt;br /&gt;&lt;br /&gt;  void operator= (Element* p) {&lt;br /&gt;   ptr = p;&lt;br /&gt;   if (p) {&lt;br /&gt;    try {&lt;br /&gt;     elemType = (ElemType)p-&gt;Type();&lt;br /&gt;    } catch(...) {}&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; };&lt;br /&gt;}&lt;br /&gt;%pragma(csharp) imclasscode=%{&lt;br /&gt; // Used by %cs_return_derived_proxy&lt;br /&gt; [StructLayout(LayoutKind.Sequential)]&lt;br /&gt; internal struct ElementPtrEtc {&lt;br /&gt;  public IntPtr Ptr;&lt;br /&gt;  public ElemType ElemType;&lt;br /&gt; }&lt;br /&gt;%}&lt;br /&gt;%pragma(csharp) imclasscode=%{&lt;br /&gt; // Name comes from New ## %mangle(Element) ## Proxy&lt;br /&gt; internal static Element NewElementProxy(ElementPtrEtc p, bool memoryOwn)&lt;br /&gt; {&lt;br /&gt;  Element e;&lt;br /&gt;  switch((ElemType)p.ElemType) {&lt;br /&gt;   case ElemType.ITSC:         e = new ItscElem(p.Ptr, memoryOwn); break;&lt;br /&gt;   case ElemType.NAMEDPOINT:   e = new NamedPoint(p.Ptr, memoryOwn); break;&lt;br /&gt;   case ElemType.NAMEDLINE:    e = new NamedLine(p.Ptr, memoryOwn); break;&lt;br /&gt;   case ElemType.NAMEDPOLYGON: e = new NamedPolygon(p.Ptr, memoryOwn); break;&lt;br /&gt;   default: e = new Element(p.Ptr, memoryOwn); break;&lt;br /&gt;  }&lt;br /&gt;  return e;&lt;br /&gt; }&lt;br /&gt;%}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-7768307274811092958?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/7768307274811092958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=7768307274811092958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7768307274811092958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7768307274811092958'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2011/04/complicated-swig-polymorphic-return.html' title='Complicated SWIG polymorphic return'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-4369829212903856731</id><published>2011-03-19T22:05:00.010-06:00</published><updated>2011-04-28T17:13:09.130-06:00</updated><title type='text'>Changing the FOV in Mass Effect 2</title><content type='html'>By default, Mass Effect 2 has a narrow field-of-view, and you may find that the lowest mouse sensitivity setting (apparently called "Camera Sensitivity" in the game) is too high for many mice. Tweaking these settings requires that you change a file called Coalesced.ini. If you installed Mass Effect 2 via Steam, this file will probably be located at one of these two paths:&lt;br /&gt;&lt;br /&gt;C:\Program Files (x86)\Steam\steamapps\common\mass effect 2\BioGame\Config\PC\Cooked&lt;br /&gt;C:\Program Files\Steam\steamapps\common\mass effect 2\BioGame\Config\PC\Cooked&lt;br /&gt;&lt;br /&gt;This strange file is a binary file that contains numerous text files embedded within it. The file must not be edited with Notepad (which corrupts it if you save changes). It can be edited with &lt;a href="http://www.flos-freeware.ch/notepad2.html"&gt;Notepad2&lt;/a&gt; (an excellent replacement for Notepad), but there are reports that doing so will cause Mass Effect 2 to crash on startup (I didn't actually verify this, I just assume the reports are true). I don't mean that you shouldn't edit it with Notepad2, just that if you do, then you need to run a special utility that "fixes" the file after you edit it. Apparently the "binary" part of the file needs to be updated whenever the "text" part is updated. It's not possible to do this manually, so you need a special program to do the job for you.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Before changing Coalesced.ini, make a backup, in case you don't like your changes, make a serious mistake, or you can't figure out how to do the "fixing" process.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are at least three programs that can fix Coalesced.ini: a &lt;a href="http://social.bioware.com/forum/1/topic/106/index/869923"&gt;C++ program&lt;/a&gt;, a Ruby program which is, apparently, no longer on the web, and a program called &lt;a href="http://social.bioware.com/forum/1/topic/106/index/834703/1"&gt;ME2CoalescedEditor&lt;/a&gt;. The last one is the one I use. ME2CoalescedEditor is actually intended to help you view, search and edit the various parts of Coalesced.ini, but its user interface is somewhat confusing.&lt;br /&gt;&lt;br /&gt;Therefore, you may wish to edit Coalesced.ini with Notepad2 instead, and only use ME2CoalescedEditor to "fix" the file so that Mass Effect 2 can load it correctly without crashing. If you choose this approach, &lt;br /&gt;&lt;ol&gt;&lt;li&gt;edit and save Coalesced.ini with Notepad2&lt;/li&gt;&lt;li&gt;Start ME2CoalescedEditor, click the Commands menu, and choose Rebuild Coalesced.&lt;/li&gt;&lt;li&gt;Exit ME2CoalescedEditor (and perhaps start ME2 to test your changes.)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;There is actually a fourth option for editing Coalesced.ini, &lt;a href="http://www.gamespot.com/pc/rpg/mass-effect-2/show_msgs.php?topic_id=m-1-53285451&amp;pid=944906"&gt;the "Coalesced Compiler"&lt;/a&gt;, but it comes with its own special "split" version of Coalesced.ini, so apparently it does not let you edit your &lt;span style="font-style:italic;"&gt;own original&lt;/span&gt; copy of Coalesced.ini.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Changing the field-of-view&lt;/h3&gt;&lt;br /&gt;My best friend and I play ME2 on a very big screen and we can't stand the default FOV. We need more peripheral vision... a lot more. The default actually 70 degrees; we use 100 or even 110 degrees instead. There is a line in Coalesced.ini that says FOVAngle=90, but apparently this line has no effect.&lt;br /&gt;&lt;br /&gt;I found a command that does change the FOV; it's called simply FOV. This command, apparently, must be part of a key binding (Command="....FOV 100...."). Unfortunately, this command overrides the FOV permanently, instead of just changing the default FOV. When you right-click to aim, your view is supposed to zoom in, but if you have already issued an FOV command then it sticks, and your view does not zoom in at all! My solution to this problem is to issue a FOV command when you right-click, and another FOV command when you release the right mouse button.&lt;br /&gt;&lt;br /&gt;My solution involves changing the Shared_Aim binding under BIOInput's &lt;span style="font-weight:bold;"&gt;[SFXGame.SFXGameModeBase]&lt;/span&gt; section. It looks like this originally:&lt;br /&gt;&lt;br /&gt;Bindings=( Name="Shared_Aim", Command="SwapWeaponIfEmpty | TightAim | OnRelease StopTightAim" )&lt;br /&gt;&lt;br /&gt;Change it as follows (change FOV 50 and FOV 100 to match your personal preference):&lt;br /&gt;&lt;br /&gt;Bindings=( Name="Shared_Aim", Command="FOV 0 | SwapWeaponIfEmpty | TightAim | OnRelease StopTightAim | OnRelease FOV 100" )&lt;br /&gt;&lt;br /&gt;The "FOV 0" command allows the game to revert to its normal FOV.&lt;br /&gt;&lt;br /&gt;During cutscenes the FOV will not work correctly correctly. In order to change the field-of-view whenever you want, I suggest binding some FOV commands to an unused key or to the number pad. Under the BIOInput heading &lt;span style="font-weight:bold;"&gt;[SFXGame.SFXGameModeBase]&lt;/span&gt;, add lines such as the following:&lt;br /&gt;&lt;br /&gt;Bindings=( Name="NumPadOne", Command="FOV 30")&lt;br /&gt;Bindings=( Name="NumPadTwo", Command="FOV 40")&lt;br /&gt;Bindings=( Name="NumPadThree", Command="FOV 50")&lt;br /&gt;Bindings=( Name="NumPadFour", Command="FOV 60")&lt;br /&gt;Bindings=( Name="NumPadFive", Command="FOV 70")&lt;br /&gt;Bindings=( Name="NumPadSix", Command="FOV 80")&lt;br /&gt;Bindings=( Name="NumPadSeven", Command="FOV 90")&lt;br /&gt;Bindings=( Name="NumPadEight", Command="FOV 100")&lt;br /&gt;Bindings=( Name="NumPadNine", Command="FOV 110")&lt;br /&gt;Bindings=( Name="NumPadZero", Command="FOV 0")&lt;br /&gt;&lt;br /&gt;Now you should be able to zoom in or out whenever you want by pressing a button on your keyboard's number pad... higher numbers give you more peripheral vision. Particularly important is the num-pad zero key, which releases your FOV override so that the game can choose the FOV. Actually, you'll want to push this key every time you start dialogue with someone, and every time a cutscene starts, so you might want to bind "FOV 0" to a more convenient key... I leave that as an exercise to the reader.&lt;br /&gt;&lt;br /&gt;In our apartment we have no need of the lower FOV settings, so we use these fun commands instead:&lt;br /&gt;&lt;br /&gt;Bindings=( Name="NumPadOne", Command="Ghost" )&lt;br /&gt;Bindings=( Name="NumPadTwo", Command="Walk" )&lt;br /&gt;Bindings=( Name="NumPadThree", Command="shot")&lt;br /&gt;&lt;br /&gt;The "Ghost" command lets you float in any direction, even through walls; "Walk" restores normal walking ability; and "shot" supposedly takes a screen-shot, although I haven't tried it yet. I got stuck in two places in Mass Effect 2, and Ghost allowed me to get un-stuck. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Changing the mouse sensitivity&lt;/h3&gt;&lt;br /&gt;To make the mouse less sensitive in-game, find the MouseSensitivity line under &lt;span style="font-weight:bold;"&gt;[SFXGame.BioPlayerInput]&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;MouseSensitivity=1.0&lt;br /&gt;&lt;br /&gt;Change this to a lower number. For me, &lt;br /&gt;&lt;br /&gt;MouseSensitivity=0.5&lt;br /&gt;&lt;br /&gt;worked best.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-4369829212903856731?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/4369829212903856731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=4369829212903856731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4369829212903856731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4369829212903856731'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2011/03/changing-fov-in-mass-effect-2.html' title='Changing the FOV in Mass Effect 2'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-2177565343631773571</id><published>2010-12-30T11:44:00.003-07:00</published><updated>2010-12-30T13:30:39.508-07:00</updated><title type='text'>Novial+English</title><content type='html'>To continue my &lt;a href="http://qscribble.blogspot.com/2010/12/novial.html"&gt;thoughts&lt;/a&gt; on a Novial-derived IAL... well, I have a couple of ideas. One idea is to create a North American IAL based on English, Spanish and French. This would be an excellent language for unifying the Americas. But how to market it, I am not sure. Another idea is to emphasize English in the language, using other languages only when the English way of saying something is ambiguous (e.g. "hard", "like", "just"), cumbersome due to its length ("understand", "approximately", "mutually exclusive"), or problematic because of its vowels.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Novial has only 5 vowels, while English has 9 or 10 "basic" vowels plus several diphthongs. Now, when we "compress" an English word down to 5 vowels, problems often appear. Either we can import the English spelling, e.g. "meat" pronounced "MEE-at" or "MEE-aht", or we can use the English pronunciation, e.g. "mit" (MEET) for "meat". If we use the spelling, at least two problems appear:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;What do we do with double vowels? I don't think we can ask people to pronounce "meet", "see", "book", and "foot" with two separate vowels, and if we say that the vowel is extra-long, people will disagree about how long is long enough. If we change "ee" to "i" and "oo" to "u", conflicts or false friends will appear: consider "boot" vs. "but", "beet" vs. "bit", etc. Likewise if we simply remove the duplicate vowel, "lok" could mean "look" or "lock", "bet" could mean "beet" or "bet", etc.&lt;/li&gt;&lt;li&gt;Some spellings will &lt;i&gt;sound&lt;/i&gt; like a different English word: "but" sounds like "boot", "sit" sounds like "seat", and "pan" may sound like "pawn" depending on how you say it ("aw" in "pawn", pronounced the same as "a" in "father", is an acceptable way to pronounce the Novial vowel "a"; it can also be pronounced like the Spanish vowel "a" which is slightly different).&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;If we use the pronunciation instead, there are even more problems:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Homonyms. English has many words that are spelled differently but sound the same: would/wood, meat/meet, so/sew, two/to/too. One cannot tell these words apart if we only use their pronunciation.&lt;/li&gt;&lt;li&gt;Many unrelated English words would map to the same word in the 5-vowel system. For example, "bit" could be "beet" or "bit", "mit" could be "meet" or "mit", "pan" could be "pan" or "pawn", "nuk" could be "nuke" or "nook", etc.&lt;/li&gt;&lt;li&gt;Some words would look like other English words when spelled phonetically. For example, rid=read, bot=boat.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Clearly, it will be necessary to take words from other languages when these conflicts arise. I consider some of the conflicts minor because one of the words involved in the conflict is minor; for example, the English word "meet" is much more common than "mit", so if we respell "meet" as "mit" then it's not difficult to teach learners that it means "meet", because hopefully they will not naturally confuse it with the uncommon word "mit". "mit" would also sound like "meat", but if we normally choose spellings based on English spellings (instead of the pronunciation), then students will develop an intuition that "meat" should be spelled "meat", not "mit". This, I hope, will reduce the amount of confusion.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In any case, we would mix Novial with English (instead of just using Novial unchanged) purely for the sake of marketing, in accordance with my &lt;a href="http://qscribble.blogspot.com/2010/12/principles-of-ial-design.html"&gt;principles of IAL design&lt;/a&gt;. Novial is a very nice language, but it has not succeeded on its own. It needs a hook: something to make people want to learn it. By infusing it with English, it could be marketed at English beginners worldwide.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my next post I think I will sketch out some ideas for what this mixed language would look like.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-2177565343631773571?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/2177565343631773571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=2177565343631773571' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2177565343631773571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2177565343631773571'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/12/novialenglish.html' title='Novial+English'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-8142170665041129135</id><published>2010-12-30T10:52:00.005-07:00</published><updated>2010-12-30T11:43:09.279-07:00</updated><title type='text'>Principles of IAL design</title><content type='html'>I was conversing recently with Bruce Gilson, who was once part of a committee of 5 to 8 people who were unhappy with the original Novial and wanted to reform it. They made numerous changes which were to be known as "Novial 98"; some I see as beneficial (such as making it possible to easily distinguish nouns from verbs), but for the most part I didn't like N98, firstly because I liked the original Novial design, and secondly because making major changes would discourage the formation of a Novial community by causing dischord between those of differing opinions about the language.&lt;br /&gt;&lt;br /&gt;Anyway, in that conversation I suggested a set of principles for IAL design that I would like to share, starting with the three most important:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Sellability: a plausible plan is necessary to get the language adopted by a large population. In my view, the plan should be inherent in the design of the language itself, so as to convince people that it is worth learning due to similarity with some language they want to learn, or to convince people it is so close to their own language that it is "easy". But it could also be a totally separate advocacy plan: convincing the UN or some organization to adopt the language for practical reasons, getting media coverage, convincing philanthropists to donate, finding a business model, etc. Really, both advocacy and language design should be part of the equation.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The greatest good for the greatest number: for example, it's good to take word roots from major living languages and even better to take common roots from multiple languages, so that the IAL is easy to learn for the greatest number of people. (However, designers often disagree about the exact formulation of this principle.)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Expressiveness: the language should be able to express most of the nuances possible in national languages, but this principle is subordinate to (1) and (2): every new word root adds a learning burden, particularly to those who do not know a language from whence the root came, but even familiar roots may need to be looked up in a dictionary in case they turn out to be "false friends". Therefore, adding roots to gain expressiveness can harm (1) and (2), while subtracting roots and senses improves (1) although not necessarily (2). For example, Esperanto religiously minimized the number of word roots. I'm sure this makes Esperanto easier to learn for all kinds of non-Europeans, but clearly the first market for Esperanto was Europeans, so this minimization didn't help the language sell.&lt;br /&gt;&lt;br /&gt;Note that it is often possible to increase expressiveness substantially by adding a single word or affix to the language. For example, Esperanto has a suffix "-ema" which means "having a tendency". Because of this, there are a series of words that are easy to learn, such as "amema" (loving, tending to love), "felicxema" (tending to be happy, as in "li estas felicxema" &lt;i&gt;he is a happy person&lt;/i&gt;), "parolema" (talkative), and "mangxema" (having a tendency to eat). In English we have special words or ways of saying this, such as "talkative" and "he is generally a happy/sad person", but this single suffix makes Esperanto more expressive, more regular and more concise than English for expressing this particular idea.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Conciceness: One thing that ticked me off about Esperanto was what I called its "longeco", longness. While often EO text was shorter, or the same length as an English equivalent, it took longer to speak. The word "estas" surely should have been shorter, and there were a lot of other examples, for example the "jn" endings made words longer even without adding syllables, "cent" is awkward compared to "sent" so it takes longer to say - I mean, the phonotactics of EO are as bad as English, but unfamiliar to us, and therefore annoying. And the compound words added to its length. I spoke more about conciseness in my previous post.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Now, I put these principles in what I think ought to be the priority order. The number one priority is one that is missing from existing language designs. Some interlinguists in the early 20th century, including Otto Jespersen (designer of Novial) seemed to think it was inevitable that an easy international language would eventually be adopted across the world, but this has proven to be untrue. Clearly, adoption of an interlanguage will not happen without some clever marketing and a lot of effort by a lot of people. Moreover, it is my belief that the language design itself can be a key part of that marketing strategy.&lt;br /&gt;&lt;br /&gt;In regard to "the greatest good for the greatest number", I do not interpret this to mean simply that we look at word roots and pick the most common one among several languages. That's not a bad thing at all, but I think it's wrong to limit oneself to that approach and none others. After all, it's rare that you can find a word root used (in the same sense!) by more than a billion people; thus for each word there are at least five billion people who would be unimpressed or baffled by each of your word choices. Therefore, in my view, using existing roots is as much about principle (1) as it is about (2), if not more so. Using existing roots makes it easier for us to get our foot in the door by saying "look how much international vocabulary you'll learn by leaning [IAL X]!" or "look how similar [IAL X] is to [language you want to learn]" or "look how easy this will be to learn because it's so much like your mother tongue".&lt;br /&gt;&lt;br /&gt;Note how these benefits disappear when the root comes from a source that a potential learner doesn't care about: for instance, most English speakers don't care to learn Norwegian, Danish or Swedish, and therefore won't like the false friend "at" (which means "to" [infinitive verb marker] in Scandinavian languages and Novial 98). I don't think it will matter to most Englishmen whether the word is "natural" or "a priori" (made up); in either case it is outside their realm of interest, as (I suspect) typical English speakers would rather learn Spanish, French, Japanese, German or even Mandarin before a Scandinavian language. Heck, in America a lot of English speakers might not care to learn anything at all besides more English (evidently, dedicated monoglots are not our target market).&lt;br /&gt;&lt;br /&gt;Now, of course, the Scandinavians will doubtlessly like the word choice "at". But a serious project should keep principle (1) in mind and ask itself: what word choices are more likely to lead to more "sales", that is, more people choosing to learn the language? It is sensible for an IAL to focus on one group of languages, such as European languages or languages around India, than to attempt mashing every single major world language together. The result of the latter approach just wouldn't interest enough people, in much the same way that an "a priori" language wouldn't interest enough people.&lt;br /&gt;&lt;br /&gt;In the end I would like to see billions of people adopt an IAL. But before that can happen, a community of millions must be built first. It makes sense, therefore, to design a language specifically to appeal to a particular group of 100-1000 millions or so, and once the design is complete, to market the language only to those millions. It doesn't matter much what that group is, as long as you have a plausible plan.&lt;br /&gt;&lt;br /&gt;Now, I have no objection to Scandinavian word roots. Nor do I object to "a priori" forms. I just doubt that Scandinavian words would fit very well into a plausible plan required by (1). If I'm right, then Scandinavian words and roots should not be considered much more valuable than a priori forms during language design. Sure, such words are good for (2), but principle (1) means keeping your eye on the prize: building a large community--and I mean large in terms of the number of speakers, not largely dispersed throughout the world, for the sheer distance between Esperanto speakers hasn't helped that language grow.&lt;br /&gt;&lt;br /&gt;"a priori" forms have their place because sometimes national languages lack an unambiguous word for a given idea, or a regular system of derivation. The preposition "ye", and the IAL standard of including part-of-speech markers or hints at the end of each word, are good examples. Surely no organic language in the world has a regular, unambiguous system of part-of-speech markers. Yet for the sake of (1) and (2), part-of-speech markers are very valuable, whether a priori (like Esperanto) or only partly a priori (like Novial). In addition, if you believe as I do that the value of a "friend" in one national language is negated somewhat by a "false friend" in another,&lt;br /&gt;it may happen that a neutral a priori form is the safest choice overall.&lt;br /&gt;&lt;br /&gt;Bruce opined, "If a language is truly going to be an INTERNATIONAL auxiliary language, it cannot mimic English TOO closely."&lt;br /&gt;&lt;br /&gt;I responded: well, that depends on what you think "international" means. I've heard more than one person say that there is already an international language: poor English. I kind of wince when I hear that, since I know that English doesn't function well as an IAL. "International" can mean "international flavor", i.e. resembling several languages, or it can mean "internationally used". I want to see a good IAL meet the second definition more than the first. If it can meet both at once, great. If not, surely it is more important for an IAL to be widely used than for it to be nominally "international".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-8142170665041129135?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/8142170665041129135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=8142170665041129135' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/8142170665041129135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/8142170665041129135'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/12/principles-of-ial-design.html' title='Principles of IAL design'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-3215732115735168390</id><published>2010-12-09T14:35:00.009-07:00</published><updated>2010-12-10T07:35:01.307-07:00</updated><title type='text'>Novial</title><content type='html'>I have been thinking lately about how difficult it is to simplify English enough to make it into a viable international auxilliary language (IAL), Haf Inglish. It can be done, although Haf Inglish would certainly be more difficult than other constructed languages such as Esperanto and Novial. However, although I could make Haf English superficially very close to English, I am concerned that the changes necessary to make Haf Inglish easier to learn also make it so different from English that &lt;i&gt;English speakers&lt;/i&gt; would find it hard to learn and use correctly. I worry that their English brains would constantly want to use English phrases that would be illegal in Haf Inglish. For example, I have noticed that certain English words are challenging to learn because they have many meanings, such as "tip". Observe the many meanings:&lt;ul&gt;&lt;li&gt;I gave her a tip of 2 dollars.&lt;/li&gt;&lt;li&gt;I gave her a tip of my hat.&lt;/li&gt;&lt;li&gt;I gave her the tip of my pencil.&lt;/li&gt;&lt;li&gt;I gave her a tip about how to do her job.&lt;/li&gt;&lt;li&gt;I will tip her two dollars.&lt;/li&gt;&lt;li&gt;I will tip her chair. Her chair will tip over.&lt;/li&gt;&lt;li&gt;The sound will tip off the police.&lt;/li&gt;&lt;/ul&gt;Clearly, if "tip" were to exist in Haf Inglish then it could not have this many meanings, because it would create major difficulties. Besides the sheer difficulty in learning so many definitions, the ambiguities would spill over into any derived forms that you might want to create. For example, would "tippic" mean "related to tips (money)", "related to tipping over", "related to tips (pointy ends)", "related to advice", or (if I may allude to a separate issue) "typical"?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Today, I have been reading again about &lt;a href="http://en.wikipedia.org/wiki/Novial"&gt;Novial&lt;/a&gt; in &lt;a href="http://en.wikibooks.org/wiki/Novial/AIL"&gt;this book&lt;/a&gt;; and the more I learn about it, the more I like it. Although some of its rules are more complicated than Esperanto, in most ways it is more regular and &lt;b&gt;just plain better&lt;/b&gt;. After having learned some Spanish, I am finding that I understand Novial after very little study, probably because a large percentage of Novial closely resembles parts of Spanish and English. In the case of English, Novial usually keeps the spelling and not the pronounciation, but some words, such as "tu" (to), "did" (did) and "vud" (would), also sound similar to English. Novial's author, Otto Jesperson, makes arguments about why his language is designed the way it is, and why he chose particular word forms... unlike Esperanto, which "just is" the way it is.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Another thing I like is that Novial is a compact language like English--you usually don't need a lot of syllables to express something. When learning Esperanto, I often complained about its longness--the fact that I had to say "li estas feliĉa", 6 syllables, to express an idea that is only 3 or 4 in English: "he's happy" or "he is happy". And then there are the redundant grammatical markers, such as "jn" in "Mi ŝatas viajn blankajn ŝuojn" (I like your white shoes), which do not add syllables but still take extra time to pronounce.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;In fact, due to its regularity, I suspect that &lt;i&gt;clear speech&lt;/i&gt; in Novial will typically be shorter than English, because in English we must use longer words to express our ideas formally or unambiguously. For example, informally I could say that something is "hard", but since this word has two meanings, I need to use the word "difficult" or "hard as a rock" if I want to speak unambiguously. English (and Spanish, by the way) also has some "holes" where no short word exists for a simple idea. For example, the common phrase "I don't understand" is 5 syllables (including long syllables "don't" and "stand"), which is just too long for such a common expression. No wonder English speakers sometimes shorten it to "I don't get it" or simply "what?". Likewise we shorten "simply" to "just", "because" to "as"/"for", "also" to "too", and so forth. These shortenings "overload" the small words with many meanings, which makes English harder to learn. At the same time, it is bad for a language to be too short, if the small words become so tiny that the listener can't hear them anymore. For example, in English "can't take" can be mistaken for "can take"; it's hard to hear the word "is" in "The dog's skillful"; and "Isn't that John smug?" could be mistaken for "Isn't that John's mug?"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Now, Novial probably has some longness issues too, but clearly fewer than Esperanto and probably fewer than English. At the same time, it is probably long enough that a listener won't often "miss" the short words. Only the words "e", "o" and "a" (and, or, to/toward) concern me in that they might be too short, but I'll give them the benefit of the doubt. One thing I don't like is the contraction del = de li, like the Spanish contraction del = de el (which makes more sense--note that you cannot contract Spanish "de la" to "del"), and the fact that you can omit the "i" suffix from most adjectives. The suffix helps the listener (who, remember, is not a native speaker) to clearly understand what is being said. Besides, if there are two ways to say the same word then it'll be harder to find that word on the web (at least until search engines support Novial specifically). Note, however, that Novial words are more invariant than words in most other languages including English. Sure, they change forms when the part-of-speech changes, but in contrast to most other languages, there is only a single verb form. Besides, I consider it largely an advantage, both for communication and searching, that the word form changes when the part-of-speech changes. Anyway, I plan to always include the "i" ending in both these cases.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I also like the fact that Novial almost always uses subject-verb-object word order (e.g. in Novial you say "I love you", and usually not "I you love" or "love I you" or "you I love".) Obviously as an English speaker I am biased, but this and other similarities between English and Novial make me wonder whether Novial can plausibly serve the same goal that I intended to pursue with Haf Inglish. Specifically, I wonder if I could get into the English-teaching business and convince learners that learning Novial would help them learn English. I have no doubt that Novial would help a person learn any major European language, especially English, and like Esperanto, I think Novial could help anyone who is learning a foreign language for the first time, but the trick is to convince others. Haf Inglish has a clear hook, that's why I pursued the idea in the first place, but could Novial suffice? If it can, then it should, for surely Novial is superior &lt;i&gt;as an IAL&lt;/i&gt;, even if it is inferior as an approximation of English.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;My goal, after all, is not that everyone should learn English or Haf Inglish or any particular language, but that everyone should be able to communicate with one another. How this goal is accomplished doesn't matter much. We can't realistically ask billions of people to learn an enormous language like English, but it would be realistic for billions of people to learn Esperanto or Novial. It would also be realistic to imagine that when one wants to learn English, one starts by learning an easier dialect first (Haf Inglish), and that once Haf Inglish has a hundred million speakers or so, a billion more people will want to learn it &lt;i&gt;instead of &lt;/i&gt;English.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Here are some example sentences in Novial and their translations. You'll see two translations; I always like to give a roughly direct translation first, in addition to a paraphrase. Yet Novial is similar enough to English that the direct translation is usually clear by itself.&lt;ul&gt;&lt;li&gt;es plu agreabli tu viva kam tu ha viva o tu sal viva.&lt;br /&gt;Is more agreeable* to live than to have live or to shall live.&lt;br /&gt;It is better to live than to have lived or to live someday.&lt;br /&gt;* &lt;a href="http://www.blahedo.org/novial/nl.html"&gt;Novial lexike&lt;/a&gt; lacks a translation for this word&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Hir es multi roses: ob vu prefera li blankis o li redis?&lt;br /&gt;Here are many roses: do* you prefer the whites or the reds?&lt;br /&gt;* If we want to be picky, "ob" literally means "whether" and is used to make yes/no questions. "Ob" replaces "do" in questions like "Do you like it?". In questions like "Is it big?", and "Are you happy?", you use "ob" in addition to "es", the word for "is/are": "Ob lum es grandi?" (Whether it is big?) and "Ob vu es felisi?" (Whether you are happy?)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Li blanki es plu bel kam li redi.&lt;br /&gt;The white is more beautiful than the red.&lt;br /&gt;The white one is prettier than the red one.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Li porte non es klosat nun; lum bli klosa chaki vespre e sal anke bli klosa dis vespre.&lt;br /&gt;The door not is closed now; it gets* close every evening and will also get close this evening.&lt;br /&gt;The door is not closed now; it gets closed every evening and will also get closed this evening.&lt;br /&gt;* "bli" only means "get" as in "to become", not "to obtain". "bli" is easier to remember if you think of it as "being": bli klosa = "being closed".&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Me non ha e non sal responda.&lt;br /&gt;I not have and not shall* respond.&lt;br /&gt;I have not and shall not respond.&lt;br /&gt;* Technically "sal" means "will", but usually "shall" is an acceptable translation which helps you remember what "sal" means.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ob vu ha manja? No, non ankore, ma men fratre ha ja e me sal bald.&lt;br /&gt;Whether you have eat? No, not yet, but my sibling has already and I will soon.&lt;br /&gt;Have you eaten? No, not yet, but my sibling has already, and I will soon.&lt;br /&gt;...After studying Spanish (which has something like 100 unique &lt;i&gt;regular&lt;/i&gt; verb conjugations plus numerous irregular conjugations), the verb constructions in Novial, which are like English but simpler, are a welcome relief.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Me ama la kom me ha men matra e kom* me sal men filies.&lt;br /&gt;I love her as I have my mother and as I shall my children.&lt;br /&gt;...It may not look like English, but it's nice that the word-for-word translation is perfect English.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;As you can see, Novial's grammar and some of its words are often very close to English, just with (perhaps optional) differences in the placement of "not". Of course, when the words look like English words they still don't sound like English words, but at least the pronounciation system is very easy to learn, easier than Esperanto and much easier than Haf Inglish (to say nothing of Full English).&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/16943816-3215732115735168390?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/3215732115735168390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=3215732115735168390' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/3215732115735168390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/3215732115735168390'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/12/novial.html' title='Novial'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-5650732204788552229</id><published>2010-10-26T14:27:00.006-06:00</published><updated>2010-10-26T16:58:48.146-06:00</updated><title type='text'>Haf Inglish proegram iydias</title><content type='html'>&lt;div&gt;Note: the prefix "dis-" means "oppisit of". "Werdery" means "dictionary" (litterully, "place for werds".)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Soundic uttack&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Haf Inglish has soundic spelling, but like English, it has diseasy spelling rules. I woood like to make a vidio game to help persuns to practis to decode spellings.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Base.d on &lt;a href="http://en.wikipedia.org/wiki/Tetris_Attack"&gt;Tetris Uttack&lt;/a&gt;, Soundic Uttack woood sho yoo piles of blocks. Each block is labullated with up to five letters and/or simbuls (puncchuayshun). One letter is &lt;b&gt;bold&lt;/b&gt;, uujhoolly a vowl or dipthong. Yor goal is to remember the sound that the secund letter makes (which chainjes base.d on the after.ic letters), fiynd uther blocks thut represent the same sound, and moov the relate.d blocks into lines to make them disuppear (gaining points at the same time). The cullers of the blocks under the pointer are sho.d temporerrily. A simmiller game coood be made base.d on &lt;a href="http://en.wikipedia.org/wiki/Dr._Mario_(video_game)"&gt;Dr. Mario&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Spelling checker/grammer highlighter/werdery&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A smaal proegram that checks each werd ugainst the Haf Inglish werd data.set. It coood identifyy misspell.d werds (with red underlines), uuz cullers to identifyy vowls, and uuz styles to identifyy parts of speakness (speshully verbs, the center.ic part of eny sentunce). Nowicly, I myyself often make Haf Inglish spelling errors cuz byy habbit I uuz English spellings. This kiynd of proegram woood be helpful for myy oen writing, not oenly for uthers. Allso, when there be th.ree vowls (or speshul disvowls) in a row, it is less clear which soundic rules applyy, so a proegram woood help to disambiguuify.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The proegram shoood include a werdery with define.shuns. I woood allso like to hav a data.set of fotoes of nouns, so that meaning can be sho.d seeicly.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-5650732204788552229?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/5650732204788552229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=5650732204788552229' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/5650732204788552229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/5650732204788552229'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/10/haf-inglish-program-ideas.html' title='Haf Inglish proegram iydias'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-359231473518694723</id><published>2010-09-13T20:51:00.002-06:00</published><updated>2010-09-13T20:56:40.216-06:00</updated><title type='text'>Metro 2033 graphics bug</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_y8ybb5S16Uc/TI7jhxaRjEI/AAAAAAAAACQ/qui7yZ6fu4E/s1600/Metro2033+graphics+bug.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://1.bp.blogspot.com/_y8ybb5S16Uc/TI7jhxaRjEI/AAAAAAAAACQ/qui7yZ6fu4E/s400/Metro2033+graphics+bug.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5516596762914163778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=IoXYvVKo2io"&gt;How it's supposed to look&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-359231473518694723?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/359231473518694723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=359231473518694723' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/359231473518694723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/359231473518694723'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/09/metro-2033-graphics-bug.html' title='Metro 2033 graphics bug'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_y8ybb5S16Uc/TI7jhxaRjEI/AAAAAAAAACQ/qui7yZ6fu4E/s72-c/Metro2033+graphics+bug.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-7838015142331855903</id><published>2010-08-31T08:00:00.014-06:00</published><updated>2010-10-26T18:09:24.130-06:00</updated><title type='text'>Haf Inglish</title><content type='html'>Haf Inglish is my idea for a simplified, one-way-phonetic form of American English designed as either a stepping stone for those learning full English, or as an international language in its own right. It would be marketed as the fastest way to learn English, because you can pick it up much faster than normal English, particularly for those without English immersion.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Its first target audience would be Latin American people, so I'll take advantage of the fact that they can type accents, encouraging (but not requiring) use of accents on stressed syllables other than the second-to-last.&lt;div&gt;&lt;ul&gt;&lt;li&gt;The most common words of Haf Inglish would be pronounced like Standard English, with spelling adjusted to be phonetic. It would be phonetic in the same sense Spanish is: you can predict the pronounciation from the spelling, but not the other way around. The spelling changes are designed so that native English speakers can still recognize the words after the spelling changes, and so that many words are spelled the same way. Consequently, the spelling rules are complex, but not nearly as bad as English.&lt;/li&gt;&lt;li&gt;Haf Inglish does not have the words "am", "are" and "were". Replace these words with "be", "be" and "was" respectively. It still has "is", "was" and "been".&lt;/li&gt;&lt;li&gt;A fixed number of spelling exceptions (under 20) will be allowed for common words like "I" and "the". Exceptions are reserved for very common words, especially those which are hard to recognize (by English speakers) when spelled phonetically, or whose spelling would no longer be unique among synonyms (e.g. be vs bee). Currently I've chosen 14 exceptions: the, of, to, I, be, some, do, their, two, come, know, does, put, knew. Notice that 8 of these (to, I, be, some, their, two, come, know) have homonyms, and if they were spelled phonetically they could be confused with their homonym.&lt;/li&gt;&lt;li&gt;In addition to these exceptions, there are a few words that &lt;i&gt;could&lt;/i&gt; be pronounced as they are spelled, but usually/often are not: a, an, been, for. Also, there are a few words which are spelled with an "s" that is pronounced "z": is, ease, always, has. However, in these cases the words are still understandable if the speaker uses an "s" sound, so I don't respell them for that reason alone. I replace "s" with "z" only if the word must be respelled for some other reason.&lt;/li&gt;&lt;li&gt;There are several short English words that end in "e": be, he, me, she, we. We could respell he, me, she, and we as "hee", "mee", "shee", and "wee", but I already decided "be" should be kept the same to distinguish it from "honey bee", and these words seem common enough to justify a special pronounciation rule just for them.&lt;/li&gt;&lt;li&gt;Phonetic rules are based on existing patterns, e.g. a silent e can make a so-called "long" vowel ("bite", "fate" vs "bit", "fat"), vowels sound different at the end of a word ("pot" vs "so"), and double letters force a "short" vowel ("better" vs "meter", "filling" vs "filing"). However, sometimes normal English spelling provides no way to distinguish between two sounds, like the "oo" in book and loot, and for these situations a new rule is required and one category of words must be respelled.&lt;/li&gt;&lt;li&gt;The rules for forming past tense and plurals would be regular with only a small number of exceptions: foot to foots, flyy to flyy.d, read to read.d, etc.; yet still, is to wuz, do to did, and this to these.&lt;/li&gt;&lt;li&gt;A dot (.) is used to separate morphemes to keep spellings phonetic. For example, it is clear in the word "same" that the "e" is silent. However, when forming the compound word "sametimely" (meaning simultaneously), Haf Inglish rules would require the "e"s to be pronounced unless a dot is added to separate the parts: same.time.ly. Two other important issues are past tense and plurals. I think for plurals, there should be a rule that the "e" in "es" is silent, or pronounced "uh" when the plural rules require it. When you consider that 3rd-person singular verb conjugations also use the plural ending, you realize that this ending is very common in English and therefore should be emulated in Haf English. However, I currently think past tense should be marked more regularly, with ".d" for all past tense (and past participle) endings regardless of their pronounciation.&lt;/li&gt;&lt;li&gt;Spelling changes would be designed so that a native English speaker can easily recognize the original word despite the changed spelling, e.g. "hee" for "he", "wuz" for "was". Being a slang spelling, the latter might strike a nerve with some, but you no doubt recognized the word, yes? If possible, a word is made phonetic by adding, removing or changing one letter, e.g. "unit" =&gt; "uunit" (where "uu" is pronounced "yoo"), "learn" =&gt; "lern".&lt;/li&gt;&lt;li&gt;Uncommon and international words (for example, the word "international") would keep their spelling the same, and pronounciation would follow the HI rules.&lt;/li&gt;&lt;li&gt;There should be a set of about 1000-1500 word roots to be learned for everyday communication; some words would be excluded specifically from the language so that English speakers learning Haf English can specifically learn &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; to use them. Words could be divided into "beginner" and "intermediate" roots.&lt;/li&gt;&lt;li&gt;The oo in book and the oo in boon would be &lt;a href="http://en.wikipedia.org/wiki/Allophone"&gt;allophones&lt;/a&gt;, but I'm thinking of using an extra letter to indicate the former ("boook")&lt;/li&gt;&lt;li&gt;The th in then and thin could also be allophones, but can we distinguish between them in writing? I notice that when a word ends with "th", it is usually unvoiced: bath, path, hath, myth, wrath; but it is usually voiced otherwise: them, that, they, bathe, lathe. Therefore, in the rare case that "th" is unvoiced but is not at the end, it could be marked with a dot (.): "th.in", "th.ick", "th.ink", "th.ing". However, since "th.ink" and "th.ing" are very common words, inserting the dot every time is a significant burden, so perhaps it should be optional.&lt;/li&gt;&lt;li&gt;The g in dog, age and garage must be distinguished. I propose "g" for gift, "j" for "gist" and "jh" for usual. However, I think the spelling of "usual" should be left unchanged because its phonetic spelling "uujhool" is too far from the original spelling.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;s and z are not allophones. With the exception of plurals that are still spelled with an s, s and z must be distinguished by changing some words spelled with "c" or "s" to use "z" instead. Less important words will not be respelled if there is no name collision; instead the learner will be allowed to pronounce the z as an s. For example, you can say "thousund" instead of "thouzund", but you must not pronounce "lose" (looz) as "loose".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Contractions of "is" are allowed, but not "was" or "are" or "am". "don't", "didn't", and "won't" are also allowed. I am reluctant to allow "can't" because it can cause confusion when someone says something like "I can take it"--and listener might think he/she said "I can't take it". Maybe contractions of "have" and "has" should be allowed, but only if it's the helping verb: I've seen and she's seen, but not I've a car or she's a car. Then again, "He's" can mean "he is" or "he has", so if the contraction for "has" is allowed, one must infer the meaning from the context. He's blue and he's eating clearly use "is", but many sentences are ambiguous: "he's leave.d" could mean "he has leave.d" or "he is leave.d".&lt;/li&gt;&lt;li&gt;Words with many meanings make English harder to understand, so to lighten the burden, certain meanings are banned in Haf Inglish. The word pronounced "too" has five meanings in English: "two apples", "to the store", "to eat", "too large", and "you too". The last of these is banned; you must say "yoo allso" instead of "yoo too". The other meanings can be distinguished by their spelling, but are harder to distinguish in voice communication. The word "that" has at least two meanings: (1) "I ate that" versus (2) "I think that you are right" and "the thing that you see". The first is a nounoid (it plays the role of a noun), the second is a connecting word (it is debatable whether the different grammars of the two phrases should be considered different meanings of "that"). I think these two meanings should be distinguished, so I will be using "that" for (1) and "thut" for (2): "I eat.d that" but "I th.ink thut yoo be right".&lt;/li&gt;&lt;li&gt;In the same vein, English allows many words to be either verbs or nouns, which I believe can make it harder for a learner to decode sentences. Haf Inglish will segregate nouns and verbs. Tentatively, "ate" is a suffix to change nouns into verbs, and "ing" changes verbs into gerunds or nouns: verbs "kick", "bite", "see" become "a kicking", "a biting", and "a seeing" and not "a kick", "a bite" and "a view" as in English. The nouns "immij" (image), "Google", and "sex" become the verbs "immijate" or "immijify" (make an image or imagine), "Googlate" (search the web), and "sexate" (have sex).&lt;/li&gt;&lt;li&gt;There will be several minor grammar changes. Usually English-style grammar is correct, but some ways of speaking are correct in Haf Inglish that are wrong (or archaic) in English, e.g. both "I eat.d not the sandwich" and "I didn't eat the sandwich" are correct.&lt;/li&gt;&lt;li&gt;Vowels are of course a disaster in English spelling. So I'm making this post to experiment with a spelling system that is phonetic by translating a short story by Terry Bisson....&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;They're Made Out Of Meat&lt;/div&gt;&lt;div&gt;They Be Made Of Meat.&lt;/div&gt;&lt;br /&gt;"They're made out of meat."&lt;/div&gt;&lt;div&gt;"They be made of meat."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;"Meat?"&lt;/div&gt;&lt;div&gt;"Meat?"&lt;br /&gt;&lt;br /&gt;"Meat. They're made out of meat."&lt;/div&gt;&lt;div&gt;"Meat. They be made of meat."&lt;br /&gt;&lt;br /&gt;"Meat?"&lt;/div&gt;&lt;div&gt;"Meat?"&lt;br /&gt;&lt;br /&gt;"There's no doubt about it. We picked several from different parts of the planet, took them aboard our recon vessels, probed them all the way through. They're completely meat."&lt;br /&gt;"Therr's no dout ubout it. We picked sevral frum diffrent parts of the werld, toook them ontoo our scout ships, exammin.d them all the way thru. They're cumplete.ly meat."&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;"That's impossible. What about the radio signals? The messages to the stars."&lt;br /&gt;&lt;div&gt;That's dispossible. Wut ubout the radio signals? The messijjes to the stars."&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"They use the radio waves to talk, but the signals don't come from them. The signals come from machines."&lt;/div&gt;&lt;div&gt;"They uuz the radio waves to tawk, but the signuls don't come frum them. The signals come frum mushéens."&lt;br /&gt;&lt;br /&gt;"So who made the machines? That's who we want to contact."&lt;br /&gt;"So hoo made the mushéens? That's hoo wee wont to contact."&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;"&lt;span style="font-style: italic;"&gt;They&lt;/span&gt; made the machines. That's what I'm trying to tell you. Meat made the machines."&lt;br /&gt;"&lt;span style="font-style: italic;"&gt;They&lt;/span&gt; made the musheens. That's wut I be tryying to tell yoo. Meat made the musheens."&lt;br /&gt;&lt;br /&gt;"That's ridiculous. How can meat make a machine? You're asking me to believe in sentient meat."&lt;br /&gt;"That's ridicuulus. How can meat make a musheen? You be asking me to beleve in sentient* meat."&lt;br /&gt;* Not phoneticized due to its rarity in English, plus the fact that it is still understandable when sounded out as "senteent".&lt;br /&gt;&lt;br /&gt;"I'm not asking you, I'm telling you. These creatures are the only sentient race in the sector and they're made out of meat."&lt;br /&gt;"I'm not asking yoo, I'm telling yoo. These creachurs are the ohnly sentient race in the erria and they be made of meat."&lt;br /&gt;&lt;br /&gt;"Maybe they're like the Orfolei. You know, a carbon-based intelligence that goes through a meat stage."&lt;br /&gt;"Maybee they're like the Orfolei. Yoo know, a carbun-base.d intéllijjence that goes thru a meat stage."&lt;br /&gt;&lt;br /&gt;"Nope. They're born meat and they die meat. We studied them for several of their life spans, which didn't take too long. Do you have any idea the life span of meat?"&lt;br /&gt;"No. They be born meat and they diy meat. We study.d them for sevral of their life-lengths, which didn't take too much time. Do yoo have eny iydia ubout the life length of meat?"&lt;br /&gt;&lt;br /&gt;"Spare me. Okay, maybe they're only part meat. You know, like the Weddilei. A meat head with an electron plasma brain inside."&lt;br /&gt;"Keep me frum it. Okay, maybee they be ohnly partly meat. Yoo know, like the Weddilei. A meat hed with an electron plasma brain inside."&lt;br /&gt;&lt;br /&gt;"Nope. We thought of that, since they do have meat heads like the Weddilei. But I told you, we probed them. They're meat all the way through."&lt;br /&gt;"Nope. We th.ink.d of that, since they do have meat heds like the Weddilei. But I told yoo, wee exammin.d them. They be meat all the way thru."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;"No brain?"&lt;br /&gt;"No brain?"&lt;br /&gt;&lt;br /&gt;"Oh, there is a brain all right. It's just that the brain is made out of meat!"&lt;br /&gt;"Oh, therr is a brain all right. But the brain is made of meat!"&lt;br /&gt;&lt;br /&gt;"So... what does the thinking?"&lt;br /&gt;"So... wut does the th.inking?"&lt;br /&gt;&lt;br /&gt;"You're not understanding, are you? The brain does the thinking. The meat."&lt;br /&gt;"Yoo be not understanding, be yoo? The brain does the th.inking. The meat."&lt;br /&gt;&lt;br /&gt;"Thinking meat! You're asking me to believe in thinking meat!"&lt;br /&gt;"Thinking meat! Yoo be asking me to beleve in th.inking meat!"&lt;br /&gt;&lt;br /&gt;"Yes, thinking meat! Conscious meat! Loving meat. Dreaming meat. The meat is the whole deal! Are you getting the picture?"&lt;br /&gt;"Yes, th.inking meat! Conscious* meat! Luvving meat. Dreaming meat. The meat is the hol deal! Are yoo getting the immij?"&lt;br /&gt;&lt;br /&gt;"Omigod. You're serious then. They're made out of meat."&lt;br /&gt;"Oh myy god. Yoo be serious then. They be made of meat."&lt;br /&gt;&lt;br /&gt;"Finally, Yes. They are indeed made out of meat. And they've been trying to get in touch with us for almost a hundred of their years."&lt;br /&gt;"Fiynully, Yes. They be indeed made of meat. And they hav been trying to get in tuch with us for allmohst a hundrud of therr years."&lt;br /&gt;&lt;br /&gt;"So what does the meat have in mind?"&lt;br /&gt;"So wut does the meat hav in mind?"&lt;br /&gt;&lt;br /&gt;"First it wants to talk to us. Then I imagine it wants to explore the universe, contact other sentients, swap ideas and information. The usual."&lt;br /&gt;"First it wonts to tawk to us. Then I imajjin it wants to explore the uunivverse, contact sentients, exchainj iydias and informayshun. The uujhool."&lt;br /&gt;&lt;br /&gt;"We're supposed to talk to meat?"&lt;br /&gt;"We be expect.d to tawk to meat?"&lt;br /&gt;&lt;br /&gt;"That's the idea. That's the message they're sending out by radio. 'Hello. Anyone out there? Anyone home?' That sort of thing."&lt;br /&gt;"That's the iydia. That's the messij they're sending out byy radio. 'Hello. Enywun out there? Enywun home? That sort of thing."&lt;br /&gt;&lt;br /&gt;"They actually do talk, then. They use words, ideas, concepts?"&lt;br /&gt;"They acchoolly do tawk, then. They uuz iydias, concepts?"&lt;br /&gt;&lt;br /&gt;"Oh, yes. Except they do it with meat."&lt;br /&gt;"Oh, yes. Exceptly they do it with meat."&lt;br /&gt;&lt;br /&gt;"I thought you just told me they used radio."&lt;br /&gt;"I th.ink.d yoo just tell.d me that they uuz.d radio."&lt;br /&gt;&lt;br /&gt;"They do, but what do you think is on the radio? Meat sounds. You know how when you slap or flap meat it makes a noise? They talk by flapping their meat at each other. They can even sing by squirting air through their meat."&lt;br /&gt;"They do, but wut do yoo th.ink is on the radio? Meat sounds. Yoo know how--when yoo hit or wave meat tugether--it makes a noise? They tawk byy waving tugether therr meat at each other."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;"Omigod. Singing meat. This is altogether too much. So what do you advise?"&lt;br /&gt;"Oh myy god. Singing meat. This is alltugether too much. So wut do yoo advise?&lt;br /&gt;&lt;br /&gt;"Officially or unofficially?"&lt;br /&gt;"Uffishully or nonuffishully?"&lt;br /&gt;&lt;br /&gt;"Both."&lt;br /&gt;&lt;br /&gt;"Officially, we are required to contact, welcome, and log in any and all sentient races or multibeings in the quadrant, without prejudice, fear, or favor. Unofficially, I advise that we erase the records and forget the whole thing."&lt;br /&gt;"Uffishully, we are reequire.d to contact, welcum, and log in eny and all sentient races or multi-beings in the quorter, without prejudice, fear, or fayverness. Unuffishully, I advise that we erase the reckerds and forget the hol thing.&lt;br /&gt;&lt;br /&gt;"I was hoping you would say that."&lt;br /&gt;"I wuz hoping yoo woood say that."&lt;br /&gt;&lt;br /&gt;"It seems harsh, but there is a limit. Do we really want to make contact with meat?"&lt;br /&gt;"It seems harsh, but therr is a limmit. Do wee truely wont to make contact with meat?"&lt;br /&gt;&lt;br /&gt;"I agree one hundred percent. What's there to say? 'Hello, meat. How's it going?' But will this work? How many planets are we dealing with here?"&lt;br /&gt;"I ugree wun hundrud percent. Wut's therr to say? 'Hello, meat. How be yoo?' But will this werk? How meny planuts be we manijjing here?"&lt;br /&gt;&lt;br /&gt;"Just one. They can travel to other planets in special meat containers, but they can't live on them. And being meat, they only travel through C space. Which limits them to the speed of light and makes the possibility of their ever making contact pretty slim. Infinitesimal, in fact."&lt;br /&gt;"Ohnly wun. They can travul to uther planuts in speshul meat cuntainers, but they can not liv on them. And, being meat, they ohnly travul thru C-space. Which limmits them to the speed of light and makes the possible.ness thut they ever make contact verry slim. Infittessimal, in fact."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;"So we just pretend there's no one home in the universe."&lt;br /&gt;"So we simply pretend therr's no wun at home in the uunivverse."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;"That's it."&lt;/div&gt;&lt;div&gt;"That's it."&lt;br /&gt;&lt;br /&gt;"Cruel. But you said it yourself, who wants to meet meat? And the ones who have been aboard our vessels, the ones you have probed? You're sure they won't remember?"&lt;/div&gt;&lt;div&gt;"Cruel. But yoo say.d it yorself, hoo wonts to meet meat? And the wuns hoo hav been ontoo our ships, the wuns you hav prob.d? Yoo be shur they wo.n't remember?"&lt;br /&gt;&lt;br /&gt;"They'll be considered crackpots if they do. We went into their heads and smoothed out their meat so that we're just a dream to them."&lt;br /&gt;"They will be th.ink.d to be dissane if they do. We went intoo their heds and smoothate.d their meat so that we be ohnly a dream to them." &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"A dream to meat! How strangely appropriate, that we should be meat's dream."&lt;/div&gt;&lt;div&gt;"A dream to meat! How strainjly fitting, thut we be meat's dream."&lt;br /&gt;&lt;br /&gt;"And we can mark this sector unoccupied."&lt;/div&gt;&lt;div&gt;"And we can mark this sector nonocuupy.d."&lt;br /&gt;&lt;br /&gt;"Good. Agreed, officially and unofficially. Case closed. Any others? Anyone interesting on that side of the galaxy?"&lt;/div&gt;&lt;div&gt;"Goood. Agreed, uffishully and nonuffishully. Case cloze.d. Eny uthers? Enywun intresting on that side of the galaxy?"&lt;br /&gt;&lt;br /&gt;"Yes, a rather shy but sweet hydrogen core cluster intelligence in a class nine star in G445 zone. Was in contact two galactic rotations ago, wants to be friendly again."&lt;/div&gt;&lt;div&gt;"Yes, a rather shyy but sweet hyydrogen core cluster intéllijjence in a class-nine star in G445 zone.&lt;br /&gt;&lt;br /&gt;"They always come around."&lt;/div&gt;&lt;div&gt;"They allways warm up to us."&lt;/div&gt;&lt;div&gt;("come around" is an idium not likely to be comprend.d. I th.ink "warm up" can be clear in-context.)&lt;br /&gt;&lt;br /&gt;"And why not? Imagine how unbearably, how unutterably cold the universe would be if one were all alone."&lt;/div&gt;&lt;/div&gt;&lt;div&gt;"And whyy not? Imajjify how nontolerably, how nonspeakably cold the uunivverse woood be if wun wuz all alone."&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-7838015142331855903?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/7838015142331855903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=7838015142331855903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7838015142331855903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7838015142331855903'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/08/haf-inglish.html' title='Haf Inglish'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-3264694442812437049</id><published>2010-07-15T12:02:00.004-06:00</published><updated>2010-07-15T12:05:56.284-06:00</updated><title type='text'>The Ultimate 3D Home Theater PC</title><content type='html'>The biggest problem with this article by Maximum PC is their suggestion to buy a $95 video card. Friends, there is very little 3D movie and TV content available and you'll probably pay a ton of money for it. Why not spring for a 3D video game PC instead? NVIDIA's 3D Vision will retrofit most of your existing games to 3D. For that you'll need at least a $350 GeForce GTX 470, because 3D mode cuts the framerate in half or worse.&lt;br /&gt;&lt;br /&gt;At my place we already have the ultimate budget 3D home theatre system. We got a PJD6531w which is probably the lousiest 3D projector on the market (with e.g. its lower brightness in 120Hz mode), but it cost just $800 (plus over $300 for 2 pairs of glasses including the NVidia 3D kit). Sit 5 feet away from your 100-inch screen, Crank up the field of view of your game to 100 degrees, play around with the "advanced" hotkeys to make objects pop out of the screen, and it's nothing like what you've played before!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-3264694442812437049?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.maximumpc.com/article/features/home_theater_vengeance' title='The Ultimate 3D Home Theater PC'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/3264694442812437049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=3264694442812437049' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/3264694442812437049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/3264694442812437049'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/07/ultimate-3d-home-theater-pc.html' title='The Ultimate 3D Home Theater PC'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-7472317680451506119</id><published>2010-07-12T23:14:00.005-06:00</published><updated>2010-07-13T00:25:23.339-06:00</updated><title type='text'>Caprica review</title><content type='html'>&lt;em&gt;My take after the first 9 episodes: simply put, Caprica sucks. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;As a fan of Battlestar, I found Caprica to be huge disappointment from the pilot onward, certainly worse than BSG's final season. BSG, I thought, started great but took a turn for the worse in season 3 and got still worse in season 4. It went uber-dark, characters became increasingly dysfunctional, and the main plot never really came together. Caprica is a couple of notches below BSG Season 4 in every possible way.&lt;br /&gt;&lt;br /&gt;Scientifically, the show demonstrates a shocking ignorance of all the science, technology and biology it is based on; any educated person should be offended. It starts with angry teenager Zoe Graystone creating a seemingly perfect replica of herself in cyberspace using little more than various computer records and videos of herself. The absurdity gets worse after Zoe dies, when her father Daniel finds out what Zoe had done and, in just a day or two, builds a completely convincing intelligent being (Tamara Adama) with an accurate and seemingly complete personality and memory, based on nothing more than whatever random database records he could find about this dead person. And that's just the beginning. The show just goes on and on and on with asinine "syfy" that is blissfully unaware of how face-palmingly stupid its technical aspects are.&lt;br /&gt;&lt;br /&gt;So the human race developed hyper-intelligent AI using... nothing more than a couple days work from Daniel and a maybe a year of her dead terrorist daughter's free time? Really? That's their explanation for the origin of the Cylons? The same cylons that try to exterminate the human race for no clear reason? Surely backstories don't get dumber than this. This show craps on the memory of BSG, friends.&lt;br /&gt;&lt;br /&gt;All the main characters are flawed, unethical to some degree, not all that likable, somewhat bland, and not well developed, so that none of them really stands out from the others. The few meaningful relationships between characters are dysfunctional to the point of being annoying, like Daniel Graystone's passing familiarity with his wife. The plot moves almost glacially slowly, as if they just can't think of anywhere to go with it.&lt;br /&gt;&lt;br /&gt;On the plus side, the acting is good and there's enough drama to keep one from falling asleep. But I hate to see a great show like BSG leaving behind nothing but a turd like this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-7472317680451506119?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/7472317680451506119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=7472317680451506119' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7472317680451506119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7472317680451506119'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/07/caprica-review.html' title='Caprica review'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-5161186397606564787</id><published>2010-01-22T10:05:00.004-07:00</published><updated>2010-06-05T17:36:59.740-06:00</updated><title type='text'>Charmaine's Tokyo</title><content type='html'>If home is where the heart is, then my heart is lost at sea&lt;br /&gt;And I, I have built my palace where the sand and waters meet.&lt;br /&gt;&lt;br /&gt;I've been living on this island, I saw you pass me by&lt;br /&gt;Calling out to me, hope within your eyes&lt;br /&gt;Love is an adventure, I'll take my chance on you, on you&lt;br /&gt;&lt;br /&gt;Chorus&lt;br /&gt;Rio, France, meet me in Mexico&lt;br /&gt;Chinatown then off to Tokyo&lt;br /&gt;It doesn't matter cause anywhere's perfect with you&lt;br /&gt;&lt;br /&gt;City lights, colors of indigo&lt;br /&gt;Sun or snow don't matter where we go&lt;br /&gt;It'll be perfect cause it's all amazing with you&lt;br /&gt;&lt;br /&gt;We're singing,&lt;br /&gt;Oh Oh Oh Oh&lt;br /&gt;Oh Oh Oh Oh&lt;br /&gt;&lt;br /&gt;Home is where the heart is, and my heart is in your hand&lt;br /&gt;n' you, you can build Your Kingdom in the center of this life.&lt;br /&gt;&lt;br /&gt;And I, I'm stepping off this island,&lt;br /&gt;never looking back, you're my only home&lt;br /&gt;&lt;br /&gt;Rio, France, meet me in Mexico&lt;br /&gt;Chinatown, then off to Tokyo&lt;br /&gt;It doesn't matter cause anywhere's perfect with you&lt;br /&gt;&lt;br /&gt;Oh Oh Oh Oh&lt;br /&gt;Oh Oh Oh Oh&lt;br /&gt;Oh Oh Oh Oh&lt;br /&gt;Oh Oh Oh Oh&lt;br /&gt;&lt;br /&gt;(Instrumental 0:23)&lt;br /&gt;&lt;br /&gt;Santa Fe, Chile, Romania&lt;br /&gt;Africa then to Australia&lt;br /&gt;It doesn't matter cause anywhere's perfect with you&lt;br /&gt;&lt;br /&gt;Open skies, freedom is beautiful&lt;br /&gt;Rain or shine, no matter where we go&lt;br /&gt;It'll be perfect cause it's so incredibly true&lt;br /&gt;It'll be perfect cause it's so amazing with you&lt;br /&gt;&lt;br /&gt;We're singing oh oh oh oh-uh-oh-uh-oh&lt;br /&gt;Whoh oh oh oh&lt;br /&gt;Whoh oh oh-uh-oh-uh-oh&lt;br /&gt;Whoh oh oh oh&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-5161186397606564787?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/5161186397606564787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=5161186397606564787' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/5161186397606564787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/5161186397606564787'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2010/01/charmaines-tokyo.html' title='Charmaine&apos;s Tokyo'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-4588335486652867158</id><published>2009-04-22T16:43:00.014-06:00</published><updated>2011-04-28T17:03:42.148-06:00</updated><title type='text'>Fastest Routing Algorithm Ever</title><content type='html'>It's called Contraction Hierarchies and it's so awesome.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://algo2.iti.uni-karlsruhe.de/documents/routeplanning/geisberger_dipl.pdf"&gt;Contraction Hierarchies: Faster and Simpler Hierarchical Routing in Road Networks&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This paper is 70 pages ... note that there is another paper that has exactly the same title, but is only 15 pages. The latter is pretty much incomprehensible so make sure to only use the long version.&lt;br /&gt;&lt;br /&gt;Oh and the same group of German researchers has come up with even faster algorithms, but I think they all use Contraction Hierarchies as a starting point. Dominik Schultes (et al?) made an older algorithm called Highway Hierarchies, but I have the impression Contraction Hierarchies makes it obsolete.&lt;br /&gt;&lt;br /&gt;How awesome are Contraction Hierarchies? They're so fast that (assuming you use plain CHs with no further optimizations) it may take longer merely to enumerate (traverse) the shortest path than to find it in the first place! This is possible because CH uses "shortcuts" that skip past most of the individual road segments on the route on the way to the destination.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Important update&lt;/span&gt;: there are a couple of things the inventors will not tell you about CHs.&lt;br /&gt;&lt;br /&gt;First, although you may have only 100 nodes settled in a CH search compared to 100,000 in a normal highway graph, the fan-out of each node is greater, and there is a performance penalty for that. On the whole it is very fast, but I'm just telling you that while the inventors like to tout the nodes settled ratio (100,000/100), it doesn't reflect the speedup you're actually going to get. Especially not if you're already using heuristics to avoid searching the whole graph.&lt;br /&gt;&lt;br /&gt;Second, and more importantly, real-world street-network routing requires a node for every street segment, and an edge for each transition from one road segment to another. This is necessary to model turn restrictions (and turn costs), as there is no other known way to support them. In street networks, this typically makes the graph about 3 times larger (in terms of the number of nodes and edges) than the graphs that the inventors usually operate on (which have a node for each intersection, and an edge for each road). They did make a paper explaining this, "Route Planning in Road Networks with Turn Costs"; however the paper does not explain the performance penalty for using this kind of network. You might think because the network is 3 times larger that it will be 3 times slower, and I assumed as much. However, I found out after implementing a whole system based on this kind of road network that CHs actually perform about 30 times slower, not 3 times slower.&lt;br /&gt;&lt;br /&gt;This second problem actually made CHs too slow for large road networks on our mobile devices. When we used Dijkstra's algorithm we could present a partial solution to the user after 5 seconds (a "best guess" about the first few turns the user should make), but a CH does not provide partial solutions nor guesses--in general, you must wait for a unique solution before reporting the first turn instruction. You can present a turn instruction before fully unpacking the route, but in a road network with turn costs, the initial search takes more time than the unpacking. Thus, in the real world CHs are only suitable for faster machines (let's say 800MHz), unless your code is carefully optimized for the specific task of dealing with the CH (unlike my code, which fit the CH into general purpose data structures that were also used by the rest of the system, yielding compute times of 30+ seconds, not including route unpacking).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-4588335486652867158?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/4588335486652867158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=4588335486652867158' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4588335486652867158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4588335486652867158'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2009/04/fastest-routing-algorithm-ever.html' title='Fastest Routing Algorithm Ever'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-320346972526700426</id><published>2009-02-03T10:36:00.017-07:00</published><updated>2009-02-03T12:07:44.834-07:00</updated><title type='text'>Far Cry 2 Review (PC version)</title><content type='html'>Everyone agrees that the graphics of FC2 are lovely, immersive (if your system is beefy enough), and really well done overall. While some people prefer linearity, I do not--I thought the extreme linearity of Half-Life 2 was the worst part about the game--so I enjoy having the freedom that FC2 gives you to go anywhere at any time. However, the game's storyline is somewhere between nonsensical and nonexistent, none of the characters have much depth, the voice acting is mediocre at best, the missions are repetitive, and there are some problems with the control scheme. Some points to consider:&lt;br /&gt;&lt;br /&gt;(1) Perhaps what throws away the game's immersive qualities more than anything else is that even though you're supposedly a "no-name scumbag", the game clearly revolves around you. Ostensibly you are just some guy caught in a civil war between two sides (UFLL and APR), but in fact the supposed two sides are indistinguishable (you can't tell if you are fighting UFLL or APR guys), there are no front lines, and you almost never see AIs fighting each other. Instead, they only fight you. The war does has two sides: you (and occasionally one of your "buddies") against nearly everyone in the entire country. These guys are vicious, too; they are without exception happy to get themselves killed if it means they might put one more bullet in you--even though, again, you're supposed to be some anonymous guy with malaria. In the second battle I was in, the AI aimed their Jeep directly at me going full speed. I jumped out of the way, and they slammed directly into a large tree. That's how obsessed they are! Plus, especially if you play in Hardcore mode, the enemies can somehow recognize your face at 300 yards away so they know it's you (therefore they have to kill you) and not somebody else (who they would allow to pass freely). Just as in the first Far Cry, the enemies often seem able to see you in the bushes, but you can't see them (regarless of whether it's you or them hiding behind behind a bush). PontifexPrimus on /. puts it more colorfully:&lt;br /&gt;&lt;blockquote&gt;The enemies are incredibly annoying. And I know that a FPS needs enemies that harass the player, and I can accept that - but here it is getting ridiculous. Every time you pass through the dense, dimly-lit jungle and any of the faction catches sight of you they will catch your scent AND THEY WILL NOT LET UP UNTIL YOU HAVE GUNNED EVERY LAST FUCKING ONE OF THEM DOWN! I mean, seriously, let's talk realism, since that seems to be the great selling point: imagine you're a member of the Imaginistani Militia, posted in the deep forest, told to keep an eye out for your mortal enemy, the Imaginistani Rangers. You spy a single person creeping through the jungle, trying to bypass your guard post without being noticed. So now you sound a general alarm, alert every patrol in a two-mile-radius, call in reinforcements on the radio, tag that creeping guy with a giant "please shoot me" neon sign, grab your weapon and go with every other person in that outpost on a single-minded suicide mission trying to KILL THAT ONE GUY whatever the cost, leaving the guard post... unguarded? Does that sound realistic?&lt;/blockquote&gt;&lt;br /&gt;(2) Ostensibly you're in the country to kill the "Jackal" guy who keeps the war going, so ostensibly you're the good guy, but for some reason you reach this goal by killing hundreds of random people that have nothing to do with this supposed objective.&lt;br /&gt;&lt;br /&gt;(3) The control scheme has issues. For example if you want to run for cover, you are only allowed to run straight forward (strafing disables running) and if you are reloading, the game forces you to finish reloading before you can run or switch weapons.&lt;br /&gt;&lt;br /&gt;(4) The bus stations that take you long distances have no staff. No ticket agent, no bus drivers, riding the bus is free, it's perfectly safe, there are no other passengers, and it gets you to your destination much faster than driving. Make sense?&lt;br /&gt;&lt;br /&gt;(5) Virtually everyone in the country is male and heavily armed. There are practically no civilians (occasionally you'll see a few unarmed people sitting down in an "underground" safehouse) and there are absolutely no children. Setting aside how unlikely this is, the lack of civilians means that you don't have any missions where your job is to save a village or do something good--it's always "kill this person" or "blow this up". And even though you have the freedom to go anywhere, the game doesn't advance until you complete these "prove-what-a-douchebag-you-are" missions.&lt;br /&gt;&lt;br /&gt;(6) There are magic boxes all over the map. Put your gun in a magic box and pull the same gun out of another box 20 miles away. Or how about the gun shop (which is normally unstaffed) where you buy the guns on a computer and the guns you bought magically appear in a warehouse next door. Make sense?&lt;br /&gt;&lt;br /&gt;The problem is that while the graphics are highly immersive, the gameplay mechanics are absurd enough to pull you out of the immersion.&lt;br /&gt;&lt;br /&gt;Finally, if you were expecting Far Cry 2 to be a sequel to Far Cry, you will be disappointed. Not only is the storyline unrelated, but certain elements that made the original Far Cry memorable have been deleted. Most notably, no longer do the bad guys make humorous conversation as you watch them with your binoculars (actually your monocular). Also gone is futuristic technology, mutants, and palm trees. Crysis is certainly closer to the original Far Cry than Far Cry 2, but Crysis also lacks the comical-mercenary elements that, to me, directly added to the fun of what is, after all, a Rambo game.&lt;br /&gt;&lt;br /&gt;Oh, and the &lt;a href="http://qism.blogspot.com/2007/02/fov.html"&gt;FOV&lt;/a&gt; is quite poor, but there is a hack so you can increase it to your liking.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ahh, DRM!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I almost forgot the evil &lt;a href="http://en.wikipedia.org/wiki/Digital_rights_management"&gt;DRM&lt;/a&gt;! Like most games today, you must play with the DVD in the drive even though the entire game is stored on your hard drive. The &lt;a href="http://en.wikipedia.org/wiki/SecuROM"&gt;SecuROM&lt;/a&gt; copy-protection software that you, as a paying customer, are forced to install and cannot uninstall, will not let you play the game if a copy of the disc rather than the original is in the drive. But the worst part is that the damn thing can't reliably tell the difference between a copy and the original! Several times now the game has refused to run with the bona fide original disc in the drive; luckily I have been able to get around this by moving the disc to the other drive (as we have two DVD drives).&lt;br /&gt;&lt;br /&gt;I am seriously considering a vow to pirate any game that treats its paying customers to this DRM in the future.&lt;br /&gt;&lt;br /&gt;Verdict: 6/10, or 4/10 if you count SecuROM.&lt;br /&gt;&lt;br /&gt;For more reviews by disappointed fans, click the title of this entry, and scroll down to the player reviews.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-320346972526700426?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.metacritic.com/games/platforms/pc/farcry2?q=far%20cry%202' title='Far Cry 2 Review (PC version)'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/320346972526700426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=320346972526700426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/320346972526700426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/320346972526700426'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2009/02/far-cry-2-review.html' title='Far Cry 2 Review (PC version)'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-6586166772873391301</id><published>2008-12-13T12:33:00.004-07:00</published><updated>2008-12-13T15:19:39.367-07:00</updated><title type='text'>English-esperanto dictionary for Pocket PC</title><content type='html'>Quite some time ago I wrote this little dictionary program for Pocket PCs (Windows Mobile). It translates words between English and Esperanto and you can even modify entries in your own personal copy, or create new entries.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_y8ybb5S16Uc/SUQlJDUZKII/AAAAAAAAABE/XH_8ycBpAfI/s1600-h/dict-screenshots.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 260px;" src="http://4.bp.blogspot.com/_y8ybb5S16Uc/SUQlJDUZKII/AAAAAAAAABE/XH_8ycBpAfI/s400/dict-screenshots.png" alt="" id="BLOGGER_PHOTO_ID_5279385500624955522" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I don't remember where I got the dictionary itself. It isn't high-quality. There are many errors, unhelpful translations, and some words missing, but this is typical of the Esperanto-English dictionaries I have seen.&lt;br /&gt;&lt;br /&gt;The dictionary is stored as a trivially simple text file, which means it is possible to edit the dictionary in Notepad or, if you are a programmer, you could easily write a program that transforms other dictionaries into a text format that this program would understand.&lt;br /&gt;&lt;br /&gt;It's very easy and quick to use. Just type the first few letters of a word and the dictionary will instantly search &lt;span style="font-weight: bold;"&gt;both&lt;/span&gt; the English-EO and EO-English dictionaries at once. The definitions are shown in a large font, in case you have a small Pocket PC phone or poor eyesight. When it shows the list of results, just press up and down on the Pocket PC's directional pad.&lt;br /&gt;&lt;br /&gt;However, I never released this program before because I never polished it. The biggest problem is that it takes at least 30 seconds to start up (on the Pocket PC).&lt;br /&gt;&lt;br /&gt;The program is written in C#. The cool thing about this is that the same program runs equally well on your PC!&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.fileqube.com/hl/LMfwDG177263/Interdictionary.CAB"&gt;Download Interdictionary.cab&lt;/a&gt;&lt;br /&gt;To install it on your Pocket PC, open your device in My Computer, and copy the CAB file to the device. Then, on the device, run File Explorer and find the same CAB file. Double-tap to install it, and then it will appear in your Programs list.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.fileqube.com/hl/BhVnrqxCy177264/Interdictionary.zip"&gt;Download Interdictionary.zip&lt;/a&gt;&lt;br /&gt;This zip file contains the cab file above, plus the &lt;span style="font-style: italic;"&gt;contents&lt;/span&gt; of the cab file so you can run the dictionary on your PC. To use, unzip this file, then double-click PPCDictionary.exe. Please note that the .NET Framework 2.0 must already be installed (it is installed on most computers already).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;If you want the source code, just email me (gmail.com, qwertie256 at). You could also use Reflector to decompile it, which is always fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-6586166772873391301?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/6586166772873391301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=6586166772873391301' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/6586166772873391301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/6586166772873391301'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/12/english-esperanto-dictionary-for-pocket.html' title='English-esperanto dictionary for Pocket PC'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_y8ybb5S16Uc/SUQlJDUZKII/AAAAAAAAABE/XH_8ycBpAfI/s72-c/dict-screenshots.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-7376354152480412233</id><published>2008-11-25T14:06:00.002-07:00</published><updated>2008-11-25T14:10:25.848-07:00</updated><title type='text'>In ATL, you can't derive one coclass from another.</title><content type='html'>Click heading for discussion.&lt;br /&gt;&lt;blockquote&gt;&amp;gt; I understand why you might want to have a deep hierarchy of &lt;br /&gt;&amp;gt; implementation classes (this style was popular at one point - witness &lt;br /&gt;&amp;gt; MFC - but has fallen out of fashion lately). But why would you want a &lt;br /&gt;&amp;gt; deep hierarchy of _interfaces_?&lt;br /&gt;&lt;br /&gt;Because the derived classes add additional functionality [and there must be a new interface to invoke the new functionality]. In my case--without going into irrelevant proprietary details--I have a 'painter' class that paints stuff, a 'control-base' class which implements a basic GUI control around the painted stuff, and a 'control' class which adds extra standard functionality.&lt;br /&gt;&lt;br /&gt;Typically the user would either instantiate 'control-base' and customize it (picking and choosing the functionality desired and composing that functionality manually), or just use 'control' for a standard set of functionality. While I suppose this doesn't *have* to be designed as a hierarchy, the code was already written that way before I knew I would have to turn it into a COM component.&lt;br /&gt;&lt;br /&gt;&amp;gt;You are busy confusing interface inheritance and implementation&lt;br /&gt;&amp;gt;inheritance. These are two different things. &lt;br /&gt;&lt;br /&gt;Actually I never confused the two, although I may have presented my thoughts in a highly confusing manner. Sorry about that! When I said IA and IB share a common interface, the common interface I meant was IA.&lt;br /&gt;&lt;br /&gt;Anyway, I have now implemented my COM hierarchy and it's working great. Thanks for your help. I ended up doing pretty much what it says to do at http://vcfaq.mvps.org/com/8.htm -- to summarize what I did, I have &lt;br /&gt;&lt;br /&gt;1. Implementation non-template classes A, B, and C (C derives from B derives from A) which don't necessarily use ATL or COM at all&lt;br /&gt;2. COM interfaces IA, IB, IC (IC derives from IB derives from IA)&lt;br /&gt;3. Wrapper classes CImpl&amp;lt;I&amp;gt;, BImpl&amp;lt;I&amp;gt; and AImpl&amp;lt;I&amp;gt; (CImpl&amp;lt;I&amp;gt; derives from BImpl&amp;lt;I&amp;gt; derives from AImpl&amp;lt;I&amp;gt; derives from I); AImpl&amp;lt;I&amp;gt; contains a pointer to an object of type A, B, or C depending on which ATL class is using it&lt;br /&gt;4. ATL classes CA, CB, and CC which are totally separate and unrelated. CA, CB, and CC have base classes AImpl&amp;lt;IA&amp;gt;, BImpl&amp;lt;IB&amp;gt;, and CImpl&amp;lt;IC&amp;gt; respectively.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-7376354152480412233?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?cat=en_US_faefca83-8824-4fb3-885c-0b574607df4d&amp;lang=en&amp;cr=US&amp;guid=&amp;sloc=en-us&amp;dg=microsoft.public.win32.programmer.ole&amp;tid=5b4c0b1b-32f7-45ba-972b-3e12790c6575&amp;mid=f0fd0b39-a6f4-4dde-' title='In ATL, you can&apos;t derive one coclass from another.'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/7376354152480412233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=7376354152480412233' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7376354152480412233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7376354152480412233'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/11/in-atl-you-cant-derive-one-coclass-from.html' title='In ATL, you can&apos;t derive one coclass from another.'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-9176422002409367545</id><published>2008-11-24T13:39:00.004-07:00</published><updated>2008-11-24T13:48:27.676-07:00</updated><title type='text'>MIDL changing your property name to lowercase?</title><content type='html'>I had a "FileName" property in my interface...&lt;br /&gt;&lt;pre&gt;interface IMyFile : IDispatch {&lt;br /&gt;   ...&lt;br /&gt;   [propget, id(6)] HRESULT FileName([out, retval] BSTR* pVal);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;and somehow in the TLB this came out as "filename" - all lowercase.&lt;br /&gt;&lt;br /&gt;It turned out to be a really weird bug in MIDL. It was triggered because I had a method that takes a parameter called "filename". I had a method like this:&lt;br /&gt;&lt;pre&gt;interface IMyFile : IDispatch {&lt;br /&gt;   [id(1)] HRESULT OpenFile(BSTR filename, long reserved);&lt;br /&gt;   ...&lt;br /&gt;   [propget, id(6)] HRESULT FileName([out, retval] BSTR* pVal);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;See, MIDL changes the case of the property (or method?) to match the case of the parameter. The solution was to rename the parameter "filename" to "FileName". This even happens if the matching parameter name appears in an unrelated interface!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-9176422002409367545?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/9176422002409367545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=9176422002409367545' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/9176422002409367545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/9176422002409367545'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/11/midl-changing-your-property-name-to.html' title='MIDL changing your property name to lowercase?'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-8205200246381535920</id><published>2008-09-17T11:07:00.004-06:00</published><updated>2008-09-17T11:40:58.305-06:00</updated><title type='text'>.NET Compact Framework unmanaged callbacks: bool not invited</title><content type='html'>The .NET Compact Framework 2.0 is supposed to support unmanaged callbacks: you pass a delegate into C/C++ code via P/Invoke and the Framework converts it to a thunk. It passes the thunk to C/C++, and when the C/C++ code calls the thunk, the thunk calls your delegate.&lt;br /&gt;&lt;br /&gt;Previously I had success passing strings:&lt;br /&gt;&lt;pre&gt;// C# declaration&lt;br /&gt;public delegate void ExceptionArgumentDelegate([MarshalAs(UnmanagedType.LPWStr)] &lt;br /&gt;    string message, [MarshalAs(UnmanagedType.LPWStr)] string paramName);&lt;br /&gt;// C++ declaration&lt;br /&gt;typedef void (__stdcall* ExceptionArgumentCallback_t)&lt;br /&gt;    (const wchar_t *, const wchar_t *);&lt;br /&gt;void SetCallback(ExceptionArgumentCallback_t callback);&lt;br /&gt;// P/Invoke declaration&lt;br /&gt;[DllImport("DllNameHere", EntryPoint="SetCallback")]&lt;br /&gt;public static extern void SetCallback(ExceptionArgumentDelegate callback);&lt;/pre&gt;&lt;br /&gt;But I couldn't pass the following delegate type:&lt;br /&gt;&lt;pre&gt;// C# declaration&lt;br /&gt;public delegate bool ProgressCallback([MarshalAs(UnmanagedType.LPWStr)] &lt;br /&gt;    string message, int itemsProcessed, int totalItems);&lt;br /&gt;// C++ declaration&lt;br /&gt;typedef bool (__stdcall *ProgressCallback)(PCTSTR, int, int);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I get a NotSupportedException with the rather vague error message "0x80131515". Thanks Microsoft! Well, it turns out that a callback is not allowed to have a bool return type. The solution: change the return type on the C# side to int, then return 0 instead of false and 1 instead of true. Just to be on the safe side, you might want to change the C++ side to return int also. But that wasn't needed in my case (XScale PXA processor).&lt;br /&gt;&lt;br /&gt;Interestingly, my cursory examination suggests you are allowed to pass bool as an argument, and even ref bool works (ref bool corresponds to bool* on the C++ side).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-8205200246381535920?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/8205200246381535920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=8205200246381535920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/8205200246381535920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/8205200246381535920'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/09/net-compact-framework-unmanaged.html' title='.NET Compact Framework unmanaged callbacks: bool not invited'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-4260127951387041848</id><published>2008-09-12T00:44:00.005-06:00</published><updated>2008-09-12T00:57:37.212-06:00</updated><title type='text'>Simulating covariant return types</title><content type='html'>For several years, Microsoft engineers have refused to add support for &lt;a href="http://en.wikipedia.org/wiki/Covariant_return_type"&gt;covariant return types&lt;/a&gt;, a trivially simple feature that should have been in the CLR from the beginning.&lt;br /&gt;&lt;br /&gt;Suppose you want to write a Clone() method that returns a copy of the current object. If implementing an interface, you can use this workaround in C# that uses explicit interface implementation:&lt;br /&gt;&lt;pre&gt;class MyCloneable : ICloneable {&lt;br /&gt;    public MyCloneable Clone() { ... }&lt;br /&gt;    object ICloneable.Clone() { return Clone(); }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The above workaround is okay for implementing an interface, but what if you are writing a class hierarchy, and you want a Clone() method that is virtual but has the appropriate return type?&lt;br /&gt;&lt;pre&gt;class BaseNode : ICloneable&lt;br /&gt;{&lt;br /&gt;    object ICloneable.Clone() { return Clone(); }&lt;br /&gt;    public virtual BaseNode Clone() { ... }&lt;br /&gt;}&lt;br /&gt;class ComplexNode : BaseNode&lt;br /&gt;{&lt;br /&gt;    override BaseNode BaseNode.Clone() { return Clone(); } // Error!&lt;br /&gt;    public ComplexNode Clone() { ... }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Oops, the workaround that you use for interfaces is illegal for class inheritance. There is still a solution, though:&lt;br /&gt;&lt;pre&gt;class BaseNode : ICloneable&lt;br /&gt;{&lt;br /&gt;    object ICloneable.Clone() { return Clone(); }&lt;br /&gt;    public BaseNode Clone() { BaseNode c; Clone(out c); return c; }&lt;br /&gt;    protected virtual void Clone(out BaseNode clone) { ... }&lt;br /&gt;}&lt;br /&gt;class ComplexNode : BaseNode&lt;br /&gt;{&lt;br /&gt;    public new ComplexNode Clone() { ComplexNode c; Clone(out c); return c; }&lt;br /&gt;    protected override void Clone(out BaseNode clone) { clone = Clone(); }&lt;br /&gt;    protected virtual void Clone(out ComplexNode clone) { ... }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;That's right. You need six Clone() methods. The last method is virtual in case you want to make a class derived from ComplexNode, e.g. VeryComplexNode:&lt;br /&gt;&lt;pre&gt;class VeryComplexNode : ComplexNode&lt;br /&gt;{&lt;br /&gt;    public new VeryComplexNode Clone() { VeryComplexNode c; Clone(out c); return c; }&lt;br /&gt;    protected override void Clone(out BaseNode clone) { clone = Clone(); }&lt;br /&gt;    protected override void Clone(out ComplexNode clone) { clone = Clone(); }&lt;br /&gt;    protected virtual void Clone(out VeryComplexNode clone) { ... }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Without covariant return types, you have to to define an additional virtual function for each additional derived class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-4260127951387041848?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=90909' title='Simulating covariant return types'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/4260127951387041848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=4260127951387041848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4260127951387041848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4260127951387041848'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/09/simulating-covariant-return-types.html' title='Simulating covariant return types'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-2727197139336870898</id><published>2008-06-25T12:41:00.003-06:00</published><updated>2008-06-25T12:48:02.333-06:00</updated><title type='text'>Integer conversion from HSL to RGB</title><content type='html'>A hue-saturation-lumination to RGB conversion that uses no floating point.&lt;br /&gt;&lt;br /&gt;Inputs and outputs are in the range 0 to 255.&lt;br /&gt;&lt;br /&gt;Derived from &lt;a href="http://tog.acm.org/GraphicsGems/gemsv/ch7-6/tga/hsl.c"&gt;an incredibly old floating-point algorithm&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;void HSL_to_RGB(int hue, int sat, int lum, int* r, int* g, int* b)&lt;br /&gt;{&lt;br /&gt;    int v;&lt;br /&gt;&lt;br /&gt;    v = (lum &amp;lt; 128) ? (lum * (256 + sat)) &amp;gt;&amp;gt; 8 :&lt;br /&gt;          (((lum + sat) &amp;lt;&amp;lt; 8) - lum * sat) &amp;gt;&amp;gt; 8;&lt;br /&gt;    if (v &amp;lt;= 0) {&lt;br /&gt;        *r = *g = *b = 0;&lt;br /&gt;    } else {&lt;br /&gt;        int m;&lt;br /&gt;        int sextant;&lt;br /&gt;        int fract, vsf, mid1, mid2;&lt;br /&gt;&lt;br /&gt;        m = lum + lum - v;&lt;br /&gt;        hue *= 6;&lt;br /&gt;        sextant = hue &amp;gt;&amp;gt; 8;&lt;br /&gt;        fract = hue - (sextant &amp;lt;&amp;lt; 8);&lt;br /&gt;        vsf = v * fract * (v - m) / v &amp;gt;&amp;gt; 8;&lt;br /&gt;        mid1 = m + vsf;&lt;br /&gt;        mid2 = v - vsf;&lt;br /&gt;        switch (sextant) {&lt;br /&gt;           case 0: *r = v; *g = mid1; *b = m; break;&lt;br /&gt;           case 1: *r = mid2; *g = v; *b = m; break;&lt;br /&gt;           case 2: *r = m; *g = v; *b = mid1; break;&lt;br /&gt;           case 3: *r = m; *g = mid2; *b = v; break;&lt;br /&gt;           case 4: *r = mid1; *g = m; *b = v; break;&lt;br /&gt;           case 5: *r = v; *g = m; *b = mid2; break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-2727197139336870898?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/2727197139336870898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=2727197139336870898' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2727197139336870898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2727197139336870898'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/06/integer-conversion-from-hsl-to-rgb.html' title='Integer conversion from HSL to RGB'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-3296534221484338927</id><published>2008-06-04T19:14:00.003-06:00</published><updated>2008-06-07T09:08:14.896-06:00</updated><title type='text'>Circular Template References in C++</title><content type='html'>I wanted to have three template classes, designed to work together, that could use facilities in one another, in such a way that any of the three classes could be replaced with a different version--something like what "Boris" describes &lt;a href="http://bytes.com/forum/thread549491.html"&gt;here&lt;/a&gt;, just more complex.&lt;br /&gt;&lt;br /&gt;It didn't seem possible and I had just about given up--I decided instead that I would give each class a non-template base class with limited functionality, and then each class would access the other two classes through this more limited interface. But on the train on the way home from work it hit me: a special "traits" class would make it possible to use circular references between templates. Here is an example:&lt;br /&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;template&amp;lt;class Combo&amp;gt; struct A&lt;br /&gt;{&lt;br /&gt;  typedef typename Combo::b_t B;&lt;br /&gt;  B* b;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template&amp;lt;class Combo&amp;gt; struct B&lt;br /&gt;{&lt;br /&gt;  typedef typename Combo::a_t A;&lt;br /&gt;  A* a;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct MyCombo {&lt;br /&gt;  typedef A&amp;lt;MyCombo&amp;gt; a_t;&lt;br /&gt;  typedef B&amp;lt;MyCombo&amp;gt; b_t;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt;  A&amp;lt;MyCombo&amp;gt; a;&lt;br /&gt;  B&amp;lt;MyCombo&amp;gt; b;&lt;br /&gt;  a.b = &amp;b;&lt;br /&gt;  b.a = &amp;a;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-3296534221484338927?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/3296534221484338927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=3296534221484338927' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/3296534221484338927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/3296534221484338927'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/06/circular-template-references-in-c.html' title='Circular Template References in C++'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-6165330398082245038</id><published>2008-03-26T10:12:00.004-06:00</published><updated>2008-03-26T10:35:04.188-06:00</updated><title type='text'>Showing current line number of a TextBox (Windows Forms)</title><content type='html'>You need code like:&lt;br /&gt;&lt;br /&gt;label.Text = string.Format("Line {0} Col {1}",&lt;br /&gt;   txt.GetLineFromCharIndex(txt.SelectionStart) + 1,&lt;br /&gt;   txt.SelectionStart - txt.GetFirstCharIndexOfCurrentLine() + 1);&lt;br /&gt;&lt;br /&gt;But the above needs some adjustment because it doesn't work correctly when the user selects multiple lines (eg the column may be negative).&lt;br /&gt;&lt;br /&gt;You need to update the line/column number upon these events:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Click&lt;/li&gt;&lt;li&gt;KeyDown&lt;br /&gt;&lt;/li&gt;&lt;li&gt;KeyUp&lt;/li&gt;&lt;li&gt;KeyPress (maybe? not sure)&lt;/li&gt;&lt;li&gt;TextChanged&lt;/li&gt;&lt;/ul&gt;No event is fired if the cursor position changes programmatically.&lt;br /&gt;&lt;br /&gt;When the user presses arrows or Home/End/PgUp/PgDn, KeyDown is fired before the cursor position actually changes, so you trap it only to show the line number changing when the user holds down a key. KeyUp is fired after the cursor position changes to you can show the correct value.&lt;br /&gt;&lt;br /&gt;You might want to show line numbers beside the text box, e.g. using a series of labels on the left side of the TextBox. This is &lt;span style="font-style: italic;"&gt;not possible&lt;/span&gt;, at least not using pure Windows Forms code, because TextBox does not generate any events (not even click events) when it is scrolled via its scrollbars.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-6165330398082245038?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/6165330398082245038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=6165330398082245038' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/6165330398082245038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/6165330398082245038'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2008/03/showing-current-line-number-of-textbox.html' title='Showing current line number of a TextBox (Windows Forms)'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-4593208290516874120</id><published>2007-08-07T14:25:00.001-06:00</published><updated>2007-08-07T16:19:45.046-06:00</updated><title type='text'>Dif between "attributed" and "unattributed" ATL projects (VS 2005)</title><content type='html'>I'm trying to figure out how to make COM objects (note that the Microsoft-approved way to make them is with ATL). First obstacle: what's this "&lt;a href="http://msdn2.microsoft.com/en-us/library/w3yk4x9b%28VS.80%29.aspx"&gt;attributed&lt;/a&gt;" nonsense?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Only the attributed version defines _ATL_ATTRIBUTES in the project settings.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Attributed version doesn't include a .tlb file from its .rc resource file.&lt;/li&gt;&lt;li&gt;In the main .cpp file (ProjectName.cpp), the attributed version has just one empty class (CProjectNameModule) with a [module] attribute attached. The nonattributed version has the same class without the attribute, and this time the class is derived from CAtlDllModuleT&amp;lt;CProjectNameModule&amp;gt; (instead of nothing) and uses DECLARE_LIBID and DECLARE_REGISTRY_APPID_RESOURCEID inside it. In addition, the nonattributed version has DllMain, DllCanUnloadNow, DllGetClassObject, DllRegisterServer, DllUnregisterServer. All these functions make calls into an object called _AtlModule of type CProjectNameModule; oddly there is no such object in the attributed project.&lt;/li&gt;&lt;li&gt;Only the nonattributed project has ProjectName.def and ProjectName.idl. The .def mentions DllCanUnloadNow, DllGetClassObject, DllRegisterServer and DllUnregisterServer; the .idl has a single construct, "[...] library ProjectNameLib {...}".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Only the nonattributed project has the generated files ProjectName.h and ProjectName_i.c which define a few mysterious things.&lt;/li&gt;&lt;li&gt;When you make an ATL project you get a sibling project with a "PS" suffix. This extra or "bonus" project is not compiled by default and starts with only one source file, ProjectNameps.def. 'PS' evidently stands for Proxy/Stub.&lt;/li&gt;&lt;li&gt;Other files are generated that I'm not mentioning (see readme.txt in the generated project)&lt;/li&gt;&lt;/ul&gt;As they build, both projects spend time processing a bunch of mysterious ".idl" and ".acf" files that are not in the project. Then it looks like the generated DLL's GUID(s?) are automatically registered in the registry.&lt;br /&gt;&lt;br /&gt;The docs say "An attributed project does not allow support for MFC or merging of proxy/stub  code." but it doesn't give any reason, so I'm baffled.&lt;br /&gt;&lt;br /&gt;This attributed/nonattributed stuff is in effect permanently:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;When you go to create a new COM class on the attributed project (right click project, choose Add =&gt; Class, then ATL Simple Object), you get an "__interface IMyComClass" and a "class CMyComClass" derived from it in your C++ header file (MyComClass.h), with attributes attached that cause code to be generated in "_ATLProjectAttributed.idl" and in other files (files that are not in the project's list of files).&lt;/li&gt;&lt;li&gt;When you create the same COM class on the unattributed project, you get something quite different. In the header (MyComClass.h) you only get a definition for CMyComClass, not IMyComClass; and this time CMyComClass has three base classes, and uses the DECLARE_REGISTRY_RESOURCEID and BEGIN_COM_MAP(...) ... END_COM_MAP() macros inside the class. IMyComClass is defined in ProjectName.idl (the attributed project has no .idl listed). The .def file is unaffected.&lt;/li&gt;&lt;/ul&gt;In both cases, the MyComClass.cpp file starts empty and gets filled as you add functions/properties (by right-clicking COM interfaces in Class View). Interestingly, Class View lists the interfaces just as well for the unattributed project, even though the interfaces are declared in an .idl file, not a C++ file. Here's something I find very intriguing: just after you generate a "MyComClass" class with a wizard, IMyComClass immediately shows up in the Class View. If you refer to IMyComClass in code and press F12 you are taken to the definition in the .idl file. However, after you compile your project, put the cursor on IMyComClass and press F12 again. This time you're taken to the definition of IMyComClass in the generated C++ header file. In Class View you'll see IMyComClass listed twice; one refers to the .idl and one refers to the .h file. An intellisense member list for the interface won't appear until after the project has been compiled.&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ctkast1b%28VS.80%29.aspx"&gt;Developing a COM DLL with COM Attributes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/dssw0ch4(VS.80).aspx"&gt;Walkthrough: Creating a COM Server Using Wizards&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-4593208290516874120?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/4593208290516874120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=4593208290516874120' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4593208290516874120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/4593208290516874120'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/08/dif-between-attributed-and-unattributed.html' title='Dif between &quot;attributed&quot; and &quot;unattributed&quot; ATL projects (VS 2005)'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-8109101927609590533</id><published>2007-07-12T10:59:00.000-06:00</published><updated>2007-07-12T12:10:09.326-06:00</updated><title type='text'>What's wrong with Java</title><content type='html'>When I see the &lt;a href="http://72.5.124.55/j2se/1.5.0/docs/relnotes/features.html#lang"&gt;features added recently to Java&lt;/a&gt;, I'm sure glad I'm using .NET, C# and boo. Even though Java is a lot older than .NET, .NET seems to get the good features first. Care in point: Generics. For a former C++ developer, it seems stupid to give up type-safe collections; I don't know how many years it took before Java got generics (10?) but .NET got them in much less time (less than 4 years, I do believe) and Java was left playing catch-up. In fact, most of the "new" features in Java 5.0 seem to be things that C# had from the beginning:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;enhanced for loop (foreach in C#)&lt;/li&gt;&lt;li&gt;autoboxing/unboxing&lt;/li&gt;&lt;li&gt;enums&lt;/li&gt;&lt;li&gt;varargs (variable argument lists - "params" in C#)&lt;/li&gt;&lt;li&gt;annotations (much like .NET attributes)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Java generics aren't even supported by the JVM, so you get the same performance penalty from casting that you did before. I've always been unhappy with Java's performance (especially for GUI programs), whereas .NET just doesn't seem slow.&lt;br /&gt;&lt;br /&gt;Look, Sun, if nothing short of competition from Microsoft can prompt you to improve Java, you must not care very much much about it.&lt;br /&gt;&lt;br /&gt;Let's see, what else...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Value types (structs). This is a big one for me because can offer a big performance boost in many situations. You don't want to allocate a new object if that object contains nothing more than an integer and some methods, do you? A new object sucks up at least 16-20 bytes of memory even if it just contains one integer or reference; creating it requires multiple method calls and all those bytes have to be initialized. Useful value types include&lt;/li&gt;&lt;ul&gt;&lt;li&gt;A "Point" type that has X and Y coordinates&lt;/li&gt;&lt;li&gt;A "FixedInt" type that contains a fixed-point number (the language must support operator overloading to make it easy to use, of course.)&lt;/li&gt;&lt;li&gt;A "BigInt" type that contains a small integer normally, but allocates a memory block for a large integer if necessary.&lt;/li&gt;&lt;li&gt;A "Handle" type that contains an opaque reference to something else&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A "Symbol" type that contains a numeric identifier that represents a string (symbols are a built-in feature of Ruby and are typically used like enums, except they are more flexible)&lt;/li&gt;&lt;li&gt;A Pair&lt;a,b&gt; type that contains a pair of values A and B; often you get better performance by not allocating memory for this purpose.&lt;/a,b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Multi-language support. Well, the JVM can certainly support multiple languages, but only .NET is specifically designed for it. Admittedly, the design isn't that great, but at Microsoft specifically considers the needs of other languages.&lt;/li&gt;&lt;li&gt;Delegates. The Java equivalent is using interfaces with one function in them, but this is relatively inflexible and certainly more annoying to use. Java provides inner (&lt;a href="http://www.exciton.cs.rice.edu/JavaResources/Java/innerclasses.htm"&gt;even anonymous&lt;/a&gt;) classes to help people use the pattern, but delegates are way better.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Closures (functions inside other functions, where the inner function can access local variables of the outer function). Java doesn't have that, does it? You can access "final" variables from a function-inside-a-class-inside-a-function, but that's all.  By the way, .NET itself doesn't actually support closures, but C# fakes it well.&lt;/li&gt;&lt;li&gt;Iterators. Now this may be my favorite feature of C# 2.0; it would be hard to choose between iterators and generics. I love them not only because you can create enumerators easily (which is great) but also because you can approximate &lt;a href="http://qdl.sourceforge.net/coroutines.html"&gt;coroutines&lt;/a&gt; with them.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Swing. Ugh! It's ugly, it's slow, and the Windows "skin" isn't very convincing. There often seem to be glitches in Swing that you don't find in other programs, such as the failure to resize a window fluidly (i.e. the window doesn't redraw itself until you let go of your mouse button). Finally, and worst of all, developing Swing GUIs is a huge pain in the ass. I absolutely can't stand it. The .NET counterpart, Windows.Forms, doesn't seem all that well designed, but it looks good, it's relatively fast, and it's easy to write code for it. Plus, of course, a good Forms designer is a standard feature of any .NET IDE.&lt;/li&gt;&lt;/ul&gt;Right now I wish I could have the C# 3.0 "var" feature because I'm sick of typing&lt;br /&gt;&lt;br /&gt;SomeJerkGaveThisClassALongName foo = new SomeJerkGaveThisClassALongName();&lt;br /&gt;&lt;br /&gt;Obviously we should be able to write simply&lt;br /&gt;&lt;br /&gt;var foo = new SomeJerkGaveThisClassALongName();&lt;br /&gt;&lt;br /&gt;And there's a lot of other great stuff in &lt;a href="http://72.14.253.104/search?q=cache:sF_fuakzdkwJ:download.microsoft.com/download/9/5/0/9503e33e-fde6-4aed-b5d0-ffe749822f1b/csharp%25203.0%2520specification.doc+C%23+3.0&amp;hl=en&amp;amp;amp;amp;ct=clnk&amp;cd=3&amp;amp;gl=ca&amp;amp;client=firefox-a"&gt;C# 3.0&lt;/a&gt; [&lt;a href="http://download.microsoft.com/download/9/5/0/9503e33e-fde6-4aed-b5d0-ffe749822f1b/csharp%203.0%20specification.doc"&gt;.doc&lt;/a&gt;]:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Lambda expressions (syntactic sugar for anonymous inner functions) with type inference&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Type inference for generic method calls&lt;/li&gt;&lt;li&gt;Extension methods (they are not well thought out, but I'd rather have them than not)&lt;/li&gt;&lt;li&gt;Object and collection initializers (to make code more brief)&lt;/li&gt;&lt;li&gt;Anonymous POD ("plain old data") classes, which work like tuples except that the fields have names.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt; Suddenly, C# is starting to seem a lot more like &lt;a href="http://boo.codehaus.org/"&gt;boo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Having said all this, there are a couple of things from Java that I might like to have in C#:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The assert statement. Typing Debug.Assert() all the time is driving me nuts.&lt;/li&gt;&lt;li&gt;Inner classes that have an implicit link to the outer class&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;And let's see, if I could have some more features I think they would include&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Traits&lt;/li&gt;&lt;li&gt;The ability to supply a default implementation for a member of an interface&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Preconditions and postconditions on methods&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Static and run-time unit checking (units as in metres, litres, bytes, pixels, etc.)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-8109101927609590533?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/8109101927609590533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=8109101927609590533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/8109101927609590533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/8109101927609590533'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/07/whats-wrong-with-java.html' title='What&apos;s wrong with Java'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-1937670640483131223</id><published>2007-07-05T23:10:00.000-06:00</published><updated>2007-07-05T23:25:02.959-06:00</updated><title type='text'>2 or 3 major bugs in ANTLR 3</title><content type='html'>No matter what I do I can't seem to make a lexer that works correctly. Weird things have been happening constantly, starting with the multi-megabyte lexer that I always end up with if I use LL(*). So I've been using LL(4) but am still running into a number of problems.&lt;br /&gt;&lt;br /&gt;I've been testing with the demo lexer below. Before I show it, I want to point out what's going on with the backslash:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;in my language, backslash is an escape for producing identifiers out of punctuation, so "\&amp;" is an identifier, as is "\a\b\c" as well as ordinary things like "abc".&lt;/li&gt;&lt;li&gt;backslash is punctuation (PUNC) if followed by a space. The space is NOT included in the token.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;By the way, should these rules be equivalent (behaviorally)? I think they should:&lt;br /&gt;&lt;br /&gt;BUG: ('_' | {false}? . | {false}? .)+; // Version 1&lt;br /&gt;BUG: ('_' | {false}? .)+; // Version 2&lt;br /&gt;BUG: ('_')+; // Version 3&lt;br /&gt;&lt;br /&gt;But as you'll see, three different behaviors may result. Another thing I've noticed is that ANTLR seems to use more lookahead than necessary to do prediction, and because of this is somehow more likely to make incorrect predictions.&lt;br /&gt;&lt;br /&gt;I've isolated a small set of rules to demonstrate some of the problems I've been having. Note that I usually use predicates like&lt;br /&gt;&lt;br /&gt;         {input.LA(2) == ' ' || input.LA(2) == '\t'}? '\\'&lt;br /&gt;&lt;br /&gt;instead of&lt;br /&gt;&lt;br /&gt;         ('\\' (' ' | '\t')) =&amp;gt; '\\'&lt;br /&gt;&lt;br /&gt;because as discussed recently, the latter does not work. And it seems that often the former doesn't work either. I've included examples of both apparently failing. Here's the grammar:&lt;br /&gt;&lt;pre&gt;/////////////////////////////////////////////////////////////////////////&lt;br /&gt;lexer grammar Bug1;&lt;br /&gt;&lt;br /&gt;options&lt;br /&gt;{&lt;br /&gt;       language = 'CSharp';&lt;br /&gt;       k = 4;&lt;br /&gt;       TokenLabelType = CommonToken;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@lexer::members {&lt;br /&gt;       public bool IsWS(int LA)        { int c = input.LA(LA); return c == '&lt;br /&gt;' || c == '\t'; }&lt;br /&gt;       public bool IsNewline(int LA)   { int c = input.LA(LA); return c ==&lt;br /&gt;'\r' || c == '\n'; }&lt;br /&gt;       public bool IsCtrlChar(int LA)  { int c = input.LA(LA); return c &amp;lt; 32; }&lt;br /&gt;       public bool IsBackslash(int LA) { int c = input.LA(LA); return c == '\\'; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;WS: WS_CHAR+;&lt;br /&gt;fragment WS_CHAR: ' ' | '\t';&lt;br /&gt;&lt;br /&gt;BUG: ('_' | {false}? . | {false}? .)+; // Version 1&lt;br /&gt;//BUG: ('_' | {false}? .)+; // Version 2&lt;br /&gt;//BUG: ('_')+; // Version 3&lt;br /&gt;&lt;br /&gt;ID: ID_LETTER+;&lt;br /&gt;fragment ID_LETTER&lt;br /&gt;       : ('a'..'z' | 'A'..'Z')&lt;br /&gt;       | {IsBackslash(1) &amp;&amp; !IsWS(2) &amp;&amp; !IsCtrlChar(2)}?=&amp;gt; '\\' .&lt;br /&gt;       ;&lt;br /&gt;&lt;br /&gt;PUNC: PUNC_CHAR+;&lt;br /&gt;fragment PUNC_CHAR:&lt;br /&gt;         {IsWS(2)}? '\\'                     // Version 1&lt;br /&gt;       //{IsBackslash(1) &amp;&amp; IsWS(2)}?=&amp;gt; '\\' // Version 2&lt;br /&gt;       //('\\' WS_CHAR)=&amp;gt;'\\'                // Version 3&lt;br /&gt;       | (':'|'.'|'~'|'!'|'@'|'$'|'%'|'^'|'&amp;'&lt;br /&gt;         |'*'|'-'|'+'|'='|'|'|','|'['|']'|'?');&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;Next, here's the testing code:&lt;br /&gt;&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;br /&gt;public static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;       ParseBug(@"ab");&lt;br /&gt;       ParseBug(@"ab&amp; ");&lt;br /&gt;       ParseBug(@"ab&amp;\");&lt;br /&gt;       ParseBug(@"ab&amp;\cd");&lt;br /&gt;       ParseBug(@"ab\ cd");&lt;br /&gt;}&lt;br /&gt;static void ParseBug(string s)&lt;br /&gt;{&lt;br /&gt;       System.Console.WriteLine(s);&lt;br /&gt;       ANTLRStringStream input = new ANTLRStringStream(s);&lt;br /&gt;       Lexer lexerBug = new Bug1Lexer(input);&lt;br /&gt;       IToken t;&lt;br /&gt;       while ((t = lexerBug.NextToken()).Type != Bug1Lexer.EOF) {&lt;br /&gt;               System.Console.WriteLine("{0} [{1}]",&lt;br /&gt;                       FooParser.tokenNames[t.Type], t.Text);&lt;br /&gt;       }&lt;br /&gt;       System.Console.WriteLine("");&lt;br /&gt;}&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;/pre&gt;&lt;br /&gt;N.B. All of these test strings should work, but they don't. ANTLR gives no warnings. The output is:&lt;br /&gt;&lt;pre&gt;ab&lt;br /&gt;ID [ab]&lt;br /&gt;&lt;br /&gt;ab&amp;&lt;br /&gt;line 1:0 required (...)+ loop did not match anything at character 'a'&lt;br /&gt;line 1:1 required (...)+ loop did not match anything at character 'b'&lt;br /&gt;PUNC [&amp;]&lt;br /&gt;&lt;br /&gt;ab&amp;\&lt;br /&gt;line 1:0 required (...)+ loop did not match anything at character 'a'&lt;br /&gt;line 1:1 required (...)+ loop did not match anything at character 'b'&lt;br /&gt;line 1:3 rule PUNC_CHAR failed predicate: {input.LA(2) == ' ' ||&lt;br /&gt;input.LA(2) == '\t'}?&lt;br /&gt;&lt;br /&gt;ab&amp;\cd&lt;br /&gt;line 1:0 required (...)+ loop did not match anything at character 'a'&lt;br /&gt;line 1:1 required (...)+ loop did not match anything at character 'b'&lt;br /&gt;line 1:2 required (...)+ loop did not match anything at character '&amp;'&lt;br /&gt;ID [\cd]&lt;br /&gt;&lt;br /&gt;ab\ cd&lt;br /&gt;ID [ab]&lt;br /&gt;line 1:2 no viable alternative at character '\'&lt;br /&gt;line 1:3 required (...)+ loop did not match anything at character ' '&lt;br /&gt;ID [cd]&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;/pre&gt;&lt;br /&gt;Now switch to Version 2 of BUG. The output is:&lt;br /&gt;&lt;pre&gt;ab&lt;br /&gt;ID [ab]&lt;br /&gt;&lt;br /&gt;ab&amp;&lt;br /&gt;line 1:0 rule BUG failed predicate: {false}?&lt;br /&gt;line 1:1 rule BUG failed predicate: {false}?&lt;br /&gt;PUNC [&amp;]&lt;br /&gt;&lt;br /&gt;ab&amp;\&lt;br /&gt;line 1:0 rule BUG failed predicate: {false}?&lt;br /&gt;line 1:1 rule BUG failed predicate: {false}?&lt;br /&gt;line 1:2 rule BUG failed predicate: {false}?&lt;br /&gt;line 1:3 no viable alternative at character '\'&lt;br /&gt;WS [ ]&lt;br /&gt;&lt;br /&gt;ab&amp;\cd&lt;br /&gt;line 1:0 rule BUG failed predicate: {false}?&lt;br /&gt;line 1:1 rule BUG failed predicate: {false}?&lt;br /&gt;line 1:2 rule BUG failed predicate: {false}?&lt;br /&gt;ID [\cd]&lt;br /&gt;&lt;br /&gt;ab\ cd&lt;br /&gt;ID [ab]&lt;br /&gt;line 1:2 no viable alternative at character '\'&lt;br /&gt;line 1:3 rule BUG failed predicate: {false}?&lt;br /&gt;ID [cd]&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;/pre&gt;&lt;br /&gt;It is worth noting that this grammar is LL(1) because all other lookahead is done with semantic predicates. However, the above symptoms only occur if k&amp;gt;1. If k=2 then two errors remain; if k=1 then the result is the same as when using Version 3 of BUG.&lt;br /&gt;&lt;br /&gt;Without further ado, here's Version 3 of BUG:&lt;br /&gt;&lt;pre&gt;ab&lt;br /&gt;ID [ab]&lt;br /&gt;&lt;br /&gt;ab&amp;&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [&amp;]&lt;br /&gt;&lt;br /&gt;ab&amp;\&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [&amp;\]&lt;br /&gt;WS [ ]&lt;br /&gt;&lt;br /&gt;ab&amp;\cd&lt;br /&gt;ID [ab]&lt;br /&gt;line 1:3 rule PUNC_CHAR failed predicate: {IsWS(2)}?&lt;br /&gt;ID [cd]&lt;br /&gt;&lt;br /&gt;ab\ cd&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [\]&lt;br /&gt;WS [ ]&lt;br /&gt;ID [cd]&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's much better! But there's a problem with the predicate because it is not getting hoisted for some reason. mPUNC() sees a backslash and decides that's all it needs to run mPUNC_CHAR. In fact, mPUNC_CHAR() itself doesn't run the predicate until after it's predicted the result. It escapes me why it would decide that the alternative succeeds, then runs the predicate afterward - which fails, of course.&lt;br /&gt;&lt;br /&gt;Now let's try Version 3 of PUNC_CHAR - something slightly different happens:&lt;br /&gt;&lt;pre&gt;ab&lt;br /&gt;ID [ab]&lt;br /&gt;&lt;br /&gt;ab&amp;&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [&amp;]&lt;br /&gt;&lt;br /&gt;ab&amp;\&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [&amp;\]&lt;br /&gt;WS [ ]&lt;br /&gt;&lt;br /&gt;ab&amp;\cd&lt;br /&gt;ID [ab]&lt;br /&gt;line 1:3 no viable alternative at character '\'&lt;br /&gt;ID [cd]&lt;br /&gt;&lt;br /&gt;ab\ cd&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [\]&lt;br /&gt;WS [ ]&lt;br /&gt;ID [cd]&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This time, mPUNC decides that a backslash alone is enough to predict a backslash, so it calls mPUNC_CHAR. mPUNC_CHAR actually bothers to run the predicate and, of course, it fails, causing a no viable alt error.&lt;br /&gt;&lt;br /&gt;Only Version 2 works as it should:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ab&lt;br /&gt;ID [ab]&lt;br /&gt;&lt;br /&gt;ab&amp;&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [&amp;]&lt;br /&gt;&lt;br /&gt;ab&amp;\&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [&amp;\]&lt;br /&gt;WS [ ]&lt;br /&gt;&lt;br /&gt;ab&amp;\cd&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [&amp;]&lt;br /&gt;ID [\cd]&lt;br /&gt;&lt;br /&gt;ab\ cd&lt;br /&gt;ID [ab]&lt;br /&gt;PUNC [\]&lt;br /&gt;WS [ ]&lt;br /&gt;ID [cd]&lt;br /&gt;/////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This concludes my little bug report.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-1937670640483131223?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/1937670640483131223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=1937670640483131223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/1937670640483131223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/1937670640483131223'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/07/no-matter-what-i-do-i-cant-seem-to-make.html' title='2 or 3 major bugs in ANTLR 3'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-7009641419911029468</id><published>2007-07-02T10:51:00.000-06:00</published><updated>2007-07-02T13:42:15.310-06:00</updated><title type='text'>ANTLR 3 - Customizing token numbers</title><content type='html'>&gt; I'm not sure if lexers support vocabulary importing (I know&lt;br /&gt;&gt; parsers do), but if they do then you should be able to do it that&lt;br /&gt;&gt; way -- make a tokens file and import it into the lexer.  Worth a&lt;br /&gt;&gt; try, anyway :)&lt;br /&gt;&lt;br /&gt;Ahh, of course, I should have tried that.&lt;br /&gt;&lt;br /&gt;And happily, it works! But I found the following caveats.&lt;br /&gt;&lt;br /&gt;There is a bug that occurs when ANTLR imports and then exports a backslash. So if I have&lt;br /&gt;&lt;pre&gt;parser grammar FooParser;&lt;br /&gt;options {&lt;br /&gt;   tokenVocab=Foo;&lt;br /&gt;...&lt;br /&gt;lexer grammar Foo;&lt;br /&gt;options {&lt;br /&gt;   tokenVocab=Foo2;&lt;br /&gt;&lt;br /&gt;// In Foo2.tokens&lt;br /&gt;'\\'=25&lt;br /&gt;// In the generated Foo.tokens&lt;br /&gt;'\'=25&lt;br /&gt;'\\'=31         // Added by ANTLR&lt;/pre&gt;&lt;br /&gt;This causes a syntax error when compiling the parser. And I guess there is another bug in ANTLRWorks because after the syntax error, ANTLRWorks will keep repeating the same error every time you try to Generate Code, until you quit and restart the program.&lt;br /&gt;&lt;br /&gt;By the way, I found that&lt;br /&gt;&lt;br /&gt;'\\\\'=25&lt;br /&gt;&lt;br /&gt;Seems to work as a single backslash.&lt;br /&gt;&lt;br /&gt;There is another important caveat: ANTLR cannot handle "holes" when importing tokens into the parser, i.e. unused numbers in the list of tokens. You must start numbering tokens at 4 and continue up from there with consecutive integers. The problem is that the token names array called tokenNames[] in your parser will not have any empty elements in it, so if your tokens are&lt;br /&gt;&lt;br /&gt;APPLE=4&lt;br /&gt;GRAPE=5&lt;br /&gt;LEMON=9&lt;br /&gt;PEAR=10&lt;br /&gt;&lt;br /&gt;then your token array will be&lt;br /&gt;&lt;pre&gt;public static readonly string[] tokenNames = new string[]&lt;br /&gt;{&lt;br /&gt;   "[invalid]",&lt;br /&gt;   "[eor]",&lt;br /&gt;   "[down]",&lt;br /&gt;   "[up]",&lt;br /&gt;   "APPLE",&lt;br /&gt;   "GRAPE",&lt;br /&gt;   "LEMON",&lt;br /&gt;   "PEAR"&lt;br /&gt;};&lt;/up&gt;&lt;/down&gt;&lt;/eor&gt;&lt;/invalid&gt;&lt;/pre&gt;&lt;br /&gt;Therefore, token name lookups will not work correctly.&lt;br /&gt;&lt;br /&gt;On the plus side, you do not have to define all tokens in your .tokens file; ANTLR can add any additional tokens you define in the lexer and will number them correctly.&lt;br /&gt;&lt;br /&gt;P.S. I'm using the C# target; perhaps YMMV for Java etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-7009641419911029468?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/7009641419911029468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=7009641419911029468' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7009641419911029468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/7009641419911029468'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/07/im-not-sure-if-lexers-support.html' title='ANTLR 3 - Customizing token numbers'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-2949955405664954875</id><published>2007-07-01T11:08:00.000-06:00</published><updated>2007-07-01T11:13:24.480-06:00</updated><title type='text'>ANTLR Warning suppression workaround</title><content type='html'>On p.285 of the ANTLR book it implies that you cannot suppress warnings in ANTLR v3 like you could in v2.&lt;br /&gt;&lt;br /&gt;However, it appears that a semantic predicate works nicely as a workaround:&lt;br /&gt;&lt;pre&gt;// Strings&lt;br /&gt;SQ_STRING: '\''! ({true}? ESC_SEQ | ~'\'')* '\''!;&lt;br /&gt;DQ_STRING: '"'!  ({true}? ESC_SEQ | ~'"')* '"'!;&lt;br /&gt;BQ_STRING: '`'!  ({true}? ESC_SEQ | ~'`')* '`'!;&lt;br /&gt;fragment ESC_SEQ: '\\' ~('\n'|'\r');&lt;br /&gt;&lt;/pre&gt;The generated code now contains LL(2) lookahead for no reason, and some redundant code. For example, code that originally read&lt;br /&gt;&lt;pre&gt;   if ( (LA19_0 == '\"') )&lt;br /&gt;  {&lt;br /&gt;     alt19 = 1;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;Now says&lt;br /&gt;&lt;pre&gt;   if ( (LA19_0 == '\"') )&lt;br /&gt;  {&lt;br /&gt;     int LA19_1 = input.LA(2);&lt;br /&gt;     if ( (true) )&lt;br /&gt;     {&lt;br /&gt;         alt19 = 1;&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;However, its behavior appears to be the same.&lt;br /&gt;&lt;br /&gt;The compiler will emit some "unreachable code" warnings. In C# you can disable them like this:&lt;br /&gt;&lt;pre&gt;grammar Expr;&lt;br /&gt;options {&lt;br /&gt;  language=CSharp;&lt;br /&gt;}&lt;br /&gt;@lexer::members {&lt;br /&gt;  #pragma warning disable 0162&lt;br /&gt;}&lt;br /&gt;@parser::members {&lt;br /&gt;  #pragma warning disable 0162&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-2949955405664954875?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.antlr.org:8080/pipermail/antlr-interest/2007-June/021686.html' title='ANTLR Warning suppression workaround'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/2949955405664954875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=2949955405664954875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2949955405664954875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2949955405664954875'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/07/warning-suppression-workaround.html' title='ANTLR Warning suppression workaround'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-1275182687038591731</id><published>2007-06-30T11:37:00.000-06:00</published><updated>2007-06-30T11:46:18.731-06:00</updated><title type='text'>ANTLR 3 C# runtime - source code found!</title><content type='html'>&gt; Does anyone know why the source code is not available? Is it closed&lt;br /&gt;&gt; source? What's the licence?&lt;br /&gt;&lt;br /&gt;While these questions remain unanswered, I have found an amazingly good tool called "Reflector" and a disassembly helper. For more information see&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;http://www.aisto.com/roeder/dotnet/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/reflectoraddins"&gt;http://www.codeplex.com/reflectoraddins&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.denisbauer.com/NETTools/FileDisassembler.aspx"&gt;http://www.denisbauer.com/NETTools/FileDisassembler.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have discovered that the assembly contains full symbol information including local variable names, and the tool outputs suprisingly high-level code. If you don't want to reconstruct it yourself, you can get it here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://qwertie.net/misc/Antlr3.Runtime-Disasm.zip"&gt;http://qwertie.net/misc/Antlr3.Runtime-Disasm.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The add-in even creates a project file! Right on!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-1275182687038591731?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/1275182687038591731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=1275182687038591731' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/1275182687038591731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/1275182687038591731'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/06/c-runtime-source-code-found.html' title='ANTLR 3 C# runtime - source code found!'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-5932451476759320908</id><published>2007-06-04T06:55:00.000-06:00</published><updated>2007-06-04T08:14:53.040-06:00</updated><title type='text'>SharpDevelop add-in system</title><content type='html'>I'm having tremendous difficulty understanding SharpDevelop's add-in system. Although they offer a free book (Dissecting a C# Application: Inside SharpDevelop), I find its explanation of Codons/addins/etc. to be almost incomprehensible. So I'll investigate them and put my tentative findings here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The add-in tree: Basics &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;See below for locations (in the source code distribution) of classes mentioned here.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;All extensions to #develop (and most core features including the entire GUI, except the splash screen) are add-ins. All addins are stored in C:\Program Files\SharpDevelop\2.1\AddIns\AddIns, except one whose XML file is in the parent folder.&lt;/li&gt;&lt;li&gt;Each add-in must have an XML file that describes it, with an .addin extension. Addins use "XCopy deployment"; to add an addin to SharpDevelop, simply create a folder that contains the add-in, then copy your folder to any appropriate subfolder of the AddIns folder mentioned above. The code of an addin is placed in one or more DLLs.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The AddIn tree is a tree of &lt;span style="font-weight: bold;"&gt;AddInTreeNode&lt;/span&gt; objects. Informally, a distinction is &lt;span style="font-style: italic;"&gt;sometimes&lt;/span&gt; made between nodes that have "Codons" and those that don't: An AddInTreeNode is called a "path" if there is no "Codon" attached or a "node" if there is. However, this is confusing terminology because a route to a &lt;span&gt;AddInTreeNode is often called a "path" regardless of whether the object at that path has a codon; meanwhile, according to its name, an &lt;/span&gt;&lt;span&gt;AddInTreeNode is &lt;span style="font-style: italic;"&gt;&lt;/span&gt;a node (even if it lacks a codon).&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;The AddInTreeNode.ChildNodes property returns the child nodes as a Dictionary{string, AddInTreeNode}. The AddInTreeNode class lacks a link to its parent node.&lt;/li&gt;&lt;li&gt;"Codon" appears to refer to the code of an add-in, whereas an AddIn seems to refer to (a) the XML file that contains the codon and (b) an instance of ICSharpCode.Core.&lt;span style="font-weight: bold;"&gt;AddIn&lt;/span&gt; which represents the XML file in memory. Ironically, AddInTreeNodes do not contain add-ins, only Codons. An add-in can contain multiple codons (at different places in the add-in tree). Also, an add-in can have "conditions" and "doozers" (discussed later).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ICSharpCode.Core.&lt;span style="font-weight: bold;"&gt;AddInTree&lt;/span&gt; (a static class) contains the root of the Add-In tree, which can be reached by calling AddInTree.GetTreeNode(null). However, usually you want to look up something deep in the tree, so call AddInTree.AddInTreeNode("/path/to/the/node"). The path to use is specified in an addin's XML file.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;All codons are stored in the add-in tree, whereas all AddIns are stored in a flat list returned by the AddInTree.AddIns property.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;According to doc\technotes\AddInTree.rtf (in the souce distro), "In the ICSharpCode.Core implementation, the AddInTreeNode class has a Codon property which is null for paths and points to a Codon instance for nodes." But in fact, the Codon property returns a List{Codon} and I don't know why.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;TODO&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ICSharpCode.Core.AddInTree: src\Main\Core\Project\Src\AddInTree\AddInTree.cs&lt;/li&gt;&lt;li&gt;ICSharpCode.Core.AddInTreeNode: src\Main\Core\Project\Src\AddInTree\AddInTreeNode.cs&lt;/li&gt;&lt;li&gt;ICSharpCode.Core.AddIn: src\Main\Core\Project\Src\AddInTree\AddIn&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://laputa.sharpdevelop.net/WritingASharpDevelopAddInTutorialVideo.aspx"&gt;Video about making addins&lt;/a&gt; &lt;a href="http://www.icsharpcode.net/OpenSource/SD/InsideSharpDevelop.aspx"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.icsharpcode.net/OpenSource/SD/InsideSharpDevelop.aspx"&gt;The book&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-5932451476759320908?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/5932451476759320908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=5932451476759320908' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/5932451476759320908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/5932451476759320908'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/06/sharpdevelop-add-in-system.html' title='SharpDevelop add-in system'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-2179379195714036301</id><published>2007-05-30T14:54:00.000-06:00</published><updated>2007-07-01T09:16:18.435-06:00</updated><title type='text'>"The Definitive ANTLR reference" is not definitive</title><content type='html'>I bought the PDF of this book for $US25, which is not a bad deal, but it should be mentioned that the book is lacking some important information like&lt;br /&gt;&lt;ul&gt;&lt;li&gt;an overview of changes from v2 (e.g. shouldn't we be given a few small v2 and v3 grammars side-by-side, highlighting the differences? what kinds of real-world grammars work in v3 that didn't work in v2? other than left recursion, what sorts of grammars still cause trouble?)&lt;/li&gt;&lt;li&gt;yes, LL(*) can handle lots of grammars, but at the cost of scanning a token or character stream repeatedly. How can a grammar be designed instead for good performance?&lt;/li&gt;&lt;li&gt;a complete reference of all the things you can put in a grammar file. There's a "basic structure" on p.90, but it's VERY brief. There's no complete list showing all available sections like options {}, @header {}, @namespace {}, @members {} ... How can it be a "definitive reference" without this?&lt;/li&gt;&lt;li&gt;a class heirarchy diagram and a summary of the methods in important classes like CommonToken, Lexer, Parser, etc. Again, "reference"? The lack of reference material in the book is quite annoying because as far as I know, the book is the only reference there is.&lt;/li&gt;&lt;li&gt;how to make a lexer-only or parser-only grammar. To do this you must write "lexer grammar foo;" or "parser grammar foo;" instead of "grammar foo;" but this is never pointed out specifically. On p.64 there is a sentence that sort of implies lexers should start with "lexer grammar", while "parser grammar" is mentioned for the first time in a code example on p.134, but it is treated like something the reader should have already known.&lt;/li&gt;&lt;li&gt;how to use ANTLR in a non-Java environment. Yeah, you use options{language=CSharp;} or whatever, but then what? where do I get the runtime? how are the runtimes of other languages different from the Java runtime? The book ignores non-Java issues completely.&lt;/li&gt;&lt;li&gt;how to create "unknown" tokens, i.e. tokens for groups of characters that the lexer has no specific rule for. There's a "filter" option to discard unrecognized characters, but in my compiler, I want to create tokens for them and actually give them to the parser.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;how to support all kinds of text file encoding schemes: UTF8, UTF16, ASCII, files using specific "codepages", MBCS, ...&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;complete&lt;/span&gt; examples. Mostly just snippets are shown with links to complete source files online. Unfortunately, as of this writing, example grammars online (such as &lt;a href="http://media.pragprog.com/titles/tpantlr/code/tour/basic/Expr.g"&gt;this one&lt;/a&gt;) have no line breaks in them.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;the discussion of lexers is a bit impoverished. No discussion of the proper way to tell apart '/*' from the sequence of two tokens '/' '*', for example. Normally tokens contain the indexes of the starting and ending character; so what happens when I use the ! suffix? Can I have a catch-all rule, invoked only if the other rules fail (because I need one)?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;an overview of the whole system - I mean there's an overview of concepts on p.22, but there isn't a concise overview of basic nuts &amp; bolts that people need to know such as: how do the lexer and parser get connected together; what are the basic classes and their capabilities/responsibilities in the system (CommonTree, Token, Parser, Lexer, ...); how can ASTs and lists of tokens be traversed manually, inside semantic actions and outside ANTLR grammar files; what functionality is provided by ANTLR (e.g. line-number counting and error message generation) versus what must/should/can be written by the user.&lt;/li&gt;&lt;/ul&gt;Perhaps a lot of this information is in the book, it's just not organized how I might like. The information you need to write a complete lexer-parser and run it is interspersed with explanations of the basic concepts of recursive-decent parsing--explanations I don't want to read because I'm already an experienced programmer who has used v2 before. The babysitting and nitty-gritty details are mixed in such a way that it's hard to skim the text looking for the technical details I want. There may be some things in the list above that are in the book but that I just haven't been able to find yet.&lt;br /&gt;&lt;br /&gt;I suspect the book would be much more useful if it were separated into sections according to use cases. I mean, there are lots of different reasons a person would use ANTLR:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Translating code from one syntax to another, with or without StringTemplate&lt;/li&gt;&lt;li&gt;Taking an AST (or a token list), doing modifications/transformations on it, and outputting the result while keeping original spacing and comments intact (apparently you can't use ANTLR to transform an AST, but keeping the spacing and comments intact is supposed to be "easy" with ANTLR v3, right? But how do you do it? Can't I do it without StringTemplate?)&lt;/li&gt;&lt;li&gt;Gathering information from a source file without necessarily doing a complete parse&lt;/li&gt;&lt;li&gt;Writing a compiler/interpreter for a small, simple domain-specific language&lt;/li&gt;&lt;li&gt;Writing a complex full-scale compiler--this may require "pulling out all the stops", using all of ANTLR's syntax and many of the classes in ANTLR's runtime. Since this is my use case, it's the one I would most like to read about.&lt;/li&gt;&lt;li&gt;Writing an extension to an existing compiler&lt;/li&gt;&lt;li&gt;Creating a new language target for ANTLR using StringTemplate&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Perhaps there should have been a section for each specific use case, with a quick overview of ALL the things a user might need to do to complete his/her task. Since the use cases overlap, each one perhaps should be pretty short and consist mostly of pointers to other parts of the book where more details can be found.&lt;br /&gt;&lt;br /&gt;(Note: certainly there are a sections geared toward specific use cases, but in general if you're trying to accomplish task X, there isn't a island paradise made just for you within the book.)&lt;br /&gt;&lt;br /&gt;Now I wouldn't put such a high standard on free documentation of course, but this is a paid-for book entitled "The Definitive ANTLR Reference". It's a title that gives the impression that&lt;br /&gt;&lt;ul&gt;&lt;li&gt;it contains all the information you need&lt;/li&gt;&lt;li&gt;it is a complete reference&lt;/li&gt;&lt;/ul&gt;well, it doesn't and isn't.&lt;br /&gt;&lt;br /&gt;But I guess I'm being overly harsh. I probably am. There are a lot of people in the world that yell "&lt;span style="font-style: italic;"&gt;You&lt;/span&gt; did it all wrong! &lt;span style="font-style: italic;"&gt;I&lt;/span&gt; know how things should be done!", when in fact if they were in charge, we'd all be worse off. And then some of those people end up getting elected, but I digress.... the point is, I haven't read the book that carefully and I'm just letting off steam.&lt;br /&gt;&lt;br /&gt;Terence has put a lot of his free time into the book and ANTLR (or so I would assume)  and he deserves compensation for it. I certainly don't regret paying for the book... but the fact remains, I'm disappointed. There's lots of space in the margins, maybe the extra information I want to see could go there...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Here's some &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,ff1dc504-f854-40b4-bfe7-250ce91efad7.aspx"&gt;helpful ANTLR information&lt;/a&gt; from Manuel Abadia&lt;/li&gt;&lt;li&gt;&lt;a href="http://wincent.com/knowledge-base/ANTLR_lexers_in_depth"&gt;Useful notes about ANTLR3 lexers&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-2179379195714036301?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/2179379195714036301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=2179379195714036301' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2179379195714036301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/2179379195714036301'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2007/05/definitive-antlr-reference-is-not.html' title='&quot;The Definitive ANTLR reference&quot; is not definitive'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-116149478198447331</id><published>2006-10-21T23:19:00.000-06:00</published><updated>2006-10-24T21:19:17.266-06:00</updated><title type='text'>Boo Compilation Steps</title><content type='html'>This post contains notes about how booc compiles boo programs. The boo compilation process is not complicated, but it is mostly undocumented and therefore can only be understood by inspecting the source code. Also, boo's developer (Rodrigo B. de Oliveira) is, sadly, allergic to comments. Here are my detailed observations - more to come later. See also &lt;a href="http://www.geocities.com/Qwertie256/misc/boo-build-process.html"&gt;the boo build process&lt;/a&gt;. A useful thing to know about the boo codebase is that (so far as I've seen) it follows the java conventions of "one public class per file", "name the file after the class", and "the namespace name corresponds to the actual path in the directory tree". For example, src\Boo.Lang.Compiler\Resources\EmbeddedFileResource.cs contains a class called EmbeddedFileResource in the namespace Boo.Lang.Compiler.Resources. A source file may contain other classes, structs and enums, but they are either internal to the file where they are declared (not used elsewhere), or they have a minor role. &lt;b&gt;BTW:&lt;/b&gt; this convention holds for the C# part of the compiler, but I don't yet know about the boo part.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;A list follows of things that booc does. To kick things off, Main() calls App.Run().&lt;br /&gt;&lt;br /&gt;App.Run():&lt;br /&gt;- I don't know what this is for:&lt;br /&gt;  AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolve);&lt;br /&gt;- CheckBooCompiler(): Emits warning if nonlocal Boo.Lang.Compiler.dll is being used&lt;br /&gt;- _options = new CompilerParameters(false)&lt;br /&gt;- ParseOptions():&lt;br /&gt; - Builds "response file list" (App._responseFileList). It is empty when cmdline &lt;br /&gt;   args is just a src file name - _responseFileList is related to args that start &lt;br /&gt;   with '@'. The default response list is automatically loaded from booc.rsp by &lt;br /&gt;   AddDefaultResponseFile(), unless -noconfig is specified.&lt;br /&gt; - Processes command-line arguments. Most cmdline args alter the configuration&lt;br /&gt;   of _options; some alter flags/variables in App itself.&lt;br /&gt; - The list of input files is added (one at a time) with _options.Input.Add()&lt;br /&gt; - Assigns the _options.Pipeline (-p option), or makes default pipeline, &lt;br /&gt;   CompileToFile(). In WSA mode, &lt;br /&gt;  _options.Pipeline[0] = new Boo.Lang.Parser.WSABooParsingStep();&lt;br /&gt; - debug-steps adds App.StepDebugger as AfterStep event handler.&lt;br /&gt; - prints header ("Boo Compiler version 0.7.6.2237 (CLR v2.0.50727.42)")&lt;br /&gt;- fragility: assumes there are two standard library paths (which are moved to the bottom &lt;br /&gt;  of the lib path list)&lt;br /&gt;- creates a Boo.Lang.Compiler.BooCompiler (.cs), "The compiler: a facade to the&lt;br /&gt;  CompilerParameters/CompilerContext/Pipeline subsystem."&lt;br /&gt;- Unless -nostdlib specified, calls _options.LoadDefaultReferences() to add default references.&lt;br /&gt;  The default references are mscorlib, System, the currently loaded Boo.Lang, and the currently&lt;br /&gt;  loaded Boo.Lang.Compiler.&lt;br /&gt;- LoadReferences(): loads assemblies previously requested with -r on cmd line; calls&lt;br /&gt;  _options.References.Add() to add each assembly&lt;br /&gt;- CompilerContext context = compiler.Run();&lt;br /&gt;  This one line compiles the code and (I think) generates the output assembly, although &lt;br /&gt;  Warnings/errors are not printed yet. Run() with no args creates a new CompileUnit (the &lt;br /&gt;  top-level AST class) and passes it to &lt;br /&gt; public CompilerContext Run(CompileUnit compileUnit)&lt;br /&gt;- Prints warnings from context.Warnings (a Boo.Lang.Compiler.CompilerWarningCollection) and &lt;br /&gt;  errors from context.Errors (a Boo.Lang.Compiler.CompilerErrorCollection)&lt;br /&gt; &lt;br /&gt;Boo.Lang.Compiler.BooCompiler.Run(CompileUnit compileUnit):&lt;br /&gt;- Creates a new CompilerContext(_parameters, compileUnit) where _parameters is the &lt;br /&gt;  Coo.Lang.Compiler.CompilerParameters object with which the object was originally initialized.&lt;br /&gt;- _parameters.Pipeline.Run(context): (Boo.Lang.Compiler.CompilerPipeline.Run())&lt;br /&gt; - virtual stub: Prepare(context)&lt;br /&gt; - calls RunStep(context, step) for each step in the pipeline. step is a parsing step, &lt;br /&gt;   e.g. BooParsingStep&lt;br /&gt;  - fires this.BeforeStep event&lt;br /&gt;  - calls step.Initialize()&lt;br /&gt;  - calls step.Run() &amp; catches exception if any&lt;br /&gt;  - fires this.AfterStep event&lt;br /&gt; - calls Dispose() on each step&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;ASTs:&lt;br /&gt;- Automatically generated classes are named Boo.Lang.Compiler.Ast.Impl.*Impl&lt;br /&gt;- Each has a derived class named Boo.Lang.Compiler.Ast.*&lt;br /&gt;- Boo.Lang.Compiler.Ast.Node is the base class for every node in the AST. Its data content is&lt;br /&gt; protected LexicalInfo _lexicalInfo = LexicalInfo.Empty;&lt;br /&gt; protected SourceLocation _endSourceLocation = LexicalInfo.Empty;&lt;br /&gt; protected Node _parent;&lt;br /&gt; protected string _documentation;&lt;br /&gt; protected System.Collections.Hashtable _annotations = new System.Collections.Hashtable();&lt;br /&gt; protected bool _isSynthetic;&lt;br /&gt;- Top-level AST element is called CompileUnit. At this point I am assuming, since only one &lt;br /&gt;  CompileUnit is created by Boo.Lang.Compiler.BooCompiler.Run(), that all boo source files &lt;br /&gt;  given to booc are merged into the same CompileUnit object. Data:&lt;br /&gt; protected ModuleCollection _modules;&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;The standard set of compiler steps follows directly from the implementation of&lt;br /&gt;CompileToFile and its base classes.&lt;br /&gt;&lt;br /&gt;CompileToFile's entire implementation is&lt;br /&gt; class CompileToFile : CompileToMemory { CompileToFile() { Add(new SaveAssembly()); } }&lt;br /&gt;inherited from:&lt;br /&gt; class CompileToMemory : Compile { CompileToMemory() { Add(new EmitAssembly()); } }&lt;br /&gt;inherited from:&lt;br /&gt; public class Compile : ResolveExpressions {&lt;br /&gt;  public Compile() {&lt;br /&gt;   Add(new UnfoldConstants());&lt;br /&gt;   Add(new OptimizeIterationStatements());&lt;br /&gt;&lt;br /&gt;   Add(new CheckIdentifiers());&lt;br /&gt;   Add(new StricterErrorChecking());&lt;br /&gt;&lt;br /&gt;   Add(new ExpandDuckTypedExpressions());&lt;br /&gt;&lt;br /&gt;   Add(new ProcessAssignmentsToValueTypeMembers());&lt;br /&gt;   Add(new ExpandProperties());&lt;br /&gt;   Add(new RemoveDeadCode());&lt;br /&gt;   &lt;br /&gt;   Add(new CheckMembersProtectionLevel());&lt;br /&gt;&lt;br /&gt;   Add(new NormalizeIterationStatements());&lt;br /&gt;   &lt;br /&gt;   Add(new ProcessSharedLocals());   &lt;br /&gt;   Add(new ProcessClosures());&lt;br /&gt;   Add(new ProcessGenerators());&lt;br /&gt;&lt;br /&gt;   Add(new ExpandVarArgsMethodInvocations());&lt;br /&gt;   &lt;br /&gt;   Add(new InjectCallableConversions());&lt;br /&gt;   Add(new ImplementICallableOnCallableDefinitions());&lt;br /&gt;&lt;br /&gt;   // TODO:&lt;br /&gt;   //Add(new InjectCastsAndConversions());&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;inherited from:&lt;br /&gt; public class ResolveExpressions : Parse {&lt;br /&gt;  public ResolveExpressions() {&lt;br /&gt;   Add(new InitializeTypeSystemServices());&lt;br /&gt;   Add(new PreErrorChecking());&lt;br /&gt;   &lt;br /&gt;   Add(new MergePartialClasses());&lt;br /&gt;   &lt;br /&gt;   Add(new PreProcessExtensionMethods());&lt;br /&gt;   Add(new InitializeNameResolutionService());&lt;br /&gt;   Add(new IntroduceGlobalNamespaces());&lt;br /&gt;   Add(new TransformCallableDefinitions());&lt;br /&gt;   Add(new BindTypeDefinitions());   &lt;br /&gt;   Add(new BindNamespaces());&lt;br /&gt;   Add(new BindBaseTypes());&lt;br /&gt;   Add(new BindAndApplyAttributes());&lt;br /&gt;   Add(new ExpandMacros());&lt;br /&gt;   Add(new IntroduceModuleClasses());&lt;br /&gt;   Add(new NormalizeStatementModifiers());&lt;br /&gt;   Add(new NormalizeTypeAndMemberDefinitions());&lt;br /&gt;   &lt;br /&gt;   Add(new BindTypeDefinitions());&lt;br /&gt;   Add(new BindEnumMembers());&lt;br /&gt;   Add(new BindBaseTypes());&lt;br /&gt;&lt;br /&gt;   Add(new ResolveTypeReferences());&lt;br /&gt;   &lt;br /&gt;   Add(new BindTypeMembers());   &lt;br /&gt;   Add(new ProcessInheritedAbstractMembers());&lt;br /&gt;   Add(new CheckMemberNames());&lt;br /&gt;   &lt;br /&gt;   Add(new ExpandAstLiterals());&lt;br /&gt;   Add(new ProcessMethodBodiesWithDuckTyping());&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;inherited from:&lt;br /&gt; public class Parse : CompilerPipeline {&lt;br /&gt;  public Parse() { Add(NewParserStep()); }&lt;br /&gt;  ...&lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;The job of NewParserStep() is to dynamically load Boo.Lang.Parser.dll (using&lt;br /&gt;System.Reflection.Assembly.Load()/LoadFrom()) and to create an instance of &lt;br /&gt;Boo.Lang.Parser.BooParsingStep (using System.Activator). Fragility: the code &lt;br /&gt;relies on the fact that the current assembly is named Boo.Lang.Compiler.dll.&lt;br /&gt;&lt;br /&gt;All of the above classes are compiler pipelines, defined in &lt;br /&gt;src\Boo.Lang.Compiler\Pipelines.&lt;br /&gt;&lt;br /&gt;inherited from: CompilerPipeline, which serves as a collection of steps and &lt;br /&gt;includes functions to run the steps (Run(), RunStep())&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-116149478198447331?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/116149478198447331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=116149478198447331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/116149478198447331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/116149478198447331'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/10/boo-compilation-steps.html' title='Boo Compilation Steps'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-115584937269600015</id><published>2006-08-17T15:15:00.000-06:00</published><updated>2006-08-17T15:16:12.713-06:00</updated><title type='text'>ENCM 599 Project Ideas</title><content type='html'>The first two projects would certainly require two semesters (and beyond); the last two might be small enough that I could make something useful in one semester.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. A note taking program&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This would be a word processor tailored to in-class note-taking on a laptop or tablet PC.  This would be an experiment in making computer note-taking feasible and useful.  Features could include:&lt;br /&gt;&lt;br /&gt;- Diagram sandboxes - you could draw a diagram in a full-screen window, and when you're finished, the drawing would be shrunk down to a smaller size within the main document.&lt;br /&gt;- Automatic tablemaking - making tables of data is time-consuming in a conventional word processor.  Making use of the tab and space keys, my note-taking program could allow users to create and arrange tables on-the-fly without opening menus or dialog boxes.&lt;br /&gt;- Minimizing the number of drawing tools by giving more than one capability to tools.  For example, the basic freehand pen tool would normally just put ink on the screen.  But if you draw in a particular fashion, other actions could happen instead:&lt;br /&gt;    - Scribble out text to erase it and place the text cursor in its place.&lt;br /&gt;    - When you click on a point, a dot is created on the screen (as you would expect from a freehand tool); but if you then begin to type, the dot is replaced with what you typed.  In other words, the pen could also do cursor placement.&lt;br /&gt;    - Draw a freehand line from one margin to another to "rip" the virtual page in half.  You could then drag the line to create new virtual paper.&lt;br /&gt;    - After you draw a line or circle something, you could run commands that change your action from drawing to something else, such as deleting or selecting.    In other words, the program could support noun-verb interaction in addition to verb-noun interaction.&lt;br /&gt;- Keyboard-based diagramming - diagrams could be drawn quickly with a keyboard.&lt;br /&gt;&lt;br /&gt;I could come up with a great many ideas, but they won't all fit in a one- or two-semester project.  I suppose I will have to decide whether I want to focus on laptop-based usage (keyboard bound) or tablet PC usage (pen bound).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. Designing a computer language/compiler&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I am not really happy with any existant language, so I would like to attempt my own design.&lt;br /&gt;&lt;br /&gt;The main focus of the language would be extensibility, and this would be primarily a research project--just trying to figure out how to make a sufficiently extensible language. I would start by making a large and diverse list of features that I think should be possible in an "ideal" language.  It would include all the major features of all the major languages, e.g.:&lt;br /&gt;&lt;br /&gt;- Object-oriented programming&lt;br /&gt;- Multiple inheritance&lt;br /&gt;- Interfaces with single inheritance&lt;br /&gt;- Templates (C++) - time-efficient genericity&lt;br /&gt;- Generics (C#) - space-efficient genericity with runtime specialization&lt;br /&gt;- Inner functions&lt;br /&gt;- Closures&lt;br /&gt;- Coroutines (Stackless Python)&lt;br /&gt;- Garbage collection&lt;br /&gt;- Dynamic typing&lt;br /&gt;- Static typing&lt;br /&gt;- Functional programming (Haskell)&lt;br /&gt;- Static type inference (Haskell)&lt;br /&gt;- Unit type checking (e.g. giving an error if the programmer attempts a + b where "a" is measured in metres and "b" in square feet.) and inference (e.g. metres * seconds / seconds = metres), and syntax to allow this feature.&lt;br /&gt;- Interface reconfiguration &amp; extension (changing/extending an object's interface without changing its identity - I can explain better if you like)&lt;br /&gt;- High performance &amp;amp; low-level programming (C/C++/Asm)&lt;br /&gt;&lt;br /&gt;I would then attempt to design an appropriate set of compiler modules with a well-defined interface between them.  The idea would be to design an open compiler architecture so that one could write 'plug-ins' that add features to the compiler.&lt;br /&gt;&lt;br /&gt;In addition to language features, I would like to consider extensible syntax. The fondest dream here is a language which can take on the syntax of another language (e.g. Java), but provide additional features not found in that language, and also to allow code using different syntax to interoperate on an intimate level.  .NET is a step toward that ideal, but inter-language interoperability is limited to a specific set of features defined by Microsoft, and (seemingly) every language used must be compiled to a DLL separate from code in other languages.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3. Something involving a dictionary&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Last semester I made a user-editable interdictionary web application: see http://qwertie.net/&lt;br /&gt;&lt;br /&gt;I would like to continue working on this project somehow, or another related project.&lt;br /&gt;&lt;br /&gt;One idea is to attempt to import some large part of Wiktionary (http://www.wiktionary.com) into my dictionary, so that the features of my application can be used to browse Wiktionary.  Perhaps a better idea is to actually contact the developers of Wiktionary, and see if I could help add features to their website.&lt;br /&gt;&lt;br /&gt;Finally, it would be nice to make a PocketPC version of my dictionary.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4. PocketPC keyboard extension&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Some time ago I wrote a keyboard application for Palm pocket computers (see http://millikeys.sourceforge.net/).  But my Palm broke a couple years back, and MilliKeys has not been updated since.&lt;br /&gt;&lt;br /&gt;PocketPCs have handwriting recognition, which is very cool, but handwriting is simply not as fast as typing can be.&lt;br /&gt;&lt;br /&gt;Recently I was inspired by an input method on a cell phone: each number key is assigned several letters (e.g. 2=ABC).  You can input a word using just numbers and the phone automatically figures out the intended word, so you type "43556" and it figures out that you want "hello".&lt;br /&gt;&lt;br /&gt;I would like to do something related, with a sort of fuzzy logic.  The on-screen keyboard on a PocketPC has very small buttons, so you must type on it, you must type carefully.  I would like to implement a keyboard with probabalistic input, that would allow you to miss keys and still get the intended output.  So if it were a Qwerty keyboard, you could hit the keys "gwklo" and it would automatically output "hello".  For each character, it would use Fitts' law to model the input and determine the likelihood that various characters were intended. Using probability formulas, in conjunction with a dictionary, it would then determine the most likely intended word.  It would also allow the user to use what he actually typed instead.&lt;br /&gt;&lt;br /&gt;Additionally, it could support features of MilliKeys, such as the ability to make a short stroke to type punctuation, capital letters, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-115584937269600015?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/115584937269600015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=115584937269600015' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/115584937269600015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/115584937269600015'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/08/encm-599-project-ideas.html' title='ENCM 599 Project Ideas'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-115318938443690082</id><published>2006-07-17T20:17:00.000-06:00</published><updated>2006-07-17T20:24:50.596-06:00</updated><title type='text'>My new fake identity</title><content type='html'>Why should I give my name, address, phone number and birthday to every stupid company from which I buy a product, just for the unknown "benefits of registration"?  Here's my identity from &lt;a href="http://www.fakenamegenerator.com/"&gt;http://www.fakenamegenerator.com/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com/search?hl=en&amp;lr=&amp;amp;amp;amp;q=%22David+Rudd%22&amp;btnG=Search" title="Search for your name on Google"&gt;David T. Rudd&lt;/a&gt;&lt;br /&gt;2337 50th Street&lt;br /&gt;Edmonton, AB T6B 2W9&lt;br /&gt;&lt;br /&gt;Email Address: &lt;a href="http://spambob.com/search.cgi?addr=David.T.Rudd"&gt;David.T.Rudd@spambob.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Phone: 780-203-2861&lt;br /&gt;Mother's maiden name: Holmes&lt;br /&gt;Birthday: &lt;span class="help" title="A person born on August 17, 1983, would be 22 years old."&gt;August 17, 1983  [ 1983-08-17 ]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Visa: 4556 3352 0574 3891&lt;br /&gt;Expires: 7/2008&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-115318938443690082?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/115318938443690082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=115318938443690082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/115318938443690082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/115318938443690082'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/07/my-new-fake-identity.html' title='My new fake identity'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-114445096293132956</id><published>2006-04-07T16:57:00.000-06:00</published><updated>2006-04-07T17:04:52.323-06:00</updated><title type='text'>Haskell: how to show tuples with more than 5 arguments</title><content type='html'>If you try to convert a long tuple with 6 or more components to a string in GHC, you get an error like&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;file.hs:17:5:&lt;br /&gt;    No instance for (Show ___)&lt;br /&gt;      arising from the 'deriving' clause of a data type declaration at file.hs:17:5&lt;br /&gt;    Probable fix: add an instance declaration for (Show ___)&lt;br /&gt;    When deriving the `Show' instance for type `___'&lt;/pre&gt;&lt;br /&gt;You can fix it with a show declaration for the number of arguments in your tuple.  For example, this gives you support for 6-tuples:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;instance (Show a, Show b, Show c, Show d, Show e, Show f) =&gt; Show (a,b,c,d,e,f) where&lt;br /&gt;    show (a,b,c,d,e,f) = "("++(show a)++", "++(show b)++", "++(show c)++", "++&lt;br /&gt;                              (show d)++", "++(show e)++", "++(show f)++")"&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-114445096293132956?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/114445096293132956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=114445096293132956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/114445096293132956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/114445096293132956'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/04/haskell-how-to-show-tuples-with-more.html' title='Haskell: how to show tuples with more than 5 arguments'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-114124194181291281</id><published>2006-03-01T12:07:00.000-07:00</published><updated>2006-03-01T12:39:03.306-07:00</updated><title type='text'>Konqueror feature request</title><content type='html'>In MS Windows, users are only given four or five file view modes, while in Konqueror the user has a multitude of options.  This could be a good thing, but it can be quite inconvenient, because the user has to do too much to get from one desired style of display to another.&lt;br /&gt;&lt;br /&gt;For example, the "Icon View with Large icons and even larger previews" is nice, but if I go to a folder with many files and I quickly scan through the file names, look at all the trouble required to switch to the equivalent of the Windows list view:&lt;br /&gt;- Click View | View Mode | Multicolumn View&lt;br /&gt;- Click View | Icon Size | Tiny&lt;br /&gt;- Click View | Preview | Disable Previews&lt;br /&gt;&lt;br /&gt;It is highly unlikely that the average user wants to use many combinations of these options.  Even a power user would probably use only three to five combinations regularly.&lt;br /&gt;&lt;br /&gt;Therefore, I propose to create a set of presets to replace this multitude of options.  The view menus "View Mode", "Icon Size" and "Preview" would be replaced by a single "View Mode" menu which would contain a customizable list of presets like this:&lt;br /&gt;&lt;br /&gt;==========&lt;br /&gt;Large icons (= Icon View, large, with previews)&lt;br /&gt;Small icons (= Icon View, medium)&lt;br /&gt;Multicolumn list (= MultiColumn view, tiny, no previews)&lt;br /&gt;Tree (= Tree view, tiny)&lt;br /&gt;Et cetera&lt;br /&gt;Other...&lt;br /&gt;----------&lt;br /&gt;Customize views...&lt;br /&gt;==========&lt;br /&gt;&lt;br /&gt;The "Customize views" item would display a dialog box that allows the user to customize the views.  This dialog box would allow the user to select one of the existing views and modify settings for it.  Views could also be created or deleted.  For each view modes, the following options would be available:&lt;br /&gt;&lt;br /&gt;- List of view modes (icons, multicolumn, etc.)&lt;br /&gt;- Any options that are specific to the view mode&lt;br /&gt;- List of icon sizes&lt;br /&gt;- Checkbox: "Show previews"&lt;br /&gt;- Checkbox: "Increase size of previews relative to icons"&lt;br /&gt;  - OR: a list of sizes for previews&lt;br /&gt;- Checkbox: "Change sort order when entering this mode", and a list of sort orders&lt;br /&gt;- Checkbox: "Use a custom background in this mode", and a button to bring up the "Background settings" box.&lt;br /&gt;&lt;br /&gt;All this could fit on one dialog box if the lists of options are combo boxes.&lt;br /&gt;&lt;br /&gt;The "Other..." menu item would bring up a smaller dialog box to change the current view settings, but without saving the changes as a new preset.&lt;br /&gt;&lt;br /&gt;More ideas:&lt;br /&gt;- Views could be hidden from the menu by having a checkbox beside each item in the list of views&lt;br /&gt;- Each of the built-in views could be hidden but not deleted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-114124194181291281?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/114124194181291281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=114124194181291281' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/114124194181291281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/114124194181291281'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/03/konqueror-feature-request.html' title='Konqueror feature request'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-114072033243562784</id><published>2006-02-23T11:30:00.000-07:00</published><updated>2006-02-23T11:45:32.446-07:00</updated><title type='text'>P5GD1 CD booting &amp; linux followup</title><content type='html'>I had just decided it was impossible to boot from an internal CD drive that Linux would recognise, but for some reason I decided to try again. &lt;br /&gt;&lt;br /&gt;There are many possible combinations of settings that can be tried with this mobo:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Upper or lower IDE connectors&lt;/li&gt;&lt;li&gt;Master or slave&lt;/li&gt;&lt;li&gt;"Enhanced" or "Compatible" IDE mode&lt;/li&gt;&lt;li&gt;"PATA+SATA", "SATA", and "PATA" modes&lt;/li&gt;&lt;li&gt;ITE IDE controller "enabled" or "disabled", and if enabled, "quick" or "normal" detection mode&lt;/li&gt;&lt;/ul&gt;Assuming the distinction between "quick" and "normal" is irrelevant, that makes 48 ways you can set up a single drive on this motherboard, although 12 of those ways won't work at all (one of the IDE connectors is disabled when ITE is disabled.)&lt;br /&gt;&lt;br /&gt;Well, I found a configuration that would let me install Kubuntu 5.10 on a "regular" IDE hard disk.  I could &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; install Fedora Core 4 under the following configuration; a kernel panic occurs in FC4 during the kernel init process.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IDE hard disk as primary master (attached to upper connector)&lt;/li&gt;&lt;li&gt;CD/DVD drive as primary slave&lt;/li&gt;&lt;li&gt;"Enhanced" mode, subtype "SATA"&lt;/li&gt;&lt;li&gt;ITE can be enabled or disabled.  If enabled, drives attached to the lower connector will work in Windows once a special driver is installed.  However, as far as I can tell, Linux cannot use these "ITE" devices (lower connector) under any circumstances.&lt;/li&gt;&lt;li&gt;Also, a SATA hard drive was attached, although this is probably irrelevant to whether it works or not.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-114072033243562784?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/114072033243562784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=114072033243562784' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/114072033243562784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/114072033243562784'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/02/p5gd1-cd-booting-linux-followup.html' title='P5GD1 CD booting &amp; linux followup'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113947583614973895</id><published>2006-02-09T01:35:00.000-07:00</published><updated>2006-02-09T02:11:17.686-07:00</updated><title type='text'>What is wrong with people who write about functional programming?</title><content type='html'>A couple years ago, after hearing here and there about "functional programming", I decided to learn about it and got a book from the library.  I found a book on OCaml and began to read.  An hour or two I gave up, finding the book both dry and hard to understand.&lt;br /&gt;&lt;br /&gt;Later I attended a course on "programming paradigms" where I learned basic Haskell.  After studying Haskell for a little while, I came across the paper "&lt;a href="http://www.math.chalmers.se/%7Erjmh/Papers/whyfp.pdf"&gt;Why Functional Programming Matters&lt;/a&gt;" (WFPM).  Its objective was to convince the reader that functional programming is good, and it started off well enough, but utterly failed as soon as it started talking about how to write functional code.  I found myself baffled when it introduced the line "sum = reduce add 0" on the fifth page.  I examined the paper carefully for several minutes to figure out what it meant, and continued reading.  Unfortunately, every new line of code was a new puzzle, and I soon gave up on it.&lt;br /&gt;&lt;br /&gt;Now that I know Haskell and lambda calculus a little better, I have tried to learn about Haskell's type system by reading "&lt;a href="http://www.haskell.org/tutorial/index.html"&gt;A Gentle Introduction to Haskell&lt;/a&gt;" (GIH).  It quickly struck me that this "introduction" wasn't "Gentle" at all!  I can't see how anyone could understand it without already having a knowledge of lambda calculus and at least one functional programming language--preferably Haskell.&lt;br /&gt;&lt;br /&gt;What strikes me about all these explanatory materials is that they are unaware of their own obtuseness.  WFPM uses phrases like "It is now obvious that" and "can be derived &lt;span style="font-style: italic;"&gt;just&lt;/span&gt; by parameterising the definition" (my emphasis). GIH's very name suggests easiness, and its introduction says it is "for someone who has experience with at least one other language, preferably a functional language".  But excluding Haskell, I know at least 5 programming languages, none of which could prepare me for GIH at all.&lt;br /&gt;&lt;br /&gt;So to be blunt, I wonder if there is something wrong with the brains of the people who write this stuff. How can they fail to see that their writing cannot be understood without a solid prior understanding of the subject matter, and that it suffers from excessive brevity?  Functional programming does matter, and I do believe a gentle introduction to Haskell is possible, but I don't know if there are any writers out there who have explained these things properly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113947583614973895?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113947583614973895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113947583614973895' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113947583614973895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113947583614973895'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/02/what-is-wrong-with-people-who-write.html' title='What is wrong with people who write about functional programming?'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113867895282257207</id><published>2006-01-30T20:27:00.000-07:00</published><updated>2006-01-30T20:45:09.476-07:00</updated><title type='text'>Beware the Asus P5GD1-VM motherboard!</title><content type='html'>In a nutshell, I replaced this mofo of a mobo because of one simple problem: it could not boot from an IDE CD-ROM drive, so I could not fix my computer.  I thought there was something defective with my motherboard, so I replaced with with exactly the same one--and the new one had exactly the same problem.&lt;br /&gt;&lt;br /&gt;However, there is exactly one scenario in which I was able to boot a CD.  I was able to boot my Windows 2000 CD correctly under the following conditions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The CD-ROM drive must be on the primary IDE channel (it worked as Slave for me).&lt;/li&gt;&lt;li&gt;In the BIOS, the "IDE mode" option must be set to "Compatible" (not "Enhanced", which is the default).  You can tell when you are in "Compatible" mode because the BIOS screen shows only "Primary" and "Secondary", with no 3rd IDE pair.&lt;/li&gt;&lt;/ul&gt;Now, there is one tricky thing you have to deal with.  "Compatible" mode changes the definition of "Primary".  There are two IDE connectors on the motherboard.  In Compatible mode, "Primary" means the &lt;span style="font-style: italic;"&gt;upper&lt;/span&gt; IDE connector.  However, in Enhanced mode, "Primary" is the &lt;span style="font-style: italic;"&gt;lower&lt;/span&gt; IDE connector.  Therefore, when you switch modes, you must physically swap the upper and lower connectors!&lt;br /&gt;&lt;br /&gt;There are a couple more caveats.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I could not boot any Linux CD correctly under any circumstances.  I tried Damn Small Linux, Knoppix and the Kubuntu Live CD (I used the current version of each CD as of Jan. 20, 2006). Even if the boot process starts, the Linux CD will be unable to mount the CD filesystem, or it will crash or freeze during startup.  You can boot Kubuntu from an external USB 2.0 drive, but not DSL or Knoppix.  I also tried a RIP Linux floppy disk, and it was unable to see the CD drive.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The Windows 2000 CD will not see the hard drive unless it is on the Primary IDE channel.  So put your HDD on Primary Master and your CD on Primary Slave. Kubuntu could not see the hard drive either when I tried it, but I don't remember what configuration I was using at the time.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113867895282257207?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113867895282257207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113867895282257207' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113867895282257207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113867895282257207'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/01/beware-asus-p5gd1-vm-motherboard.html' title='Beware the Asus P5GD1-VM motherboard!'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113798868090456832</id><published>2006-01-22T20:47:00.000-07:00</published><updated>2006-01-22T21:07:27.876-07:00</updated><title type='text'>What is the basis of a "free market" when copies are free?</title><content type='html'>A basic and fundamental economic note about my "free everything" idea:&lt;br /&gt;&lt;br /&gt;I believe in a free market for creative works, but one that works differently from traditional free markets.  A normal free market balances supply and demand of "units", where producers make one unit for every unit used by consumers. But in the world I want to see, this concept of supply is irrelevant.  There is no reason to limit supply when the incremental cost of additional units is virtually zero, as is the case on the internet.  Supply in the traditional sense, therefore, should be virtually infinite; as a result, this free market I envision is better served by a different notion of supply, which is, approximately, the supply of &lt;span style="font-style: italic;"&gt;distinct&lt;/span&gt; works (unique works, not copies).  The balance in the intellectual free market should be between the supply of distinct works and the demand for distinct works.&lt;br /&gt;&lt;br /&gt;Today, of course, the market is based on balancing supply and demand of copies only, which in my view is just plain wrong.  If copies were free, it would utterly change the face of both content industries and technologies.  The changes to technology have already begun in a limited fashion (e.g. the 60 GB IPod), but it remains to be seen whether the content industries will be willing to allow this new world, or whether they will enact ever-stronger laws to ensure we will be stuck in the 20th century forever.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113798868090456832?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113798868090456832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113798868090456832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113798868090456832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113798868090456832'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/01/what-is-basis-of-free-market-when.html' title='What is the basis of a &quot;free market&quot; when copies are free?'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112801889293428747</id><published>2006-01-11T12:25:00.000-07:00</published><updated>2006-01-11T11:24:32.823-07:00</updated><title type='text'>IAL list</title><content type='html'>Marginally interesting languages from LangMaker.com&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://home.tiscali.cz:8080/arlipo/"&gt;Arlipo&lt;/a&gt; (site is in Arlipo)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.vido.net/atlango/"&gt;Atlango&lt;/a&gt; (not much English)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.geocities.com/Athens/Acropolis/9801/lenguas/babm.html"&gt;Babm&lt;/a&gt; (not much documentation)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.geocities.com/thaopbk/"&gt;Bahasa Tumilenia&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ogden.basic-english.org/basiceng.html"&gt;Basic English&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.blitzenglish.com/"&gt;Blitz English&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ca.geocities.com/vixcafe/bonjang/"&gt;Bonjang&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.archive.org/web/20021019044548/www.invisiblelighthouse.com/langlab/bibliography.html"&gt;Bibliography of planned languages&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://home.unilang.org/main/wiki2/index.php/Cani%CF%82"&gt;Canis&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://groups.yahoo.com/group/celltiecc/"&gt;Celltiecc&lt;/a&gt; (celtic aux language)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.geocities.com/ceqli/Uploadexp.htm"&gt;ceqli (CHENG-lee)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.choton.org/"&gt;Choton and others&lt;/a&gt; by Pascal A Kramm&lt;/li&gt;&lt;li&gt;&lt;a href="http://home.comcast.net/%7Emodean52/common.htm"&gt;Common Germanic&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://thomasleigh.tripod.com/qosmiani/qosmiani.html"&gt;Qôsmianî&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Cyberyak: (&lt;a href="http://www.ebtx.com/lang/cyberyak.htm"&gt;#1&lt;/a&gt;) (&lt;a href="http://www.ebtx.com/lang/eminfrm.htm"&gt;#2&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.langmaker.com/outpost/dunia.htm"&gt;Dunia&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.geocities.com/Athens/Delphi/2464/"&gt;Dutton&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://slovensky.homestead.com/files/e2.zip"&gt;e2&lt;/a&gt; (zip file - a "tweak" of esperanto)&lt;/li&gt;&lt;li&gt;&lt;a href="http://earthlanguage.org/english/ehome.htm"&gt;Earth Language&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.edanet.de.vu/"&gt;EDA&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Ekspreso: (&lt;a href="http://www.fact-index.com/e/ek/ekspreso.html"&gt;#1&lt;/a&gt;) (&lt;a href="http://www.cafepress.com/ekspreso"&gt;#2&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.archive.org/web/20021031202752/www.invisiblelighthouse.com/langlab/dlt.txt"&gt;Esperanto de DLT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.langmaker.com/outpost/eswldeng.htm"&gt;Essential World English&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.archive.org/web/20011217075255/http://www.vision25.demon.co.uk/eurolang.htm"&gt;Eurolang&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://groups.yahoo.com/group/europeano/"&gt;Europeano&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.fasile.org/"&gt;Fasile&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.langmaker.com/folksprk.htm"&gt;Folkspraak&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.langmaker.com/bartlett.htm#Frater"&gt;Frater&lt;/a&gt; &amp;amp; &lt;a href="http://www.panix.com/%7Ebartlett/frater2.html"&gt;Frater 2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gilo.org/"&gt;Gilo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://victorian.fortunecity.com/vangogh/555/Spell/globish.html"&gt;Globish&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.glosa.org/"&gt;Glosa&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ido.li/"&gt;Ido&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.inrilan.tk/"&gt;Inrilan&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xente.mundo-r.com/utl/npro/intal.htm"&gt;Baza&lt;/a&gt; (a 'unification of esperanto derivatives')&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.archive.org/web/20021019031750/www.invisiblelighthouse.com/langlab/interglossa.html"&gt;Interglosa&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.interlingua.com/"&gt;Interlingua&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://occidental.narod.ru/"&gt;Interlingue&lt;/a&gt; (Occidental)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.langmaker.com/kalisise.htm"&gt;Kali-sise&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.eufo-institut.de/"&gt;KOD&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ca.geocities.com/handydad/konya/konya-main.html"&gt;Konya&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112801889293428747?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112801889293428747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112801889293428747' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112801889293428747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112801889293428747'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/01/ial-list.html' title='IAL list'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113683350104334800</id><published>2006-01-09T11:59:00.000-07:00</published><updated>2006-01-09T12:05:01.056-07:00</updated><title type='text'>Counterpart conjunction?</title><content type='html'>A conjunction 'X' to indicate a relationship between nouns, dependant on the context?&lt;br /&gt;&lt;br /&gt;He traded his shirt X shoes.  (X=for)&lt;br /&gt;The difference between men X women.  or: men X women differ (X=and)&lt;br /&gt;Balls and chains X prison bars serve the same purpose.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113683350104334800?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113683350104334800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113683350104334800' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113683350104334800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113683350104334800'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2006/01/counterpart-conjunction.html' title='Counterpart conjunction?'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113416050689366416</id><published>2005-12-09T13:28:00.000-07:00</published><updated>2005-12-09T20:56:46.906-07:00</updated><title type='text'>Ruby's Grand Variety</title><content type='html'>I'm starting to learn &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt; and it does seem as though it may fulfill its promise of "making programming fun again", but Ruby has a very unusual design philosophy.  A lot of languages take the stance that on a syntactic level, and in the standard library, there should be One Way to do everything--one syntax, one idiom, one function.&lt;br /&gt;&lt;br /&gt;Ruby says "to hell with that!"  There are often several ways to do something, which should make programming comfortable to a variety of programmers, but I suspect it may be difficult to understand other people's code, if they use some of the more obscure features.  Here are some of the duplicated language features you'll find in Ruby:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Two syntaxes for closure blocks, "{ &lt;span style="font-style: italic;"&gt;...code&lt;/span&gt;... }" and "do &lt;span style="font-style: italic;"&gt;...code&lt;/span&gt;... end"&lt;/li&gt;&lt;li&gt;Control structures before or after inner code, like in Perl: "x += 7 while (x % 13 != 0)" or "while (x % 13 != 0); x += 7; end"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You can choose betwen "and"/"&amp;&amp;amp;", and "or"/"||".  What's peculiar about these are their precedence rules: &amp;&amp;amp; has higher precedence than ||, and "and"/"or" have higher precedence than both of them. However, "and" and "or" have equal precedence.  Similarly there are "!" and "not" operators.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The regular expression support in the language mimics Perl, offering such opaque variable names as $&amp;, $', $` and $1.  These variables are aliases for an object-oriented regular expression information bundle in a MatchData object called (you guessed it!) "$~".&lt;/li&gt;&lt;li&gt;Several syntaxes for strings, the most common being single-quoted and double-quoted, which have different syntax rules (but multiple string types is actually useful and common in new languages, although I'm a little disappointed that Ruby has no equivalent of C#'s @"literal\string")&lt;/li&gt;&lt;li&gt;There seem to be two exception-handling mechanisms, "raise...rescue" and "throw...catch".  The relationship between them is not clear to me.&lt;/li&gt;&lt;/ul&gt;A more distressing aspect of Ruby's design is that it usually does not attempt to "save the programmer from himself": there are many mistakes you can make for which the interpreter will give no warning or error.  Here are some examples.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;'Tuple assignments' don't have to be balanced.  "a,b,c = 2,3,4" sets a=2, b=3, and c=4.  But you can also write "a,b,c = 2,3" or "a,b = 2,3,4" or "a = 0,1,2".  Can you guess the results?&lt;/li&gt;&lt;li&gt;Similary, the number of arguments to a closure doesn't have to match the number of arguments the closure accepts.&lt;/li&gt;&lt;li&gt;Problems caused by scoping rules.  For one thing, assignable methods are normally invisible to members of the same class, so that you have to write "self.property = 10" instead of "property = 10"; the latter unexpectedly creates a local variable called "property".  For another thing (which Ruby's creator called "the single biggest design flaw in Ruby), the scoping rules for blocks are weird.&lt;/li&gt;&lt;li&gt;Because Ruby is dynamically typed and interpreted, most errors occur only at run-time and are not detected if the bad code is not executed, even when it would be theoretically possible.  This, of course, is a vice of all dynamic interpreted languages.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Finally, Ruby has a number of features that can make it incomprehensible to programmers of other languages--rules that you won't find in many other languages.  Here are some examples:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Return values are implicit.  The value of the last statement in a method is the return value of the method.  "if" statements and loops can also return values this way.&lt;/li&gt;&lt;li&gt;Hidden variables and state: I haven't quite figured out how this works yet, but the special variable $_ can be implicitly used for comparisons in control constructs (if, while, etc.), and range variables (and even range literals such as 1..10) seem to have an internal boolean state that can also be used implicitly.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Enforced naming conventions (whether an identifier starts with an uppercase letter affects its meaning; also, use @ to name member variables, @@ to name static (class) member variables, and $ to name globals)&lt;/li&gt;&lt;li&gt;In addition to the aforementioned regex variables, there are many other "&lt;a href="http://www.outerbody.com/ruby/ruby-man-1.4/variable.html"&gt;punctuation variables&lt;/a&gt;" such as $@ and $/.  The "$" indicates that they are global, but in fact, some of them are locally scoped variables.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"Parallel assignment" has a lot of rules and features.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Two operators ".." and "..." with slightly different meanings.&lt;/li&gt;&lt;li&gt;There are numerous string and pseudo-string types that begin with "%".  For example, %x{blah} is equivalent to `blah`, and %Q!hi! is equivalent to "hi".&lt;/li&gt;&lt;li&gt;There are three different equality operators, ==, eql? and equal?, plus some "sort-of-equals" operators: === and =~.&lt;/li&gt;&lt;li&gt;Plenty of other stuff.  Things are just done differently in Ruby.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;By all of this, I don't mean to suggest that Ruby is "bad" (in fact, I think most of this stuff is mostly good), but I do think that if you're an experienced programmer, you should study Ruby explicitly before attempting to understand or write Ruby code, because your knowledge of other langauges might not be enough.  Luckily, the book &lt;a href="http://www.rubycentral.com/book/index.html"&gt;Programming Ruby&lt;/a&gt; is designed for you.&lt;br /&gt;&lt;br /&gt;Incidentally, while you can write clear and readable code in Ruby, you can also obfuscate it nearly to the extent of C code.  There should be a Ruby obfuscation contest...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113416050689366416?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113416050689366416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113416050689366416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113416050689366416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113416050689366416'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/12/rubys-grand-variety.html' title='Ruby&apos;s Grand Variety'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113182960725325457</id><published>2005-11-12T13:26:00.000-07:00</published><updated>2005-11-12T14:54:01.713-07:00</updated><title type='text'>An Epiphany?</title><content type='html'>I just realized today, after seeing the linked document, that there is no reason everyone shouldn't have free access to all intellectual property: software, movies, music, books, educational materials, and to a lesser extent, drugs (which, measured by price, overwhelmingly consist of IP).&lt;br /&gt;&lt;br /&gt;I should be able to view as many movies, TV shows, and books as I want; listen to as many songs; and install as much software as I want.  It shouldn't matter what my income is.  I shouldn't have to pay for anything but the hardware (and perhaps any unavoidable overhead costs of the "free access system").&lt;br /&gt;&lt;br /&gt;I should do a main blog entry on this.&lt;br /&gt;&lt;br /&gt;IP exists as "property" for one reason only: to get money into the hands of owners.  But it works by artificially limiting the amount of material to which people have access, and by limiting the means of access and the means of searching through available material.  Today's technology allows virtually anything to be transported to anyone at near zero cost, yet we are still using an "intellectual property scheme" that has remained largely unchanged (except for scope and time extensions) for centuries.&lt;br /&gt;&lt;br /&gt;The new reality is that with different systems in place, everyone with a certain level of technology could have free access to &lt;span style="font-weight: bold;"&gt;all&lt;/span&gt; software and &lt;span style="font-weight: bold;"&gt;all&lt;/span&gt; media, and the authors of the programs and songs and books and shows could &lt;span style="font-weight: bold;"&gt;still&lt;/span&gt; be paid for their work.  This is a truly new reality.  It wasn't true in 1993, when internet access was rare, and when computers weren't capable of processing high-definition video, and infastructure wasn't capable of delivering unlimited content at low prices.  But it's true now, or will be very soon (provided that the MPAA and RIAA don't get their way).&lt;br /&gt;&lt;br /&gt;Furthermore, as detailed in the article, software development and medical research today involves immense duplication of effort by different organizations who cannot pool their efforts or knowledge because the IP system keeps them apart as competitors.  Open Source Software (OSS) shows that these problems are unnecessary, but because it is difficult to make money from Open Source under the current IP regime, Open Source recieves relatively little funding compared to proprietary software.&lt;br /&gt;&lt;br /&gt;The basic purpose of IP is (or should be) to encourage creation of works that are valuable to the people, and the basic means of doing so is to pay authors for their works.  The basic problem with the IP system, however, is that authors are not paid for &lt;span style="font-weight: bold;"&gt;making works&lt;/span&gt;; but rather, income is generated from &lt;span style="font-weight: bold;"&gt;selling copies&lt;/span&gt; (or by other means which, in any case, involve money changing hands between IP providers and IP users.)&lt;br /&gt;&lt;br /&gt;This restricts everyones' access to information.  The poorer you are, the more you are affected, but it does hurt everyone to some extent.  Searching, for instance--which almost everyone uses--is impeded by the current system (consider the lawsuit against Google Print.)&lt;br /&gt;&lt;br /&gt;There are other (better) ways to ensure money gets to authors and to ensure that works are created in an efficient manner, but not much thought is put into them.  The linked document proposes a government entity to fund public-domain works.  This is an obvious solution, in hindsight at least, and perhaps the only workable one, but there are obvious concerns to be had about how money is distributed.  Whenever the government starts paying people for work, a great risk appears that the money will be used inefficiently.&lt;br /&gt;&lt;br /&gt;Of key importance is preserving the benefits of capitalism in the new regime.  The key benefit of capitalism is that it tends to create "efficient markets", as they are called--markets where resources are used efficiently.  I believe the reason capitalism achieves this is that it leverages the knowledge and intelligence of all participants in the economy to determine what is produced, and how much.  If this can be reproduced in another system, even in a government-overseen system, then that system should function well.&lt;br /&gt;&lt;br /&gt;By the way, the system proposed by the author doesn't impress me that much, since it seems arbitrarily constructed without much justification for its funding structure.  Something this important needs thorough economic analysis, and the author doesn't leave me with a good impression of economic expertise. I myself haven't figured out how an IPR-alternative system should work, though.&lt;br /&gt;&lt;br /&gt;I should develop my thoughts further.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113182960725325457?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.cepr.net/publications/windows_2005_10.pdf' title='An Epiphany?'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113182960725325457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113182960725325457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113182960725325457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113182960725325457'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/11/epiphany.html' title='An Epiphany?'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113181583588813720</id><published>2005-11-12T10:14:00.000-07:00</published><updated>2005-11-12T10:17:15.896-07:00</updated><title type='text'>Modding And The Law (link)</title><content type='html'>This guy thinks like me.  He can't talk about "modding" without complaining about any and every distasteful IP law.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113181583588813720?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.oreillynet.com/pub/a/network/2005/10/28/modding-and-the-clash-with-law.html' title='Modding And The Law (link)'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113181583588813720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113181583588813720' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113181583588813720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113181583588813720'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/11/modding-and-law-link.html' title='Modding And The Law (link)'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-113179021499626033</id><published>2005-11-12T03:05:00.000-07:00</published><updated>2005-11-12T03:14:55.066-07:00</updated><title type='text'>$100 Laptop</title><content type='html'>My suggestions for this project.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Give own staff education about life in the third world&lt;/li&gt;&lt;li&gt;Ensure that "market forces" affect software (even hardware?) available for the machine&lt;/li&gt;&lt;li&gt;Invest large amounts in educational software&lt;/li&gt;&lt;li&gt;Provide ways for local people to create educational software and e-books&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Address language barriers.  Need efficient and effective localization infastructure; should promote an international language&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create "hi-res" (640x480, 800x600) version of the laptop&lt;/li&gt;&lt;li&gt;Develop theories about how the laptop could be used to improve economies and quality of life beyond simply having laptops.  Use the "teach a man to fish" principle - but need short term benefits also.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Provide better development tools than LOGO for students&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Develop a mono version of the .NET Compact Framework for the machine?&lt;/li&gt;&lt;/ul&gt;Note to self:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Get involved in the project somehow?  I could...&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Contact others who look smart and bring them in?&lt;/li&gt;&lt;li&gt;Help promote the project at companies &amp;amp; educational institutions, and solicit investment?&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-113179021499626033?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.worldchanging.com/archives/003707.html' title='$100 Laptop'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/113179021499626033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=113179021499626033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113179021499626033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/113179021499626033'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/11/100-laptop.html' title='$100 Laptop'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112984196411183442</id><published>2005-10-20T14:58:00.000-06:00</published><updated>2005-10-20T15:03:03.393-06:00</updated><title type='text'>Prolog - Lecture 1</title><content type='html'>Prolog:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Two types of statements:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Rules&lt;/li&gt;&lt;li&gt;Propositions&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;File extension: .pl (just like Perl)&lt;/li&gt;&lt;li&gt;Periods end statements.&lt;/li&gt;&lt;li&gt;Avoid using spaces in code with the "gprolog" interpreter/compiler (GNU Prolog 1.2.16).&lt;/li&gt;&lt;li&gt;This compiler is very user-unfriendly.&lt;/li&gt;&lt;li&gt;Capital letters are "variables".&lt;/li&gt;&lt;li&gt;At the interpreter prompt, type "[X]." to load and compile a file named X.pl.  Do not type "[X.pl].".&lt;/li&gt;&lt;li&gt;Type "trace." to enable trace mode, which will display the steps done by the interpreter.&lt;/li&gt;&lt;li&gt;Type "notrace." to turn off trace mode.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;With this file:&lt;br /&gt;&lt;pre&gt;likes(jake,chocolate).&lt;br /&gt;likes(jake,apricots).&lt;br /&gt;likes(darcie,licorice).&lt;br /&gt;likes(darcie,apricots).&lt;br /&gt;&lt;br /&gt;Output of "likes(X,chocolate).":&lt;br /&gt; X = jake ? ; (it waits for command here:&lt;br /&gt;   ; to show next solution, a for all solutions, &lt;return&gt; to stop)&lt;br /&gt; no&lt;br /&gt;&lt;br /&gt;comma (",") is an "and" operator.&lt;br /&gt;Output of "likes(darcie,X),likes(jake,X).":&lt;br /&gt; X = apricots&lt;br /&gt; yes&lt;br /&gt;&lt;br /&gt;----&lt;br /&gt;grandmother(X,Y):-mother(X,Z),mother(Z,Y).&lt;br /&gt;grandmother(X,Y):-mother(X,Z),father(Z,Y).&lt;br /&gt;mother(anna,peter).&lt;br /&gt;mother(anna,clara).&lt;br /&gt;mother(mary,anna).&lt;br /&gt;father(joe,peter).&lt;br /&gt;father(jim,clara).&lt;br /&gt;father(tom,joe).&lt;br /&gt;&lt;br /&gt;The "grandmother" statements are a propositions. ":-" means "implies".&lt;br /&gt;&lt;br /&gt;grandmother(X,peter).&lt;br /&gt; X = mary ? ;&lt;br /&gt; no&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112984196411183442?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112984196411183442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112984196411183442' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112984196411183442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112984196411183442'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/prolog-lecture-1.html' title='Prolog - Lecture 1'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112975022370997637</id><published>2005-10-19T13:29:00.000-06:00</published><updated>2005-10-19T13:30:23.716-06:00</updated><title type='text'>Algebraic proof that 2=1</title><content type='html'>x=y&lt;br /&gt;x^2=xy&lt;br /&gt;x^2-y^2=xy-y^2&lt;br /&gt;(x+y)(x-y)=y(x-y)&lt;br /&gt;x+y=y&lt;br /&gt;2y=y&lt;br /&gt;2=1&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112975022370997637?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112975022370997637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112975022370997637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112975022370997637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112975022370997637'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/algebraic-proof-that-21.html' title='Algebraic proof that 2=1'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112942105345494235</id><published>2005-10-15T18:03:00.000-06:00</published><updated>2005-10-15T18:21:34.283-06:00</updated><title type='text'>Lost in translation</title><content type='html'>The software is not equipped for 10 consecutive translations of the same piece of text.&lt;br /&gt;-&gt; Which the software of the interior of 10 witnesses turned the similar partial continuation is not equipped.&lt;br /&gt;&lt;br /&gt;I want a new car for Christmas&lt;br /&gt;-&gt; I demand loaded a new automobile for them&lt;br /&gt;&lt;br /&gt;Time flows like a river. History repeats. Mind your own business. &lt;br /&gt;-&gt; The operations of the time have taste of a river. Retorts of history its material hardly of the guata of the transactions. &lt;br /&gt;&lt;br /&gt;The early bird gets the worm. Time flies when you're having fun. The blind are leading the blind.&lt;br /&gt;-&gt; The bird receives the continuous screw soon. The time flies, if you he have the safeguard. The screen of the light bulb executes the screen of the light bulb.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112942105345494235?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.tashian.com/multibabel/' title='Lost in translation'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112942105345494235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112942105345494235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112942105345494235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112942105345494235'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/lost-in-translation.html' title='Lost in translation'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112923812568317787</id><published>2005-10-13T15:14:00.000-06:00</published><updated>2005-10-13T15:15:25.686-06:00</updated><title type='text'>Haskell - lecture 7</title><content type='html'>&lt;pre&gt;-- isLower, isUpper etc. are not recognized in WinHugs if the prompt says "Main&gt;" (but it is recognized on startup when the prompt is "Prelude&gt;")&lt;br /&gt;kindOfChar :: Char -&gt; String&lt;br /&gt;kindOfChar c =&lt;br /&gt; if (isLower c)&lt;br /&gt; then "lower"&lt;br /&gt; else if isUpper c&lt;br /&gt;   then "upper"&lt;br /&gt;   else if isDigit c&lt;br /&gt;     then "digit"&lt;br /&gt;     else "other"&lt;br /&gt;-- Same function implemented with guards:&lt;br /&gt;kindOfChar2 :: Char -&gt; String&lt;br /&gt;kindOfChar2 c    -- Notice that there is no "=" before the guards&lt;br /&gt; | isLower c = "lower"&lt;br /&gt; | isUpper c = "upper"&lt;br /&gt; | isDigit c = "digit"&lt;br /&gt; | otherwise = "other"&lt;br /&gt;&lt;br /&gt;-- Acts like the prelude (built-in) function 'take'&lt;br /&gt;myTake :: Int -&gt; [a] -&gt; [a]&lt;br /&gt;myTake 0 list = []&lt;br /&gt;myTake m [] = []&lt;br /&gt;myTake m x:xs =&lt;br /&gt; x : (myTake (m-1) xs)&lt;br /&gt;-- Implementation using "case" expression&lt;br /&gt;-- Internally, this is how Haskell resolves multiple function declarations?&lt;br /&gt;myTake2 :: Int -&gt; [a] -&gt; [a]&lt;br /&gt;myTake2 n list = case (n,list) of&lt;br /&gt; (0, list) -&gt; []&lt;br /&gt; (n, []) -&gt; []&lt;br /&gt; (n, x:xs) -&gt; c : myTake2 (n-1)&lt;br /&gt;&lt;br /&gt;-- In Haskell&lt;br /&gt; -- Everything exists at the top level (mutually recursive (?))&lt;br /&gt; -- Basic libraries automatically exist in prelude&lt;br /&gt; -- Type synonym&lt;br /&gt; -- Type classes (Ord, Num, Fractional, ...)&lt;br /&gt; -- Read and Show&lt;br /&gt; -- Pattern findings&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112923812568317787?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112923812568317787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112923812568317787' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112923812568317787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112923812568317787'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/haskell-lecture-7.html' title='Haskell - lecture 7'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112923732601538163</id><published>2005-10-13T15:00:00.000-06:00</published><updated>2005-10-13T15:02:06.036-06:00</updated><title type='text'>Haskell - lecture 6</title><content type='html'>&lt;pre&gt;-- I can't figure out what's going on here.&lt;br /&gt;test1 = (\y -&gt; (-) y 1)&lt;br /&gt;-- test2 = (\y -&gt; (-) y (\x -&gt; x))     -- won't compile&lt;br /&gt;test2 z = (\y -&gt; (-) y (\x -&gt; x)) z&lt;br /&gt;test3 z = \y -&gt; (-) y (\x -&gt; x) z&lt;br /&gt;test2b a b  = (\y -&gt; (-) y (\x -&gt; x)) a b&lt;br /&gt;test3b a b = \y -&gt; (-) y (\x -&gt; x) a b&lt;br /&gt;&lt;br /&gt;-- Prof implied that Haskell has no random-access arrays;&lt;br /&gt;-- e.g. efficient hashtables cannot be created.&lt;br /&gt;&lt;br /&gt;-- Data types in Haskell&lt;br /&gt;-- Lists&lt;br /&gt;--   [l] ++ [3,4], a : b&lt;br /&gt;-- Tuple&lt;br /&gt;--   (0, "abc", 'd', 5.0)&lt;br /&gt;-- Enumerated:&lt;br /&gt;--   data Weekday = Sun | Mon | Tue | Wed | Thu | Fri | Sat&lt;br /&gt;-- Recursively defined types&lt;br /&gt;--   data Tree a = Leaf a | Node (Tree a) (Tree a)&lt;br /&gt;-- Lambda abstractions&lt;br /&gt;-- List comprehensions&lt;br /&gt;&lt;br /&gt;-- Declaration order doesn't usually matter, but module imports&lt;br /&gt;-- must come first?  Also, function signatures' patterns are&lt;br /&gt;-- checked/matched in the order they appear, every time a&lt;br /&gt;-- function is called.  For example, out of the four functions below,&lt;br /&gt;-- the first one is always regardless of the arguments.  Even so,&lt;br /&gt;-- note that the arguments must be lists, because in Haskell, all&lt;br /&gt;-- functions with the same name share the same data type&lt;br /&gt;-- signature.  Try changing the order to see what happens.&lt;br /&gt;orderTest a b = "a b"&lt;br /&gt;orderTest a [] = "a []"&lt;br /&gt;orderTest [] [] = "[] []"&lt;br /&gt;orderTest (x:xs) (y:ys) = "(x:xs) (y:ys)"&lt;br /&gt;&lt;br /&gt;-- Control Constructs&lt;br /&gt;-- Patterns: pattern matching on function signatures is implicit flow control&lt;br /&gt;-- Guards&lt;br /&gt;-- "Where" - creates temporary local variables; example below&lt;br /&gt;-- List comprehensions&lt;br /&gt;&lt;br /&gt;-- Finds the roots of ax^2 + bx + c&lt;br /&gt;-- Example: roots 1 5 6 -&gt; (-2.0,-3.0)&lt;br /&gt;roots a b c =&lt;br /&gt; if d &lt; 0 then error "imaginary" else (x1, x2)&lt;br /&gt;   where&lt;br /&gt;     x1 = (-b + (sqrt d)) / twoa&lt;br /&gt;     x2 = (-b - (sqrt d)) / twoa&lt;br /&gt;     d = b*b - 4*a*c&lt;br /&gt;     twoa = 2*a&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112923732601538163?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112923732601538163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112923732601538163' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112923732601538163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112923732601538163'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/haskell-lecture-6.html' title='Haskell - lecture 6'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112880623287267690</id><published>2005-10-08T15:15:00.000-06:00</published><updated>2005-10-08T15:17:31.933-06:00</updated><title type='text'>Movie Piracy -- oOoOoOo</title><content type='html'>Maybe I could make a main blog entry on this sort of thing... although to be honest I don't know very much about how the music &amp;amp; film industries screw real artists.  All I know is that a lot of people aren't too happy with how bug business runs things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112880623287267690?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.undergroundfilm.org/films/viewer.tcl?oftype=lar&amp;wid=1017942' title='Movie Piracy -- oOoOoOo'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112880623287267690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112880623287267690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112880623287267690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112880623287267690'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/movie-piracy-ooooooo.html' title='Movie Piracy -- oOoOoOo'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112880566888420666</id><published>2005-10-08T15:07:00.000-06:00</published><updated>2005-10-08T15:07:48.883-06:00</updated><title type='text'>What's a hoe</title><content type='html'>I must have laughed for five minutes.  But what is a rake?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112880566888420666?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.i-am-bored.com/bored_link.cfm?link_id=6899' title='What&apos;s a hoe'/><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112880566888420666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112880566888420666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112880566888420666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112880566888420666'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/whats-hoe.html' title='What&apos;s a hoe'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112862648521923679</id><published>2005-10-06T13:04:00.000-06:00</published><updated>2005-10-06T13:28:17.283-06:00</updated><title type='text'>Simplified XML?</title><content type='html'>&lt;pre&gt;?sxml version=1.0?&lt;br /&gt;root-element&lt;br /&gt;&lt;!-- this is a comment. It can be multiple lines&lt;br /&gt;    and ends with: --&gt;&lt;br /&gt;-- this is a single-line comment.  Single-line comments&lt;br /&gt;an-element attribute1="1.0" attribute2=2.0&lt;br /&gt;child-element attribute3=&amp;lt;=&amp;gt;?!"'&amp;sp;&amp;amp;        |             attribute4="&lt;=&gt;?!"' &amp;amp;"&lt;br /&gt;another-one attribute5="bla" &gt; example text&lt;br /&gt;  &gt; this text is part of the "another one" element&lt;br /&gt;&gt; this text is part of an-element&lt;br /&gt;an-element/ -- closing tag is optional.&lt;br /&gt;          -- if present, the XML reader would use it for error-checking&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112862648521923679?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112862648521923679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112862648521923679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112862648521923679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112862648521923679'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/simplified-xml.html' title='Simplified XML?'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112862459296679091</id><published>2005-10-06T12:29:00.000-06:00</published><updated>2005-10-06T13:59:17.920-06:00</updated><title type='text'>Possible useful &amp; unusual morphemes</title><content type='html'>&lt;ul&gt;&lt;li&gt;"standard", "predefined idea" - e.g. "standard second month" = febuary, "standard first day" = Sunday.  e.g. infix "o" - owundey (sunday), omunth (a month of the year), owik (a week that begins Sunday); not used with 'the'&lt;/li&gt;&lt;li&gt;"generalization" or "scope widening" affix - e.g. je&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"specialization" or "specific" affix - spe&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"unit distance or step away" affix - ste&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"the path toward something" affix - e.g. "homtoo"=the path leading home&lt;br /&gt;&lt;/li&gt;&lt;li&gt;...which is distinct from "a path or manner", "wey"&lt;/li&gt;&lt;li&gt;"direction along a path or axis" affix&lt;/li&gt;&lt;li&gt;"movement along a path or axis" affix - rd&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112862459296679091?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112862459296679091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112862459296679091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112862459296679091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112862459296679091'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/possible-useful-unusual-morphemes.html' title='Possible useful &amp; unusual morphemes'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112846001742457879</id><published>2005-10-04T15:06:00.000-06:00</published><updated>2005-10-04T15:06:57.430-06:00</updated><title type='text'>Haskell - lecture 5</title><content type='html'>&lt;pre&gt;&lt;br /&gt;-- Lambda functions are specified with a backslash.&lt;br /&gt;-- (\x -&gt; x*(x-1)) 4   =   12&lt;br /&gt;-- (\x -&gt; (\y -&gt; ((+) y 1))) 2 3   =   4&lt;br /&gt;-- (\x -&gt; (\y -&gt; ((/) x y))) 10 2   =   5.0&lt;br /&gt;-- (\y -&gt; ((+) y x)) 5   =   ERROR - Undefined variable "x"&lt;br /&gt;-- (\x -&gt; (\z -&gt; ((/) z 2)) x) 3   =   1.5&lt;br /&gt;-- (\x -&gt; (\z -&gt; ((*) x z)) x) 3   =   9&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112846001742457879?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112846001742457879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112846001742457879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112846001742457879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112846001742457879'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/10/haskell-lecture-5.html' title='Haskell - lecture 5'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112802839065408353</id><published>2005-09-29T15:12:00.000-06:00</published><updated>2005-09-29T15:13:10.656-06:00</updated><title type='text'>Haskell - lecture 4</title><content type='html'>&lt;pre&gt;--&lt;br /&gt;-- What's this?&lt;br /&gt;interleave x [] = [[x]]&lt;br /&gt;interleave x (y:ys)&lt;br /&gt; = [x:y:ys] ++ map (y:)(interleave x ys)&lt;br /&gt;&lt;br /&gt;perms [] = [[]]&lt;br /&gt;perms (x:xs)&lt;br /&gt; = [ zs | ys &lt;- perms xs, zs &lt;- interleave x ys ]&lt;br /&gt;&lt;br /&gt;-- Back to prime calculation.  Note: /= means "not equal to"&lt;br /&gt;crossOut :: Int -&gt; [Int] -&gt; [Int]&lt;br /&gt;crossOut m ns = [ n | n &lt;- ns, (n `mod` m) /= 0]   -- Could also use "mod n m"&lt;br /&gt;&lt;br /&gt;-- Excludes non-prime numbers from a list.  Must be [2..] or a list of the form [2..n]&lt;br /&gt;seive :: [Int] -&gt; [Int]&lt;br /&gt;seive [] = []&lt;br /&gt;seive (x:xs)&lt;br /&gt; = x : seive (crossOut x xs)&lt;br /&gt;&lt;br /&gt;-- output of seive [2..50]&lt;br /&gt;-- -&gt; [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47]&lt;br /&gt;&lt;br /&gt;-- Finds a bunch of integers satisfying a^2 + b^2 == c^2&lt;br /&gt;-- What's interesting about this example is that it is slow: n^3&lt;br /&gt;-- 50x50x50 = 125,000 iterations; takes about 20 seconds @ 1.6GHz&lt;br /&gt;-- Other languages would do it faster.&lt;br /&gt;triads = [(a,b,c) | a &lt;- [1..50], b &lt;- [1..50], c &lt;- [1..50], a^2 + b^2 == c^2]&lt;br /&gt;-- type:  [(Integer,Integer,Integer)]&lt;br /&gt;-- output: [(3,4,5),(4,3,5),(5,12,13),(6,8,10),(7,24,25),(8,6,10),(8,15,17),(9,12,15),(9,40,41),(10,24,26),(12,5,13),(12,9,15),(12,16,20),(12,35,37),(14,48,50),(15,8,17),(15,20,25),(15,36,39),(16,12,20),(16,30,34),(18,24,30),(20,15,25),(20,21,29),(21,20,29),(21,28,35),(24,7,25),(24,10,26),(24,18,30),(24,32,40),(27,36,45),(28,21,35),(30,16,34),(30,40,50),(32,24,40),(35,12,37),(36,15,39),(36,27,45),(40,9,41),(40,30,50),(48,14,50)]&lt;br /&gt;&lt;br /&gt;-- The quicksort (using first-element pivot)&lt;br /&gt;-- Here are two implementations.&lt;br /&gt;quicksort :: Ord a =&gt; [a] -&gt; [a]&lt;br /&gt;quicksort [] = []&lt;br /&gt;quicksort (x:xs)&lt;br /&gt;   = quicksort [y | y &lt;- xs, y &lt;&gt;= x]&lt;br /&gt;--  = quicksort (filter (&lt;x)&gt;=x) xs)&lt;br /&gt;-- You can sort numbers but also pairs:&lt;br /&gt;-- quicksort [(1,3),(6,3),(2,4),(2,0),(6,1)] -&gt; [(1,3),(2,0),(2,4),(6,1),(6,3)]&lt;br /&gt;&lt;br /&gt;-- All operators can be expressed in prefix form.&lt;br /&gt;-- (+) 1 2:  3&lt;br /&gt;-- :t (+):  (+) :: Num a =&gt; a -&gt; a -&gt; a&lt;br /&gt;-- :t (^): (^) :: (Num a, Integral b) =&gt; a -&gt; b -&gt; a&lt;br /&gt;-- This is interesting:&lt;br /&gt;-- :t (^2): flip (^) 2 :: (Integral a, Num b) =&gt; b -&gt; b&lt;br /&gt;-- ((flip (^)) 2) 3: 9&lt;br /&gt;&lt;br /&gt;-- This function performs an operation on a collection of elements like so:&lt;br /&gt;--   myfoldr (+) 1 [2,3,4] == 1 + (2 + (3 + 4))&lt;br /&gt;-- Note the right-first evaluation.&lt;br /&gt;myfoldr :: (a -&gt; b -&gt; b) -&gt; b -&gt; [a] -&gt; b&lt;br /&gt;myfoldr fn b []&lt;br /&gt; = b&lt;br /&gt;myfoldr fn b (x:xs)&lt;br /&gt; = fn x (myfoldr fn b xs)&lt;br /&gt;&lt;br /&gt;myfoldr1 :: (a -&gt; a -&gt; a) -&gt; [a] -&gt; a&lt;br /&gt;-- myfoldr1 is meaningless on an empty list: show error message&lt;br /&gt;myfoldr1 fn [] = error "applied to empty list"&lt;br /&gt;myfoldr1 fn [x] = x&lt;br /&gt;myfoldr1 fn (x:y:xs) -- x:y:xs guarantees it matches only lists with at least 2 items&lt;br /&gt; = fn x (myfoldr1 fn (y:xs))&lt;br /&gt;--&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112802839065408353?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112802839065408353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112802839065408353' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112802839065408353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112802839065408353'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/09/haskell-lecture-4.html' title='Haskell - lecture 4'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112785548253703668</id><published>2005-09-27T15:10:00.000-06:00</published><updated>2005-09-27T15:11:22.543-06:00</updated><title type='text'>Haskell - lecture 3</title><content type='html'>&lt;pre&gt;-- Here's the filter again, this time with "guards".  Guards are like&lt;br /&gt;-- case statements in other languages.  The guards are&lt;br /&gt;-- evaluated in order; "otherwise" must come last.&lt;br /&gt;otherFilter :: (a -&gt; Bool) -&gt; [a] -&gt; [a]&lt;br /&gt;otherFilter functionName [] = []&lt;br /&gt;otherFilter functionName (x:xs)&lt;br /&gt; | functionName x = x : otherFilter functionName xs&lt;br /&gt; | otherwise = otherFilter functionName xs&lt;br /&gt;&lt;br /&gt;-- This function is intended for use as a filter. It takes one pair&lt;br /&gt;-- as an argument, and returns true if y == 2*x.&lt;br /&gt;-- example use: myFilter doubleSecond [(1,2),(3,4),(5,10)] -&gt; [(1,2),(5,10)]&lt;br /&gt;doubleSecond :: (Int, Int) -&gt; Bool&lt;br /&gt;doubleSecond (x,y)&lt;br /&gt; = y==2 *x&lt;br /&gt;&lt;br /&gt;-- Here's another kind of "filter" function: a mapper.  It takes a&lt;br /&gt;-- mapping function as an argument, along with a list.  It passes&lt;br /&gt;-- each element of the list to the supplied function, and puts the&lt;br /&gt;-- return values in a new list.  Example use:&lt;br /&gt;-- myMap (^2) [1,2,3,4] -&gt; [1,4,9,16]&lt;br /&gt;myMap :: (a -&gt; b) -&gt; [a] -&gt; [b]&lt;br /&gt;myMap fn []&lt;br /&gt; = []&lt;br /&gt;myMap fn (x:xs)&lt;br /&gt; = fn x : myMap fn xs&lt;br /&gt;&lt;br /&gt;-- The inRange function determines whether a number is&lt;br /&gt;-- in a certain range.&lt;br /&gt;--    The type declaration introduces "Ord".  "Ord a" means&lt;br /&gt;-- "any type 'a' that is ordered", i.e. that supports magnitude&lt;br /&gt;-- operators such as &gt; and &lt;.  Also notice the new arrow, "=&gt;".&lt;br /&gt;-- It looks like the arrow separates the "interface constraint"&lt;br /&gt;-- on the left with the normal data type declaration on the right.&lt;br /&gt;inRange :: Ord a =&gt; a -&gt; a -&gt; a -&gt; Bool&lt;br /&gt;inRange beginning end element&lt;br /&gt; = element &gt;= beginning &amp;&amp;amp; element &lt;= end&lt;br /&gt;&lt;br /&gt;-- inRange can't be used as a filter directly because it takes 3&lt;br /&gt;-- arguments instead of 1:&lt;br /&gt;-- * myFilter inRange 2 4 [1,2,3,4,5,6] -- wrong&lt;br /&gt;-- However, we can bind the first two arguments, to produce&lt;br /&gt;-- a "new" function that takes only one argument:&lt;br /&gt;--   myFilter (inRange 2 4) [1,2,3,4,5,6] -&gt; [1,5,6]&lt;br /&gt;&lt;br /&gt;-- BTW: "zip" takes two lists and makes a list of pairs:&lt;br /&gt;-- zip [1,2,3] ['a','b','c'] -&gt; [(1,'a'),(2,'b'),(3,'c')]&lt;br /&gt;-- zip [1,2,3] "abc"        -&gt; [(1,'a'),(2,'b'),(3,'c')]&lt;br /&gt;-- zip [1,2,3,4,5,6] (map (^3) (filter (inRange 2 4) [1,2,3,4,5,6]))&lt;br /&gt;--   -&gt; [(1,8),(2,27),(3,64)]&lt;br /&gt;&lt;br /&gt;-- "List comprehensions": a way to generate a finite or infinite&lt;br /&gt;-- list from 1 to 3 parameters.  Best explained by example:&lt;br /&gt;--   [1..4] -&gt; [1,2,3,4]&lt;br /&gt;--   [5,4..1] -&gt; [5,4,3,2,1]&lt;br /&gt;&lt;br /&gt;--   [5,3.. -5] -&gt; [5,3,1,-1,-3,-5]&lt;br /&gt;--   [2,3.5..7] -&gt; [2.0,3.5,5.0,6.5]&lt;br /&gt;--   [2,3.5..7.5] -&gt; [2.0,3.5,5.0,6.5,8.0] -- strange, eh?&lt;br /&gt;--   [0,10..29] -&gt; [0,10,20]&lt;br /&gt;--   [-2..] -&gt; [-2,-1,0,1,2,...]&lt;br /&gt;--   [2,4..] -&gt; [2,4,6,8,10,12, ...]&lt;br /&gt;&lt;br /&gt;-- Here's a list-generating loop construct in Haskell.&lt;br /&gt;ex1 = [x *2 +4 | x &lt;- [1,3..10]]&lt;br /&gt;-- ex1 -&gt; [6,10,14,18,22]&lt;br /&gt;ex2 = [(x,y) | x &lt;- [1..4], y &lt;- [1..4]]&lt;br /&gt;-- ex2 -&gt; [(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(2,4),(3,1),(3,2),(3,3),(3,4),(4,1),(4,2),(4,3),(4,4)]&lt;br /&gt;ex3 = [(x, x*2+y) | x &lt;- [1,2,3], y &lt;- [4,5,6]]&lt;br /&gt;-- ex3 -&gt; [(1,6),(1,7),(1,8),(2,8),(2,9),(2,10),(3,10),(3,11),(3,12)]&lt;br /&gt;tri m = [(i,j) | i &lt;- [0..m], j &lt;- [0..i]]&lt;br /&gt;--  tri 3 -&gt; [(0,0),(1,0),(1,1),(2,0),(2,1),(2,2),(3,0),(3,1),(3,2),(3,3)]&lt;br /&gt;--  :t tri&lt;br /&gt;--    tri :: (Num a, Enum a) =&gt; a -&gt; [(a,a)]&lt;br /&gt;&lt;br /&gt;-- Tomorrow: computing prime numbers&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112785548253703668?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112785548253703668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112785548253703668' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112785548253703668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112785548253703668'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/09/haskell-lecture-3.html' title='Haskell - lecture 3'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112776042676377799</id><published>2005-09-26T12:42:00.000-06:00</published><updated>2005-09-26T12:47:06.770-06:00</updated><title type='text'>ACLU's twisted ideas</title><content type='html'>Wow.&lt;br /&gt;&lt;blockquote&gt;&lt;span style=";font-family:Verdana,Arial,Helvetica,sans-serif;font-size:85%;"  &gt;I am writing to let you know about a vitally important ACLU case that will begin in a few days. &lt;br /&gt;&lt;br /&gt;Once again, the ACLU will be defending religious freedom against those who want to force creationism into our public schools. The underlying conflict has been going on at least since the &lt;a href="http://www.answersingenesis.org/docs2005/0711scopes.asp"&gt;Scopes trial&lt;/a&gt;, a famous ACLU case from an earlier era.&lt;br /&gt;&lt;br /&gt;At the core, the conflict is between those who believe science should be taught in science classes and those who want to use our public schools to promote one set of religious beliefs over another.&lt;br /&gt;&lt;br /&gt;But, this time, the creationists have a new ploy. It's called "intelligent design" -- an "alternative" to the scientific theory of evolution that religious extremists have cooked up as a way to sneak religious proselytizing into our public schools.&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style=";font-family:Verdana,Arial,Helvetica,sans-serif;font-size:85%;"  &gt; It is all too clear that powerful political forces are not just tinkering around the edges of our religious freedom -- they have set their sights on transforming our country from a constitutional democracy to a thinly veiled theocracy. They want to turn America into a country governed by their interpretation of the Bible, serviced by faith-based, taxpayer-funded institutions and guided by religious doctrine against which neither citizens nor judges should dare to speak up.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:Verdana,Arial,Helvetica,sans-serif;font-size:85%;"  &gt;      - Anthony D. Romero&lt;br /&gt;     Executive Director, ACLU&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;hmm.&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;"The consent judgment is repeatedly violated by these individuals because they do not believe anything will happen to them," the ACLU said in its Wednesday court filing. "Their refusal to comply with the consent decree should and must result in &lt;b&gt;their removal from society&lt;/b&gt;." &lt;/i&gt;(&lt;a href="http://blogcritics.org/archives/2005/05/20/233301.php"&gt;emphasis added&lt;/a&gt;)&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112776042676377799?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112776042676377799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112776042676377799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112776042676377799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112776042676377799'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/09/aclus-twisted-ideas.html' title='ACLU&apos;s twisted ideas'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112742375775317984</id><published>2005-09-22T14:11:00.000-06:00</published><updated>2005-09-22T15:15:57.756-06:00</updated><title type='text'>CPSC 349: Haskell: 2nd lecture</title><content type='html'>-- To use Haskell on Windows, download WinHugs from here:&lt;br /&gt;  -- &lt;a href="http://cvs.haskell.org/Hugs/pages/downloading-Nov2003.htm"&gt;http://cvs.haskell.org/Hugs/pages/downloading-Nov2003.htm&lt;/a&gt;&lt;br /&gt;-- Commands in the Haskell environment start with a colon:&lt;br /&gt;  -- If this code is in test.hs, use command ":l test.hs" to load&lt;br /&gt;  -- :t gives the type of something&lt;br /&gt;  -- :? gives a list of commands&lt;br /&gt;&lt;br /&gt;-- Computes a factorial&lt;br /&gt;fact :: Integer -&gt; Integer&lt;br /&gt;  -- Int is 32 bits; Integer is unlimited.&lt;br /&gt;fact 0 = 1&lt;br /&gt;fact (n+1) = (n+1) * fact n&lt;br /&gt;&lt;br /&gt;-- Gets the sum of the diagonal of a 3x3 list&lt;br /&gt;-- e.g. diagonal [[1,2,3],[4,5,6],[7,8,9]] = 1+5+9 = 15&lt;br /&gt;diagonal :: [[Int]] -&gt; Int&lt;br /&gt;diagonal [a,b,c]    -- type decl. implies a, b, and c are lists of Int&lt;br /&gt;    = head a + head (tail b) + head (reverse c)&lt;br /&gt;&lt;br /&gt;-- Tuples: complex ordered data type with unnamed elements&lt;br /&gt;-- e.g. (1, 1.0, "1.0", '1', [1])&lt;br /&gt;-- e.g. ("my age in years", 25)&lt;br /&gt;&lt;br /&gt;-- 'points' compute the coordinates of a series of integer points&lt;br /&gt;-- along a line, where each point is 1 unit apart horizontally&lt;br /&gt;  -- points 8 0 2 4&lt;br /&gt;  -- -&gt; [(0,4),(1,6),(2,8),(3,10),(4,12),(5,14),(6,16),(7,18)]&lt;br /&gt;points :: Int -&gt; Int -&gt; Int -&gt; Int -&gt; [(Int, Int)]&lt;br /&gt;points 1 x slope intercept&lt;br /&gt;   = (x, x * slope + intercept) : []&lt;br /&gt;points (n+1) x slope intercept&lt;br /&gt;   = (x, x * slope + intercept) : points n (x+1) slope intercept&lt;br /&gt;&lt;br /&gt;-- "++": Concatenation operator: [1,2] ++ [3,4] -&gt; [1,2,3,4]&lt;br /&gt;-- ":": I don't know what it's called: [1,2] : [3,4] -&gt; [[1,2],[3,4]]&lt;br /&gt;&lt;br /&gt;-- You can produce functions from the built-in operators.&lt;br /&gt;-- Examples:&lt;br /&gt;  -- (2/) is a function that divides 2 by something, so (2/) 4 -&gt; 0.5&lt;br /&gt;  -- (/2) is a function that divides something by 2, so (/2) 4 -&gt; 2.0&lt;br /&gt;  -- (/) is the division function: (/) 21 3 -&gt; 7.0&lt;br /&gt;  -- Another example: ([1,2]++) [3,4] -&gt; [1,2,3,4]&lt;br /&gt;&lt;br /&gt;-- This function uses the output of another function as a "filter".&lt;br /&gt;-- The filter determines whether to keep an element of the list.&lt;br /&gt;myFilter :: (a -&gt; Bool) -&gt; [a] -&gt; [a]&lt;br /&gt;myFilter functionName [] = []&lt;br /&gt;myFilter functionName (x:xs) =&lt;br /&gt;  if functionName x then&lt;br /&gt;    x : myFilter functionName xs  -- Keep 'x' in the output list&lt;br /&gt;  else myFilter functionName xs  -- Discard 'x'&lt;br /&gt;-- Example:&lt;br /&gt;-- myFilter (&gt;4) [1,8,2,7,3,6,4,5] -&gt; [8,7,6,5]&lt;br /&gt;-- myFilter&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112742375775317984?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112742375775317984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112742375775317984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112742375775317984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112742375775317984'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/09/cpsc-349-haskell-2nd-lecture.html' title='CPSC 349: Haskell: 2nd lecture'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16943816.post-112725077430750314</id><published>2005-09-20T14:59:00.000-06:00</published><updated>2005-09-20T15:14:18.140-06:00</updated><title type='text'>Haskell sample</title><content type='html'>&lt;a href="http://haskell.org/aboutHaskell.html"&gt;About haskell&lt;/a&gt;  &lt;a href="http://haskell.org/"&gt;haskell.org&lt;/a&gt;&lt;br /&gt;-----------------&lt;br /&gt;len :: [a] -&gt; Int&lt;br /&gt;len []&lt;br /&gt;   = 0&lt;br /&gt;len (a  : rest)&lt;br /&gt;   = 1 + len rest&lt;br /&gt;-----------------&lt;br /&gt;everyThird :: [Char] -&gt; Int&lt;br /&gt;everyThird [] = []&lt;br /&gt;everyThird (x:y:z:xs) = x : everyThird xs&lt;br /&gt;everyThird (x:y:xs) = []&lt;br /&gt;everyThird (x:xs) = []&lt;br /&gt;-- Um, whouldn't these be ambiguous?  [1,2,3] ought to match x:xs and x:y:xs and x:y:z:xs, cxu ne?&lt;br /&gt;-- Result of everyThird "classroom" : "arm"&lt;br /&gt;-----------------&lt;br /&gt;To load a file:     :l filename.hs&lt;br /&gt;To get the type of something:    :t 123&lt;br /&gt; output: 123.0 :: Int&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16943816-112725077430750314?l=qscribble.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qscribble.blogspot.com/feeds/112725077430750314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16943816&amp;postID=112725077430750314' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112725077430750314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16943816/posts/default/112725077430750314'/><link rel='alternate' type='text/html' href='http://qscribble.blogspot.com/2005/09/haskell-sample.html' title='Haskell sample'/><author><name>Qwertie</name><uri>http://www.blogger.com/profile/04595705428290721343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://www.geocities.com/Qwertie256/myface2.jpg'/></author><thr:total>0</thr:total></entry></feed>
