Yes, indeed it helps with debugging – and reminds me of the non-typed spirit of swi-prolog. It would be good, if one could turn strictness on and off – since does help catch errors as well or at least unintended coupling in code that can later bite …
@j4n_bur53, I am glad you pointed this out – it would have never occurred to me.
Still, i wonder why the VMI generated are non-trivially different - i would have expected at most to see the additional parameter – but semantically, there should be no difference, hence, also no difference in generated VMIs.
Incidentally, in case you’re curious, the fix I’m referring to isn’t about information hiding as much as it is about optimization! When symbols are exported from the shared library, the compiler is forced to assume they might change due to external code or linker behavior, and so can’t make various optimizations. Not to mention, the more symbols that are exported, the more work the dynamic linker has to do in the first place just to load the library into memory.
If there’s any secondary goal there, it’d be about malware prevention and software incompatibilities; the library-internal code assumes that all external access is funneled through the defined API access points, so calling internal functions or changing values would likely cause undefined behavior.
I am looking for dual purpose licenses … it looks to me that the license attached to the code you posted is not such a license, so i better not use this code.
On Mondays, Wednesday, Fridays, I want strict static typing and strong distinctions between public and private; on Tuesday, Thursdays, Saturdays, I don’t want to write so much boilerplate nor things getting in my way when I change my data design. On Sundays, I want to lie on the beach and dream of a perfect world where types (including public/private) don’t slow me down and dynamic types (including the ability to reach inside “private” areas) don’t make debugging more difficult.
We’re a bit off-topic, but there are similar issues that apply to scope of term expansion. I’ve sometimes been able to write code that allowed switching between a “meta-interpreter” and term expansion; but not always … for example, this code uses term expansion to run a hierarchical data structure into a set of relational-like tables. Note that this code doesn’t actually define term_expansion/2 … the definition is where it’s used.
On Tuesday/Thursday/Saturday, I write documentation instead of type declarations.
Not that I’m aware of. And I would love to design a successor language to Prolog, but so far I’ve been unable to think of a way of removing Prolog’s faults without adding new faults that are at least as problematic.
Nope, just my poor attempt at humour – there’s no such thing as an ideal design, and I’m pretty sure that for every case where feature X makes things better, there’s another case where feature X makes things worse. If there many more instances of feature X making things better, then it’s a “good feature”; if feature X makes things better about as often as its alternative or absence makes things better, then it becomes the subject of endless religious wars. The “correct design” of term expansion and modules are probably examples of such features.
I was thinking today at macro’s in lisp are better designed that term expansion approach in Prolog – they look like function calls – just they aren’t … and it seems easier to program a macro seamlessly into the code …
Don’t know where the fault lines for lisp marco’s are … but, more generally, lisp with its brackets syntax and many forms need getting used too
While not a meta-interpreter – I have been thinking about more elaborate meta programming – to see my code as data, taking advantage of the homo-iconic nature of the language and make it used by an expanded (and more focused) inliner, to stitch together optimized code.
Both code would work – one for writing and debugging and one for running more optimally.
It seems like the good of both words – readable code and code that executes faster with much less overhead.
I think for relatively code segments, this may still work without loosing myself into the meta-void …
I wasn’t referring to an “inline” case. I was thinking about developing something more complex (e.g., a variant of DCG) – for development (or debugging), a meta-interpreter is often easier; and a compile-time expansion can sometimes be derived from the meta-interpreter.
First of all, I regret making that comment - I was merely trying to say that I didn’t see an obvious “best solution” and surmised that there wasn’t one.
Please don’t make a fight when no fight was intended. I merely observed that when some feature has many advantages but also many disadvantages, people have a tendency to defend one or the other (e.g., emacs vs vi, or static vs dynamic typing, or various flavours of module definitions).
I’m not accusing anyone in this discussion group of defending anything, religious or otherwise.
BTW, inline/1 seems to cover a lot of common cases, especially if it can easily be turned on and off for debugging. (I wonder if it could lead to an easier way of expanding things like maplist/2 than what’s in library(apply_macros)? … I don’t use them much, partly because I need slight variants, such as sequence//2) .
My aim and hope is that I can stay within swi-prolog as much as possible while at the same time keep to software engineering principles, and in particular, encapsulation of key design decisions (per Parnas).
However, until now this carried a cost of indirection. Yet, the idea behind inline/1 seems to open for me the door to eat the cake and have it too – at least for the relative simple cases I am working with.