Archive for the ‘computer’ Category

doitclient ported to Windows

Thursday, September 27th, 2012

In order to write my cycle exact emulator, I need to run a lot of little "experiment" programs on my XT to determine exactly how long various things take. But the machine is bulky and noisy so I'd rather not keep it in the living room. In Seattle I kept it in the workshop downstairs. In Cornwall I'll probably keep it in the garage. I also have a modern PC next to it which is on the network and can reboot the XT, start programs on it and collect the results.

So, in order to remotely run programs on the XT I ultimately needed a way to remotely run programs on the modern PC. I had VNC and remote desktop on the modern PC so I could use that at a pinch, but I really wanted an automatable method - i.e. a command I could run on my laptop that would cause another command to be run on the modern PC. Under Linux this would be easy, but both the modern PC and my laptop run Windows.

I looked at a couple of ways of doing this, psexec and at least one other that I don't remember, but everything I tried was rubbish - either too slow, didn't work at all, or ran in a context which didn't include my network drive mappings (which made it kind of useless for running a program I had just built locally). I thought about writing a simple TCP client/server app to do what I wanted, then I decided to check to see if anyone had already written such a thing. Of course someone has, and I was not entirely surprised (nor at all displeased) to find out that the someone was Simon Tatham. Unfortunately DoIt has one minor problem which made it impossible to use as-is for my scenario - the client part (the part that runs on the machine which dispatches the commands) is a Unix program. Fortunately it's a pretty simple C program and I was able to port it to run on Windows with just a few changes. Here's the port, with a binary, diff, modified source code and a Visual Studio project file.

I suppose I could set up some wireless serial connections instead of using a separate PC which would make this entire post redundant. It'd probably even save money in electricity bills in the long run. For now, though, I decided to work with the hardware I have.

eBay private bids

Tuesday, September 25th, 2012

There are all sorts of programs available for "eBay sniping" - automatically placing your bid in the last moments of the auction in order to minimize the amount of information available to your adversaries (the other bidders) and thereby maximize your chances of winning while minimizing the amonunt you expect to pay.

The trouble with this is that it creates two classes of eBay bidders - those who have paid extra (in money, effort or both) for the sniping software, and those who haven't. This makes the eBay user experience less friendly and more frustrating.

So I think eBay should offer its own (free) sniping software built right into the site - give bidders the opportunity to make a public or a private bid (or both). Only the highest public bid is shown but the highest bid overall (public or private) will actually win.

Why would anyone make a public bid if a private one is available? Wouldn't this turn all eBay auctions into silent (?) auctions? Not necessarily - there are some circumstances when a public bid is actually in the bidder's favour - for example if there are several auctions for equivalent items all ending around the same time, making a public bid on one of them is likely to push other bidders towards the other auctions.

Though that bit of game-theoretic oddness could also be eliminated with a closely feature closely related to private bids, which is the ability to (automatically) withdraw a private bid. This would allow one to bid on several auctions at once, while guaranteeing that you'll only win one of them. More complicated logic would also be possible, like "I want to buy either A or the combination of (B and any of C, D or E)". I'm not sure if this is currently possible with sniping software (I haven't used it). One could also set different bids for different auctions, if some are more desirable than others in some ways.

All these changes favor buyers rather than sellers, so eBay users who are primarily sellers probably wouldn't like them (after all, they help buyers save money!) But sellers already hate eBay - many of their other policies are drastically biased towards buyers. The only reason that sellers keep selling stuff on eBay is that is where the buyers are (and therefore that is where the best prices are, even after factoring out eBay's cut).

One other reason that eBay might want to do this would be that by having private bids go through the site, they get more accurate information about who is prepared to pay how much for what. I don't know if eBay currently does anything with this sort of information, but it surely must have some value to someone.

How to decide if a website is trustworthy

Monday, September 24th, 2012

Occasionally people will send me an email they have received or a link to a website they've heard about and ask me if it's genuine or a scam. Usually it's easy to tell, but sometimes (even for the savvy) it's actually quite hard. The example that prompted this entry was a program that purported to speed up your computer by cleaning up orphaned temporary files and registry entries. This is an area that's ripe for scams - a program that does absolutely nothing could still seem to be effectual through the placebo effect. Also, running such a program is a vector by which all manner of nasty things could be installed. Yet there are genuine programs which do this sort of thing, and slowdown due to a massive (and massively fragmented) temporary directory is certainly possible.

Here are some methods one can use to try to figure out if something like this is trustworthy or not:

  • Trust network. Is it trusted by people you trust to be honest and knowledgeable about such things? I've never used CCleaner myself (I just clean up manually) but people I trust (and know to be knowledgeable about such things) say it's genuine. Similarly, think about how you came to find out about a program. If it was via an advert then that lends no credence (scammers can place adverts quite easily). If it was via a review in a trustworthy publication, that's does lend some credence.
  • Do you understand the business model? CCleaner's is quite clear (a functional free program with paid support). The program that prompted this entry had a free version which just detected problems - fixing the problems required buying the full version. This business model seems just like "scareware" - the free program always finds hundreds of problems (even on a perfectly clean system) because its purpose is to convince people to buy the full version. Being honest would be a disadvantage! Even if the program starts out honest, there's a tremendous incentive to gradually become less honest over time.
  • Does it seem too good to be true? If so, it almost certainly is. (Though exceptions exist.)
  • Is there a way to verify it? Availability of source code is certainly a good sign - it's something genuine programs can do demonstrate their honesty. A scam almost certainly wouldn't bother, because anyone who could examine the source code would not be taken in by it anyway. Though of course, once this starts being a factor a lot of people look for, it'll start being gamed. As far as I can tell, that hasn't happened at the time of writing, though. I think I would have heard about it if it had.
  • What does the internet say about it? Especially known-trustworthy sites that the scammer has no control over. Remember that scammers can put up their own good reviews, but getting bad ones taken down is much more difficult. So if there's a lot of posts in different places by different people saying that it's a scam, that's a pretty good signal that it's bad (not infallible though - someone might have a grudge against the authors of the program for reasons unrelated to whether it does what it's supposed to).

Scan doubler reverse engineered

Saturday, September 22nd, 2012

My XT came with an unusual and interesting ISA card - a PGS scan doubler II. From the name, connections and the chips on it I determined that it was supposed to convert CGA RGBI TTL signals from 15.7KHz horizontal line rate to 31.4KHz, which would make it (timing wise) compatible with standard VGA monitors (it'd still need a DAC to convert from the TTL digital signals to RGB analogue ones).

Soon after I got it, I tried to make it work with my CGA card, but couldn't get anything to display on my VGA monitor. I didn't have an oscilloscope then so there wasn't really much I could do in way of diagnosis (I do have one now, but I still haven't diagnosed the problem due to my XT being en route from Seattle to the UK). For debugging purposes (and just because I was really curious about how it works) I decided to reverse engineer the card to a schematic. Here is the resulting schematic.

Interestingly, it only uses half of it's 2Kb of RAM. There are four 1024x4 bit NMC2148HN-3 SRAM chips, but address line A9 of each chip is grounded, so only the first half of each chip is ever actually read to or written from. One might be inclined to wonder why they didn't use half the number of RAM chips. The answer is memory bandwidth: for each CGA pixel (i.e. at a rate of 14.318MHz) the card has to write a pixel to RAM and read back two. Each pixel is 4 bits, so that's an access rate of 229 megabits per second, which would be too fast for two such chips by a factor of two. So the solution is to increase the bandwidth by parallelization - it turns out that accessing 16 bits at each cycle is enough, but that means having four chips instead of two.

Most of the rest of the card is pretty straightforward - just sequencing the read and write operations in the right order to the different chips, detecting the hsync pulses for genlocking and parallelizing the input pixels. There is one bit which involves logic gates coupled by capacitors - this seems to be a clever hack to double the 14.318MHz clock to generate a 28.636MHz VGA pixel clock (I haven't simulated it because I can't quite read the capacitor values - I think I'll need to unsolder them to measure them). Technically such a clock doubling probably isn't necessary, since the left pixels could be emitted on the low half of the clock and the right pixels on the high (or possibly vice-versa) but maybe the logic delays cause the pixels to interfere, or maybe it was just easier this way.

Purpose of U90 in XT second revision board

Friday, September 21st, 2012

This is an expanded version of a post I originally made over at the Vintage Computer Forums.

My plan to write a cycle exact PC/XT emulator is not going to work as well as I had hoped if it turns out that the various revisions of the PC and XT that IBM made over the years turn out not to even be cycle exact with respect to each other. So I took a look at the differences between the revisions to try to understand if there would be any such differences.

One particularly interesting revision occurred between the first and second revisions of the XT - a whole new chip (U90) was added. The designers of the first revision board had the forethought to leave a space where a standard 14-pin 74LSxx TTL logic IC could be placed, so that revisions requiring extra gates could be made without completely redesigning the board. In the second revision this spare space is populated, but I wasn't able to find any information online about what that change actually did, so I compared the schematics between the first-revision technical reference manual I had, and the updated schematic in the March 1986 technical reference. The difference seems to be this:

In the first revision, input D3 to U88 is -S0 AND -S1 AND -LOCK AND HRQDMA. In the second revision, this is changed to (-S0 AND -S1 AND -LOCK AND HRQDMA) OR (NOT (-DMACS' OR -XIOW')) (U90 is 2-input OR gates, probably a 74LS32). In other words, this input is forced high when writing to the DMA controller registers (IO ports 0x00-0x1f: the 8237). The output Q3 from U88 goes through a couple more flip-flops to HOLDA (the hold acknowledge input to the 8237).

So I guessed that this is some logic to fix a race condition between the CPU and the DMA controller. I suspected that there was a rare situation where the CPU writes something to the DMA controller at the same time that a DMA access happens, the CPU and the DMA controller end up waiting for each other and the system locks up completely. Sergey (of Sergey's XT fame) confirmed it - the logic finds passive CPU cycles when DMA transfer is requested, puts the CPU in wait mode and activates the DMA controller using the HOLDA signal.

I guess that this lockup doesn't happen every time the DMAC is accessed during a DMA transfer or the machine would hang in something like 1 in 18 floppy drive accesses due to the DRAM refresh DMAs. So presumably some "harmless" DMAs will also get delayed by a bus cycle when they happen at the same time as a DMAC transfer. That suggests that it should indeed be possible for software to determine (without checking the BIOS) whether it is running on a first or second revision XT board. And, in turn, if I rely on a piece of software running in an exact number of cycles on one machine it may run in a different number of cycles on the other, at least if the DMA controller is accessed.

For the demo application I'm thinking of, this probably doesn't matter too much - the only time I'm planning to access the DMA controller is to initiate floppy disk transfers to stream in the next part of the demo, and those DMAs will occur at unpredictable times anyway (since the floppy controller has its own crystal). However, it might be interesting to try to write a piece of software that uses small timing differences like these to get all sorts of information about exactly what computer it's running on. As well as this U90 change, it might be possible to tell PCs from XTs by checking the cassette hardware, and it may also be possible to distinguish between many of the different variants of the 8088.

Fractional exponent floating point numbers

Thursday, September 20th, 2012

The usual binary representation of floating point numbers is a sign/exponent/mantissa representation. To get an idea of what this means, consider a hypothetical 6-bit floating point format with 1 sign bit, 3 bits of exponent and 2 bits of mantissa. That gives us 64 possibilities, which is sufficiently few that it's practical to list all the possible values:

0 000 00 +0   1 000 00 -0
0 000 01 +0.0625   1 000 01 -0.0625
0 000 10 +0.125   1 000 10 -0.125
0 000 11 +0.1875   1 000 11 -0.1875
0 001 00 +0.25   1 001 00 -0.25
0 001 01 +0.3125   1 001 01 -0.3125
0 001 10 +0.375   1 001 10 -0.375
0 001 11 +0.4375   1 001 11 -0.4375
0 010 00 +0.5   1 010 00 -0.5
0 010 01 +0.625   1 010 01 -0.625
0 010 10 +0.75   1 010 10 -0.75
0 010 11 +0.875   1 010 11 -0.875
0 011 00 +1   1 011 00 -1
0 011 01 +1.25   1 011 01 -1.25
0 011 10 +1.5   1 011 10 -1.5
0 011 11 +1.75   1 011 11 -1.75
0 100 00 +2   1 100 00 -2
0 100 01 +2.5   1 100 01 -2.5
0 100 10 +3   1 100 10 -3
0 100 11 +3.5   1 100 11 -3.5
0 101 00 +4   1 101 00 -4
0 101 01 +5   1 101 01 -5
0 101 10 +6   1 101 10 -6
0 101 11 +7   1 101 11 -7
0 110 00 +8   1 110 00 -8
0 110 01 +10   1 110 01 -10
0 110 10 +12   1 110 10 -12
0 110 11 +14   1 110 11 -14
0 111 00 +Infinity   1 111 00 -Infinity
0 111 01 SNaN   1 111 01 SNaN
0 111 10 QNaN   1 111 10 QNaN
0 111 11 QNaN   1 111 11 QNaN

So we can represent numbers up to (but not including) 16, in steps of (at finest) 1/16.

The distribution of these numbers (on the positive side) looks like this:

As you can see it approximates an exponential curve but is piecewise linear. Despite there being 64 distinct bit patterns, only 55 real numbers are represented because of the infinities, Not-a-Numbers and the two zeroes. Near zero, the pattern is broken and the numbers between 0 and 0.25 have the same spacing as the numbers between 0.25 and 0.5 - these are called the "denormals" and cause enormous headaches for CPU manufacturers, OS developers, toolchain developers and developers of numerical software, since they often either don't work according to the standards or are much slower than the rest of the floating point numbers.

With IEEE-754 single precision floating point numbers, there are so many pieces to the piecewise linear curve (254 of them for each sign) that the piecewise linearity wouldn't be visible on a graph like this, and the proportion of the bit patterns corresponding to distinct real numbers is much higher (close to 255/256 rather than 7/8).

How different would the world be if we just used an exponential curve instead of a piecewise linear approximation of one? That is to say, what if instead of representing floating point number x as A*2B for some integers A and B, we represented it as 2A/k for some integer A and a constant integer k? In other words, we represent floating point numbers as the exponent of a fixed point fraction (hence, the name Fractional Exponent Floating Point or FEFP). Let's choose k such that the powers of two are the same as in the exponent/mantissa representation, i.e. k=4 in this case, and again list all the possibilities:

0 000 00 +0   1 000 00 -0
0 000 01 +0.1487   1 000 01 -0.1487
0 000 10 +0.1768   1 000 10 -0.1768
0 000 11 +0.2102   1 000 11 -0.2102
0 001 00 +0.25   1 001 00 -0.25
0 001 01 +0.2973   1 001 01 -0.2973
0 001 10 +0.3536   1 001 10 -0.3536
0 001 11 +0.4204   1 001 11 -0.4204
0 010 00 +0.5   1 010 00 -0.5
0 010 01 +0.5946   1 010 01 -0.5946
0 010 10 +0.7071   1 010 10 -0.7071
0 010 11 +0.8409   1 010 11 -0.8409
0 011 00 +1   1 011 00 -1
0 011 01 +1.1892   1 011 01 -1.1892
0 011 10 +1.4142   1 011 10 -1.4142
0 011 11 +1.6818   1 011 11 -1.6818
0 100 00 +2   1 100 00 -2
0 100 01 +2.3784   1 100 01 -2.3784
0 100 10 +2.8284   1 100 10 -2.8284
0 100 11 +3.3636   1 100 11 -3.3636
0 101 00 +4   1 101 00 -4
0 101 01 +4.7568   1 101 01 -4.7568
0 101 10 +5.6569   1 101 10 -5.6569
0 101 11 +6.7272   1 101 11 -6.7272
0 110 00 +8   1 110 00 -8
0 110 01 +9.5137   1 110 01 -9.5137
0 110 10 +11.3137   1 110 10 -11.3137
0 110 11 +13.4543   1 110 11 -13.4543
0 111 00 +16   1 111 00 -16
0 111 01 +SNaN   1 111 01 -SNaN
0 111 10 +QNaN   1 111 10 -QNaN
0 111 11 +Infinity   1 111 11 -Infinity

I moved the infinities to have "all 1s" representation, and just reserved 4 extra entries for NaNs (I'm not sure if anyone actually uses the facility of NaNs to store extra data, but a nice thing about this representation is that you can dedicate as few or many bit patterns to NaNs as you like).

A couple of improvements: our "minimum interval" between adjacent numbers is now about 1/36 instead of 1/16 and (because of the NaN tweak) we can represent slightly higher numbers.

In this representation, there's only one "denormal" (zero) for each sign. That can't fit the pattern however we cut it, since our "A" value never reaches minus infinity, however I suspect people would complain if they couldn't put zero in their floating point variables. This does mean that the interval between zero and the next highest number is larger than the minimum interval.

Would it be practical for CPUs to actually do computations with these numbers? Surprisingly, yes - though the trade-offs are different. Multiplication and division of FEFP numbers is just addition and subtraction (of the fixed point fractional exponent). Addition and subtraction are more complicated - you need to actually take the exponent of the representations, add or subtract them and then compute the logarithm to get the representation of the result. That sounds really hard, but using the CORDIC algorithms and some of the trickery currently used to add and subtract floating point numbers, I think additions and subtractions could be done in about the same time and using roughly the same number of transistors as multiplications and divisions of floating point numbers currently use. What's more, it might be possible to reuse some of the add/subtract logic to actually compute exponents and logarithms (which are themselves quite useful and often implemented in hardware anyway).

So I actually think that FEFP is superior to IEEE754 in several ways. The latter is sufficiently entrenched that I doubt that it could ever be replaced completely, but FEFP might find some use in special-purpose hardware applications where IEEE754 compatibility doesn't matter, such as signal processing or graphics acceleration.

Spam for buying instead of selling

Wednesday, September 19th, 2012

Most unsolicited commercial email tries to get its readers to buy something, but recently I had some spam that was the other way around - they wanted to give me money! Specifically, they wanted to buy ad space on one of my sites. Now, given that I don't have any costs involved in running the site in question (the hosting and domain name were donated), I don't feel I have the right to put ads on the site. I wouldn't want to anyway - it's a better site for not having ads, and it's not like the amount of money involved is likely to make the slightest bit of difference to the quality of my life. For the same reasons I don't have ads on this site (maybe if I could make enough money from the ads to give up my day job it would be a different story but none of my websites has anywhere near that amount of traffic!)

Even so, it took me a moment to decide whether to reply with a polite "no thank you" or to press the "report as spam" button. In the end I decided on the latter course of action - it's still unsolicited commercial email even if it's buying instead of selling. And one of the last things the internet needs is more advertising. It's kind of interesting though that advertisers (or ad brokers at least) are starting to court webmasters - it always seemed to me that the supply of advertising space on the internet vastly outstripped the demand, but maybe that's changing.

Similarly, my web host recently sent me a coupon for $100 of free Google ads - I have no use for them myself (I don't think anyone interested in what I have to say here is going to find it via an ad) but I hope I'll be able to donate them to someone who does have a use for them.

Recompiling only the code that has changed

Tuesday, September 18th, 2012

Designing an entirely new computer language is a ridiculously ambitious thing to attempt as a personal side project, but even so it apparently isn't ambitious enough on its own for me - oh no, I want to write a complete compiler for it as well.

Why would I go to all the trouble of doing that rather than just writing a GCC front end, starting with LLVM or even writing it as a translator to another language?

Well, the short answer is that I want to explore some parts of the design space of both compiler design and languages that I feel have so far gone under-explored. In other words, play around and have some fun.

I do have some specific ideas under that umbrella that I want to try out. Some of these ideas rely on having the entire compiler for my language written in the language itself.

Here is one specific example I've been vaguely thinking about. Suppose we have a compiler that translates ALFE code into an executable binary program. One problem with it is likely to be compilation speed - I'm eliminating separate compilation which is what makes incremental builds possible in C and C++. But I'd also like to have the edit-compile-test cycle be as quick as possible, even for large programs. For large programs, even C/C++ incremental builds are slow because the entire link step has to be done from scratch.

So how can ALFE, which doesn't even have separate compilation, have incremental build times even close to that of C/C++?

What I really need seems to be a daemonic compiler - one that hangs around in memory all the time and keeps all the state from the previous build so that instead of accepting a complete input file it accepts a diff between the input currently in memory and the desired input. The output could be a binary diff but for most of these edit-compile-test cycles we won't even care about the output binary - what we'll really want is a diff in the list of which testcases passed and which failed. It would be great if the compiler could figure out which testcases could possibly be affected by an input diff and only rerun those testcases. It might even be possible to make it sufficiently fast that that it could (asynchronously) recompile with each keystroke in a text editor, so you'll know instantly if your fix makes the broken test pass and if it breaks any other tests. That would be a fantastic boon to productivity - with the right set of tests, updates can be nearly instantaneous once the problem is found!

Such a system would improve reliability of software as well - if the edit-compile-test cycle is that much shorter then any manual testing would be a much greater fraction of it, so programmers would have a much greater incentive to make automated testcases for every bug fix, and test coverage would rapidly improve.

Writing a compiler is hard enough on its own, but taking a normal compiler and modifying it to transform diffs to diffs seems to be task of similarly daunting magnitude. But that's not necessarily the case if we have a compiler that is written in the language that it understands. Modifying the compiler to make it output a diff-to-diff compiler should, I think, be much easier than modifying the compiler to be a diff-to-diff compiler, since I wouldn't have to modify every part of the compiler - it would be a pass on the intermediate form that transformed transformations from f(x)->y form to f(x+dx)->y+dy form. Of course, that's still much easier said than done, but I think it takes it from the realm of the impossible to the realm of the merely very difficult.

Using one scrolling window inside another is annoying

Monday, September 17th, 2012

I'm very impressed with WordPress as a piece of software in general, and particularly at how it's managed to implement a text editor inside a web browser. However, as a text editor it's kind of annoying. It doesn't work terribly well in Internet Explorer for one thing. Even on Firefox and Chrome, it suffers from "one scrolling window inside another" syndrome which is common on many complicated "web applications". Once you've got a got more than a screenful of text in the edit box, you get an inner scrollbar to scroll it up and down. Being a keyboard-oriented sort of person, I usually use the PgUp and PgDn keys for this. PgDn works fine on the inner edit box until you get to the bottom, at which point it stops swallowing the PgDn keypresses and passes them on to the outer window, which then scrolls the top of the edit box off the window. I can't undo this with PgUp because that goes to the inner edit box! This behavior breaks the idea that PgUp and PgDn should do opposite things.

One way to fix this would be to make the edit box expand to fit the text instead of scrolling. There's probably a plugin for this (I've been able to solve just about every other WordPress problem I've had by installing a plugin) but I have no idea how to find it - the obvious searches didn't help. So most of the time I write blog posts in my preferred editor and paste them in. However, I still end up doing a pass over the text in WordPress to fix up the line breaks.

C++ features ALFE doesn't have

Sunday, September 16th, 2012

ALFE's closest ancestor is probably C++ (or possibly D, though I don't have much experience of that language). Though it also draws inspiration from such disparate corners as C#, PHP and Haskell. But there are several C++ features I'm planning on leaving out of ALFE:

  • C compatibility - this is the cause of a great many of the complexities of C++, though is quite probably also the only reason why C++ has been as successful as it has.
  • Separate compilation - another huge source of complexities in C++. The ALFE compiler will have a built in linker, so it will be able to generate an executable binary in a single instantiation. Actually I'm not entirely getting rid of separate compilation - you'll still be able to create and consume object files, but doing so will require explicitly specifying the ABI to use. The problems that are solved by separate compilation I'm planning to solve in different ways, which I'll write about in future posts.
  • Declarations. Declaring something separately from its definition is useful if you have separate compilation, or if you're writing a compiler that can compile programs too big to fit in RAM. RAM is pretty cheap nowadays so this isn't a particularly important use case - certainly not important enough to make programmers duplicate information and have an extra place to modify things when they change. The only things which look like declarations in ALFE will be for things like calling a function declared in an external binary, such as for platform ABI calls. I go to great lengths to minimize the number of declarations in my C++ programs.
  • The preprocessor. Well, macros specifically (anything you might want to use macros for in C or C++ will be done better with features of the core language in ALFE). Header files will still exist but will have rather different semantics. In particular, they won't be included until the code in them is needed - if you put an include statement inside a class definition and then no instance of that class is ever used, the file won't even be opened. That should drastically improve the time it takes to compile files while making it very simple to use the standard library (whose classes will all be included this way by default).
  • The post-increment and post-decrement operators. These do have some merit in C - you can write things like "while (*p != 0) *q++ = *p++;" much more concisely than would otherwise be possible. The first chapter of Beautiful Code has a nice example. However, I don't think these bits of code should be the ones we're making as concise as possible - such a piece of code should be written once, wrapped up as a highly optimized library function and thoroughly documented.
  • Digraphs and trigraphs. You'll need the full ASCII character set to write ALFE, which is probably not much of a hardship any more.
  • Unexpected exceptions (and run-time exception specifications). Exception specifications are a great idea as a compile time check but they make no sense as a run-time check, which is why most coding standards recommend against using them. But the reason that C++ needs exception specifications to be a run-time check instead of a compile-time check is because of separate compilation - there's no way to tell what what exceptions will actually be propagated from any particular function. With compile time exception specifications it's trivial to force the exception specification for destructors to be "nothrow" and thereby make propagating an error from a destructor be a compiler error, which is a much better solution than the "unexpected exception" mechanism in C++.
  • Multiple inheritance. I gave this one a lot of thought before deciding on it. Multiple implementation inheritance is something that seems to get used very little in proportion to the amount by which is complicates the language. I've only seen one even slightly compelling example (the BBwindow etc. classes in chapter 12 of The C++ Programming Language by Stroustoup) and the rationale for that goes away when you have control over all the parts of the program (i.e. you're not consuming code that you can't modify). ALFE actually goes one step further and disallows multiple interface implementation as well on the grounds that if you have a single class implementing more than one interface, it's a violation of the separation of concerns. From an implementation point of view, inheritance is a special case of composition - the parent object is just in the first position. That suggests a good way to simulate multiple interface inheritance - compose the class out of inner classes which implement the various interfaces - pointers to these inner classes are retrieved via method calls rather than casts. I might even add some syntax to streamline this if it gets too verbose. And I might still change my mind and introduce multiple (interface) inheritance if my plan doesn't work.
  • The main() function. Instead the statements in the file passed to the compiler are executed in order from the top - i.e. there is an implicit "main()" wrapped around the entire compilation unit. Command line arguments and environment variables are accessed via library functions (or possibly global variables), which means they don't have to be passed through the call chain from main() to whatever piece of code interprets the command line arguments. That greatly reduces the amount of boilerplate code.
  • public/private/protected/friend. Instead I'm planning to implement "accessibility sections", which are kind of like public/private/protected but specify which classes are allowed to access the members in the section. That way you don't have to give all your friends access to all your private parts, which is possibly the most innuendo-laden complaint about C++.
  • int to bool conversion. The condition in "while" and "if" statements must have boolean type. If you want C semantics you have to add "!= 0" explicitly. I've been doing this anyway in my own C/C++ code and I don't find it to be a source of excess verbosity - if anything it clarifies my intents.
  • Assignments (and increment/decrement) as expressions. This solves the "if (a=b)" problem that C and C++ have, in a far more satisfactory way than the "if (1==b)" abomination that some recommend. I've also been avoiding using assigments as expressions in my C and C++ code and I don't miss them - I think the code I write is clearer without them.
  • C strings (responsible for so many security bugs). ALFE will have a first-class String type, possibly consisting of a pointer to a reference counted buffer, an offset into that buffer and a length, but I'll probably try a few things to see what performs best, and the compiler might even decide to use different representations in different places if there's a performance advantage in doing so.
  • References. I can see why these were necessary in C++ but I think for ALFE they will be unnecessary because of the lack of a fixed ABI, and the "as if" rule (the compiler is allowed to use whatever implementation strategy it likes as long as the semantics don't change). So the rule for deciding how to pass an argument is simple: pass by value if it's strictly an input, pass by pointer if it the function might need to change the output. The compiler will decide whether to actually pass by value or pointer depending on what is fastest on the target architecture for the kind of object being passed.
  • Array to pointer decay. In ALFE, fixed-length arrays are first class types, so passing one to a function declared as (e.g.) "Int foo(Int[4] x)" passes by value, i.e. copies the entire array. Getting a pointer to the first element requires explicitly taking its address: "Int* p = &x[0];"