Great, that looks fine. Then you can just access the `success` key like this:
($ (require json))
(if
((w/instring json "{\"success\":false}"
($.read-json json))
'success)
'success ; proceed to login
'fail ; must be a robot then
)
Also, I don't get why the Anarki repository contains a JSON parser implemented in Racket, when the built-in Racket JSON parser works just fine with Arc:
I got an error saying #t was an unknown type when I tried to do a boolean check on it, as it was passed from a JSON response. It's the reason I started this thread to begin with.
Thanks! I think you're right that the existing JSON parser is unnecessary. But there's still an open problem about translating to Arc:
arc> (w/instring in "{\"foo\": true}" ($.read-json in))
#hash((foo . #t))
We'd like this to translate to:
#hash((foo . t))
Perhaps what we're looking for isn't related to JSON at all, but a general shim for translating the output of Racket functions. That could be broadly useful.
Why do we need to explicitly translate #t to t? Arc has no problem handling Racket booleans.
I'd like to see perhaps a specific brief example, where using Racket booleans within Arc actually is a problem, because I haven't encountered any myself.
If I try to use the hash from your example in actual Arc code, it works fine:
arc> (if ((w/instring in "{\"foo\": true}" ($.read-json in)) 'foo) 'yes 'no)
yes
arc> (if ((w/instring in "{\"foo\": false}" ($.read-json in)) 'foo) 'yes 'no)
no
> This parameter determines the default Racket value that corresponds to a JSON “null”. By default, it is the 'null symbol. In some cases a different value may better fit your needs, therefore all functions in this library accept a #:null keyword argument for the value that is used to represent a JSON “null”, and this argument defaults to (json-null).
If you set the JSON null to nil before running your example, it works as you'd expect:
I think we should get rid of json.rkt and use the Racket built-in. It's way better documented, and we should use that one. (But I'm not going to delete json.rkt myself, particularly when I know someone is working with it.)
For round-tripping between JSON and Arc, I would expect the JSON values {}, {"foo": null}, {"foo": false}, and {"foo": []} to parse as four distinct Arc values.
I recommend (obj), (obj foo (list 'null)), (obj foo (list 'false)), and (obj foo (list (list))). Arc is good at representing optional values as subsingleton lists:
; Access a key that's known to be there.
t!foo.0
; Access a key that isn't known to be there.
(iflet (x) t!foo
(do-something-then x)
(do-something-else))
Using my `sobj` utility, you can write (obj foo (list 'false)) as (sobj foo 'false).
Meanwhile, I don't think there's any big deal when we don't have Arc-style booleans....
; Branch on the symbols 'false and 'true.
(if (isnt 'false x)
(do-something-then)
(do-something-else))
; Alternative
(case x true
(do-something-then)
(do-something-else))
But now that I look closer at the ac.scm history (now ac.rkt in Anarki), I realize I was mistaken to believe Arc treated #f as a different value than nil. Turns out Arc has always equated #f and 'nil with `is`, counted them both as falsy, etc. So this library was already returning nil, from Arc's perspective.
There are some things that slip through the cracks. It looks like (type #f) has always given an "unknown type" error, as opposed to returning 'sym as it does for 'nil and '().
So with that in mind, I think it's a bug if an Arc JSON library returns 'nil or #f for JSON false, unless it returns something other than '() for JSON []. To avoid collision, we could represent JSON arrays using `annotate` values rather than plain Arc lists, but I think representing JSON false and null using Arc symbols like 'false and 'null is easier.
Having nil represent both false and the empty list is also what Common Lisp does.
Really, #t and #f are not proper Arc booleans[0], so it makes sense that Arc can't tell what type they are.
You can configure the value Arc chooses for a JSON null with the $.json-null function, which I think is fine as JSON APIs might have differing semantics.
That documentation may be wrong. On the other hand, it may be correct in the context of someone who is only using Arc, not Racket.
There are a lot of ways to conceive of what Arc "is" outside of the Racket implementations, but I think Arc implementations like Rainbow, Jarc, Arcueid, and so on tend to be inspired first by the rather small set of operations showcased in the tutorial and in arc.arc. (As the tutorial says, "The definitions in arc.arc are also an experiment in another way. They are the language spec.") Since #f isn't part of those, it's not something that an Arc implementation would necessarily focus on supporting, so there's a practical sense in which it's not a part of Arc our Arc code can rely on.
(Not that any other part of Arc is stable either.)
> Really, #t and #f are not proper Arc booleans[0], so it makes sense that Arc can't tell what type they are.
Really, #t and #f are not proper Arc anything, but the language apparently handles them so IMHO Arc should also be able to know what type they are. Otherwise, I fear, this will become a Hodge Podge language that will lose appeal.
Personally I don't care if Arc supports booleans. I only care that it can translate booleans (when need be) to a meaningful Arc semantic. That said, if we're going to support booleans then let's not create partial support.
To me, it currently reads more like the GDPR applies when you operate to users in EU,
> The GDPR is applicable to the US entities to the extent such entities process personal data in order to provide a service or a good within the EU territories.
> It doesn't matter if you operate or are established in the EU. If you have EU visitors/users they gain the protections of the GDPR and you have to comply.
Well practically speaking it only applies if there is something the EU can do about it and if you're doing business in the EU they certainly can do something. Even FB, for example, needs to conform otherwise all that ad revenue from EU companies can vanish if the EU governing bodies sees fit to do so.
But the most the EU could do about the Arc forum would be to block EU users from accessing the site (which would be a political nightmare for them in censorship terms). And, in reality, this site doesn't hold any real data worth worrying about and I somehow doubt PG is sitting around worried about what the EU thinks (regarding this site).
None of this has anything to do with what I think of the laws they are creating. Frankly from the little that I've read I kinda like what I see, but still the world doesn't abide by whatever the EU says, as a parallel example... just look at how much trump cares about nafta right now and that's an agreement they signed. (I'm Canadian btw).
Final-Recipient: rfc822; support@arclanguage.org
Original-Recipient: rfc822;support@arclanguage.org
Action: failed
Status: 5.4.6
Diagnostic-Code: X-Postfix; mail for arclanguage.org loops back to myself
> How would this be different than git submodules?
Most of the difference would be in the user interface. Git submodules might actually be a great idea for how to implement it, to encourage hacking on and submitting changes to the libraries themselves.
Git submodules don't provide a very friendly user experience though. You have to know the repository url and manage them separately. It's not terrible, but it's extra work, and doesn't handle loading the library in your own, or dependency management. Ideally, pulling in a package would also result in pulling in all of its dependencies, without pulling in multiple copies of the same library the way npm used to.
There are a lot more features that could be offered by an actual package system.