Earlier quoted context omitted.
You don't get to just add an event loop and start writing async code in Python or Java. It opens up its own can of worms now that you're straddling the sync and async worlds. Compare working with Netty (async) to Jetty (sync). It's certainly not trivial. That Javascript is async-everything is one of its best and often overlooked features in these comparisons. I think this snippet encapsulates a lot of why Javascript…
I don't think it is overlooked. JavaScript doesn't scale, both in terms of code complexity (callback hell) and across cores, and the "gold standard" these days is microservices, which has a ton of issues. If you want to look at bolt-on async working, check out C# or Rust. They've basically taken JavaScript's new async/await and added threading (at least Rust has, not sure about C#). You can write an async app and hav…
The melting pot of JavaScript (2017)
191–200 of 200 posts
Re: The melting pot of JavaScript (2017)
#192Earlier quoted context omitted.
Faster than JS doesn't make it fast enough. Look at how it fares versus C in those same tests.
Fair, but do we really need C levels of performance on the web? That's madness. They are mostly CRUD apps for God's sake. They don't have to be able to run liquid simulations at 200FPS. IMO the level of Java / Erlang performance is, and should always be, plenty enough for the web.
Re: The melting pot of JavaScript (2017)
#193Earlier quoted context omitted.
you can look everything over at runtime Correct, that's what you have to do in dynamic languages - look at what came in from the database and manually validate+convert it into the format you actually want. Also with pretty much every other form of input (JSON bodies, form posts, queue messages, etc). It's a lot of tedium. When working with node/python/ruby, I often find myself wishing I could just declare a type and…
Why do I need to manually convert anything? Even then... var results = (await sql.query` ... `).recordsets[0].map(rowToObject); It's really easy... no need for complicated ORM/ODM tooling at all. As far as the size... create a docker container from node:10-alpine to run a given node application, and create a similar container with any application running full Java. And compare the final size.
I've never heard anyone server-side care about the size of a deployable. It's the size of the codebase that's an issue. Tedious conversion code does not work in javascript's favor.
Re: The melting pot of JavaScript (2017)
#194Earlier quoted context omitted.
you can look everything over at runtime Correct, that's what you have to do in dynamic languages - look at what came in from the database and manually validate+convert it into the format you actually want. Also with pretty much every other form of input (JSON bodies, form posts, queue messages, etc). It's a lot of tedium. When working with node/python/ruby, I often find myself wishing I could just declare a type and…
> Well-written Java programs are generally more concise and less verbose than well-written JS/Python/Ruby programs. This isn't at all true. I can say this from experience using statically typed Python extensively, in an average code base, 80% of your functions, if not more, are already statically correct in Python, one just need add an annotation. Then you're just as "well written" as the Java. With or without the an…
Well I guess we'll just have to disagree there. I spend a lot of time writing code in all of these languages. By the time you've bulletproofed your dynamic code, you've got more code than if you'd just declared a simple static Java type.
I can define this...
@Data
public class Thing {
final String text;
final Instant when;
}
@Path("/thing")
public class ThingResource {
@POST
public void doSomething(final Thing thing) {
// ...blah
}
}
...and stop worrying in my implementation about what was actually passed in, or how a JSON string date got turned into a real date representation. This is mostly-vanilla Java.Sure you can, with enough extra code and clever libraries, hack together a crude typing system into dynamic languages to automate much of the conversion. At the end of the day you're still declaring types, and it doesn't end up being as elegant as having the type system built into the language.
Re: The melting pot of JavaScript (2017)
#195Earlier quoted context omitted.
> Well-written Java programs are generally more concise and less verbose than well-written JS/Python/Ruby programs. This isn't at all true. I can say this from experience using statically typed Python extensively, in an average code base, 80% of your functions, if not more, are already statically correct in Python, one just need add an annotation. Then you're just as "well written" as the Java. With or without the an…
> This isn't at all true. Well I guess we'll just have to disagree there. I spend a lot of time writing code in all of these languages. By the time you've bulletproofed your dynamic code, you've got more code than if you'd just declared a simple static Java type. I can define this... @Data public class Thing { final String text; final Instant when; } @Path("/thing") public class ThingResource { @POST public void doSo…
No, its Java EE, which like I said, has an entire library devoted to safe marshalling[1]. Marshmallow does the same thing for you in python. Java EE including a marshalling library has nothing to do with static typing.
This is python + flask + marshmallow (2 very common web libraries)+ a 2 line helper function:
@dataclass
class Thing():
text: str
when: datetime.datetime
@app.route('/thing', methods=['POST'])
def handle():
thing = unmarshall(Thing, request.form)
# blah
Or, like I said, use protos, where this would be something like from thingproto import Thing, ThingService, ThingResponse
class ThingServiceHandler(ThingService):
def HandleThing(request: Thing, response: ThingResponse):
# blah
and everything is validated.[1]: https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-...
Re: The melting pot of JavaScript (2017)
#196Earlier quoted context omitted.
> This isn't at all true. Well I guess we'll just have to disagree there. I spend a lot of time writing code in all of these languages. By the time you've bulletproofed your dynamic code, you've got more code than if you'd just declared a simple static Java type. I can define this... @Data public class Thing { final String text; final Instant when; } @Path("/thing") public class ThingResource { @POST public void doSo…
> This is vanilla Java. No, its Java EE, which like I said, has an entire library devoted to safe marshalling[1]. Marshmallow does the same thing for you in python. Java EE including a marshalling library has nothing to do with static typing. This is python + flask + marshmallow (2 very common web libraries)+ a 2 line helper function: @dataclass class Thing(): text: str when: datetime.datetime @app.route('/thing', me…
Dragging protobufs into this is weird too; you've ignored the IDL and build infrastructure required to set that up, and in any case that's specific to when you're working with protobuf APIs.
I'll go back to my earlier point, which I think you've illustrated fairly well, which is that well-written Java code tends to be more concise and less verbose than Python (and friends). Our two examples are nearly identical in terms of meaningful lines of code, but in the Python example you have to ask for marshaling.
I'll also point out that flask (which I use myself for python webapps) handlers are forced to interact with flask-specific objects and therefore are obnoxious to test; the JAX-RS example is pure program logic and can be tested as vanilla Java code. This is one of the big advantages of moving marshaling "out" of your program code.
Re: The melting pot of JavaScript (2017)
#197Earlier quoted context omitted.
> This is vanilla Java. No, its Java EE, which like I said, has an entire library devoted to safe marshalling[1]. Marshmallow does the same thing for you in python. Java EE including a marshalling library has nothing to do with static typing. This is python + flask + marshmallow (2 very common web libraries)+ a 2 line helper function: @dataclass class Thing(): text: str when: datetime.datetime @app.route('/thing', me…
I'm not quite sure what you're getting at with the "No, it's Java EE" comment. JAX-RS is a Java standard, with several implementations, and you don't need a "Java EE Server" or anything magical like that to use it. And that link to the Custom Marshalling section of the JAX-RS docs is a little weird; my example doesn't require monkeying with low-level stuff like that and most users don't. Dragging protobufs into this…
That's only an API wart. It'd be possible to elide that pretty easily if someone wanted to write a library to do that.
I could write a library function or flask extension or whatnot that resulted in
@app.myroute('thing', method=['POST')
def handle(thing: Thing):
# work with thing
and the unmarshalling is handled by the decorator and type annotation. Your prime example of java being less verbose is a wash. They're at best equally verbose, and you picked something that java has libraries specifically catered toward.>I'll also point out that flask (which I use myself for python webapps) handlers are forced to interact with flask-specific objects and therefore are obnoxious to test
Huh? Here's an example of a test from the flask docs[0] that makes a request and checks the result.
def test_empty_db(client):
rv = client.get('/')
assert b'No entries here so far' in rv.data
Its a simple example, but having written tests for flask myself1. There should be minimal logic in the handler. You should defer most logic to a library function, you can also not use the decorator form and instead declare `app.route('/path')(function)` and just test function itself.
2. Even testing the handlers and doing end to end stuff with a running server isn't that hard. I'm not sure what you're experience was, but my guess is you weren't leveraging existing libraries.
>This is one of the big advantages of moving marshaling "out" of your program code.
Here's the implementation of that:
def myroute(self, *args, **kwargs):
def wrapper(f):
@self.route(*args, **kwargs)
def new_route(*args):
arg, schema = f.__annotations__.items()
parsed = schema.load(request.form)
return f(arg=parsed)
return new_route
return wrapper
And now if you've tested that, you no longer need to worry about marshalling in your program code.Flask however is relatively generic, it can handle things that your java examples can't, like an endpoint where you don't know the schema, which might happen if you're doing something like hosting a user-provided function or something of that nature (I implemented an AWS-lambda style thing in a hackathon with that). Something like
@route('/user_endpoint')
def handle():
return convert_to_html_response(user_function(**request.form))
This was really easy to implement. I doubt it would have been as concise in Java (and note that you are leaving validation to the user here, so none needs to be done by you).Flask lets you do that. If you want to restrict yourself to schematized requests, you have more information and can make more assumptions, but flask isn't a REST framework, its a generic web framework. If you want to restrict yourself to something with known schemas, you can do that pretty concisely[1], even when dealing with relatively complex marshalling (and you can do it outside of your logical code under test via decorators).
[0]: http://flask.pocoo.org/docs/1.0/testing/
[1]: https://flask-restful.readthedocs.io/en/0.3.6/fields.html
Re: The melting pot of JavaScript (2017)
#198Earlier quoted context omitted.
I'm not quite sure what you're getting at with the "No, it's Java EE" comment. JAX-RS is a Java standard, with several implementations, and you don't need a "Java EE Server" or anything magical like that to use it. And that link to the Custom Marshalling section of the JAX-RS docs is a little weird; my example doesn't require monkeying with low-level stuff like that and most users don't. Dragging protobufs into this…
>I'll go back to my earlier point, which I think you've illustrated fairly well, which is that well-written Java code tends to be more concise and less verbose than Python (and friends). Our two examples are nearly identical in terms of meaningful lines of code, but in the Python example you have to ask for marshaling. That's only an API wart. It'd be possible to elide that pretty easily if someone wanted to write a…
@POST
public void doSomething(final Map thing) { ... }
So please stop trying to explain to me all the things that Java can't do concisely.Also you kinda missed my point about unit tests. Your test requires specialized flask-oriented objects (client, rv). Tests of the Java doSomething() can be written entirely without knowledge of the container; doSomething() is pure program logic. And the methods support refactoring.
you picked something that java has libraries specifically catered toward
I picked a basic REST service. I'd call that a pretty common use case.
There should be minimal logic in the handler. You should defer most logic to a library function
Again illustrating my point that well-written Java is more concise. You don't need to do this! The Java "handlers" I've shown are pure logic. There is no point in wrapping it with another layer.
Sure, you probably could build a webapp framework that makes Python a lot more like Java. But so far nobody's done that. So Python programmers write wordy verbose flask apps with tons of validation and marshaling logic. It's tragic.
Re: The melting pot of JavaScript (2017)
#199Earlier quoted context omitted.
>I'll go back to my earlier point, which I think you've illustrated fairly well, which is that well-written Java code tends to be more concise and less verbose than Python (and friends). Our two examples are nearly identical in terms of meaningful lines of code, but in the Python example you have to ask for marshaling. That's only an API wart. It'd be possible to elide that pretty easily if someone wanted to write a…
The Java equivalent of your example is probably: @POST public void doSomething(final Map thing) { ... } So please stop trying to explain to me all the things that Java can't do concisely. Also you kinda missed my point about unit tests. Your test requires specialized flask-oriented objects (client, rv). Tests of the Java doSomething() can be written entirely without knowledge of the container; doSomething() is pure p…
More verbose than the Python.
>Sure, you probably could build a webapp framework that makes Python a lot more like Java
Not could, did. Literally just did, in 10 lines of code. Or there's flask-rest, which I linked.
>Again illustrating my point that well-written Java is more concise. You don't need to do this! The Java "handlers" I've shown are pure logic.
And flask-rest does that! If you're writing a restful service the more concise, better specialized tooling is readily available.
Now write the unmarshalling code and tell me Java is still more concise.
Re: The melting pot of JavaScript (2017)
#200Earlier quoted context omitted.
Right, so I guess I'm not understanding your point about why comparing two languages like this is ridiculous. Java has a full blown runtime reflection system (it's "types exist at runtime"). JS doesn't. So Java wins in the reflection category.
But in JS, reflection is pretty much not needed... I don't need to use reflection to see if an object has a quack method, or that I call it with the right types... I just call instance.quack() ... It's up to you as the developer to keep your interfaces and composition in line. It's actually WAY easier than with C# or Java. Since the use-case of reflection itself is largely unnecessary.