freenode/#lisp - IRC Chatlog
Search
22:30:30
aeth
Gnuxie[m]: All of the JSON libraries are incredibly bad in different ways last time I took a look at them (who knows? maybe there's another 4 now)
22:31:57
aeth
One problem is that JSON is designed to be a trivial mapping to JS and coincidentally has very similar data structures in most other scripting languages.
22:33:51
aeth
It looks like jsown has improved recently. From the readme, "Recently, functions and macros have been added to ease the burden of writing and editing jsown objects." I guess that's the changes "a year ago" (2017-11-08) on Github.
22:38:30
aeth
Gnuxie[m]: Okay, the problem with jsown is that it appears to use alists for JSON data structures with the :obj prefix, not bad. But then for []s it uses regular, unprefixed lists, causing an ambiguity between nil-as-() and nil-as-false. It resolves this ambiguity by allowing :false or :f as the JS false value, but it *should* resolve this ambiguity by prefixing it lists instead.
22:39:32
aeth
In fact, it should be configurable which sequence results from [] because you might want vectors or (simple-array single-float (3))s or something, not lists, and now you've just added a conversion step. "high performance".
22:40:55
aeth
It looks like jsown might be the least ridiculous of the JSON libraries I'm aware of at the moment, though. At least it doesn't have nil<->null and nil<-false and nil<-[] like some of them.
22:42:46
aeth
(Similarly, a proper JSON library should let you choose between alists, plists, and hash-tables, with the third (hash-table) option potentially messing things up if you take in arbitrary JSON)
22:43:17
aeth
At least it prefixes the alists, though. So it gets a 50% for avoiding ambiguity in 1/2 of the data structures. :-p
22:45:07
aeth
It looks like jsown is *not* for serializing arbitrary standard-objects/structure-objects/etc. into JSON, though, which is a good thing. That's doing work at too high of a level imo.
22:46:06
aeth
Overall, it looks like I'd give it a 7/10, which is probably several points higher than the other JSON libraries I've seen.
22:46:50
jasom
Here's how I use cl-json for a bijective mapping: https://github.com/jasom/cl-fccs/blob/master/src/util.lisp#L25
22:47:35
aeth
jasom: Yes, it's nice that cl-json is generic enought that it can be configured to do things (somewhat) correctly, so that's an advantage over cl-jsown. Of course, defaults matter, and its defaults are terrible.
22:48:07
aeth
jsown gets you closer to correctness (with the issues above that I noted) but afaik you can't get all of the way there, unlike (potentially) with cl-json
22:48:08
jasom
the defaults are terrible on all of the options with the possible exception of the one that decodes everything to a standard-object with its own class heirarchy
22:50:03
aeth
jasom: Well, I just said what would work, at least until you get into 2+ dimensional arrays. :null<->null, nil<->false, prefix []s if lists so no truly empty list is possible because it would be something like '(:json-list), and allow the user to determine which sequence to encode/decode [] as, perhaps with a metadata scheme to allow multiple in one file.
22:50:44
aeth
You *only* need two backends for [] encoding/decoding unless you want to support multi-dimensional arrays: list and array, since the rest would just be an :element-type in make-array
22:51:35
aeth
jasom: Right, the complicating factor in the sequence/array generic approach to [] would be if you wanted to turn [[1, 2, 3], [4, 5, 6]] into #2A((1 2 3) (4 5 6)) and vice versa.
22:52:03
jasom
that seems a bit too high-level for me, though I could see the domains in which it would be useful.
22:52:08
aeth
You could, of course, not even attmept to solve it, and then you just have the list and 1D array backend, and it's pretty simple, the typical work-on-all-standard-sequences kind of exercise
22:52:48
aeth
jasom: It seems high level, but unlike a total object mapping, it's kind of necessary for efficiency for the same reason that you want to be able to specify (simple-array single-float (3))s as well: avoid coercing into the array you want, which could be expensive for long arrays.
22:53:35
jasom
aeth: but what about [[1,2,3],[4,5,6],...[7,8,9,10]]? You need to read the whole thing already
22:54:30
aeth
jasom: Because then you would either error on the first row (wrong row size) or when you either have too many or too few rows compared to what you expect.
22:55:40
aeth
jasom: So this would only work efficiently if (i) there was some form of metadata, either in a separate JSON schema, or in the JSON file itself, or in the program code or (ii) every array was of the same type.
22:57:16
jasom
st-json is the library I was trying to think about where you will always write out json equivalent to what you read by default, but unfortunatley it's nil <-> [] which I don't like.
22:57:17
aeth
jasom: So you would probably do this at a higher level library, but you would have to be able to support this sort of thing in the JSON library itself, or else you're just going to be allocating a bunch of sequences and then coercing, which won't work for some JSON formats with large arrays like e.g. 3D models (and, yes, for some reason, people do this in JSON sometimes)
22:57:59
aeth
jasom: ":null<->null, nil<->false, prefix []s if lists" is the only way to handle it imo. Well, perhaps something other than :null, but it has to be a keyword or symbol.
22:59:10
jasom
I concur, but write-what-you-read should be table-stakes and st-json and com.gigamonkeys.json appear to be the is the only ones that do that out-of-the-box
23:00:00
aeth
The way to handle the sequence-generic [] would probably be to either (i) make it the same every time (so request lists, vectors, or some other sequence type) or (ii) override it with some sort of internal schema format that can be generated by various schema/etc. methods
23:03:14
aeth
"some other sequence type" would be tricky. The easy/lazy way would be to just have length/element-type/etc. from make-array as part of the API. The hard way would be to use an extension (if possible; is it CLtL2?) to actually parse a result type so it can behave like #'map... but that 2nd approach won't get you everything (e.g. adjustable arrays with fill pointers)
23:28:26
esper0s
i have got a general question which is not related to lisp but the process of learning. I have found many times that when reading a book on programming i find nmyself spending a lot of time learning the formal way of expressing concepts as stated in the book. Do you consider such an action vain? Sorry for the irrelevance of the question to the channel
23:43:46
jasom
possibly stupid question: are condition types classes? The spec lists a "Class Precendence List" for them, but I can't find anywhere that says that any condition type other than "condition" is a class.
23:45:27
phadthai
they can be implemented with CLOS but not necessarily need to be (predating it if I remember)
23:46:38
Xach
jasom: my long-term understanding is that they are not required to be classes or to use clos
23:47:09
phadthai
esper0s: difficult to judge on learning methods, I think that learning the style is also good, however some books may not be considered good style today, or may be considered closer to scheme-style than cl-style
23:47:42
jasom
Xach: condition is specifically defined to not have standard-class as the metaobject, but it's not clear on whether or not e.g. define-condition creates a new class (that is not required to be a standard-class)
23:47:49
phadthai
esper0s: and I'm not sure if I understood well enough your question, likely not if my answer seems irrelevant :)
23:51:26
jasom
what is confusing is that it shows a class precedence list for the standard condition types, whereas other non-class types do not (e.g. short-float).
23:52:18
jasom
compare e.g. http://clhs.lisp.se/Body/e_parse_.htm to http://clhs.lisp.se/Body/t_short_.htm
0:06:37
_death
I think if you use CLOS, then it's reasonable to expect the implementation to support conditions as classes.. do you know of implementations where this expectation is not met?
0:07:00
jasom
reading chapter 9, it relatively clear that define-condition is only guaranteed to create a subtype of cl:condition, not a subclass.
0:07:25
jasom
however it is ambiguous if whether or not the standardized condition types are required to be classes.
0:07:53
_death
if you don't use CLOS, and you use or may want to use a CLOS-less implementation, then this does not exclude usage of the condition system by itself
0:08:36
jasom
_death: given that all modern implementations I'm aware of create a class for each define-condition, it's mostly academic, but it is a strange ambiguity
0:10:52
_death
jasom: well, the standard is not perfect.. it's a bit of a spaghetti in this matter.. so the next best thing is to make reasonable assumptions that agree with it
0:11:56
phadthai
the standard being this way would also allow an implementation to use faster special classes than clos ones for conditions I guess
0:12:16
jasom
(define-condition foo (condition) ()) (class-of (make-condition 'foo)) => #<SB-PCL::CONDITION-CLASS COMMON-LISP-USER::FOO>
0:19:11
Bike
yeah, condition-class and standard-class are both subclasses of slot-class (and pcl-class, and class)
0:20:16
Bike
they have the same slots, i think, so i guess the difference is in some generic function behavior
0:26:52
_death
(mapcar #'class-name (sb-mop:class-precedence-list (class-of (class-of (make-condition 'foo)))))
0:28:45
jasom
but I *think* it would be conforming for this to be true: (eql (class-of (make-condition 'foo)) (class-of (make-condition 'condition)))
4:17:09
fouric
quicklisp is still refusing to locate my local projects, and register-local-projects hangs