|
demos
Lately I write demos under thorn with a todo list using C++ under a BriarPig mu-babel license. The run and hex demos were done on 13apr2008; crc on 14apr2008; buf on 20apr2008; in on 27apr2008; ctype on 04may2008; out on 18may2008; slice on 25may2008; quote on 31may2008; escape on 31may2008; mutex on 14jun2008; rand on 16jun2008; stat on 17jun2008; primes on 19jun2008; list on 23jun2008; heap on 29jun2008; iter on 02jul2008 and 04jul2008; atomic on 06jul2008; node on 13jul2008; page on 23jul2008; hash on 27jul2008; book on 27jul2008; pile on 03aug2008; stack on 07aug2008; mu on 12aug2008; toy on 16aug2008; weight on 23aug2008; symbol on 02sep2008; imm on 04sep2008; gc on 06sep2008; map on 14sep2008; meter on 16sep2008; thread on 22oct2008; arc on 05nov2008; this menu links all demos: mu: toy, peg, imm, tag, box, symbol, token, number, bigint, class, method, reader, writer, eval, env, vm, gc, world, pcode, compiler, asm, lathe, lisp, smalltalk, design, weight, jar, card, harp, debug, profile thorn: todo, names, iovec, assert, log, run, hex, crc, buf, in, out, quote, escape, compare, file, deck, cow, arc, blob, tree, slice, rand, time, stat, heap, node, primes, page, book, pile, stack, atomic, lock, mutex, thread, map, list, iter, ctype 27jan09
¶
best laid plans
fingerprinting ¶ I found what I was looking for at work: a fast content-based way to identify data, with very high probability of sync after changes on many data populations. It's more effective than I hoped, and less involved than I feared. Best of all, on most data sets it does exactly what I wanted, enabling my next big design, which presumed I could find something close to ideal here. Now the design works. But I must not tell you how it works. You know how it goes: business is business. I must also refrain from spelling out the problem very clearly, since without a search path you can't find it too without reconstructing context. But it's not obvious even after knowing what you want. The algorithm turns a fuzzy and probablistic problem into an exact outcome saving both time and space. In a problem where you expect N similar or equivalent things, there's only one — which works in constant time. Now I can avoid major amounts of i/o and comparison. If anyone else had done this, we'd know already. I'm just happy; I don't mean to tease you. 25jan09
¶
cats singing karaoke
email proposals ¶ I spent about an hour this afternoon writing email exchanges between Koi Flywheel and Zé Thorn, along lines I designed several months ago. This is my next installment of fiction, presented in the form of Eli asking Zé questions about an email record kept in the group's wiki. The emails consist of part of an exchange between Zé and Koi, when Zé pitched the idea for his project in a bid to win angel investment from Flywheel. Of course, this is all perfectly obvious from the fiction — I'm just telling you what I was doing briefly this afternoon. I decided to include their fictional email addresses: ze@thornhog.com and koi@eflywheel.com; as of this afternoon, neither of those domains currently exist. (But I would not bet that remains true. Domain names have a strange tendency to become used once mentioned.) The reason I use emails to describe Koi's involvement is quite simple: omniscient point of view ruins the occluded view Zé is forced to hold when knowing only what Koi says, and whatever else Zé can infer. The idea, of course, is to allow readers to infer more than Zé does at first. Telling you this doesn't change how you'll read the story, as near as I can tell. Otherwise I wouldn't say this now. bioshock again ¶ Instead of writing more fiction, or drafting dialogs about interpreter top-down contexts, I watched my older son play Bioshock for a couple hours this evening. He only made it part way through a few months ago, before getting distracted with other games. Visually the game is quite interesing, and it's fun to watch someone else play. But sometimes I grit my teeth when my son — let's call him Tyr — doesn't mini-max resource expenditures to get amplified benefits. I don't recall us saying anything very funny during game play, however, so instead I'll tell another older anecdote Tyr told me recently about a couple girls at his high school. (See how I'm making a segue into a new, barely related topic, with nothing in common but Tyr as a participant? What's my underlying message here? Aha, I must be saying anecdotes about children are part of every day life, or something like that.) Anyway, one day as Tyr walked down the hall in his high school, he came upon a pair of girls standing in front of a memorial display in the school — the usual list of names immortalized in bronze kind of deal. Just as Tyr arrived, one girl turned to the other and asked, "Are these the names of people who died in the Seventh World War?" Tyr immediately boggled at seventh, expecting the other girl to cut her to the quick. But the other girl replied in puzzlement, "I thought there were only five world wars." The way Tyr tells the tale, the word idiot occurs often. I asked Tyr whether the girls had seen him coming, then staged a farce for his personal benefit. He said certainly not: they had no idea he was a witness to this exchange. But I'm not sure he fully understands sense of humor in teenage girls. As an exercise for the reader, construct a forced relation between retro video games like Bioshock and staggering ignorance of world history in teenagers. (There's really no relation except all the actors are teenagers — so there's no conclusion, because there's no theory to test.) 24jan09
¶
mental prisons
interpreter contexts ¶ "Can you tell me about interpreters?" Eli asked Wil. "I want to do one myself: I heard your idea to use lathe as a scripting tool driving systems you write in C++ for unit test purposes, and said, yeah, that sounds good." "That's a large topic," Wil equivocated, scrunching his forehead in thought. "Why do you want to roll your own? Just go download somebody's programming language and be done. There's a bunch of good ones." "I want to learn how," Eli admitted. "I started reading source code for a couple toy languages. But it's hard to understand. I think I'm missing basic ideas that implementers assume in designs." Wil slumped back in his swivel chair and exhaled slowly, suppressing the urge to grimace and rub his face because Eli would read this as evasive and unfriendly, when Wil didn't mind particularly. "The question is, why don't you use someone's existing programming language?" Eli needled. "I suspect once you explain I'll have similar motives myself. You think there's a pitfall and you're not sharing, right?" "Yes," Wil granted. "Astute observation. But pitfalls for me might not be problems for you, if you aren't solving similar problems. Most of my issues with existing language implementations are in assumptions that business as usual is fine, since some normal convention hurts me." "So you're special," Eli casually accused. Wil gritted his teeth. "Some examples might help. Most languages assume sync method dispatch — they don't return before finishing — but I need async support when what I test is async and won't dependably reveal issues in presence of unbounded latencies or to predictable timing and execution order when most code is sync." "That went right over my head," Eli made a cutting motion over his head using one hand. "But you said async — do you mean you want more non-blocking api?" "Yes," Wil nodded. "Async means non-blocking as well as concurrent with unpredictable resolution orders." "Can't you write async support in any language?" Eli puzzled. "Everyone has non-blocking libraries." "Yeeess," Wil said slowly. "But when a language is mainly synchronous, it easily hides under-the-covers sync behavior where it's hard to see and audit. For me to really get a handle on some kinds of async code, I pretty much need to know what's happening all the time. When I ask, 'What runs between point A and point B in this code?' I have to be able to figure out the answer with few provisos — total transparency would be best, with no machine code running I can't see. If you like, think of me as needing to audit down to assembler, or C as a close approximation." Eli was flabbergasted. "Why not just use C and C++, then? How can you get away with using a high level language at all? Why use a scripting language?" "Now you're asking the right questions," Wil approved. "Okay, so I write a lot of low level systems software used in, for example, networking code which is highly async and acutely time sensitive: it has to go like blazes. Think of it as little nano scale engines, methods running in nanoseconds instead of microseconds, with very high frequency. Both definition and api get intricate, even when I aim for the simplest possible thing. Async adds much complexity all by itself. Then problem is, it only gets called by higher layers with intricate complexity itself. These layers don't manage to exercise a full range of permitted behavior, for several reasons including patterns in call sequence clustering as well as partial feature sets until late in a dev cycles." Eli's eyes got big. "You're saying your code doesn't actually get exercised fully for a long time, and absence of full code coverage allows bugs to live a long time?" "Yes, or if not bugs, then open questions for a long time," Wil confirmed. "If I make a mental checklist tracking what actually gets exercised, it takes forever to hit every spot, and some never get reached." "So what would you use a scripting language for, again?" Eli asked. "Did you say already?" "I want to replace the entire high level app with a scripted simulation," Wil said. "Holy cow!" Eli exclaimed. "You want to whip up a draft version of what all the engineers on your team are doing as a group? By yourself?" "Yes," Wil looked sheepish. "So I can test what will happen when the C app is done, but before it's done enough to test my code, because by the time they learn enough to ask whether my code is perfect, it's already late in our release cycle." "Preflight a whole system?" Eli boggled. "You're a nutball class optimist. Did you know that?" "Not a whole system," Wil corrected. "Just a complete simulation of every way my own api can be used, pseudo-randomly covering all the api with high stress and data volumes — more aggressive stress than an actual app can manage at first, since usually some factor throttles a system until late in dev cycles when things ramp up." "Is that as involved as I suspect?" Eli asked. "Distributed peer to peer async codecs," Wil said. "Yeah, I'd say it was involved. Especially if I prototype future uses of code we don't have time to target for a while." Eli started putting it all together. "So a high level language helps here because ..." "Otherwise I'd never get done," Wil shrugged. "A simulated system has to use very high level code, so what little code I write actually does everything I need." "But if a language is high level," Eli reasoned, "how can it go fast enough to stress your C and C++ code at least as much as real code written in C?" "Yes, that's definitely one of the big questions," Wil confirmed. "The only reasonable answer is that I must know a lot about the high level language implementation. And its runtime must be tuned by me in order to get critical parts running as fast as I need." "Other people write fast languages too, you know," Eli sniffed. "How can you do better?" "Eli," Wil reminded, "this is me you're talking to. Here's the tradeoff: if it runs fast enough, it's compiled and I can't tell what's happening in enough detail; but if it's interpreted, then it doesn't run as fast as I can make it go." "Sounds like pissing contest posturing to me," Eli dismissed. "It's all about speed, then?" "No, it's not all about speed," Wil sighed. "In a language, I need enough speed, enough async, enough memory control, enough system api use control, and as little total complexity so I can get the whole thing in my head. I need to know whether a language runtime can ever interfere with what I'm testing. Everything must be diagnosed." "Well, if you need to know everything, you must write it yourself," Eli concluded. "Your other requirements just affect whether your simulations test your code in sufficiently real conditions and runtime constraints." "Yes," Wil agreed. "I tried to give you that basic idea from the start. You just didn't believe me." "Yeah," Eli shrugged. "You half talked me into it. But I'm afraid I'll forget again by tomorrow. It's hard to resist widespread one-size-fits-all dogma." "Imagine, for example, I try to use Python as my scripting language," Wil gestured. "That seems like a good choice," Eli nodded. "As soon as I tell folks at work, 'I want to use Python,' I'll be attacked for bringing another language into the picture we aren't using yet," Wil said. "The new dependency makes it look like fragile dependencies are my problem. Suppose I end up needing to get scripts running in a live system — but system calls no longer exist in that context which Python needs to compile and link." "But if you write your own language as a hobby project at home, then bring it into work to use in scripted test simulations, you'll still have introduced a new language," Eli objected. "That doesn't make any sense does it?" "You talk like you think people are rational," Wil noted. "I don't know where you got that idea, but it's wrong." "Help me understand then," Eli pleaded. "Okay," Wil said. "Today if I unit test my systems, it's a black box — a big pile of goop no one wants to look at but me. If one day the world changes so much a unit test stops working — because it would take too long to revamp to fit new api and system assumptions — then folks shrug and call it the price of progress. It happens." "But if you stick a language in there?" Eli asked. "Then it's still a black box no one wants to study," Wil explained. "If no one else can get them to work, that's fine, because they felt the same way about C++ unit tests. Only now I can revamp code very fast in a high level language, so a simulation matches new system assumptions. I can write new simulations very rapidly, and I can even turn around bespoke experiments in minutes to hours that would take days in C++, and thus never be done." "Wouldn't Python be the same?" Eli puzzled. "No," Wil shook his head. "Python must be installed. It has system dependencies. I won't be able to port it to the deployed platform with custom changes unlike where Python normally runs. Besides not knowing everything about it, which I already said was a requirement, I would not be able to resolve dependencies with problems." "Hmm," Eli considered with a dissatisfied look. "By embedding my own language," Wil continued, "I control all dependencies. It need never depend on an api I can't satisfy in systems where my other code runs; they would compile at the same time and become part of the same executable process, with exactly the same portability factors. No one would give me flak, as long as I don't execute my language outside unit test simulations." "So they'd never deploy your language?" Eli guessed. "Hell, no," Wil said. "I need to digest this," Eli sighed. 23jan09
¶
free prizes
top-down context ¶ I've been thinking about a dialog between Wil and Eli caused by Eli asking how to set up an interpreter from scratch. First Wil tries to point Eli at some existing programming language, but Eli persists. Eventually Wil says he'll only play along if he never has to answer a single question about how anyone else does something: Wil must be free to describe everything from first principles. Since I'm going to resume work on lathe as a toy programming language for scripting async framework drivers, it seemed a good idea to sketch out the top-down context. I find top-down context is one of the hardest for other folks to grasp when I design something. During discussion, folks reveal an endless series of misguided assumptions that suppose unnecessary constraints or vague agendas. The best way to work though these is by starting with really broad strokes, so you can reveal assumptions early about where in the world the forest should be located, generally, before you talk about trees in the forest. (In real life work contexts, this starts with short written descriptions, which most people skim and then mostly ignore pending a meeting in person where demands are voiced. Nothing written down is considered viable — no matter how many details you hammer out — until folks agree you're addressing anything like the desired problem.) Anyway, I'm thinking about diagrams Wil can draw to explain top-down context for the simplest possible way to get lathe running as a command line interpreter, along with forward looking ideas about what you might want later instead. Thus I'm planning to actually draw the diagrams and post them with the dialog. (Except Wil would draw on a whiteboard, and I'm going to draw things more polished — with a drawback of implying details are thought out, even when still tentative and vague in fact.) I can take advantage of this approach — telling a simple story about how a programming language context bootstraps — by later giving short shrift to all docs describing code that does those things. I can say those classes basically do the same thing described by the story; any other way of doing it would have worked too, and I don't care much about any particular way. That way, when folks complain about bad class names, I can say I don't care; all I care about is the story, to which the code conforms. But since it's after midnight now on a Friday, I feel like writing a bit more fiction instead of drawing diagrams in Photoshop. The next scene is related to the last. scarlet pimpernel ¶ (Moved to fiction.) 19jan09
¶
tin gods
new fiction ¶ Below you see fiction, and there are still no hidden messages, even though you see that idea mentioned. Now you can tell why the hidden messages topic recently made me think of that particular story line. This one's fairly interesting, though it might also be disturbing. (But just ignore warnings if you want to enjoy it more; having few expectations works much better.) I have several more scenes queued up: some from when I started the site, some from a few months ago, and one from my recent birthday. This is one of the main story lines, but there are others only barely related. You can see I like my science fiction mixed with thriller genre. (In real life I like calm and quiet; in stories I like wildness. Your taste may vary.) soylent green ¶ (Moved to fiction.) 18jan09
¶
intangible values
variable time ¶ While fleshing out part of a time demo so it runs on my Mac laptop, I saw the Intel hardware clock register do something pretty interesting — the number of ticks per microsecond changed all the time, depending on what else I was doing. The ratio varied by a factor of six. (In contrast, under Linux I normally see tick to microsecond ratios remain stable to several significant digits.) This ruins the way I normally measure elapsed microseconds in cheaply captured statistics. I won't be able to use Intel's rdtsc instruction to read and diff hardware timestamp counter values and get meaningful conversions. I guess I should look at other means to measure very small elapsed time statistics. A while back I read Macs had timestamp counters running out of sync with each other, under multiple CPUs, so I assumed the problem was nondeterministic context switching between CPUs with slightly different timestamp counters. To handle that, I updated my time demo to converge on a better ticks-per-usec ratio over time, by taking a longer and longer time reference, updating the ratio each time sampled in different seconds, up to some max number of ratio updates. Then I wrote a simple test: looping continuously, sleeping two seconds between each time sample, causing the ratio to resample with a longer yardstick vis-a-vis the original timestamp captured at program start. If I did nothing but watch output printed, the ratio of ticks per microsecond typically rose slightly, then fell every couple seconds, indefinitely, as if the processor ran slower every second the machine was not demanding anything very strenuous. Guessing blindly, I suspected the processor might run faster if I did anything Apple wanted to execute faster, such as smooth screen updating in the UI. So while the test ran in the background, I pulled up a Finder window and grabbed the resize box, dragging it vigorously all around while watching the ticks per microsecond ratio printed every couple seconds by my test. In response to all my dragging, the ratio shot up dramatically: my laptop ran more ticks per second when I did something UI intensive. So I re-ran the test, but already prepared to start my resize box dragging from the very start, to see how high I could get the ticks to microseconds ratio to go. It started at 370 ticks per usec, then rose very rapidly to 1700 and then to 1900 ticks per usec while dragging the resize box vigorously. In contrast, if I simply let the test run without any UI activity, the ratio would bounce around a little then then slowly fall below 350 ticks per usec. In any case, it's clear I can't expect the hardware timestamp counter to mean anything consistent when measuring in a server running on my Mac. Not if the rate of change varies by a dramatic amount, depending on what the machine is doing. 17jan09
¶
careening egos
art vs noise ¶ I wrote part of a story, then planned to kill it before bringing it back before sleeping. See the micro-story fragment below labeled raggedy man. Part of that was an experiment in keeping slightly more story detail at the cost of slowing down momentum. The story is only barely worth reading if you like any other fiction I've done; it's lightweight, without much meat, and slightly wordy in style. I was going to kill it as noise. But then I wondered: what if someone likes it? Maybe I shouldn't be so harsh. (My technical ideas today mainly involved visualizing graphs and analyses of data, looking for algorithms yielding a kind of edge detection I want. Only folks at work will see diagrams I draw on whiteboards. And then only if they can stand another round of that sort of thing. No, I'll take that back. The diagrams must always be drawn later in explanations, in reply to questions about what happens in this situation or that one.) hidden messages ¶ (Here I removed some introductory material, keeping only the part prompting the start of some fiction afterward.) Hey, for the record, I basically never hide secret messages here. I indulge in occasional nonsense and amphigorey — my headlines often mean nothing — but it could look like it meant something if you only knew the code. But there's no code. I'm not a code guy. The only code I do is software, space optimization, and languages. I don't play any cryptographic message games. One of my characters is an unusual kind of spook. Whatever Finch is really doing presents a problem for other characters to figure out. I can't say much about it without tipping a hand one way or the other about whether Finch is playing a game, or which parts of things are games. Since the project Zé started is a kind of fiction game, it's hard to decide where it begins and ends with (fictional) folks participating. Let's see, I was going to work a reference Finch makes to Three Days of the Condor into a story recently. What was that about? Oh, yeah. Maybe I should see if I can reach that part. raggedy man ¶ (Moved to fiction.) 16jan09
¶
sunk costs
edge detection ¶ I'm working out a rather abstract sort of edge detection to distill an algorithm suiting my needs. Earlier this week I finished code measuring exactly how well an algorithm fits the profile I want, so now I can try variants to seek one maximizing value I targeted in measurements. I can't spell out the details; if I did, you'd have too good an idea how I formulate a problem best left obscured in trade secret territory. So I won't clarify either what I'm looking for, or how I measure it precisely, both of which matter. However, it doesn't hurt to tell you I'm reading web pages about edge detection while telling myself, "Think of it as edge detection," so I can get random sideways insights into the problem I'm solving, by projecting visual metaphors into the math involved. In other words, what I'm doing is only vaguely related to edge detection, but some computational parameters are analogous. The first time I took a shot at this a couple years ago, I applied a visual analogy simulating what a person does when finding patterns in graphs. The result of that study worked quite well, although the first version coded ran too slowly. (Which I fixed by trying simpler but loosely related variations, until I found a good one by surprise.) Lately I seek a much better version of the same sort of identification scheme, informed by a lot of stuff I mulled over a long time; so far intuition says to expect an exact, highly useful new variant of an old algorithm with a much better yield in probability of recovery after perturbations. Parts most closely resembling an image edge detection context involve aspects of scale in picking context of relevance. That sounded like gibberish, didn't it? 13jan09
¶
fashionable itches
codecs ¶ My approach to codecs is very functional, but I code functional effects in a runtime using mutable memory. A functional model is the target semantics, but the model manifests as a side effect of subtle processing with a lot of scatter/gather dataflow. The definition of objects, their identities and lifetimes, and where they live at the moment — all have a clean sounding story. But the administration of this story has all the usual moving parts and manual memory management of any other systems programming task. At the bottom, details get hairy. For example, if anyone manages memory slightly wrong anywhere, interesting things can happen, manifesting as certain parts of objects not having expected values in some spots. So when folks tell me about odd values they see in narrow contexts, I suggest experiments to run to detect changes where none should occur if all invariants are true. I bet that's unclear, huh? Sorry, I can't report details. I guess what I'm trying to say is simpler than appears above: I find it easy to imagine which memory lifetime mistakes occuring in which contexts might cause odd data observed, and I know how to test for those mistakes (provided you're willing to make a change to the code that's challenging for developers in general). Hmm, this blog item isn't working; it lacks a crisp story. Anyway, I can't easily imagine doing what I do in another language besides C or C++, since so much of it takes very careful management of memory — with great care taken to size, location, distribution, and access patterns, because number of cache lines I touch have the most effect on CPU cycles used. I could probably manage something very similar in Java or another language with garbage collection, but only by imagining exactly how memory is used, despite being unable to control it directly myself. I require at least a model of how much memory is touched and where, so I can minimize it in algorithm design, and roughly schedule when it happens to bound latencies. (That is, I must also know when memory is touched, and not just where and how much.) Planning to let me do that in your language? One of my coworkers specializes in profiling and assembler; he's very old school, and quite good. I trust his profiling more than output of any other tool I've seen folks use. (He wrote the profiler himself; it's been part of his bag of tricks a long time.) He's the guy in a position to verify my cache line cost intuitions, so I get real world feedback to keep my mental models in line. After minimizing how many new cache lines are touched at various points in time, the only other way to make some bottlenecks go faster is by rewriting critical inner loops in assembler to use more registers than the compiler is willing to assign as we like. Some of the tricks he tells me about make me slightly nervous. (I avoid describing them because you'd infer too much — can't have you go around drawing inferences.) Sometimes I write the same routine in C and C++ versions because the C++ version is easier to grasp, but the C version is easier to see turned into assembler. Interestingly, sometimes C++ runs faster than the C version with optimization turned on. I've been guessing the use of inlines in C++ help scope value liveness better for register scheduling. |
Entries appear in reverse chronological order.
Content here is permanent: Each entry has a permalink
(¶) to
the long-lived persistent copy here. Clearly, to link
anything, you'd best link the permanent copy.
12jan09
¶
borgesion fabulations
interactive stats ¶ In my day job I miss a capability easily had in dynamic, interpreted systems, like those I drove with Lisp foreign function interfaces for years starting in the middle 90's. What I really want to do is change code in a system while it's running — I want part of it interpreted in a DSL even if most code is compiled. For example, not being able to write interpreted scripts to process statistics hampers me to no end. Or it feels like that even if it's not true; I want to write stat-watching scripts. At work we have many stats reporting this and that — hundreds of stats. In fact, too many to see at one time. So to investigate odd behavior, you must try to guess what stats you must study, and carry the whole burden in your mind. If a stat changes and you did not look to notice that interesting fact — too bad. I want to write event handlers that fire when stats do certain things, calling code to fetch, analyze, and compare various other stats to form specific opinions about a state of affairs that has not yet become clear. Actually I want to do that for many things and not just statistics. But not being able to do it with statistics is frustrating when it's the puzzle at hand. Even without event handlers, it would be nice to run scripts by hand in polling mode, if events cannot be sent as notifications. It would be feasible to write shell scripts for some things, if you didn't mind how much a shell language differed from general high level languages one prefers to get stuff done. I haven't even broached the idea of being able to dynamically modify system state from interactive scripts, but I want that too of course. You can find pages (not too many of them unfortunately) on this site where I indicate my wish to use a Plan9 style (or Linux proc file system style) namespace to represent potentially mutable bindings, so you can edit dynamic behavior in a namespace sandbox and try out new variations there, while old versions continue running on the side. That's my nirvana view, which is admittedly asking a lot. 10jan09
¶
low hanging fruit
braces ¶ My older son made an interesting remark when we picked up his faux guitars for playing Guitar Hero this evening at his mother's house. Let's call him Tyr since I never gave him a good codename before, unlike the one chosen by his brother Fenrir. (Since they fight often, I thought Tyr might work, since Tyr lost his right hand to Fenrir in Norse mythology.) As he came back out to the car and loaded both instruments, Tyr said a single word about his mother's apartment: "Popcorn." Perhaps I imagined a trace of buttery smell that seemed to cling to him. Trying to be funny I told him, "That's a line from Gross Pointe Blank." "I knew that," Tyr replied. Then after a pause he added, "Well I didn't right after you said it, but then I remembered." I put the car in gear before Tyr continued, "He shoves the television over the guy's head and says, 'Popcorn!' because Dan Akroyd said it earlier." As I tried to think of an interesting comment about the movie, Tyr told me braces ruined his love of popcorn, and gum as well. Puzzled, since he hasn't worn braces for over a year, I asked what he meant. "I wasn't allowed to eat popcorn or chew gum when I had braces," Tyr explained. "So I stopped caring." Apparently, since he stopped caring about popcorn, now Tyr no longer enjoys it, even though he remembers craving it once. Tyr seemed frustrated by this, and the problem vexed him a few minutes. I told him I understood what he meant, but I didn't explain, because it would take too long. When I was about four years old, with three brothers and a sister (all of us less than six years old — what can you say: my parents were Roman Catholic) my older brother tickled us too often, and I didn't like being ticklish. So I decided to stop being ticklish. When someone tried to tickle me, I said I wasn't ticklish, and it became true: I stopped having that reaction. By the time I was a teenager I had no trace of ticklish reactions, and could barely remember what it felt like. Even today if you try hard (catching a muscle just the right way) you can only get a muscle to spasm, which seems odd, but doesn't give me the least bit of tickled feeling. I'm not ticklish anywhere, not even knees or feet; nothing. I assume Tyr went through something similar with popcorn cravings he could not satisfy. They were very inconvenient, so he suppressed them, and now they won't come back. rugrats ¶ "Let me get this straight," Ulf sat on the arm of a couch near Wil's desk. "When you were a kid, there were four pre-schoolers at home with your mom? And your older brother was in kindergarten?" Wil sighed and contemplated brushing off Ulf's inquiry. "That's right," Wil gave up. "I was oldest of four still in the house." Ulf squinted as if this was implausible. "Did your mom have any help?" he asked. "Relatives?" "That's a good question," Wil pointed a finger. "No. No, she didn't have any help. And my father was gone all week — traveling salesman. So, four kids in the morning, five the rest of the day." "It's a miracle you even learned to talk," Ulf marveled. "With three younger siblings, how did you get any attention?" "I got no attention I recall," Wil shrugged. "My folks were of the 'benign neglect' school of child care. I remember being told to go outside a lot." Ulf tried to bore a hole in Wil's skull with his stare alone. "And yet you turned out okay," he suggested doubtfully, as if he believed otherwise. "What could go wrong?" Wil asked. "I bet you were an only child? Did you get enough of your parents cooing and praising over everything you did, no matter how lame? That spot feels sore, huh?" "We're deconstructing you, not me," Ulf dismissed with a wave. "I was thinking maybe... attachment disorder. That might explain why you don't divide the world into insiders and outsiders." "Attachment disorder?" Wil echoed. "Is that the one where young kids are separated from parents and later have poor bonds to caretakers? So they connect easily to anyone at all, appropriate or not?" "That's the one," Ulf pointed at Wil. "And now for some reason you seem to like everyone, instead of treating folks like crap when they're not in your inner circle. You need some soul hardening." Wil shook his head with a sour expression. "That's crap, Ulf," Wil replied. "I never had any bonding with random adults as kid. Where do you get this stuff? Do you psycho babble everyone you know?" Ulf remained leery. "Something must have gone wrong if you were raised mostly by one adult, with a shitload of kids underfoot, pardon my french." Wil stopped and considered. "I did have trouble hearing people," Wil admitted. "If you didn't say my name first, I would not hear a word you said when I was a kid. Really pissed off my parents." "Aha!" Ulf pounced, snapping his fingers. "I'm sure it means something. I'm not sure what." "Whatever," Wil dismissed. "Although something interesting happened to me in middle school. One day, I finally started hearing what was said to me before I heard my name first. It was as if sounds buffered in short term memory, and I re-heard speech from there once I noticed I should pay attention; I could get maybe five or six seconds in there." "Hey, what's this picture over here," Ulf pointed at an old snapshot of four kids on the front steps of a house. "Is that you and your siblings?"
"No, you retard," Wil laughed. "My dad sent me that a couple months ago. He's the little guy, second from the left here. This is 1938, and that's his brother and two sisters. Looks like the depression, no?" "Irish breed like vermin," Ulf blurted suddenly. Wil got a dark look and turned red before turning to pick up a small aluminum bat next to his desk. "I didn't hear you right," Wil held a hand up next to his ear. "Did you say you wanted to be kneecapped?" "No, no!" Ulf spread both hands defensively, easing away to get his knees out of reach. "That's what I thought," Wil nodded. "You should be more careful what you spout when it might accidentally sound disparaging to folks with less even temper than me. Finch would not have hesitated." "How can I insult her ancestry when I don't know what it is?" Ulf complained. "If I had to guess, I'd say Italian. What do you think?" "I have no idea," Wil put the bat back down, in easy reach. "What kind of last name is Finch? British?" "Have you noticed she never answers direct questions?" Ulf asked. "Or is it just me?" 09jan09
¶
rat races
worthwhile tasks ¶ My current task is trying to think of something worth doing that's also likely to be used for the intended purpose. (Note that means used by me since I'm my target audience; my itches top yours.) Most likely I'll resume where I was with little change (from your perspective) since it might still look like the same bottom up stuff. But the top-down view will be different. That's the part that was broken. I need to feel like what I'm doing is actually hooked up to the end result, or it feels academic. I enjoy my day job, and I have the good fortune of getting to work on something rather interesting: designing and coding a new peer-to-peer codec. One reason I enjoy my day job so much is because I know what I'm doing will get used. The whole context is geared around hosting the ideas I imagine so they can be made real, and the result has great value to others, and this is rewarding. (If I had to do everything myself, it would take forever and be less rewarding.) Deciding worthwhile tasks to pursue at work usually seems very easy: all inputs to consider grow clearly over time, as wish lists and pain lists. I need merely target as many wishes as possible while avoiding as many sore spots as possible. Of the two, seeking wishes and avoiding pain, the latter often yields larger emotional wins, because ditching an old agonizing nuisance seems a profound relief — especially when the schedule ought to get better. (I want to laugh in glee when four man months of work, or more, stop being necessary after a problem no longer exists.) In contrast, when I work on hobby projects, I seldom apply the same impartial eye to what I'm doing, perhaps because my habit assumed unbounded amounts of time could be used if I wished. However, I probably should think about my home projects more critically. I assume lack of criticism contributed to lack of momentum — or actually, lack of connection to a believable end deliverable, which is more subtle with similar effect. So at home I need to do the same thing I do at work all the time: ask myself what will happen if I make a choice, and then go with my call, whatever it is, without second guessing myself or making excuses. And I need to favor simple, controllable outcomes. Part of the recipe is making mental lists (I just don't write down lists — they mutate and age too quickly) of good things to seek and bad things to fix. Unfortunately, I don't have much in the column of good things to seek — not if I'm honest and trust my gut reaction about plausible useful goals. It's easy to include "faster" in the good column, but that begs the question, "A faster what?" What needs to go fast? I think my answer was development in the middle 90's. But that's far too big a bite for me to chew. And I no longer think I'll ever have enough time to do anything with a user interface frontend; I'm mainly a backend guy, and life is short. So as much as I would like to make a development environment (I was thinking of one for my sons originally) I no longer think I have time — not if I wear my call-it-fast-and-simple hat. Anyway, my list evolves slowly at the moment. I can articulate some things more easily than others. One possible goal sounds like this: "Make something to test async codec engines more easily." Notice that would be useful eventually in my day job. Almost certainly it would turn into a use of programming languages I was writing, but tuned to a specific target app: scripting things I need driven in a way that lets me confirm, explore, and stress everything without a lot of hassle. Since I once did this with my Scheme plus Smalltalk object system variant in the 90's, partly this is a goal to enable the same sort of end use. This line of thought has an advantage of avoiding tarpits of general purpose programming languages, which easily turn into solutions in search of problems. Next thing you know, nice integrated development environments (IDEs) become a goal deliverable because it sounds cool and not because you need it. If I stay focused on whether I really need something to test a gnarly async framework, I can target minimalism and ignore everything folks say requesting cool language features. And at any time I can test my progress by asking: Can I test feature X yet? Knowing when you're done is a big part of defining a project so it will get completed. If you can't define a done state, you have a problem. So bounding what you need is an early step to pursue. And in my case lately, I need that bounded part to connect with something I need to do, so it seems useful immediately, and not for some vague future purpose. I want my next worthwhile tasks to have narrow focus with clear connection to the real world. Though nice to have profoundly general tools that might do anything, motivation is easier to find in highly specific tools for immediate application. If I find generality instead, I want it to occur incidentally in pursuit of getting things done. dream script ¶ This morning before I woke up, I had an odd dream about writing a script for the cast of characters populating Wil's apartment. And although I knew I was "writing," I was seeing the script as enacted by the characters. It seemed a variant of hypnagogic imagery, in the sense I was awake enough to know I was dreaming, but all my attention was devoted to the inventive aspect. A new character was in Wil's aparment: a guy named Dr. Laughs who Zé and Eli had found in the park. Laughs believed he was a medical doctor, but he was more a crank or comedian/faker — a friendlier and saner version of nuts like the one Mork befriended in Mork and Mindy. In the dream I tried to think of his short first name because Laughs is too long; Leo was an early candidate with awkward fit. Most of Dr. Laughs' routine parodied House material; he kept saying "differential diagnosis" to invite analysis of personality defects in people like Ulf, who he ultimately prescribed the following treatment: "Twice a day, ask Finch to hit you as hard as she can." I suppose this dream was partly inspired by a story idea I had on my 50th birthday earlier this week, which I liked so much I almost wrote it up immediately. I figure that one's likely to show up here sooner or later. Parts of the story I imagined obscured a few seconds of Benjamin Button when I was in the theater. It's not very often I think of something I find more entertaining than the movie I'm watching right this second. It has a bit of time travel theme to it, of course, which goes along with the time demo Wil is writing soon, and also complemented a time theme in Benjamin Button, which could be why it kept intruding. 06jan09
¶
tar babies
reading binge ¶ Between kids and movies, I read a new novel I enjoyed a lot. Instead of conserving it by reading in smaller pieces, I just finished it off. This relates to my main thesis today. casually seeking fun ¶ I hope to find something interesting to do with my spare time. Last week gave me a new problem to think about: when I wasn't working and my kids weren't around, there was nothing I wanted to do. I had hours when I could say, well here's a block of time in which I can do anything I want — what should I do? But I could think of nothing. This told me I neglected cultivation of my interests in some fairly severe way. It seemed an awfully negative sign, like a headline in the Onion reading, Local Man Can't Think of Anything to Do. Little alarm bells went off in my mind. I've always had the problem of too much I wanted to do for time available. So what happened? I'm unsure thus far, so I granted myself a high priority for distraction by anything that might catch my eye, hoping something will light a fire under me, checking my mental pulse for odd rhythms. As I ran through random options like scrolling through a menu, I noticed my lack of interest was partly due to an idea I knew exactly what would occur in each case of possible recreation, and it was boring. Hmmm. How did my world view get boxed in like that? In any case, it doesn't seem healthy, so I'm fishing for impulses I can give rein as they show up. I considered writing fiction here: did I feel like writing? Again no, and that was a bit surprising. I don't learn quite as much from writing fiction now, and the surprise factor of seeing what happens is no longer strong. A slope of marginal entertainment looked downward leaning, though it would be fun at first. At the moment I'm trying to feel around in the dark to see if there's something technical I want to pursue that's not in line with my previous plans for this site. I don't care whether it's off course, I just want the craving so I have something to do for joy. I haven't learned much in coding for a long time now, partly because I already know what's going to happen, and I have to resolve problems I've done before without any new insights. So I'm giving myself a lot of slack. I hope I think of something odd to do in a technical vein. The background chatter and imagination in my mind is running an interesting program lately, but it's not one that leads to anything right now as an activity. I'm recalling past situations with other people — typically from long ago, like when I was twenty — and I'm seeing the other 80% I didn't read at the time, and sometimes it makes my jaw drop, especially when the first time around all I could do was scratch my head in puzzlement. When I was young I was unable to guess what insane set of premises might explain default perspectives in outlooks of most folks around me. And now I think I get it. (I still think the premises are absurd, but that's people for you.) In part, it was the incredible shallowness that threw me. Basically, just suppose the emotional maturity of most people is about nine or ten years of age, and then crank up the reasoning skills a notch, with energy mostly devoted to the problem of "what can I get?" or maybe "what's in it for me?" A bit like everyone stars in their own first person shooter, and everyone else is a zombie or supporting actor. I had trouble empathizing with complete lack of empathy and mirror based reasoning. Of course, I'm not actually going to be able to explain in detail. It's just very strange to review old dead memories and find them alive with social dynamics, where I read clear intention now in behavior totally mystifying me then. Often I puzzled other folks just as equally because I never aimed to screw them, or to seek unwarranted advantages, and their strategies required I try to do so first. It was very hard to cheat me because I was utterly honest. Anyway, I won't be talking about this anymore (I think). If I get my wish, I'll take different tacks around here as soon as I can figure out what to try. 03jan09
¶
happy endings
lock latency ¶ As I flesh out another revision of file i/o using a paged cache, I'm reminded once again how much harder it is to explain little details I feel free to toss in the mix. When I write code without needing anyone else to understand, I just think of what I want, and do it. Sometimes the details get thick, but who cares? But the stats I've been adding to capture average lock latency in microseconds will take some explaining. Next thing I know, I'm fleshing out the time demo, so I might write it first since otherwise I won't have a basis for capturing latency in microseconds already covered. The cache for files will be thread-safe, and the unit test will use many threads at once to read and write pseudo-randomly sized and selected parts of a file cached this way. So one of the little utilities I need in a unit test is a way to keep threads from stepping on one another using read-write locks, because the expected result of comparisons isn't valid unless multiple writers never overlap written ranges concurrently. This little utility stripes the locks (maps tiled file segments onto a finite array of read-write locks) and always locks array members in ascending order, since consistent lock order guarantees absence of deadlock caused by holding more than one lock at a time. So far, so good. Note using the array of striped read-write locks does not require stats on average latency to lock, but I want the stats anyway. The demo would be incomplete without the stats. I started thinking about how I should explain how important the stats on latency are in real life practice. Here's the short version. If you make a thread-safe feature with some parts requiring mutex (whether using read-write locks or plain vanilla mutex) then you're the guy in the hot seat when anything runs slowly at runtime in a live system test. Guess what? The live system test is always going to run slowly under different conditions for a large number of reasons, until everyone chases down the part of latency added by their own code. (It only takes one thing to wait somewhere and make everyone get in line.) They know you might have done it, because you're the one with mutexes. All the obscure unlighted parts of the code don't look as easy to search for problems. So you're guilty until you prove there's no latency in the locks — in any of the locks. You can only do this by directly measuring latency to lock each and every time you lock. If you do this, and the time involved is negligible (and it is — what else are those big arrays of striped mutexes for, after all?) then you're off the hook for the unexplained wall clock time; nope, sorry, it wasn't lock contention. Look somewhere else. A demo that doesn't include stats measuring lock latency isn't a real demo, because those stats are required in practice. Without them, a prevailing theory will be that threads caused the problem. Average and standard deviation for lock latency are the bare minimum. You need more if latency ever gets high enough to be noticeable. Then you must also capture a highwater mark: the highest latency ever seen. Given a central bottleneck lock someplace, you need to ensure the biggest latency ever seen is under an acceptable value. For such a central bottleneck lock (if you have one) under certain interesting and surprising conditions, the highest latency seen can go up to a value that shocks you, causing you to invent new techniques to ensure it can't happen. But if you don't measure the latency, you won't find out this work is necessary. To solve problems like those, when surprises surfaced, I taught myself refinements in lazy incremental invalidation and lockless ways to get more things done. The best technique is one that makes corruption look like invalidation to resolve conflict as passively and cheaply as possible. But it makes code more complex, because instead of putting house-keeping code in one isolated place, you do house-keeping continuously, padding each constant time operation with extra constant time piggy-backed overheads. Note I won't show any of that, though, because parts seem worth playing very close to the vest, even when just little tricks; publishing why they work might reduce market advantage, if competitors noticed what kinds of fat could be trimmed. (I've rarely worked with folks who like central parts described, especially when they don't seem obvious after I explain them, even when trivial as in this case.) Anyway, I only went on that little tangent because you only reach those problems in code by measuring latency. Then after thinking about how to avoid unacceptable latency, you have ideas. I'm only going to show you how to measure lock latency, which won't be big enough to notice in a threaded file unit test. The code doing it will likely seem unnecessarily complex C++ drivel. But it's your only proof when the questions start, and your evidence when you ever find an actual problem. So don't be quick to flinch. 02jan09
¶
fuzzy arguments
implicit deals ¶ "Hey, Wil," Eli began with a hesitant frown. "I read that thing you wrote about morality, and there seems to be a lot of subtle things wrong with it. I hope you don't mind me saying, but it feels a bit cockeyed." "Yes, I know," Wil rubbed his eyes. "It happens when making strong statements for sake of clarity without necessary provisos refining details. I hope you're not going to make me keep talking about it; it's on the boring side, even though I wrote it as a rant." "You know, research shows folks use differing standards in social and commercial contexts," Eli said carefully. "When you mix them by talking about normal social agreement as contracts... it's a little weird. My dad would have no trouble casting you as a nutball." "I know, don't worry about my feelings," Wil assured with a grin. "Think of everything I said as a kind of model that's hard to reach in practice, if for no other reason than most understandings are implicit, and little objective evidence says whether folks' ideas are in sync." Eli relaxed slightly. "Well, contracts are explicit and commercial," he essayed. "So isn't that the wrong word to use? I tried to think of another word, like deal, but all of them smack of commercial undertones." Wil shrugged. "It's not my fault we don't have the perfect word for everything we want to say. Let's say deal when we mean understanding between parties, even when implicit, social, fuzzy, and non-commercial. I'm sure sociologists have a better term." "Then what was the point of your rant?" Eli asked. "Okay," Wil raised his hands with fingers spread as if grasping a loose pile of something. "We all have a theory about what others are thinking — call it theory of mind. Part of this theory includes a grasp of errors we see in what others think, according to our theory." "This is going to get complex really fast, isn't it?" Eli said miserably. "Can I take a rain check?" "I'll speed it up," Wil promised. "To simplify, let's use POV to mean point of view — it's a theory about perspective held by one person. I can talk about my POV and your POV without getting totally snarled in as-far-as-I-know qualifications, which are understood." "So your model of my POV is understood to be rough and we don't need to keep saying that over and over," Eli granted. "Okay. But you want to talk about errors in my POV? Where you see I'm missing something?" "Exactly," Wil said. "In my ethics, honesty requires I fix your POV as gently as I can when we have some kind of deal — usually implicit of course — where you're going to lose because of your mistake. Even if, especially if, I would benefit by a mistake." "How do you know I'm mistaken?" Eli probed. "That's complex," Wil sighed. "Let me answer by asking a question: Have you ever noticed someone else has the wrong idea about something?" "Of course!" Eli laughed. "Okay, I get your point. I grant you often see my wrong ideas. Everyone does." "Yes, in varying degree," Wil confirmed. "How good you are at grasping someone's thought process depends on many variables which I won't enumerate." "Thank god," Eli rolled his eyes. "But some folks are very good at it," Wil said slowly. "Much better than you or I. And they aren't always honest in the sense I mentioned. So what do you think happens to you when you make deals with them?" "Depends on whether they want to screw me," Eli said slowly. "But how bad could it get?" "Suppose they explore a deal space, searching for a spot where your mistake and therefore your loss is maximized?" Wil asked with raised eyebrows. "Ouch!" Eli's eyes glazed over in thought. "But does that ever happen in practice?" "You are so naive," Wil sighed. "Yes, but you can learn to recognize a set of behaviors that correlate with someone looking for you to give yourself a raw deal." "You mean they have a playbook?" Eli asked mockingly with an arched eyebrow. "More or less," Wil agreed easily. "But it's a big playbook and folks specialize in different variations, like chess masters in styles of opening games." Eli stared blankly for a moment. "You're thinking I'm paranoid," Wil observed, then smiled at Eli's surprised expression. "I must be easy to read," Eli chuckled nervously. "Maybe I should give it consideration. What should I do?" "Think about it, for starters," Wil suggested. "Then start imagining what a bad hat might do if they can guess what you want, since it predicts part of your negotiation. Try to avoid being herded." Eli covered his eyes. "This is going to make me paranoid," he mumbled. "What's the first sign I should worry about? Any common tricks to notice?" "Yes, one is quite common," Wil said. "It's hard to recognize what it means, because it's an absence of something, and negatives are hard to interpret. When the other person seems to have a poker face, that's not a good sign. Or similarly, when very little info is offered, this is easy to confuse with no info present, which is why curiously blank starting positions are offered to you." "How do I lose that way?" Eli wondered. "If you reveal where you're coming from first," Wil began, "it tells a lot about deal structure you expect, letting others cater to your confirmation bias, letting you see what you want. You might read noise as agreement." "This is way creepy," Eli said. "Yes, it is," Wil agreed. "Had enough for today?" "I want to renegotiate the deal," Eli joked. "Tell me when I'm not going to like something first, okay?" 01jan09
¶
smart conversations
morality ¶ When I mention morality in passing, it's easy to mistakenly assume I mean something similar to what others meant by it when you heard them harping about morality in the past. For example, the word appears in religious discussions or in cultural analysis — the cliché would be 1950's style condemnations of moral relativism, such as appeared in 1960's counter culture. So the word morals is typically freighted with judgmental stance — unless you took a class in sociology and learned sociologists use this word to mean mores (wikipedia), which are norms and customs in the practices of a society. So when I toss "morals" casually into a discussion, what I really mean something a bit specific: anything that constrains what you feel free to do, based on some principle (whether yours or imposed by society). Compared to various times in the past (say the 1950's as an exemplar easy to lampoon since you can see moving records in television from that period) today our social mores are highly influenced by relativism, as opposed to moral absolutism. The idea anyone is constrained by morality more strict than obeying the letter of the law is now passé, and often mocked in media. Folks with old-fashioned sensibilities are quaint — they're hicks. If you travel anyplace where old mores still exist — say in the countryside, the south, or perhaps the midwest (anyplace but the coasts) — you can expect a small or large trip back in time courtesy of local hicks with their quaint mores. Am I guessing your bias here correctly? That's okay, I tend to think of folks where I grew up as hicks, too, except that doesn't mean I look down on them. They drove me crazy when I lived in Iowa thirty years ago, and I couldn't get away fast enough. However, I don't use the term hicks to be insulting; I know it's derogatory, so I only use it to refer to an idea I expect is present in readers' minds, and not because it's my own view. Modern hip folks steeped in moral relativism hold to an idea there is no right and wrong, just legal responsibility, and anyone who believes in right and wrong is a hick, or perhaps just an intellectual child. But I think such inability to think about right and wrong is just intellectual laziness on the part of folks who quickly gave up after hitting the first conundrum: not everyone can be right if no one even agrees on basic underlying principles. I'm personally very areligious (that's non-religious if you can't figure out what the a-prefix means). I don't believe in anything supernatural, whatsoever. So I completely ignore the role of religion when thinking about morality. And yet, for some reason I believe in an idea some principles are more right than others. I found this very puzzling when I was 20, and spent a lot of time thinking about it. I was tempted to suppose I grandfathered in rules of my elders taught to me when I was a boy. But on further reflection, that didn't seem to be it: no resonance there. As near as I could tell, I had assumed a principle of symmetry was a priori correct, as an axiom: right and wrong should not depend on your point of view (POV). That is, you cannot be in the right just because it validates your position; if you swapped places with another party, that should not change who is right. If you allowed that, you could rationalize anything for self serving reasons, and so you would. (Does that sound like you?) I'm talking about something very similar to the idea called the golden rule, often paraphrased as, "Do unto others as you would have them do unto you" — except updated to include a more mathematically sophisticated view that utility is not the same for everyone. Thus, fair balance has to be reached by negotiation between sides declaring their views on utility, backed up with explained expectations of future events plus good faith disclosure of information on both sides, until a contract is reached when an agreement is formed. Lying is basically contract breaking, because it means you didn't have good faith during disclosure, so the other person could not agree fully informed. Trickery is just a complicated form of lying, where you allow POV's of others to stay incorrect with respect to facts you know differ (or will differ later) from those understood by all. Of course, we don't know everything in advance, so sometimes we make decisions and contracts based on false information. That's okay, it only means an adjustment is required as you go along. If materially new facts appear as time progresses, you adjust a contract by agreement to fit new facts. The adjusted contract might be the old one as it would have been if all the facts had been known at the start; or one party can buy out the contract on reasonable pro-rated terms. It might amuse you that I describe contract law (which I have never studied) like it's morality, but that's very close to my idea of what is right: being truthful and making good contracts — and sticking by the spirit, not just the letter — based on understanding how your point of view (POV) differs from folks you deal with. It might sound dry and mechanical to you, but I feel it in my gut as morally right, seated down deep where you expect religious beliefs to live. Relativism has no place, because you are obligated to identify and factor out differences in POV as you negotiate; it's part of due diligence. In other words: honor your freaking contracts. Also, not disclosing everything you think about a deal is lying or trickery (same thing) when it might alter the contract, or even kill it. It's wrong, even when you're smarter, more educated, and better informed than other parties. If it would be a bad for you on the other end of the deal for the same reasons you're not disclosing, then your behavior is evil. (Evil is generally diminishing others outside of well-formed contracts.) People use the idea of moral relativism as a smoke screen to rationalize their own evil behavior when they contract in bad faith. It's easy to pretend you aren't being evil when your bad faith is hard to catch. You tell yourself there is no such thing as right and wrong, so you can ignore your wrong actions. But unenforceable is not the same thing as okay. Just because it's not feasible to punish you doesn't mean your actions are good, or neutral. A good man acts as though everything is enforceable, even when it's not, because it's the right thing to do. Only jackals get while the getting is good. |