You have just described OSF/1 (and later – Tru64) – a certified UNIX with a hybrid kernel operating over a Mach microkernel, BSD userland, POSIX conformance etc.
This could be a great fit for Prolog, in fact, as it excels at the search.
Each resolved record would be asserted as a fact, and a tiny search implementation would run after all assertions have been made to resolve the IP address irrespective of the order in which the RRsets have arrived.
A micro Prolog implementation could be rolled into glibc's resolver (or a DNS resolver in general) to solve the problem once and for all.
Finnish case markers vary a lot from word to word, because of not only vowel harmony but other features of the word stem, and consonant gradation which is a weird feature of Uralic languages.
For the subtraction example, some numbers would be 50:tä 5:llä and others 6:tta 3:lla. Of course you could encode for all those possibilities and successfully parse them, but it would feel weird for a compiler to reject an expression because it's ungrammatical Finnish.
Also it would feel weird if you first write (vähennä muuttujaa 256:lla) but then realise you made an off-by-1 and have to change it to (vähennä muuttujaa 255:lla) but that doesn't compile because it should be 255:llä, so you have to remember to change two things.
But on the other hand, that's just how it is to write in Finnish, so in prose we don't really think about it. In natural language, it's normal to have to change other stuff in a sentence for it to continue making sense when you change one thing.
A grammatical mood indicates the modality of the verb, and some languages possess rich inventories of the grammatical moods. They are called differently in different languages, but mood is an established term in English.
English has indicative («go», «is going» etc), subjunctive / conjunctive / conditional («went» in «as if they went»), imperative («go!»).
German has two conditional moods – Konjunktiv I and II, for example.
> English has ... subjunctive / conjunctive / conditional («went» in «as if they went»)
That isn't the English subjunctive.
You're correct that this construction expresses the same thing that another language might express by marking a non-indicative mood on the verb, but it would not conventionally be said to use a non-indicative mood. That went is a normal past-tense indicative verb and the modality is expressed by the whole structure of the clause, not just by the inflection of the verb.
In linguistics there's a whole set of parallel vocabulary where one set is for grammatical forms and the mirror set is for the semantics usually expressed by those forms. So you have grammatical "tense" and semantic "time" or grammatical "mood" and semantic "modality". You got the modality right, but not the mood.
Compare the conventional analysis that he will be there tomorrow expresses future time, but is not in future tense because there is no English future tense.
No, it is not a proper English subjunctive (a correct example would have been «as if they were» – past subjunctive) or «[we suggested] that they go».
I deliberately lumped subjunctive, conjunctive, and conditional together for brevity. Part of the problem is that many English speakers do not differentiate between subjunctive and conjunctive (conditional) and incorrectly label the latter as subjunctive, but that happens because English does not have a conjunctive (conditional) mood.
English subjunctive is translated into other Indo-European languages either as the conjunctive or indicative mood, as there is no 1:1 mapping in existence.
> Chinese novels are on the other side of the spectrum. The sentences simply can't be very long and but often don't have any connecting words between sentences. The readers have to infer.
There is no grammatical ceiling on sentence length in Sinitic languages, Chinese languages (all of them) can form long sentences, and they all do possess a great many connecting words. Computational work on Chinese explicitly talks about «long Chinese sentences» and how to parse them[0].
However, many Chinese varieties and writing styles often rely more on parataxis[1] than English does, so relations between clauses are more often (but not always) conveyed by meaning, word order, aspect, punctuation, and discourse context, rather than by obligatory overt conjunctions. That is a tendency, not an inability.
Sure. You can try to create arbitrarily long sentences with nested clauses in Chinese. Just like in English you can create arbitrarily long sentences like: "I live in a house which was built by the builders which were hired by the owner who came from England on a steamship which was built...".
But it feels unnatural. So most Chinese sentences are fairly short as a result. And it's also why commas, stops, and even spacing between words are a fairly recent invention. They are simply not needed when the text is formed of implicitly connected statements that don't need to be deeply nested.
To give an example, here's our favorite long-winded Ishmael: "Yes, here were a set of sea-dogs, many of whom without the slightest bashfulness had boarded great whales on the high seas—entire strangers to them—and duelled them dead without winking; and yet, here they sat at a social breakfast table—all of the same calling, all of kindred tastes—looking round as sheepishly at each other as though they had never been out of sight of some sheepfold among the Green Mountains." The Chinese translation is: "是的,这里坐着的是一群老水手,其中有很多人,在怒海中会毫不畏怯地登到巨鲸的背上——那可是他们一无所知的东西啊——眼都不眨地把鲸鱼斗死;然而,这时他们一起坐在公共的早餐桌上——同样的职业,同样的癖好——他们却互相羞怯地打量着对方,仿佛是绿山山从未出过羊圈的绵羊"
Or word-for-word: "Yes, here sitting [people] are the group of old sailors, among them there are many people, [who] in the middle of the raging sea can/will without fear on the whale's back climb. That whales were something they knew nothing about".
The subordinate clauses become almost stand-alone statements, and it's up to the reader to connect them.
I can see your point now, and we are in agreement that nested clauses are uncommon and at the very least sound unnatural in Sinitic languages, but it is distinct from «The sentences simply can't be very long and often don't have any connecting words between sentences».
Strictly speaking, complex nested clauses are slowly on the way out of English as well due to the analytical nature of its present form, which is what the cited article partially laments, and remain a distinctive feature of highly inflected languages (German, Scandinavian, Slavic, etc.).
> Some English translations of Russian literature can run into the absurd (sentences at half a page long), but even then there is a beauty to it.
C. K. Scott Moncrieff and Terence Kilmartin’s translation of Marcel Proust’s «In Search of Lost Time (Remembrance of Things Past)» contains nearly half-page long sentences.
Many modern readers complain about the substantial difficulty in following such sentences, although I personally find them delightful.
Meet TIMI – the Technology Independent Machine Interface of IBM's i Series (nèe AS/400), which defines pointers as 128-bit values[0], which is a 1980's design.
It has allowed the AS/400 to have a single-level store, which means that «memory» and «disk» live in one conceptual address space.
A pointer can carry more than just an address – object identity, type, authority metadata – AS/400 uses tagged 16-byte pointers to stop arbitrary pointer fabrication, which supports isolation without relying on the usual per-process address-space model in the same way UNIX does.
Such «fat pointer» approach is conceptually close to modern capability systems (for example CHERI’s 128-bit capabilities), which exist for similar [safety] reasons.
[0] 128-bit pointers in the machine interface, not a 128-bit hardware virtual address space though.
It is, although TIMI does not exist in the hardware – it is a virtual architecture that has been implemented multiple times in different hardware (i.e., CPU's – IMPI, IBM RS64, POWER, and only heavens know which CPU IBM uses today).
The software written for this virtual architecture, on the other hand, has not changed and continues to run on modern IBM iSeries systems, even when it originates from 1989 – this is accomplished through static binary translation, or AOT in modern parlance, which recompiles the virtual ISA into the target ISA at startup.
> But we don't have a linear address space, unless you're working with a tiny MCU.
We actually do, albeit for a brief duration of time – upon a cold start of the system when the MCU is inactive yet, no address translation is performed, and the entire memory space is treated as a single linear, contiguous block (even if there are physical holes in it).
When a system is powered on, the CPU runs in the privileged mode to allow an operating system kernel to set up the MCU and activate it, which takes place early on in the boot sequence. But until then, virtual memory is not available.
Those holes can be arbitrarily large, though, especially in weirder environments (e.g., memory-mapped optane and similar). Linear address space implies some degree of contiguity, I think.
Indeed. It can get ever weirder in the embedded world where a ROM, an E(E)PROM or a device may get mapped into an arbitrary slice of physical address space, anywhere within its bounds. It has become less common, though.
But devices are still commonly mapped at the top of the physical address space, which is a rather widespread practice.
And it's not uncommon for devices to be mapped multiple times in the address space! The different aliases provide slightly different ways of accessing it.
For example, 0x000-0x0ff providing linear access to memory bank A, 0x100-0x1ff linear access to bank B, but 0x200-0x3ff providing striped access across the two banks, with evenly-addressed words coming from bank A but odd ones from bank B.
Similarly, 0x000-0x0ff accessing memory through a cache, but 0x100-0x1ff accessing the same memory directly. Or 0x000-0x0ff overwriting data, 0x100-0x1ff setting bits (OR with current content), and 0x200-0x2ff clearing bits.
> Because the attempts at segmented or object-oriented address spaces failed miserably.
> That is false. In the Intel World, we first had the iAPX 432, which was an object-capability design. To say it failed miserably is overselling its success by a good margin.
I would further posit that segmented and object-oriented address spaces have failed and will continue to fail for as long as we have a separation into two distinct classes of storage: ephemeral (DRAM) and persistent storage / backing store (disks, flash storage, etc.) as opposed to having a single, unified concept of nearly infinite (at least logically if not physically), always-on just memory where everything is – essentially – an object.
Intel's Optane has given us a brief glimpse into what such a future could look like but, alas, that particular version of the future has not panned out.
Linear address space makes perfect sense for size-constrained DRAM, and makes little to no sense for the backing store where a file system is instead entrusted with implementing an object-like address space (files, directories are the objects, and the file system is the address space).
Once a new, successful memory technology emerges, we might see a resurgence of the segmented or object-oriented address space models, but until then, it will remain a pipe dream.
I don't see how any amount of memory technology can overcome the physical realities of locality. The closer you want the data to be to your processor, the less space you'll have to fit it. So there will always be a hierarchy where a smaller amount of data can have less latency, and there will always be an advantage to cramming as much data as you can at the top of the hierarchy.
while that's true, CPUs already have automatically managed caches. it's not too much of a stretch to imagine a world in which RAM is automatically managed as well and you don't have a distinction between RAM and persistent storage. in a spinning rust world, that never would have been possible, but with modern nvme, it's plausible.
Cpus manage it, but ensuring your data structures are friendly to how they manage caches is one of the keys to fast programs - which some of us care about.
Absolutely! And it certainly is true that for the most performance optimized codes, having manual cache management would be beneficial, but on the CPU side, at least, we've given up that power in favor of a simpler programming model.
Part of giving up is what is correct changes too fast. Attempts to do this manually often got great results for a year and then made things worse for the next generation of CPU that did things differently. Anyone who needs manual control thus would need to target a specific CPU and be willing to spend hundreds of millions every year to update the next CPU - there is nobody who is willing to spend that much. The few who would be are better served by putting the important thing into a FPGA which is going to be faster yet for similar costs.
«Memory technology» as in «a single tech» that blends RAM and disk into just «memory» and obviates the need for the disk as a distinct concept.
One can conjure up RAM, which has become exabytes large and which does not lose data after a system shutdown. Everything is local in such a unified memory model, is promptly available to and directly addressable by the CPU.
Please do note that multi-level CPU caches still do have their places in this scenario.
In fact, this has been successfully done in the AS/400 (or i Series), which I have mentioned elsewhere in the thread. It works well and is highly performant.
> «Memory technology» as in «a single tech» that blends RAM and disk into just «memory» and obviates the need for the disk as a distinct concept.
That already exists. Swap memory, mmap, disk paging, and so on.
Virtual memory is mostly fine for what it is, and it has been used in practice for decades. The problem that comes up is latency. Access time is limited by the speed of light [1]. And for that reason, CPU manufacturers continue to increase the capacities of the faster, closer memories (specifically registers and L1 cache).
I think seamless persistent storage is also bound to fail. There are significant differences on how we treat ephemeral objects in programs and persistent storage. Ephemeral objects are low value, if something goes wrong we can just restart and recover from storage. Persistent storage is often high value, we make significant effort to guarantee its consistency and durability even in the presence of crashes.
I shudder to think about the impact of concurrent data structures fsync'ing on every write because the programmer can't reason about whether the data is in memory where a handful of atomic fences/barriers are enough to reason about the correctness of the operations, or on disk where those operations simply do not exist.
Also linear regions make a ton of sense for disk, and not just for performance. WAL-based systems are the cornerstone of many databases and require the ability to reserve linear regions.
Linear regions are mostly a figment of imagination in real life, but they are a convenient abstraction and a concept.
Linear regions are nearly impossible to guarantee, unless the underlying hardware has specific, controller-level provisions.
1) For RAM, the MCU will obscure the physical address of a memory page, which can come from a completely separate memory bank. It is up to the VMM implementation and heuristics to ensure the contiguous allocation, coalesce unrelated free pages into a new, large allocation or map in a free page from a «distant» location.
2) Disks (the spinning rust variety) are not that different. A freed block can be provided from the start of the disk. However, a sophisticated file system like XFS or ZFS, and others like it, will make an attempt do its best to allocate a contiguous block.
3) Flash storage (SSDs, NVMe) simply «lies» about the physical blocks and does it for a few reasons (garbage collection and the transparent reallocation of ailing blocks – to name a few). If I understand it correctly, the physical «block» numbers are hidden even from the flash storage controller and firmware themselves.
The only practical way I can think of to ensure the guaranteed contiguous allocation of blocks unfortunately involves a conventional hard drive that has a dedicated partition created just for the WAL. In fact, this is how Oracle installation worked – it required a dedicated raw device to bypass both the VMM and the file system.
When RAM and disk(s) are logically the same concept, WAL can be treated as an object of the «WAL» type with certain properties specific to this object type only to support WAL peculiarities.
Ultimately everything is an abstraction. The point I'm making is that linear regions are a useful abstraction for both disk and memory, but that's not enough to unify them. Particularly in that memory cares about the visibility of writes to other processes/threads, whereas disk cares about the durability of those writes. This is an important distinction that programmers need to differentiate between for correctness.
Perhaps a WAL was a bad example. Ultimately you need the ability to atomically reserve a region of a certain capacity and then commit it durably (or roll back). Perhaps there are other abstractions that can do this, but with linear memory and disk regions it's exceedingly easy.
Personally I think file I/O should have an atomic CAS operation on a fixed maximum number of bytes (just like shared memory between threads and processes) but afaik there is no standard way to do that.
I do not share the view that the unification of RAM and disk requires or entails linear regions of memory. In fact, the unification reduces the question of «do I have a contiguous block of size N to do X» to a mere «do I have enough memory to do X?», commits and rollbacks inclusive.
The issue of durability, however, remains a valid concern in either scenario, but the responsibility to ensure durability is delegated to the hardware.
Futhermore, commits and rollbacks are not sensitive to the memory linearity anyway; they are sensitive to durability of the operation, and they may be sensitive to the latency, although it is not a frequently occurring constraint. In the absence of a physical disk, commits/rollbacks can be implemented using the software transactional memory (STM) entirely in RAM and today – see the relevant Haskell library and the white paper on STM.
Lastly, when everything is an object in the system, the way the objects communicate with each other also changes from the traditional model of memory sharing to message passing, transactional outboxes, and similar, where the objects encapsulate the internal state without allowing other objects to access it – courtesy of the object-oriented address space protection, which is what the conversation initially started from.
What is the point that you are making?
reply