Dense, multi-use blocks are part of the magic of New York. And there are hotels comingled with residential buildings all over the city. I'm not saying tenants should be free to violate their agreements with landlords, but these uses of Airbnb are solving a problem that city laws have created (an extreme lack of housing and hotel supply). I blame those city laws as a root cause. Putting supply on Airbnb is just water moving around obstacles the laws have created.
These people didn't just "commingle" hotels alongside other buildings; they implanted hotels into apartment buildings. That is definitely not a norm in NYC.
There are externalities, though, to running a hotel, which is why we have taxes and rules to mitigate those things. These people are trying to bypass these mitigations, and push the externalities back on the populace. That is not ok.
One distinction I should have drawn is between running an Airbnb with a landlord's permission (or as a landlord yourself) versus doing it in violation of other agreements you have (like with your landlord or co-op board or whatever). If you're violating contracts, then yeah, you shouldn't be doing that and other people in the building have a right to be upset.
But if you own the building and are running it as an Airbnb hotel, I don't know that it's a self-evident fact that you're putting significant negative externalities onto your neighboring buildings. I can imagine negative externalities, but I can also imagine plenty of positive ones. These are exactly the kind of calculations that regulators are empirically horrible at making, even when they have the best intentions (and often they don't have even that going for them).
The ban on short-term rentals is a ban on a use of property which is provably very valuable to the people on both sides of those transactions. Banning that use destroys value for both those sides. The objection is that short-term rentals divert housing stock away from long-term renters, but that's not a problem with short-term rentals (which are, as we can see from the fact that they're so popular, an even more in-demand use of the property than long-term rentals), it's a problem with the low supply of housing. Which is a problem caused by the very regulators who are riding in to "save" renters from Airbnb.
Taxes on hotel stays are popular with politicians because the people who pay the tax aren’t typically residents. It’s more likely that these taxes were an easy sell rather than something that offsets a negative externality of having a hotel nearby.
I guess it is "housing" but I think you'd find a lot less housing as in traditional places you can rent or buy long term, I belive we're already seeing that with Airbnb.
The community generally wants extremely restrictive building regulations. We're currently going through this in Edinburgh, which is a world heritage site as well.
An extra complication here is that the communal stair wells of apartments are comunally owned, so landlords attaching keyboxes outside the door are usually violating the property rights of their neighbours.
Even just one poorly designed library can cause serious memory issues and trigger a ton of events. Usually it’s the marketing and ad people that throw around this “but they are async loaded”. That’s true, but doesn’t change the the fact that 40 trackers and their dependencies that come with it are slowing down and infringing on the users privacy. Let’s be real.
Random Reddit page, content: medium-sized image. 164 requests, ~12 seconds to render the page on the test rig. 60 Javascript requests. 1.5 MB of JS downloaded to display the post, a 46kb image. There's a 30:1 ratio of JS to post content (what the user wanted to see) here. And there's other bloat beyond the JS.
I just picked these two sites at random. You can do this all day with random websites. I would guess that most sites behind a .com (or .co.uk, etc.) will look similar.
I don't mean to pick on these sites, just wanted to point out that these practices are widespread and even reputable developers engage in them. Which will make it more difficult to undo the rot.
I see there is a lot of JavaScript but are you certain that is JavaScript with the sole purpose of tracking or application code? I’m not gonna say these sites could not be implemented better but the claim was these are all tracking pixels. Is that true?
You're parsing this too narrowly. I'm not making a claim about the purpose of each request. I'm looking at the totality and saying that maybe making 200 requests to display 200 words of content is overkill.
The larger claim was that the pages are loaded with junk that affects the performance of the pages. The signal:noise ratio on modern sites is broken, and optimizing the junk can only accomplish so much. Developers need to advise stakeholders of the downside costs, performance among them, of loading sites with bloat.
Here's an article I read a while back on the impact of specifically Javascript:
I agree but if you look at the parent response claimed 40+ tracking scripts, I just don’t see 40 tracking scripts I see a website using probably too many scripts to implement functionality but I can’t claim to know they can do it with less scripts - I can only assume and that is what the website posted in the original document talks about how to optimize... hence async and trackers not blocking comment was correct
There are three main ways to reduce errors in code: tests, asserts and abstractions. All three have advantages and disadvantages and generally deal with different classes of errors.
In this thread, we discuss asserts, not abstractions. Monad is an abstraction. (On the other hand, many people only see tests and forget about two other solutions, which are as important.)
Assertions, yes, in so far as they mean "I know this can't happen, but I can't structurally prevent it in the program in an elegant fashion, with the tools I use". However, I can't see how monads are suddenly going to make this problem disappear.
As for throws/try-catch - beyond assertion use, they also report all problems that are outside your control (like IO failing due to HDD damage, or connection dropping). Those kinds of problems are here to stay.
Sure, monads provide an elegant way to structure code with error conditions, but I don't see a problem with using simple assertions, throws, try-catch to enforce invariants. Personally, I don't care about elegance as much as whether or not it works, as long as it is simple to use and maintain. I can return something like a Maybe/Either, or I can throw an exception - both approaches are fine by me if it forces the programmer to account for error cases.
Throwing is a side effect breaking flow of control for no good reason. It’s takes you down the same path as all other spaghetti code.
Not as much elegance as it is about purity. Minimizing side effects is the number one way to reduce bugs.
It should be the number one guiding principle when creating out reliable software. Which means, you simply cannot use the primitive try catch or similar construct. Don’t break flow of control. Guide it to a terminal value instead.
These days, when I see try-catch and if-else constructs (which is in most codebases) it’s clear there will be bugs over the life of the application.
It’s fine, use them, but there is a world of greatness when you ditch these faulty constructs. Just like ditching OOP constructs. All built on false premises.
If you application is interacting with the outside world, you will be dealing with side-effects, and sometimes error conditions will happen.
For example, today I am working on a service that:
- uses a database
- calls external APIs
- publishes and consumes from a message broker
- interacts with local and remote filesystems over a variety of protocols
All of these things entail error conditions, most of which throw exceptions in the corresponding libraries. Sometimes they are converted to Either/Maybe, and sometimes they are wrapped in "native" checked exceptions.
The important bits:
1. The type system and compiler make sure the programmer has to deal with the error conditions at some point. From a programmer's perspective, a checked exception bubbling up the stack is not very different from returning a monadic object up the stack.
2. The core of the application is entirely pure. No exceptions (in both senses of the word). All side effects are pushed to the boundaries.
Nobody here is saying that monadic error handling isn't good (in case it wasn't abundantly clear, my comment was this thing that people call a "joke"). The issue is pmichalina flippantly disparaging asserts, one of the few good things left in this hell world:
It wasn't abundantly clear, but I'm often humorless.
Sorry for being so crusty. I just found out that about a third of my professional career was essentially waste because I was too thick to adopt Prolog twenty years ago. It almost physically hurts to think about it.
Anyway, I think OP's right about assertions being a code smell: an assertion is literally the place where you tell the machine you don't know exactly what you're doing, eh?
I've been working towards an error-free mode of development, a combination of Dr. Margaret Hamilton's "Higher Order Software" concept that developed out of the Apollo 11 project with mathematical derivation of programs. I'm just about ready to "productize" it but I'm not going to market it to other developers. I'm going to sell it directly to consumers. They won't know enough to argue with the method, they'll just be able to use the computer to solve problems, I won't tell them that they are programmers.
Bottom line: error-free software development methods have been available for decades but the industry tends to ignore them. In 2018 writing "assert", "throw" or "raise", etc. is a code smell: you are doing it worng. If I sound cranky it's because I am.
I hope you succeed, and I say that sincerely, but regardless of whether or not program synthesis should have been pursued more aggressively in the past, I'm not aware of any support for your statement that "error-free software development methods have been available for decades" for any reasonable definitions of "error-free" or "available".
>Anyway, I think OP's right about assertions being a code smell: an assertion is literally the place where you tell the machine you don't know exactly what you're doing, eh?
The whole point of the original article is that, today, the only thing keeping planes in the air is fault tolerance and lots of redundancy (see also: Erlang). Assertions are about humility and it's good to be humble.
>In 2018 writing "assert", "throw" or "raise", etc. is a code smell: you are doing it worng.
But somehow writing ">>=" isn't? On one hand you seem to suggest that error handling is bad because there shouldn't be errors (what about I/O? user error?) while on the other hand you seem to be defending the position that monadic error handling is a panacea.
Brother, I really don't want to have this argument again. I don't care anymore if my peers believe me or not. I'm just going to bring it to market as best I can and see how it goes. Thank you for the well-wishing, and I apologize again for being so cranky.
A few lil points:
> I'm not aware of any support for your statement that "error-free software development methods have been available for decades" for any reasonable definitions of "error-free" or "available".
I know. You are making my point: The methods are there, and no one has ever even heard of them.
The primary method I am talking about was developed by Margaret Hamilton during the Apollo 11 mission to the Moon, and she has unsuccessfully marketed ever since AFAIK. Dijkstra once reviewed it and panned it harshly. It was a rare case of him not getting it. It went right over his head.
Hamilton, by the way, is the person who first coined the term "Software Engineering".
I'm not going to go into it further now, suffice it to say if you are typing text into a text editor to write code you are doing it wrong. There's a book, "System Design from Provably-Correct Constructs" by James Martin, that presents Hamilton's method if you're interested.
> The whole point of the original article is that, today, the only thing keeping planes in the air is fault tolerance and lots of redundancy (see also: Erlang). Assertions are about humility and it's good to be humble.
Planes stay in the air because they are designed to survive the failure of the individual parts. Now I would never suggest that proven-correct software cannot fail. Of course it can. Need I invoke the Cosmic Rays? I heed Murphy.
But you only write an assertion if you're not certain, eh? You're saying, in code, I think this will never ever happen, so if it does STOP-THE-LINE.
That kind of uncertainty is absurd, inexcusable, in software. (One of the very few realms that this is true, Herr Gödel notwithstanding. Software is electrified math, math is the "Art of What is Certain".)
I'm saying that our current common methods of software development are pathetic, that we are working far too hard to write software with far too many bugs, and it doesn't have to be this way. I'm further saying (to the OP) not to waste breath arguing with folks who can't or won't even accept the possibility! I've been doing it for a few years now and it's thankless. I've managed to convince exactly one other person and he's a brilliant programmer who came to it from a background in philosophy. He's a thinker rather than a puzzle-addict or complexity junkie.
Anyhow, if I manage to bring this thing together I'll make a noise here on HN (despite YC getting into bed with the Chinese Communists, the greedy fools.)
> On one hand you seem to suggest that error handling is bad because there shouldn't be errors (what about I/O? user error?) while on the other hand you seem to be defending the position that monadic error handling is a panacea.
Nope. Nothing like that. I can't explain it all her and now, but uh... Have you heard of Elm-lang? They boast zero front-end errors. Zero. The Elm compiler makes the JavaScript and it does not error. They do not write "error handling" to achieve this.
pp. 76-77 of Ousterhout's "A Philosophy of Software Design" talk about the issues with boilerplate try-catch. He basically does not approve, as they make readability suffer and often do not do what they advertise (truly catch errors.) I don't know how he would feel about production assertions, but I'm guessing he would buy into it if it helps reduce complexity. In the sense of finding remedies to troublesome bugs--which will occur.
This kind of absolutism only works in the lab and the journal.
The real world of software engineering is enormously varied and each project faces a different set of legitimate constraints and objectives. It's more valuable to discuss how and when to use "assertions, throws, and try-catch[es]" than to pretend that they're universally superceded by some other construct.
Because treating something like a moral failing is hardly helping anyone. Instead treating it like a disease means actually helping people in the situation they are.
“Treating something like a disease” encourages one to not take ownership of the issue but instead provides a mechanism to play victim and give up. It’s victim mentality, denies the concept of freewill, and sets the stage for all sorts of slippery arguments.
There are tons of things that lodash still provides that can't be easily replicated.
Just in the last month or so I've used throttle, debounce, uniqBy, memoize, get, and i'm sure more.
Sure, things like map, filter, find, reduce, etc... are made obsolete, and `Object.values` is a huge win to iterating objects or arrays with the same code, but lodash is far from useless.
And the way the library is structured, pulling in just one or 2 functions is fairly lightweight if you are using a bundler like webpack/rollup.
Yeah the iteratee shorthand stuff in lodash is massively convenient, however I'm starting to shy away from it in favor of more "obvious" approaches like your second example.
Although that being said, for deep property access like you have, i still reach for lodash's `get`, or more recently i'm beginning to use the new stage-1 proposal for "optional chaining" (also known as null-conditional operator in C#) [0].
As nice as lodash's syntax is, it can be confusing for those who don't know it, and even I need to step back sometimes when I see it used heavily somewhere and almost replay what is happening in my head.
Luckily there are fairly simple polyfills that can be used for that (including using babel's preset-env system to configure it based on browser support!)
There are still heaps of tiny but useful utility functions in Lodash (`fromPairs`, `takeWhile`, ...). Sure those are trivial to code yourself, but with recent bundlers' tree-shaking abilities, it's just better practice to import a thoroughly tested version instead.