<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Lover of ideas</title>
  <link>http://omnifarious.dreamwidth.org/</link>
  <description>Lover of ideas - Dreamwidth Studios</description>
  <lastBuildDate>Tue, 08 Nov 2011 22:13:54 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>omnifarious</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <atom10:link rel='self' href='http://omnifarious.dreamwidth.org/data/rss' />
  <atom10:link rel='hub' href='http://pubsubhubbub.appspot.com/' />
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/5368.html</guid>
  <pubDate>Tue, 08 Nov 2011 22:13:54 GMT</pubDate>
  <title>Working on a small library, what should I name it?</title>
  <link>http://omnifarious.dreamwidth.org/5368.html</link>
  <description>&lt;p&gt;I&apos;m working on a small library to express computations in terms of composable trees of dependencies. These dependencies can cross thread boundaries allowing one thread to depend on a result generated in another thread. This is sort of a riff on the whole &lt;code&gt;promise&lt;/code&gt; and &lt;code&gt;future&lt;/code&gt; concept, but the idea is that you have chains of these with a potential fanout in the chain greater than 1. Kind of like the venerable &lt;code&gt;make&lt;/code&gt; utility in which you express what things need to be finished before starting on the particular thing you&apos;re talking about.&lt;/p&gt;
&lt;p&gt;But I&apos;m not sure what I should call it. Maybe &lt;em&gt;Teleo&lt;/em&gt; because it encourages to express your program in terms of a teleology.&lt;/p&gt;
&lt;p&gt;I&apos;m writing this basically because I&apos;ve encountered the same problem on at least two different projects now, and it occurs to me that it would be really good to have a well-defined standard way of launching things in other threads and waiting for the results that suggested an overall program architecture. The projects I worked on were all set to develop a huge mishmash of different techniques that wouldn&apos;t necessarily play well together or be easy to debug.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=5368&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/5368.html</comments>
  <category>computers</category>
  <category>projects</category>
  <category>programming</category>
  <category>ideas</category>
  <lj:mood>creative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/5033.html</guid>
  <pubDate>Thu, 20 Oct 2011 22:43:44 GMT</pubDate>
  <title>Architecture problem...</title>
  <link>http://omnifarious.dreamwidth.org/5033.html</link>
  <description>&lt;p&gt;I used to have a really good idea of what the architecture of a system that had to respond to multiple different possible sources of input or other reasons to do things (such as some interval of time expiring). My idea was basically to make everything purely event-driven and have big event loops at the heart of the program that dispatched events and got things done.&lt;/p&gt;
&lt;p&gt;This solves the vexing problem of how to deal with all these asynchronous occurrences without incurring excessively complex synchronization logic. Nothing gives up control to process another event until the data structures its working with are in a consistent state.&lt;/p&gt;
&lt;p&gt;But there are two problems with this model. One is old, and one is relatively new.&lt;/p&gt;
&lt;p&gt;The old problem is that such event-driven systems typically exhibit &lt;a href=&quot;http://en.wikipedia.org/wiki/Inversion_of_control&quot;&gt;inversion of control&lt;/a&gt;, and that makes them confusing and hard to follow. There are ways to structure your program to give people a lot of hints as to what&apos;s supposed to happen next when you give up control in the middle of an important operation only to recapture it again at some later point in time in a completely different function. But it&apos;s still not the easiest thing in the world to follow.&lt;/p&gt;
&lt;p&gt;The &apos;new&apos; problem is that silicon-based CPUs have not been getting especially faster recently. They&apos;ve instead been getting more numerous. This is a fairly predictable result. CPUs have a clock. This clock needs to stay synchronized across the entire CPU. Once clock speeds exceed a certain frequency, the clock signal takes longer to propagate across the entire chip than the amount of time before the next pulse is supposed to happen. This means that in order to have an effectively faster CPU on a single chip you need to break it up into independent units that do not need to be strictly synchronized with each other. It&apos;s a state horizon problem.&lt;/p&gt;
&lt;p&gt;But most programs are not designed to take advantage of several CPUs. If you want a program that&apos;s a cohesive whole, but still gets faster as the hardware advances, you need to break it up into several threads.&lt;/p&gt;
&lt;p&gt;It seems like maybe it would be simple to do this with a program that had multiple threads. You just have multiple event loops. But then you end up with several interesting problems. How do you decide what things happen in which event loop? What happens if you need to have data shared between things running on different event loops? You run the risk of re-introducing the synchronization issues you avoided when you added the event loops in the first place, all with the cost of inversion of control. It doesn&apos;t seem worth it.&lt;/p&gt;
&lt;p&gt;Additionally, if you have inter-thread synchronization, what happens if it takes awhile for the other thread to free up the resource you need? How do you prevent deadlocks? Most event systems do allow you to treat the release of a mutex or a semaphore as an event, so you can&apos;t just fold waiting for the mutex back into the system as just another event without doing some trick like spawning a thread that waits for the mutex and writes into some sort of IPC mechanism once it&apos;s acquired.&lt;/p&gt;
&lt;p&gt;And splitting up your program into multiple event threads is not trivial either. How do you detect and prevent the case of one thread being overworked? Also, there is &apos;state kiting&apos; to consider. Preferably you would prefer one CPU to be handling the same modifiable state for long periods of time. You want to avoid situations where first one CPU cache, then the next have to load up the contents of a particular memory region. Typically, each core will have its own cache. If for no reason other than efficient use of space, it would be good if each core had a disjoint set of memory locations in cache. And to avoid the latency of main memory access, it would be good if that set was relatively static. This means that a single event loop should be working with a fairly small and unchanging set of memory locations.&lt;/p&gt;
&lt;p&gt;So simply having several threads, each with its own event loop seems a solution fraught with peril, and it seems like you&apos;re throwing away a lot of the advantages you went to an event driven system (with the unpleasant inversion of control side-effect) for in the first place.&lt;/p&gt;
&lt;p&gt;So the original idea needs modification, or perhaps a completely new idea is needed.&lt;/p&gt;
&lt;p&gt;One modification is embodied in the language &lt;a href=&quot;http://en.wikipedia.org/wiki/Erlang_%28programming_language%29&quot;&gt;Erlang&lt;/a&gt;. Erlang still has an event loop and inversion of control. You waiting for messages that come in on a queue. Any other loop can add messages to any queue it knows about. These messages are roughly analogous to events. But the messages themselves convey only information that is immutable. Since it is immutable, shared or not, no synchronization is required since it cannot change.&lt;/p&gt;
&lt;p&gt;Erlang also encourages the creation of many such event loops, each of which does a very small job. Hopefully, no individual loop is too overloaded. Modern operating systems are adept at scheduling many jobs, and so this offloads the scheduling of all of these small tasks onto the OS.&lt;/p&gt;
&lt;p&gt;I do not think Erlang does overly much to solve the locality of reference problem.&lt;/p&gt;
&lt;p&gt;Another approach is the approach taken by the &lt;a href=&quot;http://en.wikipedia.org/wiki/E_%28programming_language%29&quot;&gt;E programming language&lt;/a&gt;. It makes extensive use of a concept called a &apos;future&apos; or &apos;promise&apos;. This is a promise to deliver the result of some operation at some future point in time. It &lt;a href=&quot;http://kentonsprojects.blogspot.com/2011/02/converting-ekam-to-c0x.html&quot;&gt;allows these promises to be chained, so you can build up an elaborate structure of dependencies between promises&lt;/a&gt;. In a sense, the programming language handles the inversion of control for you. You specify the program as if control flow were normal, but the language environment automatically launches as many concurrent requests as possible and suspends execution until the results are available.&lt;/p&gt;
&lt;p&gt;It is possible to build a set of library-level tools in C++11 to implement this kind of thing somewhat transparently in that language.&lt;/p&gt;
&lt;p&gt;I am unsure if there are any major tradeoffs in this approach. Certainly in C++ there is a great deal of implementation complexity, and that complexity cannot be completely hidden from the user as it is in E. I wonder if that implementation complexity introduces unacceptable overhead.&lt;/p&gt;
&lt;p&gt;I also suspect that it may be difficult to debug programs that use this sort of a model. They appear to execute sequentially, but in truth they do not. It is possible, for example, to have two outstanding promises for bytes from a file descriptor, but which order those promises will be fulfilled in will not be readily apparent from reading the code. And error conditions can crop up at strange times and propagate to non-obvious places in the control flow of your program.&lt;/p&gt;
&lt;p&gt;I also suspect this model will not exhibit the best locality of reference semantics. There will be a tendency to frequently spawn and join threads to handle asynchronous requests. And it will not be immediately apparent to the OS CPU scheduler which threads need to work with which memory objects. And this may lead to active state kiting between CPUs.&lt;/p&gt;
&lt;p&gt;Also, those calls to create and destroy threads have a cost, even if that cost is fairly small, it&apos;s still likely much more expensive than acquiring an unowned mutex, and probably even more expensive than the call to wait for a file descriptor readability event or waiting for a briefly held mutex to become available.&lt;/p&gt;
&lt;p&gt;Of course, it may be possible to implement all of this without creating many threads given a sufficiently clever runtime environment that implements its own queue that folds IO state and semaphore/mutex state events into a single queue. Such an environment would still need a lot of help from the application programmer though to divide up the application to maximize locality of reference within a single thread.&lt;/p&gt;
&lt;p&gt;This is a fairly long ramble, and I&apos;m still not really sure what the best approach is.  I think I may try to set up some kind of &apos;smart queue&apos;. This queue will have a priority queue of runnable tasks, and a queue of tasks that could potentially execute given a set of conditions. When a condition is met, the queue will be informed, and if that conditions enables one or more tasks to be run, these tasks will be added to the priority queue.&lt;/p&gt;
&lt;p&gt;I envision that the primary thing on which the priority queue will be prioritized is length of time since the task was added to the &apos;wait for condition&apos; list.&lt;/p&gt;
&lt;p&gt;I can then write a C++11 library that will allow you to automatically turn any function that returns a promise into a function that uses these conditions to split up its execution. At least, if you use sufficient care in writing the function.&lt;/p&gt;
&lt;p&gt;The conditions (since fulfilling a promise will be a possible condition) will have data associated with them. If this data involves shared mutable state, that will require a great deal of extra care.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=5033&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/5033.html</comments>
  <category>concurrency</category>
  <category>computers</category>
  <category>programming</category>
  <category>ideas</category>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/4859.html</guid>
  <pubDate>Fri, 24 Jun 2011 05:43:36 GMT</pubDate>
  <title>Digital signatures and documents</title>
  <link>http://omnifarious.dreamwidth.org/4859.html</link>
  <description>&lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;
&lt;p&gt;Documents and the digital signatures that apply to them are necessarily separate. Most current cryptographic systems either digitally sign things on the fly (TLS) or send a library of digital signatures with the document they sign (OpenPGP). Though, to be fair, in the OpenPGP case, each of those digital signatures signs a variant document.&lt;/p&gt;
&lt;p&gt;In CAKE there are documents to be signed. Examples are documents that say &quot;This public key exists, was created at time X, is valid for new sessions and signatures from times A through B, and is considered invalid at time E.&quot;, or &quot;This public key is reachable at this URL from times A through B.&quot;, or &quot;Public key I has agreed to store and forward messages for public key J from times A through B.&quot;, or &quot;My name for public key J is N.&quot;.&lt;/p&gt;
&lt;p&gt;For some of these documents there is only one key who&apos;s signature is relevant. For others, a specific small set of keys is relevant (the store and forward case, for example). And for others you care about all signatures, but especially signatures by other keys you trust.&lt;/p&gt;
&lt;p&gt;Of course, you could consider the document signed to include the name of the signing entity, in which case, each signature would be for a different document.&lt;/p&gt;
&lt;p&gt;I&apos;m not completely sure how to handle this. In my system there will be some documents that cannot be considered valid until multiple signatures have been received. So the signature has to be totally detached from the document.&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=4859&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/4859.html</comments>
  <category>computers</category>
  <category>projects</category>
  <category>ideas</category>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/4381.html</guid>
  <pubDate>Tue, 21 Jun 2011 19:01:25 GMT</pubDate>
  <title>People are so weirdly emotional about money</title>
  <link>http://omnifarious.dreamwidth.org/4381.html</link>
  <description>&lt;p&gt;I&apos;ve been paying a lot of attention to &lt;a href=&quot;http://www.bitcoin.org/&quot;&gt;bitcoin&lt;/a&gt; recently. It&apos;s a fascinating idea, and I&apos;m really curious as to where it will go. But reading the comments on the Internet about it is even more interesting, though also kind of upsetting. People say the most ridiculous and stupid things, and it&apos;s all out of nearly violent emotion. I don&apos;t really understand.&lt;/p&gt;
&lt;p&gt;Some people say ridiculous things like &quot;It can only go up!&quot; (in reference to the USD/Bitcoin exchange rate) or &quot;It can&apos;t fail!&quot;. Optimism beyond the point of sanity. Bitcoin can fail. It can fail if it turns out that nobody wants to accept it. Currency that nobody will trade anything for is just as useful as a small piece of paper, and in bitcoin&apos;s case, even less useful. And that&apos;s a very definite possible future of bitcoin.&lt;/p&gt;
&lt;p&gt;People also go through all kinds of logical contortions to declare it a scam. But it doesn&apos;t fit the definition of a ponzi scheme any more than any other currency does, nor does it fit the definition of a pyramid scheme at all. The closest it comes to is a hot tech stock. And nobody calls those scams unless they accuse them of &apos;pump and dump&apos;. But &apos;pump and dump&apos; doesn&apos;t fit the profile of most people who are interested in bitcoins and are trading them either.&lt;/p&gt;
&lt;p&gt;And then people declare it valueless, as if any currency (even gold) has any intrinsic value beyond people&apos;s willingness to trade stuff for it.&lt;/p&gt;
&lt;p&gt;Very few people talk about the worthiness of the cryptography. But even the ones who do paint either incredibly rosy pictures or ridiculous apocalyptic scenarios, neither of which really approach the truth of things.&lt;/p&gt;
&lt;p&gt;I just find the way people ignore any reason and base their opinions on pure emotion to be kind of upsetting. And I notice this in a lot of arguments. But the arguments over bitcoin are almost comical in just how incredibly intense this phenomena is. The only thing that makes it not comical is that you realize these people are deadly serious.&lt;/p&gt;
&lt;p&gt;I think a lot of people have a lot of unexamined hang-ups about the meaning of money. It&apos;s deeply tied to their fundamental beliefs about politics, ethics, morality, and even self-worth. I think most people are terribly unequipped to tease these things apart and examine them separately. Money is &apos;magic&apos;. People do not see it as the societal cooperation tool that it is.&lt;/p&gt;
&lt;p&gt;I think, perhaps, that is one of the most valuable parts of the bitcoin project. Its nature provides a handle or a window for examining money as a societal and organizational tool. I suspect most people won&apos;t be able to take advantage of this, but I suspect many will, and our society will become richer for it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=4381&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/4381.html</comments>
  <category>society</category>
  <category>psychology</category>
  <category>economics</category>
  <category>money</category>
  <category>politics</category>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/4096.html</guid>
  <pubDate>Fri, 10 Jun 2011 23:48:36 GMT</pubDate>
  <title>Help! DynDNS has become prohibitively expensive!</title>
  <link>http://omnifarious.dreamwidth.org/4096.html</link>
  <description>&lt;p&gt;They want to charge me $40/yr per domain for secondary DNS! $40/yr! This is completely ridiculous. With the volume of lookups I get, I could probably host all the domains on my own server on a DSL line if I wanted.&lt;/p&gt;
&lt;p&gt;Is anybody out there willing to provide secondary DNS for a few domains for me? I&apos;m willing to cough up the equivalent of $10/yr in bitcoins for the service if you really want.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=4096&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/4096.html</comments>
  <category>angst</category>
  <category>computers</category>
  <category>message</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/3936.html</guid>
  <pubDate>Mon, 30 May 2011 12:48:35 GMT</pubDate>
  <title>Session properties</title>
  <link>http://omnifarious.dreamwidth.org/3936.html</link>
  <description>&lt;p&gt;I&apos;ve been puzzling over a minimal and orthogonal set of properties for a session. I at first thought there were 3:&lt;/p&gt;
&lt;dl class=&quot;propdesc&quot;&gt;
&lt;dt style=&quot;font-style: italic;&quot;&gt;Message boundaries preserved&lt;/dt&gt;
&lt;dd style=&quot;margin-left: 2em;&quot;&gt;Whether or not your messages are delivered in discrete units, or whether they are delivered as a stream of bytes in which the original sizes of the send calls bear no relevance to how the bytes are chunked together on the other end.&lt;/dd&gt;
&lt;dt style=&quot;font-style: italic;&quot;&gt;Ordered&lt;/dt&gt;
&lt;dd style=&quot;margin-left: 2em;&quot;&gt;Whether or not data arrives in the order you sent it&lt;/dd&gt;
&lt;dt style=&quot;font-style: italic;&quot;&gt;Reliable&lt;/dt&gt;
&lt;dd style=&quot;margin-left: 2em;&quot;&gt;Well, this has a tricky definition. For TCP it means that failure to deliver is considered a failure of the underlying connection. But after such a failure you can&apos;t really be sure about exactly which bytes were delivered and which weren&apos;t.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;But, as is evidenced by my description of &apos;reliable&apos;, these properties are not as hard-edged as they might seem. I also thought about latency, for example a connection via email is relatively high latency, and a connection between memory and the CPU is generally pretty low latency. But I&apos;m looking for hard-edged, yes/no type properties that are in some sense fundamental. Latency seems like a property that&apos;s rather fuzzy. It exists on a continuum, and isn&apos;t really a defining feature of a connection, something that would drastically alter how you wrote programs that used the connection. In an object model, it would be an object property, not something you&apos;d make a different class for.&lt;/p&gt;
&lt;p&gt;But I find TCP&apos;s notion of &apos;reliability&apos; very curious. It isn&apos;t really, in any sense, particularly reliable. I&apos;ve had ssh connections that died, but when I reconnect to my screen session, I discover that a whole bunch of the stuff I was typing made it through, it just wasn&apos;t echoed back.&lt;/p&gt;
&lt;p&gt;It also interacts with &apos;ordered&apos; in an odd way. It might make sense to have an unordered connection that was &apos;reliable&apos;, but what does that really mean then? If it&apos;s a TCP notion of reliability, you could just deliver the last message and have the connection drop. Also, what would it mean to have an unreliable, but ordered connection? Would that mean you could send a bunch of messages and have only the first and last ones delivered? And would it make any sense at all to have an unordered, unreliable connection in which message boundaries were not preserved?&lt;/p&gt;
&lt;p&gt;So I&apos;ve come up with a different division...&lt;/p&gt;
&lt;dl&gt;
&lt;dt style=&quot;font-style: italic;&quot;&gt;Message boundaries preserved&lt;/dt&gt;
&lt;dd style=&quot;margin-left: 2em;&quot;&gt;Whether or not your messages are delivered in discrete units, or whether they are delivered as a stream of bytes in which the original sizes of the send calls bear no relevance to how the bytes are chunked together on the other end.&lt;/dd&gt;
&lt;dt style=&quot;font-style: italic;&quot;&gt;Ordered&lt;/dt&gt;
&lt;dd style=&quot;margin-left: 2em;&quot;&gt;Whether or not data arrives in the order you sent it&lt;/dd&gt;
&lt;dt style=&quot;font-style: italic;&quot;&gt;Must not drop&lt;/dt&gt;
&lt;dd style=&quot;margin-left: 2em;&quot;&gt;This means that if a message does not make it through, the connection is considered to be in an unrecoverable error state, and no further messages may be sent. Though you may not know which message didn&apos;t make it through.&lt;/dd&gt;
&lt;dt style=&quot;font-style: italic;&quot;&gt;Delivery notification&lt;/dt&gt;
&lt;dd style=&quot;margin-left: 2em;&quot;&gt;Whether or not you can know that a message made it to the other side or not.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;These are not fully orthogonal. For example, if message boundaries are not preserved, then, in order for a connection to be in the least sensible, it must also have the &apos;ordered&apos; and &apos;must not drop&apos; properties. Also, if you must not drop messages, I&apos;m not sure that it would then be sensible to have out-of-order delivery.&lt;/p&gt;
&lt;p&gt;One of the rules of the system I&apos;m designing is that any property that is not required may be provided anyway. This makes non-orthogonality much easier to deal with. So the prior cases aren&apos;t really a problem.&lt;/p&gt;
&lt;p&gt;Can any of you think of a better set of properties, or important properties that I left out?&lt;/p&gt;
&lt;p&gt;Some good discussion also happens in this &lt;a href=&quot;https://profiles.google.com/115018508252522790254/posts/MJPSkn2Jyuw&quot;&gt;Google Buzz post that mirrors this entry&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=3936&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/3936.html</comments>
  <category>computers</category>
  <category>projects</category>
  <category>ideas</category>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/3651.html</guid>
  <pubDate>Wed, 04 May 2011 22:00:08 GMT</pubDate>
  <title>The hidden cost of your iPad</title>
  <link>http://omnifarious.dreamwidth.org/3651.html</link>
  <description>&lt;p&gt;Suicide is so common in Chinese iPad factories that the company has taken to &lt;a href=&quot;http://www.dailymail.co.uk/news/article-1382396/Workers-Chinese-Apple-factories-forced-sign-pledges-commit-suicide.html&quot;&gt;forcing prospective employees to sign no-suicide pacts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Talk about treating the symptom instead of the disease.&lt;/p&gt;
&lt;p&gt;A friend of mine has pointed out that this story is made to seem a lot worse than it really is. In particular the suicide at Foxconn plants is much lower than it is at other similar facilities in China. He is also not much of a fan of Apple the company, so he doesn&apos;t have a fanboy bias. I&apos;m not completely sure I agree with this way of looking at things, but here is what he wrote, so you can make up your own minds:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This story has been highly sensationalized. The reality is almost exactly the opposite of what you read.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Eighteen Foxconn employees committed suicide in 2010 [1]... out of 920,000 workers [2]. That&apos;s a rate much lower than the Chinese average of 66 per million [3], which itself is like half of the American average of 111 per million [3].&lt;/li&gt;
&lt;li&gt;Apple is just one of many Foxconn clients. Others include Amazon (Kindle), Intel, Dell, Nintendo, Sony, Samsung, and many others [2]. Apple products are a small minority of Foxconn&apos;s output, yet the media calls them the &quot;iPad factory&quot;. This is obviously intended to sensationalize the story -- scandal involving Apple is much more interesting that scandal involving Samsung.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I suspect that Foxconn came up with these no-suicide pledges in a desperate attempt to placate the media, and due to cultural differences they don&apos;t understand that to the American audience it only makes them look worse.&lt;/p&gt;
&lt;div&gt;
[1] &lt;a href=&quot;http://en.wikipedia.org/wiki/Foxconn_suicides&quot;&gt;http://en.wikipedia.org/wiki/Foxconn_suicides&lt;/a&gt;&lt;br /&gt;
[2] &lt;a href=&quot;http://en.wikipedia.org/wiki/Foxconn&quot;&gt;http://en.wikipedia.org/wiki/Foxconn&lt;/a&gt;&lt;br /&gt;
[3] &lt;a href=&quot;http://en.wikipedia.org/wiki/List_of_countries_by_suicide_rate&quot;&gt;http://en.wikipedia.org/wiki/List_of_countries_by_suicide_rate&lt;/a&gt;
&lt;/div&gt;
&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=3651&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/3651.html</comments>
  <category>angst</category>
  <category>social</category>
  <category>money</category>
  <category>politics</category>
  <lj:mood>annoyed</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/3368.html</guid>
  <pubDate>Tue, 19 Apr 2011 13:29:38 GMT</pubDate>
  <title>Building codes</title>
  <link>http://omnifarious.dreamwidth.org/3368.html</link>
  <description>&lt;p&gt;Building codes serve a few functions. The most important one is safety. But another is ensuring that your home does not fall to pieces in 10 years (after the builders are long gone) by forcing certain minimum standards of construction.&lt;p&gt;
&lt;p&gt;To the latter end, I think building codes for multi-unit dwellings should require that each and every single unit have a single fiber drop in the unit. I assume there are standards for phone hookups today (and possibly cable), and the fiber standard would have a very similar purpose and structure.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=3368&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/3368.html</comments>
  <category>ideas</category>
  <category>politics</category>
  <lj:music>Goodbye Stranger - Supertramp</lj:music>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/3123.html</guid>
  <pubDate>Mon, 28 Mar 2011 16:10:59 GMT</pubDate>
  <title>CAKE has reached a small milestone</title>
  <link>http://omnifarious.dreamwidth.org/3123.html</link>
  <description>&lt;p&gt;&lt;a href=&quot;http://www.cakem.net/&quot;&gt;CAKE&lt;/a&gt; reached a new milestone early this morning. It now successfully both generates and parses messages that use the new protocol. It also successfully detected a re-used session id. I also think the code that does this is also a lot better designed than the old code was. It&apos;s easier to see how to put it in the context of a larger system that implements a node that speaks the protocol&lt;/p&gt;
&lt;p&gt;It&apos;s also much more extensively tested at a deeper level with tests that are designed to document the inner workings of the system.&lt;/p&gt;
&lt;p&gt;Overall, it&apos;s in a much better state than I left it when I sort of stopped working on it much in 2004. And I&apos;m going to handle the hard problems first, how to maintain the relationship between sessions and transports, and having two way realtime conversations between nodes. This rather than concentrating on the messages that will be traded back and forth at a higher level (which will be done using &lt;a href=&quot;http://code.google.com/p/protobuf/&quot;&gt;protobuf&lt;/a&gt;). That can come later, especially since I&apos;m not likely to get it right the first time anyway.&lt;/p&gt;
&lt;p&gt;I also need to think about getting nodes to participate in a DHT to share assertions (like how to reach a particular node) in a distributed way.&lt;/p&gt;
&lt;p&gt;Lastly, the protocol has something of a problem with &apos;liveness&apos; because I designed it with the idea of conversations being able to be initiated without any round trips. There are some mitigation for this problem in session ids, but that mitigation is somewhat problematic because it requires the recipient of a conversation initiation to keep track of some stuff for everybody who tries to talk to it.&lt;/p&gt;
&lt;p&gt;I&apos;m not really sure how to handle the &apos;liveness&apos; problem though and still preserve the lack of round trips property. I could require that session ids contain an &apos;hour number&apos; or something similar. Though that introduces a requirement for at least very coarse grain time synchronization for all nodes.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=3123&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/3123.html</comments>
  <category>diary</category>
  <category>computers</category>
  <category>projects</category>
  <lj:mood>accomplished</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/3000.html</guid>
  <pubDate>Fri, 25 Feb 2011 20:17:52 GMT</pubDate>
  <title>Memory</title>
  <link>http://omnifarious.dreamwidth.org/3000.html</link>
  <description>&lt;p&gt;Memory is stored in so many places. A sea shell contains the memory of the organism that made it. Its trials and tribulations are recorded in the layers of material it deposited. Since it was unable to make a meaningful decision based on these memories, we hesitate to call them so, but our scientists eagerly read them, read the memories in whole stratas of seashells, the memories of entire ecosystems.&lt;/p&gt;
&lt;p&gt;We implicitly recognize this when we say something like &quot;this house is full of memories&quot;. Every nick and change, unnoticeable by some, tells a tale of something that happened there. The patterns of wear on the floor, the neglected dusty corners tell tales as well.&lt;/p&gt;
&lt;p&gt;Forensics is the art of reading memories from these structural changes. Reading memory from these things we hesitate to call memory because they are not immediately accessible to a living process. But memories they are.&lt;/p&gt;
&lt;p&gt;We have a collective memory too. The most obvious and directly accessible is books. But we have memories in our cities, in our tools, in the structures both great and small. They are like mankind&apos;s seashells.&lt;/p&gt;
&lt;p&gt;We think of ourselves as relatively self contained. We are divided from the world by the interface of our immediate perceptions. But that division is fuzzy and indistinct. We are much larger than our bodies. And much of our memory lives outside our heads.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=3000&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/3000.html</comments>
  <category>writing</category>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/2666.html</guid>
  <pubDate>Wed, 02 Feb 2011 22:46:39 GMT</pubDate>
  <title>Interesting design problem with serialization and deserialization</title>
  <link>http://omnifarious.dreamwidth.org/2666.html</link>
  <description>&lt;p&gt;I have been working on a serialization framework I&apos;m happy with for Python.
  I want to be able to describe &lt;a href=&quot;http://www.cakem.net/&quot;&gt;CAKE
  protocol&lt;/a&gt; messages clearly and succinctly.  This will make it easier to
  tweak the messages without having to rip apart difficult to understand code.
  It will also make it easier to understand if I drop the project again and
  then come back to it years later, or if (by some miracle) someone else
  decides to help me with it.&lt;/p&gt;

&lt;a name=&quot;cutid1&quot;&gt;&lt;/a&gt;

&lt;p&gt;Here is what I&apos;ve come up with as the interface, along with one
  implementation fo that interface for a simple type:&lt;/p&gt;

&lt;pre&gt;class Serializer(object):
    &quot;&quot;&quot;This is class is an abstract base class.  Derived classes, when
    instantiated, create objects that can serialize other objects of a
    particular type to a sequence of bytes, or alternately deserialize
    a sequence of bytes into an object of a particular type.&quot;&quot;&quot;

    __slots__ = (&apos;__weakref__&apos;,)

    def __init__(self):
        super(Serializer, self).__init__()

    def serialize(self, val):
        &quot;&quot;&quot;x.serialize(value) -&amp;gt; b&apos;serialized value&apos;

        This is implemented in terms of serialize_iter by default.

        It is suggested that derived classes only implement serialize
        or serialize_iter and implement one in terms of the other.&quot;&quot;&quot;
        if self.__class__ is Serializer:
            raise NotImplentedError(&quot;This is an abstract class.&quot;)
        return b&apos;&apos;.join(x for x in self.serialize_iter(val))

    def serialize_iter(self, val):
        &quot;&quot;&quot;x.serialize_iter(value) -&amp;gt; an iterator over the bytes
        sequences making p the seralized version of value.&quot;&quot;&quot;
        if self.__class__ is Serializer:
            raise NotImplentedError(&quot;This is an abstract class.&quot;)
        return iter((self.serialize(val),))

    def deserialize(self, data, memo=None):
        &quot;&quot;&quot;x.deserialize(data, [memo]) -&amp;gt;
        (value of the appropriate type, memoryview(remaining_data))

        data must be of type &apos;bytes&apos;, or &apos;memoryview&apos;.  The memo must
        be a value extracted from a previous NotEnoughDataError.

        It is undefined what happens if you use memo and do not pass
        the same data (plus some possible extra data on the end) into
        deserialize that you originally passed in when you got the
        NotEnoughDataError you extracted the memo from.

        May raise a ParseError if there is a problem with the data.
        If the failure was because the parser ran out of data before
        parsing was finished, this is required to be a
        NotEnoughDataError.&quot;&quot;&quot;
        return self._deserialize(data if not isinstance(data, bytes) \
                                     else memoryview(data),
                                 memo)

    def _deserialize(self, memview, memo=None):
        &quot;&quot;&quot;x._deserialize(memoryview) -&amp;gt;
        (value of the appropriate type, memoryview(remaining_data))

        Exactly like deserialize, except a memoryview object is
        required.  deserialize is implemented in terms of
        _deserialize.  Derived classes are expected to override
        _deserialize.&quot;&quot;&quot;
        raise NotImplentedError(&quot;This is an abstract class.&quot;)

&lt;hr /&gt;

class SmallInt(Serializer):
    &quot;&quot;&quot;This class is for integers that are 8, 16, 32, or 64 bits long.
    They may be signed or unsigned.  No other sizes are supported.

    &amp;gt;&amp;gt;&amp;gt; s = SmallInt(2, True)
    Traceback (most recent call last):
        ...
    ValueError: size is 2, must be 8, 16, 32 or 64
    &amp;gt;&amp;gt;&amp;gt; s = SmallInt(8, True)
    &amp;gt;&amp;gt;&amp;gt; b = list(s.serialize_iter(5))
    &amp;gt;&amp;gt;&amp;gt; b == [b&apos;\\x05&apos;]
    True
    &amp;gt;&amp;gt;&amp;gt; o = s.deserialize(b&apos;&apos;.join(b))
    &amp;gt;&amp;gt;&amp;gt; o = (o[0], o[1].tobytes())
    &amp;gt;&amp;gt;&amp;gt; o == (5, b&apos;&apos;)
    True
    &amp;gt;&amp;gt;&amp;gt; o = s.deserialize(b&apos;&apos;.join(b) + b&apos;z&apos;)
    &amp;gt;&amp;gt;&amp;gt; o = (o[0], o[1].tobytes())
    &amp;gt;&amp;gt;&amp;gt; o == (5, b&apos;z&apos;)
    True
    &amp;gt;&amp;gt;&amp;gt; s = SmallInt(8, True)
    &amp;gt;&amp;gt;&amp;gt; b = s.serialize(-5)
    &amp;gt;&amp;gt;&amp;gt; b == b&apos;\\xfb&apos;
    True
    &amp;gt;&amp;gt;&amp;gt; s = SmallInt(8, True)
    &amp;gt;&amp;gt;&amp;gt; s = s.serialize(128)
    Traceback (most recent call last):
        ...
    ValueError: 128 is out of range for an signed 8 bit integer
    &amp;gt;&amp;gt;&amp;gt; s = SmallInt(64, False)
    &amp;gt;&amp;gt;&amp;gt; b = s.serialize(2**64-1)
    &amp;gt;&amp;gt;&amp;gt; b == b&apos;\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff&apos;
    True
    &amp;gt;&amp;gt;&amp;gt; s = SmallInt(64, True)
    &amp;gt;&amp;gt;&amp;gt; b = s.serialize(-2**63)
    &amp;gt;&amp;gt;&amp;gt; b == b&apos;\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00&apos;
    True
    &quot;&quot;&quot;

    _formats = dict((
            ((8, True),   &apos;&amp;gt;b&apos;),
            ((8, False),  &apos;&amp;gt;B&apos;),
            ((16, True),  &apos;&amp;gt;h&apos;),
            ((16, False), &apos;&amp;gt;H&apos;),
            ((32, True),  &apos;&amp;gt;i&apos;),
            ((32, False), &apos;&amp;gt;I&apos;),
            ((64, True),  &apos;&amp;gt;q&apos;),
            ((64, False), &apos;&amp;gt;Q&apos;)
        ))

    __slots__ = (&apos;_size&apos;, &apos;_signed&apos;, &apos;_low&apos;, &apos;_high&apos;, &apos;_format&apos;)

    def __init__(self, size, signed):
        if size not in (8, 16, 32, 64):
            raise ValueError(&quot;size is %d, must be 8, 16, 32 or 64&quot; % (size,))
        self._size = size
        self._signed = bool(signed)
        self._format = self._formats[(size, signed)]

    def serialize(self, value):
        if not isinstance(value, (int, long)):
            raise TypeError(&quot;%r must be an int or long&quot; % (value,))
        value = int(value)
        try:
            ret = _struct.pack(self._format, value)
        except _struct.error:
            raise ValueError(&quot;%d is out of range for an %ssigned %d bit &quot;
                             &quot;integer&quot; % (value,
                                          (&quot;un&quot; if not self._signed else &quot;&quot;),
                                          self._size))
        return ret

    def _deserialize(self, memview, memo=None):
        numbytes = self._size // 8
        if len(memview) &amp;lt; numbytes:
            raise _NotEnoughDataError((self._size // 8) - len(memview))
        else:
            data = memview[0:numbytes].tobytes()
            remaining = memview[numbytes:]
            try:
                result = _struct.unpack(self._format, data)[0]
                return result, remaining
            except _struct.error as err:
                raise ParseErrror(err)
&lt;/pre&gt;

&lt;p&gt;There is also a &lt;code&gt;CompoundNumbered&lt;/code&gt; type for representing
  tuples. This allows you to represent structured messages with multiple
  fields.  Here is example of how you might
  represent &lt;a href=&quot;http://www.cakem.net/v2/sessions.html#newsession&quot;&gt;CAKE new
  session messages&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;cake_newsess_v2 = _serial.CompoundNumbered(
    _serial.Count(), # Version
    _serial.Count(), # Type
    _serial.KeyName(), # Destination key
    _serial.KeyName(), # Source key
    _serial.SmallInt(64, False), # Session serial #
    _serial.CountDelimitedByteString(), # Encryption header
    _serial.CountDelimitedByteString(), # Signature.
    _serial.FixedLengthByteString(32) # Header HMAC
)
&lt;/pre&gt;

&lt;p&gt;There is a problem though.  The signature and header HMAC are supposed to be
  encrypted, but the deserializer can&apos;t know the key to use until it&apos;s
  decrypted the encryption header.  This means that later parts of the
  deserialization process need to know about things from previous parts.&lt;/p&gt;

&lt;p&gt;I have a way for the deserialization process to save state.  This is used so
  that if deserialization throws a &lt;code&gt;NotEnoughDataError&lt;/code&gt; because not
  enough data is available, the exception may have a &lt;code&gt;memo&lt;/code&gt; field.
  This &lt;code&gt;memo&lt;/code&gt; field can then be passed in again to resume close to
  where deserialization stopped.  &lt;em&gt;(Though now I&apos;m sort of wondering if I
  shouldn&apos;t do something generator based instead...)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But this mechanism does not allow state to be passed forward from a previous
  deserializer to a new one.  And this applies the other way around too.  When
  serializing there is stuff that&apos;s not really a part of the data being
  serialized (like the current HMAC or encryption state) that needs to be known
  by serializer in order to serialize properly.&lt;/p&gt;

&lt;p&gt;I&apos;m thinking of adding an optional &lt;code&gt;context&lt;/code&gt; parameter to the
  serialization and deserialization functions that&apos;s just an empty dictionary
  into which this sort of state can be stuffed.  But this seems really messy.
  Can anybody think of any better ways to do this that are fairly general?&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=2666&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/2666.html</comments>
  <category>computers</category>
  <category>projects</category>
  <lj:music>Supreme Beings of Leisure - Strangelove Addiction</lj:music>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/2312.html</guid>
  <pubDate>Sat, 04 Dec 2010 23:26:39 GMT</pubDate>
  <title>Protocol buffers?</title>
  <link>http://omnifarious.dreamwidth.org/2312.html</link>
  <description>&lt;p&gt;I have a problem for which &lt;a href=&quot;http://code.google.com/apis/protocolbuffers/&quot;&gt;protocol buffers&lt;/a&gt; seem like a good solution, but I&apos;m reluctant to use them.  First, protocol buffers include facilities for handling the addition of new fields in the future.  This adds a small amount to a typical protocol buffer message, but it&apos;s a facility I do not need.&lt;/p&gt;

&lt;p&gt;Also, I feel the variable sized number encoding is less efficient than it could be, though this is a very minor issue.  I also feel like I have a number of special purpose data types that are not adequately represented.&lt;/p&gt;

&lt;p&gt;I&apos;m also not completely pleased with the C++ and/or Python APIs.  I think they contain too many googlisms.  I would like to see public APIs published that were free of adherence to Google coding standards like do-nothing constructors and no exceptions.&lt;/p&gt;

&lt;p&gt;I think, maybe, I will be using protocol buffers for some messages that are sent by applications using CAKE as a transport/session layer.  These include some of the sub-protocols that are required to be implemented by a conforming CAKE implementation.&lt;/p&gt;

&lt;p&gt;On a different note, I think Google&apos;s C++ coding standards are lowering the overall quality of Open Source C++ code.  This isn&apos;t a huge effect, but it&apos;s there.&lt;/p&gt;

&lt;p&gt;It happens because Google&apos;s good name is associated with a set of published standards for C++ coding that include advice that while possibly good for Google internally is of dubious quality as general purpose advice.  It also happens because when Google releases code for their internal tools to the Open Source community, these tools follow Google&apos;s standards.  And some of these standards have the effect of making it hard to use code that doesn&apos;t comply with those standards in conjunction with code that does.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=2312&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/2312.html</comments>
  <category>computers</category>
  <category>projects</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/2058.html</guid>
  <pubDate>Sat, 22 May 2010 00:05:25 GMT</pubDate>
  <title>Today&apos;s XKCD</title>
  <link>http://omnifarious.dreamwidth.org/2058.html</link>
  <description>&lt;p&gt;Normally XKCD is amusing for very positive reasons.  But I frequently feel a lot like the guy with the beard in this cartoon.  It&apos;s really frustrating.  So, today&apos;s XKCD is darkly amusing to me.  Freedom is such a hard sell before people lose it.  People choose convenience every time, frequently until it&apos;s almost too late to fix the problem all the while berating the people who were worried in the first place.&lt;/p&gt;
&lt;a href=&quot;http://xkcd.com/743/&quot;&gt;&lt;img src=&quot;http://imgs.xkcd.com/comics/infrastructures.png&quot; title=&quot;The heartfelt tune it plays is CC licensed, and you can get it from my seed on JoinDiaspora.com whenever that project gets going.&quot; alt=&quot;Infrastructures&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=2058&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/2058.html</comments>
  <category>society</category>
  <category>angst</category>
  <category>computers</category>
  <category>politics</category>
  <lj:music>MC Frontalot - Special Delivery</lj:music>
  <lj:mood>amused</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/1810.html</guid>
  <pubDate>Tue, 18 May 2010 23:32:06 GMT</pubDate>
  <title>Eben Moglen Tech Talk at Google</title>
  <link>http://omnifarious.dreamwidth.org/1810.html</link>
  <description>&lt;p&gt;&lt;a href=&quot;http://emoglen.law.columbia.edu/&quot;&gt;Eben Moglen&lt;/a&gt; is one of the principle lawyers behind the GPL.  He&apos;s also a tireless free software advocate, and significantly more photogenic and diplomatic than Richard Stallman.&lt;/p&gt;
&lt;p&gt;He recently gave this interesting tech talk at Google about &lt;a href=&quot;http://youtube.com/watch?v=PL7BaJFotnU&quot;&gt;the perception of Google by entities outside it&lt;/a&gt;.  It was really well done, and struck a strong chord with me.&lt;/p&gt;
&lt;p&gt;I&apos;ve noticed that people frequently are incapable of believing that some things Google does are for the reasons Google says they&apos;re doing them.  For example (and I don&apos;t really have the time to find references just now) many people seem to think that &lt;a href=&quot;http://www.google.com/logos/&quot;&gt;Google Doodles&lt;/a&gt;, those fun, timely modifications to their main search page, are a marketing tool, when in fact they are largely done purely out of whimsy.&lt;/p&gt;
&lt;p&gt;I suppose, in one sense there is marketing purpose.  Google is projecting their image of themselves out into the world.  It&apos;s brand building.  But, on the other hand, there isn&apos;t.  I doubt that Google Doodles started as an idea for brand building in some marketing department.  I&apos;m betting some random small group of people decided one day that it would be fun to do, and the idea sort of caught on and now it&apos;s a tradition.&lt;/p&gt;
&lt;p&gt;But people seem to want to analyze doodles for the marketing message they contain, despite the fact there generally isn&apos;t one.  The more enigmatic the doodle is, the more determined people seem to be to find the marketing message in it.&lt;/p&gt;
&lt;p&gt;This means there is a disparity in perception between people outside Google and people inside Google.  One that might serve Google very poorly in the future.  It&apos;s very important that Google understand this and respond appropriately.  Perception is reality and people and organizations live up to expectations.  Google risks becoming what people perceive them to be unless they act to correct that perception.&lt;/p&gt;
&lt;p&gt;Google also frequently doesn&apos;t realize how the fact that they are so large and powerful affects people&apos;s perceptions of them.  Witness the brouhaha over Buzz.  Google did do some somewhat wrongheaded things in introducing it, but Buzz was not anywhere near the privacy destroying aggregator that people thought it was.  And the fact that people perceived Buzz in this way seemed to mystify people inside Google, even though it was predictable given Google&apos;s size and people&apos;s perceptions.&lt;/p&gt;
&lt;p&gt;Again, this points to a need by Google to better manage people&apos;s perceptions of them, and to manage their product releases better in terms of how people perceive them.&lt;/p&gt;
&lt;p&gt;Eben Moglen suggests, quite wisely, that one thing Google could do is to change their policy on contributing internal changes back to Open Source projects.  I think this is a good idea, but I doubt it will really be enough.&lt;/p&gt;
&lt;p&gt;I am a little worried that if Google takes this advice to heart that they will grow a PR arm that does what every other PR arm in the world does, which is to try to make sure that perception stays far more positive than reality instead of simply trying to make perception match reality.  But Google should do something, since I think people think far more ill of them than they generally deserve.&lt;/p&gt;
&lt;p&gt;Google is, in fact, the only company I know of that has a revenue stream greater than 1 billion dollars a year that I actually have a positive opinion of.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=1810&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/1810.html</comments>
  <category>computers</category>
  <category>politics</category>
  <lj:mood>contemplative</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/1460.html</guid>
  <pubDate>Fri, 07 May 2010 17:27:02 GMT</pubDate>
  <title>The evils of Flash</title>
  <link>http://omnifarious.dreamwidth.org/1460.html</link>
  <description>&lt;p&gt;This was a &lt;a href=&quot;http://slashdot.org/comments.pl?sid=1641910&amp;amp;cid=32099608&quot;&gt;Slashdot comment&lt;/a&gt;, but I think it deserves a top level post here.  It&apos;s in response to &lt;em&gt;&lt;a href=&quot;http://www.crafted.com.au/blog/2010/05/05/apples-attack-on-adobe-flash-its-all-about-online-video/&quot;&gt;Apple’s attack on Adobe Flash, it’s all about online video&lt;/a&gt;&lt;/em&gt; &lt;strong&gt;NOT&lt;/strong&gt;.  (I added the &apos;NOT&apos; because that&apos;s the author&apos;s conclusion.)&lt;/p&gt;
&lt;div style=&quot;font-size:1.2em; font-weight: bold;&quot;&gt;Pot calls kettle black, kettle complains,
but it&apos;s just as black.&lt;/div&gt;
&lt;p&gt;Flash is a despicable disgrace. Most of the time when I talk to a Flash developer, the thing they&apos;re the happiest about is the control they get over my computer. This is directly because the Flash player is a piece of garbage closed source tool that purposely caters to developers over end-users. The Open Source &lt;a href=&quot;http://www.gnu.org/software/gnash/&quot;&gt;gnash&lt;/a&gt; (not ganash) player has an option to pause a Flash program. The Adobe player will never, ever end up with that option, ever. Giving me control over my own computer is against Adobe&apos;s best interest. That makes Adobe&apos;s Flash player is little more than a widely deployed trojan horse that, IMHO, is little better than spyware (Flash cookies anyone? Where&apos;s my control over those?).&lt;/p&gt;

&lt;p&gt;I wouldn&apos;t complain so bitterly about this if the gnash player were actually a decent drop in replacement for the closed source Flash player, but it isn&apos;t. I have to either choose my freedom  to have my computer do what I want instead of what some random corporation wants with Flash that is broken most of the time, or Flash that works while giving up my freedom. I will choose my freedom, thank you very much, but I will be bitter about the stupid choice I&apos;m forced to make.&lt;/p&gt;

&lt;p&gt;So, when one maker of a closed, proprietary platform that steals people&apos;s freedom purposely does things to the detriment of another closed proprietary platform that steals people&apos;s freedom, I can&apos;t help but cheer. And I hope Adobe finds a way to play nasty games with Apple too. The more these two companies can find ways to hurt eachother, the more the rest of us benefit.&lt;/p&gt;

&lt;p&gt;If Adobe Open Sourced the Flash player (I could care less about the developer tools, they will end up with Open Source implementations no matter what Adobe does if the player is truly open) my objections to Flash would completely disappear.  I could realistically choose a fully functional Flash player and I&apos;m certain I could find one with a pause button, or one that refused to store cookies for longer than a week.  I could make it myself if I wanted to.&lt;/p&gt;

&lt;p&gt;And lest you tell me that I&apos;m just whining, the majority of large sites out there no longer look right without Flash.  By not using Flash, I&apos;m cut off from a significant part of the experience of the web.  I shouldn&apos;t be forced to give up control of my computer in order to browse the web.  That&apos;s a completely and utterly ridiculous assertion.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=1460&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/1460.html</comments>
  <category>angst</category>
  <category>computers</category>
  <category>politics</category>
  <lj:music>Humming fans</lj:music>
  <lj:mood>annoyed</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/1127.html</guid>
  <pubDate>Tue, 30 Mar 2010 16:49:53 GMT</pubDate>
  <title>Walking data structures</title>
  <link>http://omnifarious.dreamwidth.org/1127.html</link>
  <description>&lt;p&gt;It&apos;s common programmer tech speak to talk about &apos;walking&apos; data structures, meaning following all the pointers around to put all the data back together again.  I think that &apos;brachiation&apos; is a more apt metaphor, and fits well with the concept of &apos;code monkey&apos;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=1127&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/1127.html</comments>
  <category>silliness</category>
  <category>computers</category>
  <lj:mood>amused</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/990.html</guid>
  <pubDate>Mon, 22 Mar 2010 15:20:19 GMT</pubDate>
  <title>The new health care bill</title>
  <link>http://omnifarious.dreamwidth.org/990.html</link>
  <description>&lt;p&gt;From what I&apos;ve heard, the new health care bill will impose fines on people who don&apos;t have health insurance. Is this true? If it is, I&apos;m tempted to refuse my employers health insurance plan on general principles.&lt;/p&gt;
&lt;p&gt;I&apos;m ambivalent about the idea of such a bill in the first place.  I wanted Obama elected in the hopes that he&apos;d fix things like the influence of lobbyists and money and restore civil liberties and have a more open and accountable government.  Health care was really low on my list of priorities, and I was nearly certain I wasn&apos;t for any kind of solution that involved perpetuating the stupidity that is the current health insurance system.&lt;/p&gt;
&lt;p&gt;Unfortunately, Obama seems to be standing still or going backwards on all the things I really care about.  For example, his administration has refused significantly more FOIA requests than the previous one.&lt;/p&gt;
&lt;p&gt;I&apos;m rather disappointed.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=990&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/990.html</comments>
  <category>angst</category>
  <category>politics</category>
  <lj:mood>disappointed</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/540.html</guid>
  <pubDate>Thu, 18 Mar 2010 18:14:05 GMT</pubDate>
  <title>I hate perl</title>
  <link>http://omnifarious.dreamwidth.org/540.html</link>
  <description>&lt;p&gt;Case in point, the &lt;code&gt;&lt;a href=&quot;http://search.cpan.org/dist/Net-IP/IP.pm&quot;&gt;Net::IP&lt;/a&gt;&lt;/code&gt; module.  The documentation looks nice.  It handles IPv6 and IPv4 addresses.  It looks clean and simple.&lt;/p&gt;
&lt;p&gt;Then, I decided I would like to be able to have &lt;a href=&quot;http://www.tcpipguide.com/free/t_IPv6IPv4AddressEmbedding-2.htm&quot;&gt;IPv4 mapped IPv6 addresses&lt;/a&gt; match the IPv4 address ranges I&apos;m singling out for special treatment.  So I look into its tool for extracting an IPv4 address from an IPv6 address.&lt;/p&gt;
&lt;p&gt;The call, &lt;code&gt;&lt;a href=&quot;http://search.cpan.org/dist/Net-IP/IP.pm#ip_get_embedded_ipv4&quot;&gt;ip_get_embedded_ipv4&lt;/a&gt;&lt;/code&gt; doesn&apos;t seem to work on IPv6 addresses created with &apos;new&apos;.  It only works on IPv6 addresses represented as strings.  This leads me to dive into the implementation.&lt;/p&gt;
&lt;p&gt;I discover that the is no coherent internal representation.  Just a lot of different attributes that are used at different times for different purposes and are converted from one another as needed.&lt;/p&gt;
&lt;p&gt;Additionally, there appears to be no way to import particular symbols of certain classes from the module.  You have to import them using the import statements specified in the documentation or take your chances on whether or not it will work.  This is because the import mechanism and which symbols are global or not is handled in a fairly ad-hoc sort of way and re-implemented in each module according to the whims of the author.&lt;/p&gt;
&lt;p&gt;It&apos;s really quite surprising the module works at all.  And I&apos;m left feeling like I really ought to re-write it if I want something I can count on.&lt;/p&gt;
&lt;p&gt;In reality, looking at the module&apos;s implementation was a mistake.  This is always what happens to me when I look at a perl module.  Either it works in a completely mysterious way using language mechanisms I&apos;ve never seen used before, or it works in a way that&apos;s totally broken and practically guaranteed to break for any use that varies from the specific use-cases described in the documentation.  Frequently both are the case.  Aigh!  Run away!&lt;/p&gt;
&lt;p&gt;I hope I can convince my new workplace to stop using perl.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=540&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/540.html</comments>
  <category>angst</category>
  <category>diary</category>
  <category>computers</category>
  <lj:music>Humming fans</lj:music>
  <lj:mood>aggravated</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://omnifarious.dreamwidth.org/270.html</guid>
  <pubDate>Mon, 15 Mar 2010 00:18:24 GMT</pubDate>
  <title>I&apos;m on Dreamwidth now!</title>
  <link>http://omnifarious.dreamwidth.org/270.html</link>
  <description>&lt;p&gt;Thank you &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://foxfirefey.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;http://s.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;http://foxfirefey.dreamwidth.org/&apos;&gt;&lt;b&gt;foxfirefey&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://leora.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;http://s.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;http://leora.dreamwidth.org/&apos;&gt;&lt;b&gt;leora&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, and &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://fallenpegasus.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;http://s.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;http://fallenpegasus.dreamwidth.org/&apos;&gt;&lt;b&gt;fallenpegasus&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;.  :-)  I used &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;http://foxfirefey.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;http://s.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;http://foxfirefey.dreamwidth.org/&apos;&gt;&lt;b&gt;foxfirefey&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&apos;s code because she&apos;s the first person I learned about the existence of Dreamwidth from.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.dreamwidth.org/tools/commentcount?user=omnifarious&amp;ditemid=270&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>http://omnifarious.dreamwidth.org/270.html</comments>
  <category>diary</category>
  <category>message</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>

