There are many people who think that the concept of the special value null (as it is used in lanuages like C, Java, C#, Perl, Javascript, SQL etc.) is a bad idea. There are several questions about this on SO and P.SE, such as Best explanation for languages without null and Are null references really a bad thing? .
However, I could not find any language that does without them. All the languages I'm familiar with have null, or something similar (e.g. "undefined" in Perl).
I realize that proably every language needs some way to express "absence of a value". However, instead of having "null" or "undefined", this can also be made explicit by using something like Maybe (Haskell) or Optional (Guava). The principal difference to having "null" or "undefined" is that an object can only have "no value" if it has a specific type (Maybe, Optional...). In contrast, "null"/"undefined" is typically a valid value possible for every type.
Are there any languages that do not have nullor a similar concept in this sense?
Here's an incomplete list of languages that are null-safe in the sense that they don't have any non-nonnullable types:
Dart (2021): Has optional types with ? syntax.
C# 8 (2019): Has opt-in "nullable reference types".
Kotlin (2015): Has optional types with ? syntax.
Pony (2015). Uses union type where one of the types is None.
Swift (2014): Has optional types with ? syntax.
Crystal (2014): Does have nil, but prevents all null pointer exceptions at compile-time.
Hack (2014): Has optional types with ? syntax.
TypeScript (2012): Has union types that can have undefined or null as a variant.
Elm (2012): Has union type Maybe.
Ceylon (2011): Has optional types with ? syntax.
Rust (2010): Has optional type Option.
Fantom (2005): Has optional types with ? syntax.
F# (2005): Has union type Option.
Nice (2003): Has optional types with ? syntax.
Netlogo (1999) has no type null
OCaml (1996): Has union type option.
Haskell (1990): Has union type Maybe.
Standard ML (1990): Has union type option.
Tcl (1988)
Erlang (1986)
Prolog (1972): A logical variable stands for "anything at all". There is no concept of "null" or "undefined".
Feel free to complement the list. The years represent the first public release.
Tcl has no concept of null whatsoever. Everything is a value and all values have a string representation (typically summarized as "Everything is a String").
The closest thing to null is the empty string.
To convey the concept of "no value" requires some creativity.
Of course, as mentioned above, some people use the empty string to signify no value. For this to work, empty strings cannot be valid in the data set you're processing. Surprisingly, a lot of real world data falls into this category.
Another way to indicate absence of value is to simply throw an error. In some cases this is exactly what should have been done instead of returning some null or error value (an anti-pattern learned from C and a habit that's hard to get rid of).
Yet another way is to return an empty list (a list is Tcl's equivalent of arrays in other languages). The string representation of an empty list is the empty string. But fortunately the string representation of a list containing an empty string is two double quotes: "\"\"". This difference allows one to differentiate between a list that contains "nothing" and a list that contains a string that has no characters in it.
Finally some people simply indicate the absence of values by simply not declaring the variable (or undeclaring it, which is a thing in tcl). This may sound odd because variables seem to be a compile-time construct (while values are run-time construct) but in tcl everything is run-time. Thus it's possible for code to use non existence of the variable as a signal. Trying to read an undeclared variable results in an error which you can catch. In addition, Tcl also allows you to use introspection to check the state of the interpreter. So you can use [info exist x] to check if a variable called x exists.
V is a newer language with Golang-like syntax that has no nulls.
You already mention Haskell as an example of a language without "null". There are also the languages in the ML family like Standard ML, OCaml or F#. Many dynamically typed languages also do not feature null pointers, scheme would be a good example.
Related
In Python it is common to marshal objects from JSON. I am seeking similar functionality in Prolog, either swi-prolog or scryer.
For instance, if we have JSON stating
{'predicate':
{'mortal(X)', ':-', 'human(X)'}
}
I'm hoping to find something like load_predicates(j) and have that data immediately consulted. A version of json.dumps() and loads() would also be extremely useful.
EDIT: For clarity, this will allow interoperability with client applications which will be collecting rules from users. That application is probably not in Prolog, but something like React.js.
I agree with the commenters that it would be easier to convert the JSON data to a .pl file in the proper format first and then load that.
However, you can load the predicates from JSON directly, convert them to a representation that Prolog understands, and use assertz to add them to the knowledge base.
If indeed the data contains all the syntax needed for a predicate (as is the case in the example data in the question) then converting the representation is fairly simple as you just need to concatenate the elements of the list into a string and then create a term out of the string. Note that this assumption skips step 2 in the first comment by Guy Coder.
Note that the Prolog JSON library is rather strict in which format it accepts: only double quotes are valid as string delimiters, and lists with singleton values (i.e., not key-value pairs) need to use the notation [a,b,c] instead of {a,b,c}. So first the example data needs to be rewritten:
{"predicate":
["mortal(X)", ":-", "human(X)"]
}
Then you can load it in SWI-Prolog. Minimal working example:
:- use_module(library(http/json)).
% example fact for testing
human(aristotle).
load_predicate(J) :-
% open the file
open(J, read, JSONstream, []),
% parse the JSON data
json_read(JSONstream, json(L)),
% check for an occurrence of the predicate key with value L2
member(predicate=L2, L),
% concatenate the list into a string
atomics_to_string(L2, S),
% create a term from the string
term_string(T, S),
% add to knowledge base
assertz(T).
Example run:
?- consult('mwe.pl').
true.
?- load_predicate('example_predicate.json').
true.
?- mortal(X).
X = aristotle.
Detailed explanation:
The predicate json_read stores the data in the following form:
json([predicate=['mortal(X)', :-, 'human(X)']])
This is a list inside a json term with one element for each key-value pair. The element has the syntax key=value. In the call to json_read you can already strip the json() term and store the list directly in the variable L.
Then member/2 is used to search for the compound term predicate=L2. If you have more than one predicate in the JSON file then you should turn this into a foreach or in a recursive call to process all predicates in the list.
Since the list L2 already contains a syntactically well-formed Prolog predicate it can just be concatenated, turned into a term using term_string/2 and asserted. Note that in case the predicate is not yet in the required format, you can construct a predicate out of the various pieces using built-in predicate manipulation functionality, see https://www.swi-prolog.org/pldoc/doc_for?object=copy_predicate_clauses/2 for some pointers.
Yeah there is! I made this question to share my knowledge, Q&A style since I had a hard time finding it myself :)
Thanks to https://stackoverflow.com/a/67821482/1561441 (Barbaros Özhan, see comments) for pointing me into the correct direction
The answer is: look here and here
Correct me if I'm wrong, but: Wow, currently to my knowledge a single .java file on GitHub, last commit in 2017, holds relevant parts of the official documentation of the JOLT syntax. I had to use its syntax since I'm working with NiFi and applied its JoltTransformJSON processor (hence the SEO abuses in my question, so more people find the answer)
Here are some of the most relevant parts copied from https://github.com/bazaarvoice/jolt/blob/master/jolt-core/src/main/java/com/bazaarvoice/jolt/Shiftr.java and slightly edited. The documentation itself is more extensive and also shows examples.
'*' Wildcard
Valid only on the LHS ( input JSON keys ) side of a Shiftr Spec
The '*' wildcard can be used by itself or to match part of a key.
'&' Wildcard
Valid on the LHS (left hand side - input JSON keys) and RHS (output data path)
Means, dereference against a "path" to get a value and use that value as if were a literal key.
The canonical form of the wildcard is "&(0,0)".
The first parameter is where in the input path to look for a value, and the second parameter is which part of the key to use (used with * key).
There are syntactic sugar versions of the wildcard, all of the following mean the same thing; Sugar : '&' = '&0' = '&(0)' = '&(0,0)
The syntactic sugar versions are nice, as there are a set of data transforms that do not need to use the canonical form, eg if your input data does not have any "prefixed" keys.
'$' Wildcard
Valid only on the LHS of the spec.
The existence of this wildcard is a reflection of the fact that the "data" of the input JSON, can be both in the "values" and the "keys" of the input JSON
The base case operation of Shiftr is to copy input JSON "values", thus we need a way to specify that we want to copy the input JSON "key" instead.
Thus '$' specifies that we want to use an input key, or input key derived value, as the data to be placed in the output JSON.
'$' has the same syntax as the '&' wildcard, and can be read as, dereference to get a value, and then use that value as the data to be output.
There are two cases where this is useful
when a "key" in the input JSON needs to be a "id" value in the output JSON, see the ' "$": "SecondaryRatings.&1.Id" ' example above.
you want to make a list of all the input keys.
'#' Wildcard
Valid both on the LHS and RHS, but has different behavior / format on either side.
The way to think of it, is that it allows you to specify a "synthentic" value, aka a value not found in the input data.
On the RHS of the spec, # is only valid in the the context of an array, like "[#2]".
What "[#2]" means is, go up the three levels and ask that node how many matches it has had, and then use that as an index in the arrays.
This means that, while Shiftr is doing its parallel tree walk of the input data and the spec, it tracks how many matches it has processed at each level of the spec tree.
This useful if you want to take a JSON map and turn it into a JSON array, and you do not care about the order of the array.
On the LHS of the spec, # allows you to specify a hard coded String to be place as a value in the output.
The initial use-case for this feature was to be able to process a Boolean input value, and if the value is boolean true write out the string "enabled". Note, this was possible before, but it required two Shiftr steps.
'#' Wildcard
Valid on both sides of the spec.
The basic '#' on the LHS.
This wildcard is necessary if you want to put both the input value and the input key somewhere in the output JSON.
Thus the '#' wildcard is the mean "copy the value of the data at this level in the tree, to the output".
Advanced '#' sign wildcard
The format is lools like "#(3,title)", where "3" means go up the tree 3 levels and then lookup the key "title" and use the value at that key.
I would love to know if there is an alternative to JoltTransformJSON simply because I'm struggling a lot with understanding it (not coming from a programming background myself). When it works (thanks to all the help here) it does simplify things a lot!
Here are a few other sites that help:
https://intercom.help/godigibee/en/articles/4044359-transformer-getting-to-know-jolt
https://erbalvindersingh.medium.com/applying-jolttransform-on-json-object-array-and-fetching-specific-fields-48946870b4fc
https://cool-cheng.blogspot.com/2019/12/json-jolt-tutorial.html
I've read through a few questions on this and I'm still unclear. Which is correct:
{"some_parameter": "true"}
or
{"some_parameter": true}
I assume the second is the correct, proper way to send boolean values via json? But the first is still valid json...
The context here is that I'm building an API (used by some 3rd party applications) and I'm wondering if it's reasonable to simply disallow the first type altogether (reject with error) or accept boolean data as strings like this, and just attempt to handle (convert) them?
Short answer, yes that is the proper way to send the JSON. You should not be placing anything other than a string inside of quotes.
Long answer,
It depends on the data type. For the Key, yes you have to use quotes but only for strings. Also, you can use single quotes if you want to place a quotation mark inside of it. (or use escape)
'
for instance,
vs
"
As for your bool value, if you want it to convert straight into a bool, than you do not need to include the quotes. Same for integers and double values.
But if you want to pass it as a string, than you will need to put it inside of quotes.
Generally, these types of questions are asked when you discuss what types of systems will be accepting your data.
It's generally much easier to use strings everywhere, but it's also extremely inefficient and results in your recipient needing to cast them if they want to do arithmetic with an int for instance, but it's passed as a string.
Boolean values must be passed without quotes. Boolean is one of the types supported by json: https://www.json.org/json-en.html and the expected values are true or false, without quotes.
It may still work with quotes when the receiving end parsing the data is a weak typing language like Javascript which converts the value automatically when you use it in a boolean context, but it's always better to follow what the standards say.
Yes, We can pass Boolean value in Json. Just we need to write value in small case.
For Example
{
"fullName": "Deepak Dongre",
"gender": true,
"dob": "1986-11-16",
"mobileNumber": 97959000321,
"tblMstHobbyDetails": []
}
I am converting an existing project from MySQL to Postgres. There are quite a few raw SQL literals in the code that use ? as a placeholder, e.g.
SELECT
id
FROM
users
WHERE
name = ?
But I get this error:
DB query error: error: operator does not exist: character varying = ?
I don't want to convert all my existing SQL from ? to postgres-style operators like $1.
Is there some way of having node-postgres accept the question marks instead, or an utility that can convert to postgres style params?
Note that some sort of Regex-based hack is not acceptable because question marks can be inside quotes, or backslash escaped to any depth.
Is there some way of having node-postgres accept the question marks instead?
NO. And there is no direct correspondence between ? and $1 syntax, because the latter implies parameter re-use, while ? doesn't allow it. For example, using ? ? ? implies that you have 3 formatting parameters, while $1 $2 $2 implies that you have two formatting parameters.
or an utility that can convert to postgres style params?
Not likely, since there is no direct correspondence, the conversion is possible only one-way, which would make such an utility fairly useless. You can replace everything yourself, with a single regular expression, replacing each ? with $ + index + 1.
I don't want to convert all my existing SQL from ? to postgres-style operators like $1.
You don't really have much choice in this. It has to be done. Besides, $1 is way more flexible than ?, due to parameter re-use, plus optional extensions. For example, pg-promise extends them very nicely, with various formatting modifiers that are needed frequently: ^, ~, :json, :csv, etc...
Note that some sort of Regex-based hack is not acceptable because question marks can be inside quotes, or backslash escaped to any depth.
You will likely spend less time converting your SQL by hand, than the time to write an utility for the one-way proper conversion.
Actually converting ? to $1, $2 etc will always work. Converting $1, $2 back to ? won't work if you've repeated parameters.
It would be valuable for those porting software from MySQL and others if PG supported the ? parameter stub.
In mysql, if I do something like
round((amount * '0.75'),2)
it seem to work just fine like without single quotes for 0.75. Is there a difference in how mysql process this?
In the hope to close out this question, here's a link that explains type conversion in expression evaluation: https://dev.mysql.com/doc/refman/5.5/en/type-conversion.html
When an operator is used with operands of different types, type
conversion occurs to make the operands compatible. Some conversions
occur implicitly. For example, MySQL automatically converts numbers to
strings as necessary, and vice versa.
mysql> SELECT 1+'1';
-> 2
In your case, MySQL sees arithmetic and performs implicit conversion on any string contained in the expression. There is going to be an overheard in converting a string to number, but it's negligible. My preference is to explicitly type out a number instead of quoting it. That method has helped me in code clarity and maintainability.