When you think about it all constants are named. The constants themselves don’t exist (ok they have an ideal existence!), we use their names. The constant 42 is not a number, it’s a numeral that is used to name a number.
Now, both icd10hypertensionand 'R02.0' are ‘constants’. It’s just two different names for the same thing. You just write your code to accept either or both.
You can then define a translation table, for example (although it might make more sense to split out the ‘icd10’ part into a 3rd column, giving the code (icd10, snomed, cpt4, etc.); or have multiple code tables.
No, the purpose of named constants (generally) is:
to have a single place in your code to bind a name to value
allow the single name to be referenced in many places
allow the name to be used in place of the value (providing the reader the meaning to the value), and,
(most importantly), complain if the name does not exist (e.g. mispelled).
If I place this name in a single exported predicate, prolog will fail silently on misspellings or missing codes:
code(icd10hypertension, 'R03.0').
% f(X)--->false, but should be an error. icd10hypertons is not a missing predicate
f(X) :- code(icd10hypertons, C), f(icd10hypertension, 'R03.0').
right? So,
icd10hypertension('R03.0').
% icd10hypertons is a missing predicate
f(X) :- icd10hypertons(C), f(icd10hypertension, 'R03.0').
...
is preferred. However, now if I create ‘code.pl’ to define and share these named constants, I need to export each of 50, right? (A PITA, and is easy to miss some).
I don’t define all 20,000 icd10 codes this way – I would get them from a database – just this small number have special meaning in the prolog program and I don’t want to paste in meaningless-to-the-reader icd10 values at those places, or have the program continue without error due to silly spelling mistakes.
Hmmm… interesting.
if I queried the database for the list of predicates, would it find icd10hypertension, or does this method magic it into existence during the query?
If the latter. Perhaps would be better to query constant during the module’s initialization and assert those names?
@peter.ludemann Thank you. This would thwart any static error analysis. I’m not sure this makes a difference in Prolog-land though, since it seems to be without many compile-time types. :
It also means more visual noise (therefore less readable) than one predicate per code.
We must:
code(icd10hypertension, C), g(C).
instead of
icd10hypertension(C), g(C).
I was kinda hoping it would be possible to reduce it to:
g(icd10hypertension.value).
where predicate.value is a macro that rewrites outer(predicate.value) as predicate(X), outer_predicate(predicate) , or somesuch. (ie. or some similar syntax). Does prolog have the notion of unaries-- names bound to exactly one value (in which case the perhaps the compiler could be coerced into simply re-writing the name with its single value)?
Yes, that predicate would be defined. term_expansion/2 is essentially macros for Prolog; loading the file would re-write the constants(whatever, 'R0.3). line to be as if you had written whatever('R0.3'). :- export(whatever/1).
Nifty. So its evaluated while the file is compiled? Like a directive? (The docs says "When defined by the user all terms read during consulting are given to this predicate…, ‘consulting’==on load_file?)
If i understand this correctly, all approaches discussed here suggest having a named constant that is retrieved during runtime – in one way or another – via predicate lookup.
I guess this is always slower than a named constant in compiled languages where the symbol gets replaced during compile time by the declared value.
So, to have “real” named constant in prolog would require some kind of extension – perhaps an extension of the macro facility.
Not so much extension. Just use the macro mechanism for replacing some term. The only gotcha is that you somehow have to recognise the thing you want to expand from anything else, so you can give an error if the constant does not exist. You could for example expand c.name. The ffi package does something like that to get access to C #define macros
seek another language that is more acceptable for you,
fall back and use something you already have fluency in, or
continue as you are suffering much frustration.
I was there with Prolog in the early 1990s (eventually did no. 1). I’m there with another language right now (doing no. 4 I’m afraid, but economics will force me into no. 1).