Hacker News new | past | comments | ask | show | jobs | submit login

The article seems to be lamenting three things:

1) Batteries-included web frameworks (like Rails and Django)

2) Interpreted languages without strict typing (like Ruby and Python)

3) Programmers relying on large numbers of dependencies (e.g. ruby gems), and the resulting difficulty in reasoning about the software

The last paragraph then goes on to suggest that different languages are required. This seems wrong. If you want to write web software you can reason about, you can still use web frameworks (maybe Flask or Sinatra) and you can still use third party packages (gems or things from pypi).

If you import a library (left pad or whatever) and call it from your code, then you can still reason about what's going on. The problem comes when you rely on adding packages that just talk directly to your framework (like Django middleware). Once you do that a few times, you really don't know what's going on between a web request hitting your server, and your own code running.




> The problem comes when you rely on adding packages that just talk directly to your framework (like Django middleware). Once you do that a few times, you really don't know what's going on between a web request hitting your server, and your own code running

I think this is where the lack of strict typing can make things harder to figure out. Especially if you're trying to understand middleware functions with opaque signatures (like kwargs in Python). IDEs like PyCharm do their best at providing "Find all references", "Go to defintion" etc, and that helps, but it's not quite the same. Putting the info in the docstring is better than nothing, but it's still harder to parse (and maybe not machine parseable) and who knows if it's really correct?

Personally I'm really hoping mypy or type-hinting really takes off in Python 3, and makes everyone's life easier.


The key is consistency I think. For matplotlib (which is probably one of the most commonly used modules that heavily uses args and kwargs), it's really useful. On the other hand it's only useful because their web documentation is really good and most of the time the args/kwargs are consistent between functions.

It also helps that most matplotlib kwargs can be controlled using an additional function, if you have a reference to the line/plot you want to modify. So you could do:

    plt.plot(range(10), ls='solid')
or equally:

    lines = plt.plot(range(10))
    lines[0].set_linestyle('solid')
But in the end it comes down to documentation. I think Python traces are generally pretty good at telling you what you did wrong.


But is that really a problem of non-strict typing, or rather a problem of metaprogramming? I could imagine even a very strongly typed system in Haskell or Scala would probably be hard for an IDE to support if it uses a lot of complex abstractions to create internal DSLs (like Rails and I guess Django as well do).


IDEs can typically query a strongly-typed language for useful information without actually running the code. As long as the DSL uses static types, the IDE can just ask the compiler / type-checker to tell it what's going on and what portions of the source contribute to that meaning.

This is where the fuzziness of the phrase "strongly typed" becomes a bit of a problem, but the fundamental idea is that there are two levels of meaning in the program, one static, and one dynamic, and the static level produces useful info. There are lots of levels this can take. The most common is in an IDE for a language like C or Python; it compiles or style-checks the file, warning you about issues, but it doesn't have any sense of what the program means. Another very common one is where you have non-code configuration files for GUI layout. You usually don't need a Turing-complete language to describe your GUI, so putting it in some other format like XML means the IDE can render the GUI and let you make changes to it without having to actually run your code. Strong typing for DSLs is just another example of the same sort of thing. If you're able to e.g. describe your models to the ORM entirely statically, it can figure out what a ton of your code means without running any of it.

I think this is basically what you mean by metaprogramming, except with the constraint that one of the two languages is pure and Turing-incomplete and doesn't rely on external input. Then the IDE can safely run that language.


It sounds to me like a complaint about stupid metaprogramming. Every kind of programming can be done badly: there is stupid imperative, stupid OOP, stupid functional, stupid declarative, stupid pattern matching, stupid reactive, stupid aspect-oriented, ...

I'm not saying that Rails is stupid anything (I'm not familiar with it), but maybe that's the way it is in the blog author's view.

Here is an example of stupid: someone writes some class framework or whatever. It's open-source. Yet, the next someone wants to extend it---but instead of a proper source code patch, they implement some monkey patch which relies on mutating things in the original framework after it's loaded. Then the next someone after that does the same thing to the second someone's customizations, and so on. Then to find out what is being called you have to trace through to understand the side effects of several run-time patches.

Let's not dump dynamic because of stupid dynamic.


I can't speak for Rails, but at least with Python (primarily Flask) it's not internal DSLs that have caused me problems. I don't think Flask attempts to be a DSL at all, actually. From what little I've seen of Django it isn't trying to be a DSL either (unless I'm misunderstanding that term). It's more when I have 2 or 3 Flask libraries or middleware and they each are documented as if they exist in a vacuum but I want to use them all together and I wish it was easier to see that all 3 have functions that take a Flask Blueprint object, so they're probably all related, or that these functions work with URL objects, etc...

It's a general complaint about Python and the tooling I suppose, not specific to web application frameworks.


>From what little I've seen of Django it isn't trying to be a DSL either (unless I'm misunderstanding that term).

Django bundles two DSLs - the ORM (filter, etc.) and the templating language.

>I don't think Flask attempts to be a DSL at all

Flask bundles jinja2 and sqlalchemy which perform the same purpose.


Thanks, now I have a better idea of what constitutes a DSL. It had occurred to me that the ORM might be one, but I forgot about Jinja2 which clearly is.

Though, being pedantic, Flask doesn't bundle SQLAlchemy (though it's what you end up using) unless things have changed recently.


The problem is accepting/returning a wide and disjoint type set, together with metaprograming itself.

Static typed languages tend to require that code deals with only a restrict set of types, and avoid metaprograming in exchange of other kinds of code abstraction.

I don't think this specific problem is big, tough. The dependencies one, by its turn, is huge.


All 3 of those lamentations could also apply to Clojure, but I don't think anyone who used Clojure would lament it.


Yes they would. The rumblings of clojure and the dynamic language trap are already out there.


Haven't heard them myself and I'm quite involved with the community.

Some disappointments about core.typed not being what some would have liked, but other than that...


>> 3) Programmers relying on large numbers of dependencies (e.g. ruby gems)

So many gems are either not written well, or not maintained well. How many times have you seen the case where you update gem to fix a bug, and then cause two more?

It's not Rails or Ruby's fault, it's the community.


Ruby's got a lot of software that's been produced over the years, and one of the risks here is that people burn out on projects and move on. A slow accumulation of dangerous deadwood occurs over time and unless people work to clear the brush it can be catastrophic when problems strike.

Consider: ImageMagick and OpenSSL.

Newer platforms haven't had this problem because they've already broken all their old software (Rust) or because they're still changing rapidly enough that new software is still emerging (Swift).

It's not the community's fault. It's that it gets harder and harder to keep things clean the longer your language has been around.


Ruby gems in particular host a lot of abandonware and basically little turds that entice "I read pragprog, watch screencasts, and am now leet Rails dev!" Folks into using them with the promise of easy Lego style coding. It never ends well.


Do you have a scat fetish? What is it with you and turds?

People get hyped about any language the same way. How many Erlang "experts" or Node.js "ninjas" are there out there? Give it a rest. If people want to get excited about something don't shit all over them.


> Do you have a scat fetish? What is it with you and turds?

Right about now is when you should go ahead and read his username, ideally out loud in your best Sean Connery voice.


Assembler solves all 3 of those problems, right?


> The last paragraph then goes on to suggest that different languages are required. This seems wrong.

I feel that the programming languages are being used here as proxy for something else: the community surrounding them.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: