Cyril Brulebois: Snowing
0x2603,
0x2744, 0x2745, 0x2746.
(Not.)
0x2603,
0x2744, 0x2745, 0x2746.
(Not.)
Gintautas
Miliauskas blogs about a computer program that can generate
something which reportedly really sounds like composer-written music;
apparently it has passed a 'turing test' where people listened to music
generated by this thing, and music written by a human composer.
I'm afraid, however, I'll have to disappoint him a bit, really.
If we ignore the effect that music can have on the emotional state of a
living being for a moment, then it's a plain and simple fact that music
is pure math:
Thanks to Koha, TTLLP is partly a library services worker cooperative and just now there’s a massive flame-storm about the largest library services consumer cooperative - OCLC, the Online Computer Library Center - because it just updated the terms for sharing its book data collection. OCLC seems to be treating it as a private asset that it can exploit, not the common resource that many librarians thought it was. I’ve been watching this fire with interest - because, at best, I don’t think it’s helping other cooperatives that sell to libraries - and here is my summary.
OCLC and the Great Library Scandal is a good introduction and there’s a summary of the Talis Podcast about OCLC WorldCat Record Use Policy with Karen Clahoun and Roy Tennant which reveals some of the OCLC thinking.
Just like CC and Open Source? Still No is a great illustration of how some librarians think OCLC is reaching the wrong conclusion, which then leads to asking Is OCLC truly cooperative? and What would it look like if OCLC was broken up?
A commenter on Tom Watson: Library data asks: “Why would libraries play this game?” Well, the road to hell is paved with good intentions and this road has taken 40 years. First off, OCLC is essentially a good idea - libraries cooperating to act as a counter-weight to the large library service companies.
However, I believe OCLC predates many recent company rule innovations (stronger common asset locks) and data licensing innovations (Share-Alike, Fiduciary Licensing and the general free and open source software movements), so there’s nothing to stop them trying to privatise the assets (library data) that the libraries have given to OCLC and it was only a matter of time before someone tried.
I’m having a similar discussion with another organisation that has been given data by its members under vague terms and is now apparently about to exploit that data for the organisation’s benefit, to the detriment of some members. TTLLP is a member but has not contributed much data because I was suspicious of the lack of terms.
In time, hopefully, asset locks and more awareness of data licensing will eliminate these problems, but there’s going to be a lot more people getting burnt first.
Finally, a quick shout-out to the Open Library Environment as a possible emerging alternative to OCLC for practical services. Raw Thought: Stealing Your Library: The OCLC Powergrab covers some of its motivation (and includes a link to a petition to OCLC, if you want something to sign), but I share Stefano’s (now there’s someone I’d not read in 7 or so years) analysis of some of the challenges:
“any grass-root approach that will get big enough to take on OCLC on the metadata collection and redistribution service that libraries need will have to incorporate under the pressure of its users (if only for legal liability protection) and will have to find an answer to the same set of problems (policy, governance, financial sustainability) that OCLC has.”
This might be a good message to write in Spanish... But then again, a long time ago I decided this is an English-posting site. So be it, I'll only have to give more background information.From 12 by
Effective immediatly --
If you're annoyed by the spelling of something I've written,
I will accept a patch -- preferably generated by git-format-patch,
but diff -u is also acceptable.
Any other communication about spelling mistakes will be ignored,
unless the mistake has ramifications that will cause undue pain and
suffering to people who are not English majors.
Furthermore, if the spelling "mistake" is that I spelled "-ize"
as "-ise", it's not a mistake -- I prefer to use the latter form
for obscure reasons, with a few exceptions.
PS,
I realise that these are entirely arbitrary rules forced upon you
willy-nilly. Teh irony..

(Written on Friday 16th, posted on Monday)
As I write this, I'm on a plane off the coast of the Netherlands, on the way back from a couple of days designing APIs with Rob McQueen and the RTCom people at NRC Helsinki (who we work with on the chat and VoIP functionality for Nokia internet tablets).
We've had a very useful couple of days, mainly designing the next-generation channel requesting and dispatch API for Telepathy (the same APIs I've been doing preparatory work for on the Telepathy mailing list in the last couple of weeks). API sketches for review and comment are either on are on Merge Monkey or on the way there.
Before even reaching Nokia, Rob and I did a lot of design on the plane over to Helsinki, and I took some notes: here they are, by way of a glimpse at how the Telepathy design process works when we don't have a whiteboard[1] :-)
- Geoloc looks good in principle, needs some more work
- add more docstrings
- add a way to ask people for uncached info (RequestLocations)
- move access control to Co.I.Presence, call it RichPresenceAccessControl?
- DeliveryReporting looks good, ish
- improve wording of delivery-echo and rationale
- when sending a delivery report, add a reason for the status (using Channel_Text_Send_Error?)
- Uniqueness requirement for (channel, handle_type != 0, handle) is in the way - let's drop it
- MSN should use "authentic" 1-1 chats, and use Ch.I.UpgradeableToRoom (name tbd) to migrate the underlying switchboard to be a room
- XMPP should use Ch.I.UpgradeableToRoom too, but the 1-1 channel may also stay open
- Mutable handle => handle 0 must stay (for requestotron's benefit)
- bundles ftw
- renaming: we want SelfHandleChanged in the core
- TpC* - add ability to subscribe to ifaces ay construct time (blocks Ready) or later
- Dispatching: when registering a c'handler, specify everything it can handle
- If a new bundle can be handled in its entirety by the same handler (call it 'the bundle handler'), do it. Otherwise split it up completely (there is no 'bundle handler').
- If a channel in an existing bundle can be handled by the bundle handler, send it there, else send to the default handler.
- Group - add SelfHandleChanged, maybe? Also Connection
- Add HandleOwners: prop a uu , HandleOwnersChanged(a uu , au)
- Use TargetHandleType, TargetHandle
- Stringified initiator handle as a separate property
- Maybe even a FirstMessage property, although this stretches the definition of "immutable"
- org.freedesktop.Telepathy.Client interface
Nokia's Mikhail Zabaluev kindly took notes for some further discussion we had with him and Alberto Mardegan about the dispatch API, which he already posted to the mailing list.
We hope this API will make it possible to integrate Telepathy into the desktop better - it should make it a lot easier to share connections between processes in a useful way and hand out incoming channels to the appropriate handlers, which was always a major goal for Telepathy. It should also let us and others implement exciting new notification mechanisms (hi to the people on IRC and the mailing list wanting to patch their media players to integrate with Telepathy! :-)
| [1] | When we do have a whiteboard, the design process is: "Robot101 scribbles on a whiteboard, smcv writes down <tp:rationale> elements" |
--exclude Packages* --exclude Sources* --exclude Release* --exclude ls-lR*The first stage must not delete any files. The second stage should then transfer the above excluded files and delete files that no longer belong on the mirror. Rationale: If archive mirroring is done in a single stage, there will be periods of time during which the index files will reference files not yet mirrored. And that will lead to a lot of confusion for our users.
I opened my eyes this morning at 7:00, and immediately felt he was also awake. He got up and briefly wandered around. I felt this incredible expectation, even while barely awake. Something important had happened. As he returned to bed, I asked Who won? . Monsieur Obama , he replied as he slipped back into bed. I broadly smiled and he cuddled up against me, hugging me from behind. I peeked through the open bedroom door and could see the cats smiling in the living-room. Still one more hour before I had to get up for work and life was already good. That early in the morning! Definitely good.
(or Taxation without Representation)
Wow, it's finally over, and best and right man won. I'm very excited and
happy with the result.
It has been very interesting being able to observe the entire process from
start to finish. All the primaries and caucuses, the protracted battle
between Clinton and Obama in the Democratic primaries, the record breaking
money Obama raised, the campaigning, the misinformation.
It'll be very interesting to see what the next four years brings. It's an
exciting time to be living in America.
California is an interesting state. It has "ballot initiatives". Its
constitution can (and has been) amended by essentially referendums whenever
there's some other excuse for a vote. Anyone can propose a ballot initiative
with sufficient backing by petition. Wikipedia has a good writeup of all of
California's
propositions. Probably the most controversial one this time around is
Proposition
8, which seeks to essentially reverse the same-sex marriage right that
the Californian Superior Court ruled on earlier this year.
This concept of ballot initiatives seems to trickle all the way down to the
city level, where they're called Measures. San Francisco has some ridiculous
number of them this time around. They use letters, and I think they go all
the way to V. There's one to rename a sewage
treatment plant after George W Bush, there's one to decriminalise
prostitution. A co-worker who lives in San Francisco brought the official
voter guide book to work with her today. It's about the size of a phone book
and about 1.5 centimetres thick. I don't see how it's possible to make an
informed decision on everything you're expected to vote on, when there's
that much reading.
The observation I've made is that Americans seem to have an inherent
distrust of their governments, so that's why so many bits of it are directly
elected by the people. Judges are voted for, county sheriffs are voted for.
You vote for your school board. It seems like very few positions of any
power are appointed by someone.
Coming from Australia, where it's really the opposite, I'm not sure what I
think is better. I think I like the simplicity of the Australian system. You
vote for someone, and you essentially delegate power to and place trust in
them.
Everyone must submit himself to the governing authorities. . . The authorities that exist have been established by God. . . Consequently, he who rebels against the authority is rebelling against what God has instituted, and those who do so will bring judgment on themselves. For rulers hold no terror for those who do right, but for those who do wrong. . . Therefore, it is necessary to submit to the authorities, not only because of possible punishment but also because of conscience.

class Server < Struct.new(:host, :port, :password)
def to_s
port == 6600 ? host : "# host :# port "
end
end
That particular one's from Njiiri (which may clue you in that it took
me several months to get around to writing this post). For educational
purposes, it's nice: you can point out how we give a name to a class
(I've also tried to explain assignment as "naming" rather than
"storing"), that there's an unnamed class (classes are also objects!),
and overriding a method (which uses the dynamically defined stuff),
without any boilerplate to get in the way.
So it's tempting to use this in a lesson. Unfortunately, Ruby is a
little bit weird here, and you run into those distracting "practical"
issues about the particular language you're working in. Your classes
can't subclass Class, and thus you can't say Foo.new like you can
Struct.new. Struct is actually implemented in C (or Java, or
whatever's native). So you have to do some handwaving.
This is because the "metaclasses" we have in Ruby are implemented, so
to speak, as singleton classes of objects (including class objects). I
do not mean this as a criticism of Matz at all, but they seem like
more of a serendipitous thing than an intentional design -- "hey, if
we implement classes in this particular way, we get this sort of
metaclassing automatically [1]." (The clearest explanation of why
this is that I've found is in the first chapter of Advanced Rails
by Brad Ediger.)
I wanted to be able to just subclass Class, rather than have all that
fun power that we normally get to abuse in Ruby, only because I think
this is the clearest way to explain the abstraction. Even I still have
trouble describing singletons in plain English. Struct is intuitively
a class of classes, and factors out similar/boring stuff -- a good
practice. It could be an example of how to refactor some simple
classes, if only we could follow it.
I decided to give up on the idea for my tutorial, but it kept me up at
night. Ruby metaclasses clearly can do anything that the sort of
Struct-like metaclasses I have in my mind -- "parametric" classes, if
you will -- can do, and I can dynamically define just about anything;
why not make it happen? We can instantiate Class itself, but the
tool we have to shape that class is singleton methods. This can
certainly be abstracted away. So, I whipped something up.
Before getting to it, though, let's visit a new construct in Ruby
1.9 and 1.8.7: Object#tap. Apart from the obvious debugging use
described in its documentation, it makes it quite easy to factor out
this pattern:
def gimme_a_thing thing = Thing.new thing.do_stuff_to_it thing endInto something closer to the style of functional or declarative programming:
def gimme_a_thing
Thing.new.tap thing
thing.do_stuff_to_it
end
end
(Well, "do stuff" is obviously still procedural, but A for effort.)
Which one is "better" could probably be the subject of much debate,
but: I really prefer the second one; even though it has exactly the
same effect, it looks like "what" rather than "how" (something else I
try to beat into impressionable young heads. :-)), which is I think
easier to write tests for. I'm going to use it here, because it's
shorter.
Now, Object#tap passes the object as an argument to the block; in our
case, we are going to define a metaclass, so we want to work with
self, instead. So we define a new version, class_tap -- by
analogy with class_def, I suppose --- which class_evals the
block rather than simply evaluating it:
class Class
def class_tap(&blk)
tap _self _self.class_eval &blk
end
end
And to do the following trickery, we make use of MetAid, written by
why the lucky stiff -- it's very small, so we could always just
incorporate the bits we want into the code here, but this short file
provides a common vocabulary for talking about metaclass stuff which
is quite valuable.
Now, we can write a method to create our new classes on the fly.
Here's what I came up with:
require 'metaid'
class << Class
def meta(_super=Object, &blk)
new.class_tap do # 1
meta_def :new do *args # 2
Class.new(_super).class_tap do # 3
class_exec *args, &blk # 4
end
end
end
end
end
(Note the "class << Class", opening the singleton, rather than
"class Class", opening Class itself. Also, the distinction between
new and Class.new -- they are the same method, but from inside
the meta_def we're no longer in the Class class.) The lines of
meta itself mean:
Nary an assignment in sight! The (embarrassing) caveat is that methods in the block that defines the new class instance cannot use def to create methods as normal. A def is evaluated in a totally fresh scope (I don't think I get the opinion behind this decision, to be honest), so we need to use class_def instead. This is, I must admit, rather hideous. Perhaps someday the language will change. But, first things first: now we can implement Struct in pure Ruby.
- The value of this thing is a generated class, which we will describe thusly:
- Its singleton class has a new method, which gives you a value that is:
- Another generated class, which is defined by:
- the original block, which now gets run with new's arguments.
class MyStruct < Class.meta \
do *args
attr_accessor *args
class_def :initialize do *instance_args
args.zip(instance_args).each do attr, val
instance_variable_set :"@# attr ", val
end
end
end
end
The real Struct class does a few other nice things for you, but this
is the heart of it; I can go back to that Njiiri example and just swap
in MyStruct for Struct (Providing an instant performance gain
of -200%... :-)).
Here's a "shapes" example from my abandoned OO lesson:
class Polygon < Struct.new(:sides)
def perimeter
@sides.inject(&:+)
end
end
class RegularPolygonClass < Class.meta(Polygon) \
do n_sides
class_def :initialize do side_length
@sides = [side_length] * n_sides
end
class_def :area do
@sides.size * @sides.first**2 / Math.tan(Math::PI / @sides.size) / 4
end
end
end
class Square < RegularPolygonClass.new(4); end
class Pentagon < RegularPolygonClass.new(5); end
(Note that area has no free variables and thus could actually be
defined with def. It would just look funny.)
You only have to change one number here to make new polygon classes,
rather than accumulating parameter lint or explicitly subclassing and
redefining something implicit just for the derived class [2]. In a way it
the exact analogue of the imperative vs. tap style described above.
There is quite a bit of aesthetics involved; one way is not "right".
Apart from the syntactical wart, I like being able to do things this
way. Ruby is, as they say, optimized for programmer happiness and the
principle of least surprise. Still, I'm sure it is quite slow, and
I don't particularly need it for any real-world application right now.
For an intro to OO it's way too much complexity to have lurking
unexplained beneath the surface and still requires getting bogged down
in the language you happen to be using. But hey! It's neat.
| [1] | I basically try to do this whenever possible, anyway. Design decisions are like sex: they're better when they're free. |
| [2] | Of course, if Ruby class variables were not leaked across the entire inheritance hierarchy, something as trivial as this one-variable example would be... trivial. At least, few people would actually miss metaprogramming features. Blub blub blub. |

| [1] | Incidentally: Linode has been great. Highly recommended. |
| [2] | Also: yeah, I know my footnotes are broken. Working on it. |
The Debian Lenny release has still quite a big list of Release Critical bugs, and as Debian developer I feel that I should do my share, and at least look at the list of bugs and see if there's any I could do something for.
I'm now reaching the very bottom of the Debian
localization radar that points out packages with pending debconf
l10n bug reports.
About 20 packages are currently still under work (either waiting for
the maintainer's answer, or in a translation update round...or waiting
for the package to go out from DELAYED).
That should be completed in about 10 days. The remaining packages are
those with very recent l10n bug reports and I can't decently nag
maintainers for bugs sent since less than one month.
The result is now that we have 3 languages that reached near 100% completeness: German, French, Portuguese. Czech is over 97%. Swedish has been dramatically revived and now over 85%. And some more translation teams such as the Basque, Russian, Italian and others have taken this last opportunity to get as many translations as possible in the game.
The overall quality of several packages I NMU is not optimal. I often refrained myself from trivial fixes as this is not the policy during freezes but that's really sad.
I might initiate a QA NMU campaign when we enter the squeeze
development round, to fix all those trivial lintian warnings (obsolete
debhelper compat level, maintainer scripts ignoring errors,
debian/rules ignoring make errors, typos here and there, etc.)
Anyway, once this l10n NMU stuff is done, the question becomes: what will I do now and until we release lenny?
Maybe come back to the French translation of the Developer's Reference which I worked on during the trip to Debconf8, then left aside since then....
Spent last weekend in Mountain View where Google had invited a number of
mentors for the Summer of Code
project that Google once again graciously sponsored. A rather impressive
list of projects sent up to two people each, giving a probably unparalled
sample of major Open Source projects.
I had a blast. Chris, Leslie and the rest of the Google's Open Source
Programs Office facilitated a really nice
unconference
that spawned a few really nice sessions, and they took very good care of us.
And just about everybody met a number of folks in person that were previously
known only via email or irc. As the saying goes: nothing like the bandwidth
of a face-to-face meeting...
Last but not least I should issue a health warning. Sharing a room with the
fearless Debian DPL is not for the faint
of heart: His snooring is truly world-class.
Next.