Imagine that I want to give readers the option to choose between italic emphasis, bold emphasis, or no emphasis (as I did in my last work).

Further, imagine a work in which the player character can enter the shadow world of Super Mario Bros. 2 or the Up Side Down of Stranger Things. (Neither of these is exactly what I want to do, but each is a near enough analogue.) The same room or objects would remain visible, but they might somehow not be as they were -- they might look different, and they might not respond the same way when the player character tries to interact with them.

In TADS 3 I might declare constants like this:

Code:

#define Italics 1#define Bold 2#define ShadowWorld 4

And once these values had been ORed together, I would use bitwise AND to determine which options had been selected.

The above code implies that '(bold emphasis)' and '(italic emphasis)' are global flags, that can be set or cleared using '(now)' syntax. You'd call that routine from the game intro, and then you'd define an '(emph)' predicate for enabling the player-selected style. Here's what the rest of the program might look like:

Now, under the hood, the compiler will map these global flags to individual bits in some register. So while you are using high-level symbolic predicate names, the compiled code will be using bitwise-and and bitwise-or (and the z-machine 'TEST' instruction) to check and modify the flags.

If you test several flags in the same condition, e.g.

Code:

(if) (first flag) (second flag) (then) ... (endif)

or

Code:

(if) (first flag) (or) (second flag) (then) ... (endif)

then, currently, the compiler isn't smart enough to combine it all into a single check. But such an optimization could be added in the future, if it turns out to have a measurable impact on performance.

hmmm... there's people whose strive for compactness to the extreme, e.g. if something has a narrow range, ends packed together with other short range value variable and/or flags in a bit/word field. and a Z-machine story file is indeed centered around packed (five bits) short-range character strings, but the sheer majority of those strings are static.my 2 €c, and

Yes, this is a fascinating part of language design, and there are many ways to think about it.

Personally, I am very fond of the nitty-gritty details of low-level optimization, but I don't think it belongs at the story level. When in "author mode", I want to focus on characters, plot, and scenes, as well as robustness, puzzles, geography, hints, synonyms, and responses. Getting bogged down in bitfields would be a distraction.

Ideally I want a high-level language that can be converted into efficient low-level code, using all kinds of clever optimization trickery in the compiler. That doesn't work unless the language is designed with such optimizations in mind, but that is the case with Dialog. In my example above, '(bold emphasis)' compiles down to a single bit of memory. I don't see how the people who "strive for compactness to the extreme" could do any better than that.

Meanwhile, there's another danger when you begin to expose too much detail at a high level: It becomes more difficult to optimize the code automatically. If, for instance, you allow the story author to specify numeric constants for the compass directions, so they can be stored in four bits, then you might inadvertently prevent the compiler from picking a two-bit encoding for stories that only use north, south, up, and out.

Now, as it happens, the current Dialog compiler doesn't perform that particular optimization. And, in fairness, there are aspects of the language where I've valued versatility over compactness. But as a general rule of thumb, high-level code tends to be more amenable to automated analysis and optimization.

Dialog predicates turn into executable code, z-machine object flags, global registers, bits, linked lists, arrays, word tables stored inside object properties, etc. etc. depending on how they are accessed from the rest of the program. The author shouldn't have to bother with it, and shouldn't be allowed to meddle with it, getting in the way of the optimizer.

Bitfield packing is no panacea. You bring up z-machine text encoding as an example. That happens to be a very inefficient solution; a Huffman code would fare way better, and would certainly fit inside the memory of an 8-bit system, while improving loading times due to the increased compression ratio. But, despite its flaws, I think z-machine text encoding is a good example of a nicely designed optimization, precisely because it stays out of the way of the author, who is free to focus on more important things.

The only benefit of symbolic constants is that they increase the clarity of the code, but the code you have written is quite clear. I also like that Dialog allows a variable representing the control code to be inserted into the text printed to the screen; I was afraid I would have to give that up if I moved away from TADS 3.

Agree on all this, albeit personally I think that some corner can be cut, for example, as you pointed:

lft wrote:

Yes, this is a fascinating part of language design, and there are many ways to think about it.

Meanwhile, there's another danger when you begin to expose too much detail at a high level: It becomes more difficult to optimize the code automatically. If, for instance, you allow the story author to specify numeric constants for the compass directions, so they can be stored in four bits, then you might inadvertently prevent the compiler from picking a two-bit encoding for stories that only use north, south, up, and out.

it's a case for "semi-auto optimisation", (conditional compiling, macros, defining variable types) as I call it, but this require a pre-processing of the code, and I guess that you don't want trading elegancy and simplicity for flexibility.

OTOH, IF libraries needs means for customisation, at least of the stock responses (going up while angel, one of my favorite jokes on sins and mimesis... but let's not open again THAT debate )

Yes, I want to support several languages. The Dialog programming language isn't restricted to English, apart from keywords and the names of built-in predicates. User-defined names can contain UTF-8 characters.

In order to write a non-English story, one would first have to translate the standard library. I know that somebody is looking into making a German translation, and I've added a feature to the language (removable word endings) to facilitate that. I'm willing to add other features that are necessary for other languages, as long as it fits reasonably well with the rest of the system design.

Who is online

Users browsing this forum: No registered users and 2 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum