I’m working on an app that will accept user jsons. Assuming the user enters spec-compliant json, that’s not going be interpretable directly in prolog, ie.
?- J = _{a:1,b:2,c:3}, O = J.b .
J = _{a:1, b:2, c:3},
O = 2.
?- J = {a:1,b:2,c:3}, O = J.b.
ERROR: Type error: `dict' expected, found `{a:1,b:2,c:3}' (a compound)
How do I convert an entered {a:1} into prolog _{a:1} if it’s not coming from a stream?
Then just write _{k:v, ...}. It is more interesting if the JSON comes from a stream. There is json_read_dict/2 and a couple of related predicates that read and write JSON and transform it into a Prolog dict (or visa versa). As JavaScript objects, Prolog dicts look like JSON, but they are not the same thing. For a start, dicts can hold things JSON cannot such as arbitrary Prolog terms.
Alright then just to confirm, if I’m getting user input as a direct argument my source code, and let’s say that user isn’t familiar with prolog, let alone prolog data structures/conventions, and who would be tempted based on most other programming languages to pass in a spec-compliant json, the only way to handle that is through a readme and/or user training?
>>> from jose import jwt
>>> token = jwt.encode({'key': 'value'}, 'secret', algorithm='HS256')
u'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ2YWx1ZSJ9.FG-8UppwHaFp1LgRYQQeS6EDQF7_6-bMFegNucHjmWg'
so if this source code is sitting on someone’s laptop, they can just load python and go jwt.encode({'key': 'value'},'k'). I was hoping I could provide the same ease of use in prolog. If I implement this and deliver it to someone else, they’re not going to know to use _{'key': 'value'} instead, and I would prefer that they don’t have to save a single line in a file just so I can open it and read it from stream.
I just wanted to confirm that basically my only option is to put in the readme that they have to pre-pend the json with an underscore.
You have many options. E.g. do similar in Prolog to what you’re doing in Python - put the user-editable text in a string, and then do the conversion into a Prolog dictionary as part of the source code that the users are meant to not mess with.
However - I would love to see Standards documentation which states that giving non-programmers write access to programming source code is a good idea
Credentials, in particular, should not be part of source code. That’s a Security anti-pattern.
Alright then it sounds like there’s no way to work with a spec-compliant json directly in the repl I’ll just put a note in the readme.
Can just put JSON in a JSON file - why isn’t this the first choice?
I was hoping I could provide the same ease of use in prolog. If I implement this and deliver it to someone else, they’re not going to know to use _{'key': 'value'} instead, and I would prefer that they don’t have to save a single line in a file just so I can open it and read it from stream.
I mean I guess I can add an option for that too but I was really hoping I could just do
Now the question is how did one get the JSONobj. If it was entered in toplevel query,as in your examples, the Prolog parser recognizes the JSON syntax as entered and built the JSONobj term for free. If it came from somewhere else, e.g., in string from from a stream, then you’ll need to use one of the builtin predicates which parses strings and produces a term, e.g.,
?- term_string(T,"{a:1,b:2,c:3}").
T = {a:1, b:2, c:3}.
All I’m trying to do is cast spec compliant json into prolog jsons. That’s all — some predicate specjson_swijson/2 that would take {a:1} and give me _{a:1}.
Your get_json_b_param/2 is cool, and thanks for showing me that, but the reason I was looking for a way to convert it to an actual json in prolog is so I can use it with prolog predicates.
Now that I understand your requirements better, ignore my last post (it’s wrong because the argument to {} is a single term - a comma list) and consider:
The internal representation should be exactly the same whether the Prolog parser produces a dict from a literal (in the parser, probably using dict_create/3) or the dict is produced dynamically, i.e., from user code. Prolog is a dynamic (vs. static) language, everything can be done at runtime (including modifying the program, which is a bit scary).
Was that really your expectation given that the Prolog and JSON (and JavaScript, from which it comes) syntaxes come from totally different origins at different times? It should actually be a bit surprising this can be done so easily.
JSON was certainly not ubiquitous in the 70’s when Prolog was in its formative stages, nor even in the 90’s when the current ISO standard was being worked. SWIP does provide a library for supporting JSON serialization, in particular converting between JSON strings and either dictionaries or json terms.
But a “standard” library implies some kind of standards body/process to approve such things and AFAIK that doesn’t exist. The same applies to dictionaries, so don’t expect any of this to be portable, even though it’s “easy”.