Here is a use case. I have a function that takes variable parameters, so there is no formal type control:
int Foo(int a, ...);
But in fact the types are restricted depending on a call type, set by 'a'. So I could add a wrapper for a specific variant:
static inline FooVar1(char b, long c)
{
return Foo(FOO_VAR_1, b, c);
}
All the wrapper does is adds a bit of type control during compilation, otherwise it must be just a function call to 'Foo'. It is like a supermacro. It does make sense to put that into 'static inline' in a header.
That is not an option - it may be layers on layers of them and force you to recreate half the library and force you to have to redo subsequent version updates in your code. Then a shim is the preferred solution. But anything that requires a C compiler for FFI is something that won't make anyone happy. Hence my claim that it really is something that needs fixing on the language or linker level.
But FooVar1 isn't part of the library, that's the point. Sure, the library developer could choose to make it a part, but he explicitly choose to not make it a part of the library. Hence, it is also nothing that needs fixing, because it is already possible to make the interface boundary somewhere else, people just choose to do it this way. As far as the language and the linker is concerned FooVar1 is part of your code, not part of the library.
If the language provides nice features to libraries for C language users by sabotaging the library for use outside the language, then this is absolutely a problem on the language side.
The library interface says to do X call `Foo(FOO_VAR_1, b, c)`. That is what you need to somehow call from another language using FFI. In addition it also has an example wrapper for convenience. You can choose to also include that example as part of your implementation in another language, but you don't need to. I fail to see how that is sabotaging.
It also does not have to do anything with the language, because it IS possible to have FooVar1 as part of the interface. The library developer just didn't want that, likely because they do not want tons of slightly different functions in the interface that they would need to maintain, when they already exposed that functionality.
EDIT:
Concerning your earlier complaint, that you would need to
> have to redo subsequent version updates in your code.
, such a change would be ABI-incompatible anyway and demand a change in the major version number of the library. Neither your FFI, nor any program even when written in C, is going to work anymore. The latter, would just randomly crash, not sure about the former.
Note, that you also see here, where the real interface is. A change to Foo itself, would break programs written in C as well as your FFI, while a change to FooVar1 wouldn't matter at all. Both C programs and your FFI will continue to run just fine without any changes.
> likely because they do not want tons of slightly different functions
No. They do it because it avoids the overhead of dynamic dispatch. Nothing else.
So when I've seen these in reality in real library interfaces they have not been 'example wrappers'. They are real intended usage of the API, and in some cases the lib authors recognize that it is a problem and even provide ways to build it without the issues - either by compile time flag or always outputting two variants of the .so. The former moves the question to the distro - should they provide the version optimized for C or the one optimized for other languages? In the case of the latter it obviously creates a situation where the vast majority of both .so-s are duplicated.
As an example of the compile flag, there is libpipewire. As an example of providing two versions of the .so, there is liburing.
So no, this is clearly something the language ecosystem lacks a good answer to. There is currently no way to make everyone happy.
> such a change would be ABI-incompatible anyway
True, but the C based ones can at least simply rebuild and the problem would go away.
I dabbled into literate programming and wrote C basically in reStructuredText. Used '#line' to specify the correct file name and line number in my reStructuredText sources. Worked as advertised, no complaints.
In my case I had long-ish fragments, so I only put '#line' at the start of a fragment. The compiler counted subsequent lines itself.
It was a cross-platform project and worked equally well with GCC, Clang and MS Visual C++.
All artificial things that we make are rough inside. Yet the living things are not, they are beautiful on every level. And above the mere survival needs we do have a yearn for the same quality in what we make.
I want to write general apps in C. Such as a raster image editor. I have some idea and C has exactly the right mix of simplicity and flexibility that I need. C is a constructor, and as a constructor it places few limits on what you can do. Other environments are way more rigid. E. g. I find Python way too rigid compared to C.
16 bytes is a lot. 4 bytes are within reach, we can scan all of them quickly, but even 8 bytes are already too much.
Kolmogorov said that computers do not help with naturally hard tasks; they raise a limit compared to what we can fo manually, but above that limit the task stays as hard is it was.
Couldn't it be merely a criminal claiming to be a political victim to avoid extradition? Never heard the name here at all, let alone in a political context.
I myself know from close hearsay a fellow who happily traded grain until 2022 when he left for US with $50m of a bank's money in his pocket. A few people in the bank lost their jobs as a result. Those people would certainly welcome that critic back.
I guess he could be, but Interpol themselves seems to disagree with that since they canceled the request after looking into it deeper:
> After Pestrikov had spent almost two years on the wanted list, the CCF ruled that his case was predominantly political. He showed us CCF documents that said the information Russia had provided was "generic and formulaic" and there had been an "inadequate explanation" of the alleged crime. Interpol cancelled the request for Pestrikov's detention.
As an oligarch who acquired a mining company on the cheap during the post soviet gangster 90s he doesnt exactly fit the profile of a beleagured peace activist.
The way that he is described by the BBC as a businessman (not an oligarch) also suggests that he was taken off the list for political reasons. London collects activist Russian oligarchs the same way Washington collects activist ex-Iranian monarchy.
Yes, you either put your trust with CCF, BBC and this man, or Russia, both sides could claim the same about the other. I don't have any experience with CCF, I do trust BBC, I don't trust that man, so in the end I trust that what BBC writes is closer to the truth.
That's a mistake. BBC has perfected the art of omitting relevant information thus creating a completely different story.
My favorite example so far is that after that debacle with Canadian parliament giving standing ovation to a very old Ukrainian who fought against the USSR (and also collaborated with Nazi, as some Canadian Jewish organization was quick to point out), the BBC counteracted "Russian propaganda" by pointing out that almost all Ukrainians fought against Nazis in WW2, completely forgetting to mention the fact that post-2014 regime in Kiev glorifies former Nazi collaborators and demolishes memorials of Soviet generals who fought Nazis.
The most cynical was the renaming of major avenue in Kiev leading to Babiy Yar (the place where thousands of Jews were massacred) to honor Bandera and the renaming of the avenue that used to honor Nikolai Vatutin[0], Soviet general who fought Nazis on the territory of Ukraine, after Shukhevych[1], another Nazi collaborator and mass murderer.
It's not a black & white "believe everything they say".
It's a "You have these two parties, with different stories, who do you trust more?" and in this case, easily BBC, even though they, like any media organization, commit mistakes sometimes.
And again, I don't trust what BBC claims without thinking about it myself, just like I won't take what CNN says at face value. But context matters.
Semantic in machine processing is actually very simple: if a machine has an instruction to process an element and we know what it does, then the element is semantic.
So, for example, <b> and <i> have perfect semantic, while <article> not so much. What does the browser do with an <article>? Or maybe it is there for an indexing engine? I myself have no idea (nor that I investigated that, I admit).
But all that was misunderstood, very much like XML itself.
The <article> command in HTML can be useful, even if most implementations do not do much with it. For example, a browser could offer the possibility to print or display only the contents of a single <article> block, or to display marks in the scrollbar for which positions in the scrollbar correspond to the contents of the <article> block. It would also be true of <time>; although many implementations do not do much with it, they could do stuff with it. And, also of <h1>, <h2>, etc; although browsers have built-in styles for them, allowing the end user to customize them is helpful, and so is the possibility of using them to automatically display the table of contents in a separate menu. None of these behaviours should need to be standardized; they can be by the implementation and by the end user configuration etc; only the meaning of the commands will be standardized, not their behaviour.
"Meaning" has a rather vague meaning, but behavior is exact. If I know the behavior, it becomes a tool I can employ. If I only know supposed behavior, I cannot really use that. E.g. why we have so much SEO slop and so little "semantic" HTML? Because the behavior of search engines is real and thus usable, even when it is not documented much.
See that the difference is only two characters? Yet XML also has a four-character element name, which JSON lacks. And JSON is packed to the limit, while XML is written naturally and is actually more readable than JSON.
I like XML and I use it for myself daily. E.g. all documentation is XML; it is just the perfect tool for the task. Most comments that denigrate XML are very superficial. But I disagree with this article too.
My main point is that the very purpose of XML is not to transfer data between machines. XML use case is to transfer data between humans and machines.
Look at the schemas. They are all grammatical. DTD is a textbook grammar. Each term has a unique definition. XSD is much more powerful: here a term may change definition depending on the context: 'name' in 'human/name' may be defined differently than 'name' in 'pet/name' or 'ship/name'. But within a single context the definition stays. As far as I know Relax NG is even more powerful and can express even finer distinctions, but I don't know it too well to elaborate.
Machines do not need all that to talk to each other. It is pure overhead. A perfect form to exchange data between machines is a dump of a relational structure in whatever format is convenient, with pretty straightforward metadata about types. But humans cannot author data in the relational form; anything more complex than a toy example will drive a human crazy. Yet humans can produce grammatical sequences in spades. To make it useful for a machine that grammatical drive needs only a formal definition and XML gives you exactly that.
So the use case for XML is to make NOTATIONS. Formal in the sense they will be processed by a machine, but otherwise they can be pretty informal, that is have no DTD or XSD. It is actually a power of XML that I can just start writing it and invent a notation as I go. Later I may want to add formal validation to it, but it is totally optional and manifests as a need only when the notation matures and needs to turn into a product.
What makes one XML a notation and another not a notation? Notations are about forming phrases. For example:
This is a description of a C function, 'open'. Of course, a conventional description is much more compact:
int open(char const*, int, ...)
But let's ignore the verbosity for a moment and stay with XML a bit longer. What is grammatical about this form? 'func' has '@name' and contains 'data' and 'args'. 'data' is result type, 'args' are parameters. Either or both can be omitted, resulting in what C calls "void". Either can be 'data' or 'addr'. 'data' is final and has '@type'; addr may be final (point to unknown, 'void') or non-final and may point to 'data', 'func' or another 'addr', as deep as necessary. 'addr' has '@mode' that is a combination of 'c', 'v', 'r' to indicate 'const', 'volatile', 'restrict'. Last child of 'args' may be 'varg', indicating variable parameters.
Do you see that these terms are used as words in a mechanically composed phrase? Change a word; omit a word; link words into a tree-like structure? This is the natural form of XML: the result is phrase-like, not data-like. It can, of course, be data-like when necessary but this is not using the strong side of XML. The power of XML comes when items start to interact with each other, like commands in Vim. Another example:
<aaaa>
<bbbb/>
</aaaa>
This would be some data. Now assume I want to describe changes to that data:
See those 'make' and 'drop'? Is it clear that they can enclose arbitrary parts of the tree? Again, what we do is that we write a phrase: we add a modifier, 'make' or 'drop' and the contents inside it get a different meaning.
This only makes sense if XML is composed by hand. For machine-to-machine exchange all this is pure overhead. It is about as convenient as if programs talked to each other via shell commands. It is much more convenient to load a library and use it programmatically than to compose a command-line call.
But all this verbosity? Yes, it is more verbose. This is a no-go for code you write 8 hours a day. But for code that you write occasionally it may be fine. E.g. a build script. An interface specification. A diagram. (It is also perfect for anything that has human-readable text, such as documentation. This use is fine even for a 8-hour workday.) And all these will be compatible. All XML dialects can be processed with the same tools, merged, reconciled, whatever. This is powerful. They require no parsing. Parsing may appear a solved problem, but to build a parser you still must at least describe the grammar for a parser generator and it is not that simple. And all that this description gives you is that the parser will take a short form and convert it into an AST, which is exactly what XML starts with. The rest of the processing is still up to you. With XML you can build the grammar bottom up and experiment with it. Wrote a lot of XML in some grammar and then found a better way? Well, write a script to transform the old XML into the new grammar and continue. The transformer is a part of the common toolset.
reply