Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upEdge cases and defaults #18
Comments
|
@dcooley Moving the conversation from #17 over here:
Here's the rationale for going about
|
| JSON | R Representation | equivalent/print() |
|---|---|---|
{"a":1} |
structure(list(1L), .Names = "a") |
list(a = 1L) |
{} |
structure(list(), .Names = character()) |
named list() |
[]
And similarly you're returing [] as NA_LOGICAL?
See above: [] returns Rcpp::LogicalVector(0) (vector of length 0):
RcppSimdJson:::.deserialize_json('[]')
#> logical(0)This is really a matter of deciding which of the following represents []:
vector()vector(mode = "list").
But it does raise a few other questions:
- Are empty arrays recursive?
- Are empty arrays homogeneous?
- Are empty arrays "just arrays"... or are they really a special case?
{jsonify} and {jsonlite} use this pattern for simplifcation:
| JSON | R | str() |
|---|---|---|
["a",3.14,1,true,null] |
c("a","3.14","1","TRUE",NA) |
chr [1:5] "a" "3.14" "1" "TRUE" NA |
[3.14,1,true,null] |
c(3.14, 1, 1, NA) |
num [1:4] 3.14 1 1 NA |
[1,true,null]' |
c(1L, 1L, NA) |
int [1:3] 1 1 NA |
[true,null]' |
c(TRUE, NA) |
logi [1:2] TRUE NA |
[null] |
NA |
logi NA |
[] |
list() |
list() |
RcppSimdJson:::.deserialize_json()'s current default uses rcppsimdjson::Type_Policy::anything_goes, which follows nearly the same pattern of collapsing arrays of scalars into R vectors, no matter what.
Here's the same table with the proposed default {RcppSimdJson} pattern for simplification in bold:
| JSON | R | str() |
|---|---|---|
["a",3.14,1,true,null] |
c("a","3.14","1","TRUE",NA) |
chr [1:5] "a" "3.14" "1" "TRUE" NA |
[3.14,1,true,null] |
c(3.14, 1, 1, NA) |
num [1:4] 3.14 1 1 NA |
[1,true,null]' |
c(1L, 1L, NA) |
int [1:3] 1 1 NA |
[true,null]' |
c(TRUE, NA) |
logi [1:2] TRUE NA |
[null] |
NA |
logi NA |
[] |
logical(0) |
logi(0) |
[] |
list() |
list() |
The idea behind the proposed {RcppSimdJson} approach is to just consistently following the same pattern.
I'd say the difference is that it treats [] as non-recursive and homogeneous (thus becoming a vector) instead of a special case like {jsonify} and {jsonlite} seem to do (potentially recursive and/or homogeneous?).
|
I like how set user-drive policy options otherwise. That is simply the most flexible. @lemire Thoughts? |
|
It seems @dcooley and I don't quite agree with some of the default choices Jeroen Ooms' The jsonlite Package: A Practical and Consistent Mapping Between JSON Data and R Objects is a wonderful deep dive into the a lot of the gory, R-specific details. |
|
@knapply your logic all makes complete sense. I also tried to stay consistent with toJSON( NULL )
# {}
fromJSON('{}')
# named list()to_json( NULL )
# {}
from_json('{}')
NULLSo in summary, I don't have any issues with the defaults chosen for |
|
I'll try and sort the user-passable options ASAP so we at least have maximum flexibility. I think there are good arguments both ways to be honest. I have a deployed shiny app that uses The tinkering I had to do was all in excel-related packages to get round trips to pass |
|
I swapped out the JSON parsing routine for an API client with I probably have some variation of
So it's on the TODO list. |
|
Anything actionable here now? I may have lost track of the main storyline... |
|
The last open checkbox/comment before yours #18 (comment) (unless someone makes a case why it's a bad idea) is the only thing remaining. It's a matter of adding a Ultimately, the returned value is here: rcppsimdjson/inst/include/RcppSimdJson/deserialize/simplify.hpp Lines 211 to 212 in d1b22f3 so that would just need to change from It's the same pattern as I left the issue open as a reminder to myself, but it can be closed. |
|
Is what we have "good enough" to be added to master to form 0.0.6? |
|
Yes. |
|
Ok, no pending merge or pr. I look over what we have and roll it up this eve or tomorrow. |
|
single |
What are the edge cases
{RcppSimdJson}needs to handle?What should be the defaults (internal and user-level)?
{}Current candidates:[ ]named list():structure(list(), .Names = character(0))same asjsonlite::fromJSON()[ ]NULLsame asjsonify::from_json()NULLas the defaut).[]Current candidates:[ ]vector():logical(length = 0L)[ ]vector(mode = "list"):list()same asjsonify::from_json()andjsonlite::fromJSON()NULLas the defaut).null{}and[], allow user to pass any R object to replace singlenull, withNULLas the default.