Saturday, May 12, 2012
Monday, May 07, 2012
PARTICIPANT:This guy did not make it.
[Reading names of classes]
Binary reader, Buffered stream, Reads and writes...
[Pauses, Scrolls through list of classes].
So let me just...stream writer. Implements a text writer writing characters to a stream in a particular encoding. Umm...stores an underlying string. Text...hmmm. Text reader, text writer. Represents a writer that can write a sequential series of characters. This class is abstract.
[scrolls up and down through list of classes]
So it, you know, it sounds to me like it's, you know, it's more low-level kind of stuff. Whereas I just want to create a text file. Umm.
[Points at the description of one of the classes]
Characters to a stream in a particular encoding. I'm not sure what...obviously a text writer for writing characters to a stream.
[Clicks on the link to view more details about the TextWriter class. Then looks at list of classes that derive from TextWriter]
System dot IO dot StringWriter. This seems too low-level to me to be a text writer thing but maybe I am wrong. Umm...
[scrolls through description of the TextWriter class]
Text writer is designed for character output, whereas the stream class is designed for byte input and output.
[Sigh. Clicks on link to view TextWriter members]
Probably going where no man should have gone before here.
Neither did any of the other 7 professional programmers that were participants in that experiment! Their task was "to write a program that would write to and read from text files on disk". They had 2 hours for that and could browse all of the relevant documentation. They were testing the API of the then new programming framework called .NET - the programmers did not know it yet - but they had programmed in VisualBasic. This is an example code fragment using the file writing API that they were expected to write: After that experiment they added a new 'File' API: and ran the experiment again. This time all participants were able to complete each task in 20 minutes and without browsing the documentation. This is the story from the "Chapter 29 How Usable Are Your APIs?" in Making Software.
Fascinating puzzle - isn't it? The article proposes following solution to it: there are three types of programmers - opportunistic, pragmatic and systematic. The opportunists tend to use the high-level abstractions and try and experiment with what would work and they intuitively get the File API as opposed to the
StreamWriter API. And it just happened that all 8 participants of that study were opportunist programmers?!
The developers who participated in the file I/O studies were very much in the opportunistic camp. The way they used theSounds like a weak argument:
FileObjectclass in the second study was almost a perfect example of opportunistic programming. The contrast with the more abstract classes they had to use in the first study was stark. Indeed, one of the main findings from the file I/O studies was that without such high-level concrete components, opportunistic developers are unlikely to be successful.
- Copy pasting examples and playing with the code is the most efficient way to learn a new API - so I suspect that what they call 'opportunistic programming' is actually learned behaviour that would be characteristic of any experienced programmer.
- Expecting a file related API sounds quite natural and not really related to being opportunistic or systematic, the task at hand was exactly file related IO and in most programming languages there is such an API, it also makes sense that there is one because file operations are very common.
- I don't see anything higher level or more concrete in the
FileObjectrelated example code - it looks on the same level of abstraction as the
StreamWritercode. The authors claim that it is the fact that you have both
StreamReaderthat makes it lower level then
FileObjectwhich is only one - but I don't see how that follows.
Wednesday, May 02, 2012
- Overloading and parameter types validation.
- Clash between overloading hashification and arrayification and the
valueswith the new dereferencing semantics.
- There is no way to know if you received characters or binary data, lots of libraries and even core functions work differently in these cases - but often it is not documented.
- In Perl observing a variable changes it - for example - reading a variable containing a string in a number context will fill in its number slot (as far as I understand it - see perlguts for the details). Normally it does not matter - but it makes threading less efficient (because shared variables need to go through additional loops to work).
$character makes the one making checking
$@after eval unreliable.