Because new buildings these days are invariably the same boring gray dull shit that robs any place of its identity?
7,372 karma · joined February 19, 2008
Because new buildings these days are invariably the same boring gray dull shit that robs any place of its identity?
What are you on about? Redux is literally about global state everywhere. But with three to four layers of abstractions between.
You define your state globally. Then use hooks to fetch data from that global state, and then "dispatch" aka call actions on that global state. If something else somewhere else updates data in that global state your component will be affected if it uses that data.
But it also requires you to write an insane amount of useless stuff like "define your store, then reducers, then slices, then god knows what" to arrive at almost the same code:
// redux
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
export function Counter() {
// note how we reach into magical global state that useSelector knows about
const count = useSelector((state: RootState) => state.counter.value)
const dispatch = useDispatch()
return <>
<button onClick={() => dispatch(increment())}>Increment</button>
<span>{count}</span>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</>;
}
// solid
// state is immutable. It's also not magical, you explicitly refrence and import it
//
// increment and decrement would use a `set` function to update the store to required value
// see https://www.solidjs.com/docs/latest/api#createstore
// and https://www.solidjs.com/docs/latest/api#updating-stores
//
import { state, increment, decrement } from './counter-store';
export function Counter() {
return <>
<button onClick={() => increment()}>Increment</button>
<span>{state.count}</span>
<button onClick={() => decrement()}>Decrement</button>
</>;
}And you never use only local state. You advocate for Redux in a different comment which is literally a global state where you are going to have something suddenly change somewhere from the point of view of a component.
Let's see:
--- start quote ---
A gun in the Czech Republic is available to anybody subject to acquiring a firearms license. Gun licenses may be obtained in a way similar to a driving license – by passing a gun proficiency exam, medical examination and having a clean criminal record.
the issuing authority (police) firearm owners' database is connected to information needed for a background check and red flags any incidents that may lead to loss of license requirements. Similarly, health clearance by the general practitioner is needed for periodical renewal of license (every ten years).
* also very specific restrictions depending on license *
Obtaining the license requires passing a theoretical and practical exam.
https://en.wikipedia.org/wiki/Gun_law_in_the_Czech_Republic
--- end quote ---
Oh look, already more strict than many states in the US (and some states are busy removing any restrictions).
Let's say you're a teacher with known dissident tendencies. Boom. Suddenly the only place you can get work is one of these remote regions with lax control. Yes there is less government there, and you can even start a book club or something to read and discuss banned literature, and no one will bother you.
But try and get out because you're tired of rural life... and no place in the "mainland" will acept you. Or will only offer you menial jobs and unskilled labor.
This was a very widely and well-used tactic in the USSR. Can't see why China (or any other authoritatian state) wouldn't do the same. Especially China with their current state of surveillance tech.
Strange that you don't like spaghetti, but then praise Redux that is spaghetti exemplified: dozens of functions, and wrappers, and hooks eerywhere. Trying to trace how a value gets changed through the three-four layers of wrappers is like pulling teeth through the anus.
And looking at the current reincarnation of this abomination, it is marginally less spaghetti, and converging on the same signals code that everyone is converging on.
- The Evolution of Signals in JavaScript, https://dev.to/this-is-learning/the-evolution-of-signals-in-...
- React vs Signals: 10 Years Later, https://dev.to/this-is-learning/react-vs-signals-10-years-la...
- Making the Case for Signals in JavaScript , https://dev.to/this-is-learning/making-the-case-for-signals-...
Those two code examples are different because that's the tradeoff that Solid made. It allows Solid to track changes in a uniform way even if the data isn't inside a component. Because in Solid components are just a way to organize code, not a unit of rendering (like in React).
And on top of that if you think that React still somehow has unidirectional data flow, it doesn't. Hooks make it anything but unidirectional. And not that different from signals: https://res.cloudinary.com/practicaldev/image/fetch/s--upMC6... But often less predictable.
See also The Cost of Consistency in UI Frameworks, https://dev.to/this-is-learning/the-cost-of-consistency-in-u... which is slightly related to this.
Even those that you assume "just have it" most likely just have enough means and connections to try and fail and eventually succeed than most of us.
18% of households in the US say they can't afford home internet service: https://ntia.gov/blog/2022/switched-why-are-one-five-us-hous...
This comment has the relevant quote: https://news.ycombinator.com/item?id=35024721
A smart authoritarian government will have these "free" zones as a pressure release valve:
- Most active dissidents jailed
- Active dissidents allowed to flee the country
- Somewhat active ones allowed to "flee the regime to the free-thinking zones far from government control"
/s
And it's hard to overstate, but to also properly explain, how important this is and how it feels like magic when you do it. Because it lets you tap into everything Elixr (and Erlang VM) have to offer on the backend without ever having to think of "how the hell do I bring all that to the client".
My use-cases are: a big chunk of data is being processed, and while its being processed regular updates are sent over PubSub. Most actions a user initiates are long-ish-running and their updates are also sent over PubSub. Things that other users are doing are sent over PubSub and possibly need to be reflected in the UI.
In "traditional" JS-on-the-client-whatever-on-the-server model you have a plethora of questions of how to get that to UI: which endpoints to query, which updates to send over the wire, the formats, the frequence, authorisation, auth...
With LiveView your "client" is an Elixir view living on the server which just updates the view based on those PubSubs (or timers, or Kafka streams, or user-initiated actions, or...) and LiveView takes care of upating the DOM/HTML in the browser.
"Build a real-time Twitter clone in 15 minutes with LiveView and Phoenix 1.5" will give a good overview of this: https://www.youtube.com/watch?v=MZvmYaFkNJI
[1] Built-in in Phoenix, https://hexdocs.pm/phoenix_pubsub/Phoenix.PubSub.html
Those designers were/are more illustrators than designers [1]. Design is, or at least should be, as much about the function of an object as about it's looks. A design that hinders functionality isn't a good design.
[1] I call the modern breed of such designers "Dribbble-driven"
GQL literally allows unbounded queries.
All the "tooling" around like "field complexity", "data loaders" and other hacks are literally that: hacks and workarounds, and they are not even consistently, evenly or even efficiently implemented among the various GQL libraries and frameworks.
> it automatically comes with documentation for your API
Unless it's specified in code, and to create actual documentation you have to run a server, connect to it with a tool, and dump it (can't remember which lib did that, was it in Java or in Go).
> you think that using GQL automatically comes with the infrastructure I described.
This: GQL doesn't come with infra. And for every thing that REST aready has and for every issue that GQL has, and REST doesn't, you need to add more and more infrastructure and "rich ecosystem":
- Caching is literally built-in in HTTP. GraphQL's default method is POST, so to "solve" caching frameworks like Apollo have to act as middlemen unpacking every incoming request and every outgoing response looking for certain fields to figure out what to cache. Of course, this isn't available in other libs and framewroks
- Unbounded queries are literally not an issue in REST (unless you build something weird). In GraphQL you need to "specify field complexity" if you framework allows that
- Your REST endpoints know what exactly is requested, and can have specific hyperoptimised queries for that specific thing. GraphQL is ad-hoc by nature, any query is potentially n+1, so you have the workarounds with dataloaders which by definition cannot be optimised unless your specific framewrok gives additional insights into what's being requested.
Literally everything around GraphQL is "nothing works well, and if you're lucky, a particular graphql implementation for your programming language will have some solutions for some of the problems".
How do I know?
I built a service prototype for an internal tool in 5 different languages with 6 different libs:
- Typescript, Apollo
- Java, graphql-java
- C#, graphql-dotnet
- go, glgen and graphql-gp
- Elixir, absinthe
GraphQL sucks ass for everyting and everybody except client developers who couldn't care less how it looks on the backend
> you simply integrate
> or something
"simply", "essentially", "something". An equivalent of "just".
In reality: none of this is solved, non of this is "simply" etc. because every single lib and framework (often multiple for a language) will have their own awkward workarounds for these "solved" problems.
> Just not really an issue in practice, and really comes down to the underlying transport medium. JSON is limited
It is an issue in practice because every single framework does implement a date/time/datetime extension to built-in types. And this has nothing to do with JSON. Every single modern protocl for some reason forgets that dates, times and timestamps are sued everywhere and by everyone. See protobuf for example. Encodes to binary, has no dat representation.
> How is this a problem with GQL? Do you think that API versioning is in any way easier to when you have REST APIs?
Yes. API versioning is easy with REST API. You can even evolve schema versions for the same resource without ever changing the endpoint by looking at "Accepts" headers. When you have ad-hoc clients doing ad-hoc queries with GQL you can't even be sure which particular subset of data is requested by whom, and can you remove or deprecate or change it.
Yeah, yeah, here the "solution" is to use a hack called "persisted queries" which is literally REST but with all the good parts removed, and a lot of unnecessary steps added.
- GQL allows unbounded arbitrary queries. The awkward workarounds turn it into REST with none of REST semantics
- default query method (POST) cannot be cached by literally anything in the infrastructure because POST is not cacheable by definition. The awkward workarounds require you to parse and look up fields in both request and response. Both of them arbitrarily large.
- instead of delegating requests to optimized queries (db or services) you now collect all that data manually, in-memory, on the server with little to no insight into what the data is, and how to optimize its retrieval
- default types doesn't provide useful primitives like dates
- you now have to keep up with evolution of every single microservices you depend on
There's more that I've forgotten.
It's really good for building internal tools that usually have different requirements than what existing APIs provide you
And yet, YCombinator's top companies lose billions for years and keep getting the money. What's the "proven path to profitability"? The flimsy belief that "just wait a bit and we'll have a next Facebook?"
Most of the companies that get mentioned as "big innovative companies" in HN threads have been around for 5+ or even 10+ years, lost incalculable amounts of money, never turned a profit, and we're led to believe that there's an expectation to turn a profit in any of these scenarios.
US has next to zero privacy protections, and unlimited investor money with zero expectations for a company to ever turn profitable. E.g. all of YCombinator's "top companies" lose hundreds of millions and billions dollars a year.
China and Russia have cheap labor and yes, zero privacy.
Edit: the same people who clamor for Russia and China-style big companies will immediately shout for government to step in if any company ever gets to the size and influence of Yandex or AliBaba.
Or over 40 (I'm 42) :)
> Almost all its conventions come from a small little island, it's like marsupials in Australia, their own little parallel evolution.
This is a great analogy. And people forget that to program any system effeciently you need to know that system. Not necessarily inside-out, but good enough. A brief look at any emacs config will show you just how many weird and inconsistent things you have to contend with: major modes, minor modes, hooks, global variables, global functions, mode-specific global functions, special lists, non-special lists, and a myriad API calls and functions in between.
Wikipedia says that emacs has 10 000 (ten thousand) built-in commands [1] That's probably on par with JVM :)
or it's already available in pretty much any IDE out of the box. Most people advocating for emacs or vim usually have no idea what a modern IDE is, and pretend modern IDEs have not surpassed win3.1 notepad in terms of functionality.
Is it accessible? Why would I want to spend time learning the idiosyncrasies of a 40-year-old editor to write something that I might use once in a blue moon?
I have other, more interesting things in life.
Light and color weren't scientific concepts until basically Newton. And then you needed significant advances in chemistry, optics etc. to even begin measuring and thinking about such mundane things as application of color to house exteriors.