It's the first one people have come across with no way to navigate without a keyboard. It seemed to people a very odd UI, given that many web connected devices don't have them.
I think you conflate passive aggression with open derision.
Regarding the former "passive-aggressive behavior is characterized by a habitual pattern of passive resistance to expected work requirements, opposition, stubbornness, and negativistic attitudes in response to requirements for normal performance levels expected of others".
I don't think a snarky response qualifies.
>It's the first one people have come across with no way to navigate without a keyboard.
Lots of web slideshows only navigate with a keyboard. I've seen the same question/answer several times in the past on HN.
It's not like it should take more than 5 seconds to try to press "->" and see what happens....
Yeah, because being self aware means celebrating the 1000th "how can I play this slideshow" question in the same forum, from people who work day in day out with computers...
I dunno, seems like clicking on the next slide, or the edges of the current slide works just fine for navigation as far as mouse controls goes, and swiping is also working fairly well on my mobile devices, though I can't claim to have tested all possible mobile devices, so your mileage may vary.
Meanwhile, in Ruby...foo could contain any conceivable data structure, which you'll have to reflect on and test against extensively in a production environment if you don't want your application falling flat on its face at the first sign of unexpected input.
Go would have similar problems with unexpected input, it just frontloads the work, so if you do something stupid then you'll know it up front.
Not the same due to types... the win being reliability and security due to more precise input validation. The loss is programmer time and overall code bloat/complexity, both for the spec and the handling.
Architecturally, it would have been better to separate the spec. When I saw the intro I thought they were going to generate Go from a JSON Schema (which would have been at least more cross platform and reusable). Instead, we got more Go. Meh.
How does this deal with deserializing json arrays? Unless you have reified generics it's impossible. This is a common headache when working with Jackson.
Not the parent, but my biggest issue with arrays and nested objects is this:
Most JSON arrays come in the form
{
"objects": [{"foo": "bar"}, ...]
}
Instead of `[{"foo": "bar"}, ...]`. So I need to create a temporary struct, it would've been nice to be able to provide a starting point or similar. Like `json.UnmarshalFrom(data, &foos, "objects")` (hmm, this gave me an idea!).
Another example is this:
type Address struct {
street string
city string
}
And I want to parse that populate that struct with the data from
For deeply nested structures, it'll always be a bit of a hassle. In your toy example, you can use struct literals to get to the guts of the object quickly.
Sorry I actually meant Lists. In Java List<String> is just List (since they aren't reified) at compile time so you have to explicitly deserialize an String[] and then manually throw it into an ArrayList<String>.
Not a very fair comparison due to Go's (mostly) static typing and Ruby's very dynamic typing.
In this case, the author wants to use a struct with custom user-defined types as members, while JSON only has concepts of primitive types. That's why you're going to need a lot more code than you would otherwise.
I agree there needs to be a better way to do it though. And "go generate" seems like the hackiest thing in the world for 95% of use cases, including this one.
For what it's worth, you don't need to even need to type out the struct manually when unmarshalling JSON; you can generate it automatically[0] (this tool is compatible with `go generate`).
In addition to the effects of being statically typed, which you mentioned, Go is a bit lower level than Python or Ruby, so it will always perform at least slightly worse when compared on a strict line-by-line basis. Fortunately, though, it's not that much more verbose in this case. And as an added benefit, the struct value, once unmarshalled, is typesafe (which is not true in Python[1]).
[1] Because Python is not only dynamically typed but strongly typed, I've more than once run into an issue where a misbehaving API returns a string instead of an int, and then Python throws a runtime exception because it can't add a string and an int.
As far as I understand the type providers evaluate the samples at compile time. This means that you have at that point of a time a correct version of the data samples. If at compile time everything is ok there is no security or corruption issue for the runtime.
I also think it won't be a good idea to just pull in arbitrary code (or resources) through http(s) during compilation. I think what you really should do is download the files, review them, add them as resources to your project and use those as input for the type providers.
It's quite possible to write a parse method in go such that
foo := json.Parse(os.Stdin)
would work. I'll acknowledge that it would be extremely unidiomatic to ignore errors and not provide the parse call with type hinting information. A more idiomatic version would look like:
var foo SomeType
err := json.NewDecoder(os.Stdin).Decode(&foo)
instance FromJSON Person where
parseJSON = withObject "Person" $ \o -> do
name <- o .: "name"
age <- o .: "age"
return (Person name age)
let person = case decode some_bytestring of
Success p -> p
Error e -> error "Malformed JSON"
It works with arbitrary data types (including enums!), lets you easily, exactly specify what sort of data to accept, and doesn't require stepping outside the language.
Certainly compact; as written, though, it has a few deficiencies compared to the Go version:
1. no specific error messages; these take up a good portion of the Go code, although they could certainly be more automatic;
2. does not allow the same code to be used for encoding and decoding (i.e. you don't have to write a list of fields twice, and can specify which format to encode to/decode from once rather than separately specifying the encoding and decoding functions - note that the format may not be uniquely determined by the final type you want in the output, e.g. you just want a generic date value out, but you need to use a specific date format for the JSON conversion).
The first is more of a nitpick (are those going to show up in 'e' anyway?), but the second is important. Do popular Haskell JSON libraries have a way to do that?
Also, reflection is not really stepping outside the language.
36 comments
[ 4.7 ms ] story [ 79.6 ms ] threadThanks!
It's the first one people have come across with no way to navigate without a keyboard. It seemed to people a very odd UI, given that many web connected devices don't have them.
s/people/I/g
I think you conflate passive aggression with open derision.
Regarding the former "passive-aggressive behavior is characterized by a habitual pattern of passive resistance to expected work requirements, opposition, stubbornness, and negativistic attitudes in response to requirements for normal performance levels expected of others".
I don't think a snarky response qualifies.
>It's the first one people have come across with no way to navigate without a keyboard.
Lots of web slideshows only navigate with a keyboard. I've seen the same question/answer several times in the past on HN.
It's not like it should take more than 5 seconds to try to press "->" and see what happens....
80 lines of code to parse some JSON?
Meanwhile, in ruby...
Go would have similar problems with unexpected input, it just frontloads the work, so if you do something stupid then you'll know it up front.
Even with full blown JSON schema validation we'd arrive at 2 lines of ruby code plus ~5 for the schema.
Architecturally, it would have been better to separate the spec. When I saw the intro I thought they were going to generate Go from a JSON Schema (which would have been at least more cross platform and reusable). Instead, we got more Go. Meh.
http://play.golang.org/p/H5yFV6VYaT
There is some boiler plate, since you have a typed system, so you must define your types. Beyond that two lines of Go will parse a JSON blob.
The article is giving examples of using an Unmarshal interface to convert the JSON code into typed Go objects. Hence more lines of code.Such as the example of converting the JSON time string into a Time type.
edit: updated the example link
Most JSON arrays come in the form
Instead of `[{"foo": "bar"}, ...]`. So I need to create a temporary struct, it would've been nice to be able to provide a starting point or similar. Like `json.UnmarshalFrom(data, &foos, "objects")` (hmm, this gave me an idea!).Another example is this:
And I want to parse that populate that struct with the data from Again I have to use temporary struct.https://play.golang.org/p/VE90fwT0sE
In this case, the author wants to use a struct with custom user-defined types as members, while JSON only has concepts of primitive types. That's why you're going to need a lot more code than you would otherwise.
I agree there needs to be a better way to do it though. And "go generate" seems like the hackiest thing in the world for 95% of use cases, including this one.
In addition to the effects of being statically typed, which you mentioned, Go is a bit lower level than Python or Ruby, so it will always perform at least slightly worse when compared on a strict line-by-line basis. Fortunately, though, it's not that much more verbose in this case. And as an added benefit, the struct value, once unmarshalled, is typesafe (which is not true in Python[1]).
[0] https://github.com/ChimeraCoder/gojson
[1] Because Python is not only dynamically typed but strongly typed, I've more than once run into an issue where a misbehaving API returns a string instead of an int, and then Python throws a runtime exception because it can't add a string and an int.
It is pretty awesome that languages exist that let you do this.
I also think it won't be a good idea to just pull in arbitrary code (or resources) through http(s) during compilation. I think what you really should do is download the files, review them, add them as resources to your project and use those as input for the type providers.
1. no specific error messages; these take up a good portion of the Go code, although they could certainly be more automatic;
2. does not allow the same code to be used for encoding and decoding (i.e. you don't have to write a list of fields twice, and can specify which format to encode to/decode from once rather than separately specifying the encoding and decoding functions - note that the format may not be uniquely determined by the final type you want in the output, e.g. you just want a generic date value out, but you need to use a specific date format for the JSON conversion).
The first is more of a nitpick (are those going to show up in 'e' anyway?), but the second is important. Do popular Haskell JSON libraries have a way to do that?
Also, reflection is not really stepping outside the language.
Data.Aeson.TH[1] can automatically generate JSON decoders and encoders for data types, if that's what you want.
[1] http://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-A...