Monday, February 26, 2007
Announcing the SpeakRight Framework
Currently SpeakRight has only been tested on the Voxeo community site. It's VoiceXML 2.0.
A key part of the plan are "SROs". SpeakRight Objects are re-usable speech objects that, being open-source, should help encourage a growing body of components to build speech apps out of.
Can't wait to try SpeakRight out on Linux, and on MSS 2007!
Tuesday, February 13, 2007
Grokking StringTemplate
Update: I have corrected errors in the original post. Namely $if(it.CountIsOne)$ is the syntax for referencing $it$ inside an $if$.
First of all let's start with something that works. We want a field tag to output a prompt tag for each prompt in the list promptL Assume promptL contains an ArrayList of two strings "a" and "b". This is the XML we want (ignoring whitespace issues)
<field>
<prompt>some a</prompt>
<prompt>some b</prompt>
</field>
Here are the templates that successfully did this.
//generate the field tag
field(promptL) ::= << <field> $prompts(promptL)$ </field> >>
//generate atag for each item in the list. There are other prompt tags so we parameterize tagname
prompts(promptL) ::= << $promptL:prompt(tagname="prompt"); separator="\n"$ >>
//output a single tag
prompt(tagname) ::= << <$tagname$>some $it$</tagname>
>>
Now let's add one thing to the output and see what template changes are required. Let's say we want each prompt tag to have a count attribute that is "1" for the first tag, "2" for the second and so on. Like this:javascript:void(0)
Publish
<field>
<prompt count="1">some a</prompt>
<prompt count="2">some b</prompt>
</field>
This is easy. We can just use the built-in $i$ to do this:
prompt(tagname) ::= << <$tagname$ count="$i$">some $it$</tagname>Now let's say we want to output the count attribute only when the count is greater than "1". This is where things got tricky.
>>
This DOESN'T WORK. ST doesn't let you compare values in $if$. This would go against the spirit of ST whose goal is a strict seperation between presentation and model logic.
prompt(tagname) ::= << $if($it.count$=="1")$ <$tagname$ count="$i$">some $it$</tagname>Maybe we can replace the strings in promptL with Java objects that have a getCountIsOne method. We'll also need a getText method to get the string as well. Recall that $it.someFunc$ resolves in Java to a search for a method named getSomeFunc().
$else$
<$tagname$ count="$i$">some $it$</tagname>
$endif$
>>
This WORKS!. Just remember the syntax is is to leave the '$' characters off it when inside a $if$. You're inside $$ already.
prompt(tagname) ::= << $if(it.countIsOne)$ <$tagname$>some $it.text$</tagname>Another approach is template application. We change our Java method to getCountNotOne and have it return null when it's the first item in the list, and the count otherwise.
$else$
<$tagname$ count="$i$">some $it.text$</tagname>
$endif$
>>
This WORKS! We apply the template docountattr on $it$
prompt(tagname) ::= << <$tagname$ $it.countNotOne:docountattr()$>$it.text()$</tagname>Template application is powerful. You can pass parameters in as well.
>>
//a way of outputting count attr only when count not 1
docountattr() ::= << count="$it$">>
THIS WORKS!. We're applying the template prompt with two parameters tagname and bargeIn.
//generate atag for each item in the list. There are other prompt tags so we parameterize tagname bargeIn="$bargeIn$"
prompts(promptL) ::= << $promptL:prompt(tagname="prompt",bargeIn="true"); separator="\n"$ >>
prompt(tagname, index) ::= << $if(it.CountIsOne)$ <$tagname$ count="$i$" bargeIn="$bargeIn$">some $it$</tagname>
$else$
<$tagname$ count="$i$">some $it$</tagname>
$endif$
>>
Once you've grokked things, StringTemplate gives you excellent separation of presentation from logic, and is very good at extracting what it needs from ordinary Java objects.
Friday, February 09, 2007
Learning Java
And Eclipse is free. In fact, one person with a laptop, GMail, Eclipse, and SourceForge is the equivalent of a five person company from the 1980s.
Open-source software is unstoppable in many ways. You just can't compete with free. Software tool vendors have to keep moving into more and more niche areas. All the big ones, like source controls, IDEs, and bug tracking, are well covered by OSS. That being said, Microsoft has something like 50 billion dollars in the bank. They could not earn a cent for the next ten years and keep paying every employee. That's kind of unstoppable too!
Saturday, February 03, 2007
Daily backup of a laptop
(Be sure to get the latest version from Gerald's web site)
My app zips several important directories into zip files in c:\zip. Then, using a free account at box.net I upload the zip files daily. The free account has a limit of 1 GB and each file must be less than 10 MB. But for 5$ a month you get much larger maximums.
Not the finest solution; but it'll do for now. KISS.
Update: A Mozilla plug-in called GSpace turns your GMail account into a FTP site. Each file you upload becomes an e-mail. GMail now has 2.5 GB of storage.
Thursday, January 18, 2007
MySpace is Show Biz
"MySpace started small, with two Web servers talking to a single database server. Originally, they were 2-processor Dell servers loaded with 4 gigabytes of memory"
Again and again MySpace was re-written to add: replicated databases, SANs, ASP.Net, and 64-bit servers. One interesting lesson was the addition of caching
To further lighten the burden on its storage systems when it reached 17 million accounts, in the spring of 2005 MySpace added a caching tier—a layer of servers placed between the Web servers and the database servers whose sole job was to capture copies of frequently accessed data objects in memory and serve them to the Web application without the need for a database lookup.
This sounds a lot like what GigaSpaces is offering. It's a LindaSpace-like type of middleware that replaces a messaging paradigm with a associative shared memory approach. Intense caching and heuristics to move data closer to its clients.
Scott Rosenberg makes the point that Web 2.0 successes may look easy from the outside, but behind the scenes there are huge challenges. Like Show Biz!
Friday, January 12, 2007
Why to use code generation techniques
True, but validating, or what used to be called "laundering your input", still has to be done. Whether it's in the gatekeeper or the business object, the code has to be there.
But that’s really no way to write long-lived software, is it?Yes, it's fine actually. Who cares where the error message "producttype '4' not allowed" comes from. All that matters is that at any instant in time it either processes valid messages or returns a suitable error message.
If splitting validation code from the business logic represents a maintainability problem, then consider code generation. Frameworks like StringTemplate make code generation easy. CodeGen tackles the common problem that a feature requires changes up and down the software stack. The traditional way to do this was manually make all the changes and rely on comments and checklists to ensure all the required changes are done. With CodeGen you can use a more literate programming style. Define in one place, generate various bits of code, and inject it into the appropriate places in your code. Patterns such as Chain Of Responsibility help.
The Beauty of Unreal
I entirely agree with the audience targeting critique you make. I was thinking about the historical roots of programming, the social aspects, and how they must be considered, not just for fuzzy artsy reasons but for because they are part of the sociology of skills and attitudes that mold the field (we are the medium of programming).
I think programming has strong roots in telephony and in code-breaking and
in mathematics. These roots influence the need for interfacing at the hardware level,
efficiency and high abstraction.
The PC revolution is in a way an extension of the business view of data processing, which was very much separate from the scientific programming done on mini-computers. In fact now that I think of it, this may be why DEC missed the boat on PC's - PC's are for business and now are appliances, not really computers - but data processors (ironic given the PDP name - there's a story there...).
So what this guy is advocating is a reconciliation of these two worlds, a wrapper view. Not sure that can fly in social terms, for the reasons you identify, and because we have two worlds in software, the programming in the old telephony-coding=math sense and the data processing view with forms, HTML, windows and high-level object libraries.
Alan Kay's deep thoughts on similar topics are here:
I hadn't really thought about the two ends of programming like that before. I guess there are two cultures. Part of my confusion is from watching his SubText video, where he shows how it works. Although it meets all the aims in the manifesto (text-is-a-dead-end, don't-copy-and-paste, avoid-control-flow), the feel of video is very mathematical. It feels like LISP programming with recursion. Recursion is a strange concept to most people; like postfix notation. In this way SubText (as it exists in the video) is a failure for end-user programming. Ordinary users will prefer 10 PRINT "HELLO" style of programming.
Perhaps he can take SubText into more of a wrapper thing that works at the component level. Who was that guy in the 1980s -- Brad Cox, who talked about software ICs. Connect up the output of this algortithm to that report view...
Speaking of "Language Matters" and "It's usability, stupid", have a look at the Unreal Tournament Engine. It's become that gaming engine of choice for lots of top games. A very clean design with a virtual machine and a simple language, but extended with a few key gaming features, like states.
Unreal Engine architecture
Wednesday, January 10, 2007
Example-centric programming
End-user progamming is a dubious thing. It comes and goes as the Next Big Thing. The problem is that most people don't have the patience to write & debug software, no matter how wonderful the syntax is. Even something simple (to programmers), like control flow is a powerful and therefore dangerous notion. If you remove you drastically limit the expressiveness of the language; if you leave it in, people will stumble into the pitfalls.
End-user content, though is a killer app. My 10 year old son creates animations, web sites, and videos. A big part of video games now is the design-your-own-superhero. Choose body type, hair colour, clothes, etc. They often spend longer on it than playing the game. This isn't programming in a traditional sense. It's a type of visual programming where users assemble pre-existing components that know how to fit together. The components do the heavy lifting, while the user still feels they are "telling the computer what to do". And isn't that what programming is all about. Drag-and-drop telephony toolkits for IVRs are much the same :)
Tuesday, October 31, 2006
When more is less
The cry always went out for more machines, which arrived "clean" and ready to go. Of course, after a testing cycle the new machine could end up just as messed up as all the others. Later, when the next release rolled around it was "we need more machines" all over again.
Reminds me of the old tale about the workbench with 25 screwdrivers and a set of storage slots for the screwdrivers, but only 24 slots. In the beginning each screwdriver was in its appropriately marked slot. Except #25 which someone borrows. Then another worker borrows #15. When the first worker returns, he puts #25 into the only open slot, #15's slot. Then he borrows #7. Now the second worker returns and puts #15 into slot #7. Pretty soon all the screwdrivers are in the wrong slots. The whole storage system fell apart because of a single insufficient slot.
Monday, October 30, 2006
Even in Windows-land, OSS is here
Yes we still use Exchange, Visual Studio, and GotoMeeting.com. But in five years?
Tuesday, October 17, 2006
Ballmer on Vista
Then after XP they pinned the needle the other way, and a rewrite orgy began. It produced some good things. XAML is good. They completely rewrote Window's TCP/IP stack; which is quite an act of chutzpah, and now it supports multi-core CPUs in useful ways. But overall they ended up suffering exactly the sort of problems that a Big Bang approach would bring.
In a way it's a smart move though. Most people are quite happy with XP. Any next version had to be a long-term, next-generation thing. People will love Vista in 2009.
Wednesday, October 04, 2006
Estimating Software Projects
Two rules of thumb:
- Make a guess and double it. I find this one surprisingly accurate. Probably because I tend to work on the same sorts of projects; but then don't most programmers!
- Brook's book The Mythical Man Month says that every app has a core set of functionality that can be done in X weeks. To create a product will take 9X because of all the wrapper code for config/reporting/error handling, and all the user documentation that needs to be provided. People constantly underestimate this factor of 9.
The whole game of making & meeting estimates is about what features are "in" and what's "out". I like to tie estimates to an explicit list of what features users will and won't get. Requirements are bound to change, and managers sometimes have a habit of forgetting that your estimate was tied to a feature set.
As usual, Joel has written on this already.
Wednesday, August 23, 2006
You can't tune silence
Tuning is time-consuming because a human has to listen to the audio recordings of hundreds of phone calls. If the system can log speech rec errors, then the person doing the tuning can zero in on those utterances. If not, and we will see how this can happen, tuning becomes very difficult.
Out-of-grammar errors are the easiest to detect because the speech recognizer returns a NoRec error. These may be due to coughs, background noise or other audio problems that grammar changes can't fix. Others are due to variations in pronounciation that your grammar doesn't know about. People's names are notoriously hard this way because: (a) names are multi-lingual in origin, and (b) many people will mis-pronounce a name they've only read. We had a Mr Biber here, pronounced bee-ber, but many people would say bye-ber. Tuning revealed this, as well as the fact that some people would say only the last name. The grammar needed to be changed to cover all these possibilites.
The more difficult problem is what we call the Rumplestiltskin error. Most speech engines want to recognize. Try saying "Rumplestiltskin" to a speech-rec auto-attendant. You'll be suprised at how often it will find a (wrong) match. Saying something completely outside the grammar will cause a medium-confidence recognition of some wrong word in the grammar. Of course you can affect this by raising the recognition and confidence thresholds, but that may cause other unwanted recognition problems. Confirmation, for example, is an added step in the dialog that callers can grow to resent. The problem with a Rumplestiltskin error is that it's invisible; the system really has no knowledge that a recognition error has ocurred. This makes finding the error a time-consuming task for the tuner. The caller may be saying an acceptable alternative for a word, but until we discover this and add it to the grammar, the system will not be pleasing this caller.
Tuning becomes a big problem when dyamic grammars are used, because you can't do any pre-deployment tuning. The app will read a list of phrases from a database, say Little League team names, and generate a grammar. Consider the "Nowell Gnats". It's not unusual for the TTS engine to pronounce a word differently from what the speech rec engine accepts as a pronounciation. This is bad because your prompt may say it as "you can say Nole Nats..." whereas the speech rec engine wants "Now-well Nats".
It's easy to end up with a situation where the app won't accept any sensible pronounciation for a word, and even tells callers the wrong pronounciation to use! All without generating any recognition errors. Silent failure.
Can the speech rec platform help? Yes, here are a couple of ideas. First, the app should have "tuning mode" that can be set temporarily. It increases reco thresholds to force more confirmations, and logs all rejected confirmations as candidates for tuning. Secondly, the system should have a batch process that studies patterns of calls. If the same person calls back in several times in a row and never seems to complete a transaction, then these calls are also tuning candidates.
Tuesday, August 08, 2006
Bye Bye Speech Server -- Hello SPS
I have fairly mixed views about this move. First, the negatives. Yet again, Microsoft is making a mid-course correction with their speech offering. At the beginning the vision was multimodal speech. Then it was telephony-based speech rec by web developers (by sprinkling "SALT" on their web pages to speech-enable them). Then it telephony-based speech rec using more standard methods, such as VoiceXML. Now it's speech rec as part of an enterprise information system. For developers actually trying to build applications, all these course corrections are unnerving, to say the least. If the overall goal, as Microsoft says, is to create an "ecosystem" then they need to realize that stability is a key factor. Wandering climate change isn't helping.
Now the positives. OCS is a strategic product for Microsoft. Communication is becoming a key part of every organization. Communication across devices. Synchronous and ayschronous communication. Features such as: presence, IM, VoIP, video, Find-Me, Follow-Me, and ad-hoc conferencing. Think EMail++. For speech rec to be bundled into such a strategic product is a huge win. It also shows that the speech folks at Microsoft have been listening and learning. Changing course often works out better than not changing course!
Lets hope the transition to OCS is as seamless as possible for existing MSS speech developers.
Nice Clutch Play by Microsoft
Turns out it was a Longhorn bug with its audio software. Today Rob did the demo again, at SpeechTek no less! Eight minutes long and it worked fabulously. It was a nice comeback and a gutsy move -- way to go guys!
Friday, June 16, 2006
Charlie Wilson's War -- Book Review
Charlie Wilson was a Dem senator from Texas. Most of the book deals with his efforts in Washington to get funding and support to his beloved mujahadeen. Washington is revealed not as a massive beurocratic system, or machine; but as a personality driven clique. One person, with the right skills (and Mr Wilson seems to have been a master), can find and grab the levers of power over literally billions of dollars in funding.
The other feature is the Alice-in-Wonderland nature of the world of the 1980s vs today's post-911 world. Then it was the Soviets who invaded a muslim country and faced a fierce insurgency. The US supported the insurgency at the urging of a Democratic president.
They supported (and were cheered) by fundamentalist jihadis, giving them secret weapons for attacking convoys and shelling bases.
One interesting question regarding today's Iraq is the lack of a Stinger missile. It made a huge difference in the Afghan war; as it would in Iraq. Strange that twenty years on there aren't tons of Stingers and its imitations available on the black market.
A movie is being made of the book.
C# Cookbook -- Book Review
MSDN is great if you already know the name of the class or function that you're interested in. But if you don't, then it can be very hard. Date formatting, for example, is under string.Format() instead of under DateTime.
C# Cookbook is goal-driven. Each topic, such as "Writing a TCP Server", "Increasing StringBuilder Performance" or "Creating a Priority Queue" is a full solution to a programming problem. It covers C# 2.0 so generics and anonymous methods are covered.
Put it beside your desk. Read ten snippets a day, and in a month you'll be a better programmer.
Wednesday, June 07, 2006
Eating with Kids at the Bar-B-Barn
The kids couldn't believe we were planning to eat in this low-ceilinged room with creaky floors and exposed heating ducts. My older son couldn't get over the menu. He kept asking "But there's only two items on the menu?". Yes, I'ld reply: chicken or ribs. "Just two things!?" and "Is that really it?" For someone used to the multi-page menus of a typically eatery, it blew his mind.
Son #2 is precise and his criticisms were detailed: the ribs had too much sauce, the fries were too long, and "this bun sucks!". Summing up, he concluded that "at least a crappy restaurant could have better lighting". Needless to say this sort of side commentary dulls the enjoyment of the others at the table. But we all got through it, and the food is actually pretty good. A broadening experience; for when I asked days later if they had told their friends about the Bar-B-Barn, they said "it wasn't that bad."
Friday, May 26, 2006
The Joy of Ethereal
Whoever thought up the idea of human-readable message protocols should get a Nobel Prize. Protocols like SIP, HTTP and RSS are so much easier to troubleshoot because of this. The bad old days of RPC, ASN.1, and ISDN are hopefully nearly gone.
Of course, security may force encryption of the human-readable protocols : so we may end up back where we started...
Wednesday, December 07, 2005
Memory leaks in .Net
The culprit is async sockets.
The the buffer we pass to Socket.BeginReceive gets "pinned" in memory, preventing GC memory compaction. Since all new allocation uses the top of the stack, .Net has no choice but to keep allocating more Private Bytes.
Here's a thread about someone else having this problem
http://groups.google.ca/group/microsoft.public.dotnet.framework/brows...
Strangely, the addition of a Thread.Sleep(1) seems to make the memory
leak go away.
Basically, here is the BeginReceive callback function:
void AsyncReceiveCallback(IAsyncResult result)
{
VeoAsyncIOInfo thisConnection = (VeoAsyncIOInfo)result.AsyncState;
int num_read = thisConnection.m_socket.EndReceive(result);
if (0 != num_read) {
ProcessNewData(thisConnection.m_buffer, num_read,
thisConnection.m_socket);
}
Thread.Sleep(1); //hack hack hack
thisConnection.m_socket.BeginReceive(thisConnection.m_buffer, 0,
MAXMSGSIZE, SocketFlags.None, new AsyncCallback(AsyncReceiveCallback),
thisConnection);
}