I don't know if that's idiomatic webcomponent or not but that looks unmaintainable, even for such a minimal component, imagine once it grows. It's not separating presentation from state and logic. querySelector need to match classes and elements in the markdown. Mutating textContent is going to run out of sync as soon as you have more than one event source doing the same. Those are all problems that React solve by separating state and only rendering in one path.
That's the best case scenario and already looks like crap. If that looks sane to you, I don't know what to say.
Make it have an initial count via attributes, sync it with the DOM so if the attribute changes the count resets, and make the JS property always match the attribute (and vice-versa) so it behaves sanely. You're in for a world of pain even for something as simple as this.
Plus they're not declarative: you will only make me use innerText-based updates by threatening me and my family.
Plus they only work with JS enabled, while I can use JSX in SSR.
I've worked extensively with Web Components. They suck.
Web components are intentionally low-level, they’re not really meant to be used directly. You should see them more as performant, interoperable building blocks. Have you tried lit?
This circles back to the OP's point: they're not appropriate to use directly, so we layer a framework on top of them (Lit), and now we're just using another framework with one small piece swapped out.
Except for the hyphens, I don't feel any closer to the platform when I use Lit.
You can inspect a Lit component directly in Chrome, it’s just a custom element. No need for a browser dev extension. You can use this custom element from React or any other JS framework. You can also use this custom element in a server-rendered template, no need for any custom SSR setup. Feel close to the platform yet?
If you do this you might as well just write JavaScript without using WebComponents. APIs like innerHTML, querySelector, addEventListener have been around for decades.
Well for one thing, I don't find that to be particularly succinct or nice example. There's a lot going on there:
- HTML in a string. No syntax checks. If you interpolate it, you have to escape manually or you could create trivial XSS vulnerabilities. Your editor will probably not syntax highlight it, making it harder to tell when you break it.
- Manually formatted update logic that is redundant with the string. Not so bad here, but try formulating a practical large component.
- Completely ad-hoc state management, no reconciliation. Again, fine for Hello World, not fine after that.
Using raw WebComponents, your application has to care about all of this on its own and more. You can use templates and slots (which you should) but that makes this even messier IMO and brings back the split that React became famous for getting rid of. We left manual DOM reconciliation, ad-hoc data flow and non-reactive components that manually call a render routine at arbitrary points for a reason: it sucked. It made for buggier, harder to maintain code. It can be done, but usually any decent app will wind up encapsulating patterns into utilities that get reused. And... That's precisely why we want a good library. That's what I want, a library that packages up good reusable patterns for constructing UIs effectively.
And that's exactly my point, which is WebComponents or not, the solution is still basically the same, use libraries. Which begs the question: if I have to use Lit, what is the point of "using the platform"? What is WebComponents doing for me here that React wouldn't be? And in my case, I struggle to see it.
Interoperability? The old way of embedding external components works quite fine. Switching APIs where you pass a DOM node for something to mount into and get back an object with an API to one where you instantiate a component and communicate via properties and events feels like a strictly lateral move. I can't think of a condition where this would be particularly more convenient, but I can think of some where it is actually less. Next.
Isolation? Yes, WebComponents does add tools to provide better isolation between components. For some use cases this is a genuinely useful feature, although it also isn't without tradeoffs (I mean, the flexibility of having things be not isolated comes in clutch sometimes, it's hard to argue this.) But I use React primarily to construct components in an application, where I find this property more undesirable than desirable.
The one thing I thought could be cool with WebComponents is if you could build them in pure HTML when you only needed basic templating, but no: the design they went with always requires subclassing in JS AFAIK.
I could go on and get more specific, but I feel like people will pick everything I just said apart quite enough. I hope I'm at least able to make the case that:
- I do in fact, get the general gist of WebComponents.
> If you interpolate it, you have to escape manually
Well, for some definition of "manually".
If you have untrusted variables to interpolate, you can do
this.innerHTML = html`Hello ${name}!`
Where html is a function that escapes the variables.
The arguments brought forward against web components all seem to fall under "But it does not contain every functionality you want to use out of the box". Personally, I don't think browsers should provide more and more functionality, but rather a good base to build upon.
The great thing with software is you can write your own functions. It would look something like this:
function html(strings, ...values) {
let result = strings[0];
for (let i = 0; i < values.length; i++) {
result += escapeHtml(values[i]);
result += strings[i + 1];
}
return result;
}
The reason react sites are bloated is because there are a lot of things that are easy to do once you have better DX, there is nothing stopping you from making completely static sites with no js (solid-js 2.0 has a whole "htmx-like" mode that lets you have good interactivity even with js disabled).
WebComponents are useful for cases where you want something slightly more integrated than an iframe or want to make a library of small widgets
> Isolation? Yes, WebComponents does add tools to provide better isolation between components. For some use cases this is a genuinely useful feature, although it also isn't without tradeoffs
I hate the guts of every site that uses those. Shadow DOM makes the site hard to operate and fix programmatically from user end.
I mean, these days I can just throw an LLM at it so I don't care as much, but sometimes I want to still do things hands-on. Not to mention, Shadow DOM is often a difference between "simple userstyle/userscript that is allowed at work by security extensions" vs "requiring things that are banned on corporate-managed browser".
For starters, that it introduces weird special cases to DOM parsing and structure, thereby breaking .isEqualNode whenever <template> elements are present.
I think the problem is not what I don't like about WebComponents individually. The problem is that to use WebComponents, you have to use JavaScript anyway and if it does not do exactly what you wanted, then you're right there, in JS, ready to DIY the problem away.
If WebComponents were purely declarative, I would try harder to use them.
(preface by saying I use webcomponents regularly, I can show you a game that's currently online where they're used extensively)
I don't really understand why people are complaining that this is unmaintainable on the replies to this snippet but there's plenty of things with webcomponents in general that could be better done on the browser side.
For one the innerHTML (or some new method) should be able to reference a `template` directly. If you want to use templates you need to do:
And if you want to use templates then you need to render the templates in a part of the dom that is parsed before this JS is run - there's no way of specifying dependencies for this kind of things - which is a short-coming of the platform as a whole.
One the same topic there's no way of providing an url for retrieval of a fragment that contains templates and have it parsed directly and available to subsequent JS if you could do:
`<HTML-FRAGMENT href="/my-endpoint/returns-templates.html" required="true" id="MAIN_FRAGMENTS">` or doing `fetch("/my-endpoint/returns-templates.html", {DOCUMENT_ID="MAIN_FRAGMENTS")` would parse the result and make it available to the browser engine then you could have on subsequent JS:
`<script requires="MAIN_FRAGMENTS" wait="GLOBAL_LOADING_INDICATOR`>....</script>` or in a file/module `requires DOCUMENT_ID: MAIN_FRAGMENTS` and the file/script execution would block until that would be available, just that would go a long way. You could specify fragments (the component DOM templates to be used) that are needed for the webpage to work at all, fragments that would only show loading for their own content, etc (you could style the TAG with a pseudo-state indicator, so if it had a wait not resolved yet, CSS could target it with `MY-TAG:state(waiting)`).
Another issue is `attributeChangedCallback` - this doesn't take into account how most of the times one can/will update the attributes of an element, so it fires once for each change, even if you made X changes in one swoop, making it so that you have to have to make a more complex "update_render" function to work around that, or lots of small functions that are composable (ideally, but not practical or wanted in many cases where the whole thing is to be treated as a single update) or create a `batched_attributeChangedCallback` that you implement yourself as part of a class mixin and then extend the HTMLElement class on declaration and use that, because most of the times you want to re-do/update the whole component and when you have multiple properties (equivalent to react props and similar in other frameworks) and multiple components this can result in expensive updates to the page that the user feels as sluggish on their end. Something like:
`batched_attributeChangedCallback(attributes, old_values, new_values, batch_timer_window: 200, batch_timer_fn: true)` where the default for the batch window is 200ms, but can be provided a `fn` that does the evaluation to. So even if the updates are done independently but under the timer window they're batched instead of run 1 by 1 (or immediately if the `fn` returns true, defaulting to true when it's independent 1 by 1 updates).
I usually have a function `_set_handlers(boolean)` that is used on connected and disconnected callback but this is just plain js organisation:
And the connectedCallback just calls `this._set_handlers(true)` and disconnected `this._set_hanlders(false)`.
I use them, you can use them to great effect, but I think the biggest problem is the lack of connection between the different APIs. This includes things like indexDB as well, it's not very complex, but it does look messy on "first-glance". Like your example, but when you actually read it, it's pretty straightforward (ignoring the bad/non-existing functionality/APIs). The same with SSE. This could be a great solution for many things, but you always need to wire up yourself how it works. Would be great if you could declare "receiving beacons", at the page level, or component level, with automatic teardown on removal/navigation. So a component could have `static SSE_BEACONS() { ["https://something.com/path"] }` and would mark the state of the component automatically with `BEACONS: [WAITING | CONNECTED | ERROR]`
The loading indications, still seems strange that after 40 years of web development the transition between webpages are basically "white page", "freeze current view". Just having some way of specifying loading states would make any webpage feel 90% of a webapp between page transitions. Make it be a restricted subset of CSS that can be included as a header at the document top level and cached for subsequent visits `<LOADING_STYLES version=X><MAIN>background-color: white;</MAIN><LOADING_INDICATOR>shape: square; rotation: 1s; main-color: blue; secondary-color: turquoise</LOADING_INDICATOR></LOADING_STYLE>`. This would also allow to evolve it while maintaining strict backwards compatibility by starting from a very basic set of possible values - but just this would make website loading a much more app like experience. It could be used together with webcomponents too:
`<MY-WEBCOMPONENT ...><LOADING_STYLES>...</LOADING_STYLES></MY-WEBCOMPONENT>` that then could be automatically derived from the `states` I mentioned prior.
Anyway... Spent too much time with frameworks and webcomponents by now. It probably would also make writing code for LLMs less error prone.
Just a rant, don't take it too seriously, but sometimes I wonder with all the resources poured into frameworks by the big Gs, that must amount to millions and millions of dollars when you take into account the salaries some of the people working on them take, if it wouldn't have been better spent somewhere else on the "base" implementation.
It was pointed out to me that `this.appendChild(document.importNode(template))` is faster due to "adoption" (`importNode` clones and adopts the nodes for the current document at the same time/single tree walk, saving appendChild from having to do a separate adoption pass/tree walk; template.content exists in a fake separate document so the nodes need to be "adopted" by the current document).
Which is a point in favor of the current complexity of the JS API for working with templates. I agree that "HTML Modules" would be nice to have and more declarative template usage that doesn't require the Shadow DOM would be lovely. Both are still proposed standards going through various debate cycles.
> making it so that you have to have to make a more complex "update_render" function to work around that
One potential simplifying answer when trying to deal with batched updates to attributes is a simple "dirty flag" and requestAnimationFrame callback as your "update_render". Most things changing more than one attribute at a time are likely going to do it all between animation frames and even if they can't, rAF provides other throttling that prioritizes user interaction.
There's still complexity in that approach, but it is isn't as complex as trying to build a throttling timer.
> I usually have a function `_set_handlers(boolean)` that is used on connected and disconnected callback but this is just plain js organisation:
It looks like you could replace some or most of your `_set_handlers` function by implementing `handleEvent(e)` for the Web Component. It's an auto-registered/unregistered handler at the component level of the event bubble.
Thanks for the `handleEvent` tip, that's useful for component wide events, but it creates some problems if you need to prevent the event at the input level, because some (specially those related to submit) will need to pass through the form to bubble to the component level and will trigger it, and preventing it at the component level wouldn't cut it if I'm not mistaken? It also doesn't cover events on the document, but that can be worked around and perhaps even clearer to have it separated (`set_global_events(boolean)`). it's a good option to be aware of but I also like segregating them in that way since it allows me to turn on/off from other parts of the component outside the lifecycle calls (or even from a parent component) - sometimes useful too.
You would also need to switch inside the handle event to deal with the different types plus the different targets that might be bound to those events inside the component so I think that for anything with a modicum of complexity it doesn't cut it, unless I'm misunderstanding how to apply them in those cases (pattern matching with multiple function heads would definitively make it read like a declarative model but is not really serviceable in JS even if you syntactic sugar it, you wouldn't be able to describe `target` html elements probably - like:
The importNode I think there was some issues with some properties not being copied outside of clone? I can't recall why I defaulted to `cloneNode`, could also be I just missed the `importNode` altogether or misread it at the time, but it has worked fine since then so I didn't look for ways to do that better.
Regarding batching, I basically have been using the same class extension since I've started working with webcomponents and it works, it uses a timestamp to control if we're inside the batch window for the inner working and then the "apply/build" part of each component has to compare those and decide - this is the part I would rather not have to code and have it handled natively (some events might actually run a single pointed update while others run the "full" apply/build function). It's nonetheless a bit more wiring and someone that never seen it might have the same reaction as some people here, even though they're fine in importing 50 libs, or 20 lines of useMemo with useState and useWhatever but heavens forbid they might need to read a 50loc class module. At some point many components need to ditch the `attribute` change handles as parsing the attributes into json/objects can get expensive, and you need to start doing parent->child direct data transmission and this is the only real bottleneck I've experienced when using attributes and requires an overhaul to how data is passed into the children (either from parent orchestration from top level attribute parsing that is fairly less taxing when done once only, but at a certain point can still stall the main loop just the same, at which point you need to parent-level requests, websockets, SSR that then you can pass directly to the child child_component._set_whatever_data_function(data) or setting the prop directly if it's workable in the particular case).
The thing with being able to load html fragments (or, even if whole html docs would be what we settle into) and having it be available would be that you could separate them into cacheable requests - so if you have `/essential-templates.html` , `/signed-in-templates.html`, `/special-page-templates.html` they could be cached, which means they would only need to be refetched if they changed or TTL expired. But with no way of declaring dependencies it can (will) also introduce bugs - if there were we could probably do some cool (as in useful) things too. I guess this is what many frameworks end up doing when they need code splitting, modules, and to create the initialization tree of a page/component, but then need to be re-implemented from scratch by each and leave vanilla webc out of an inbuilt system for it.
Here I might just be lacking some knowledge, and perhaps with TS it would be possible to, but the same way you write `static get observedAttributes() { return ["data-flux"]; }` would be great to have a `prop` like system, say `observedProps` that specified the `required` props when the node is to be attached to the DOM (not before, since `createElement` doesn't take options right? for the constructor or otherwise) for the cases you're adding elements from inside another component, that don't derive their inner state/data from attributes due to parsing cost and require directly setting those props.
Shadow dom is not something I use very much because I'm not creating widgets for third parties, or having to have locked components, but I do understand their existence and think it makes sense to have that mode too.
I imagine this is a complex topic altogether to push forward in the context of wrangling so many disparate interests (companies with lots of power and the only real players when it comes to browsers) but nonetheless not having them forces everyone and the webplatform to be way more spaghetti and troublesome than it needs to be. And I think that at a certain level, these issues go beyond the implementation and RFCs into the way browsers actually work, their engines and choices made before, that don't seem to be reasonable in hindsight when looking at from where we landed but asking for a new model will have 0 traction (of the type that matters) since there's too much at stake for what I imagine are "other" reasons.
give it a normal text prompt, and it
continues that prompt by searching
for the byte sequences that compress
best.
One moment, how are we supposed to know how well that search was done? There is no way to search a meaningful part of the search space.
So the result only gives us some lower bound of how well gzip works as a "plausibility tester" of a continuation of a text. The space of possible sequences is many orders of magnitude larger than what was searched. So there might be sequences in there that compress much better.
The text mentions beamsearch, but I don't see a discussion about how well beamsearch performs in finding the global optima when it comes to gzip compressibility of a text?
That's a fair question. Suppose we have a way to find a byte sequence x that globally minimises len(gzip(context + prompt + x)) over all sequences x of length n. Here + denotes string concatenation.
It's unclear if this is very useful.
The reason it may not be very useful is that one of Deflate's ingredients is a pass that replaces repeated substrings with backreferences to the earlier occurrence in the plaintext input stream.
E.g. suppose we want to find an n=200 byte sequence x that minimises len(gzip(context+prompt+x)).
If there exists any 200 byte sequence y such that prompt+y is a substring of context, then Deflate can encode prompt+y as a backreference to that earlier sequence - it needs to store a match-length & a distance-length, encoded using its Huffman trees. This candidate solution y may not be a global minima to our stated objective function, but if not, it's probably going to be a very good near-optimal approximate solution.
Taking a step back, repeating huge chunks of the input context produces something that's great for minimising compressed output size but doesn't seem particularly helpful as a generative model.
edit:
Yep, I tried it out by running an experiment. Searching for the prompt in the context & then copying the following text as the solution produces solutions that are much better, in the sense of minimising the compressed output length, than beam search, while also being unhelpful as a generative tool.
With the same example as the blog post:
context: first 30,000 bytes of tinyshakespeare.txt
prompt: 'MENENIUS:\n'
Let x denote a solution, x is a string of length 200.
Let L(x) denote len(gzip(context+prompt+x)), our objective function
Let's call the proposed search method of searching for the prompt in the input rfind (after python's str.rfind).
Then we have
search method soln soln length feasible? objective value search time (wall clock, s)
------------- ---- ----------- --------- --------------- ---------------------------
emptystring "" 0 no 13,023 0.04s
gzipt beam search see blog post 200 yes 13,051 11.93s
rfind see below 200 yes 13,026 0.04s
So 'rfind' is finding a solution that does a better job of minimising the objective function -- it only takes 3 bytes more to encode than the infeasible emptystring solution, and costs 25 fewer bytes than the solution found by the beam search implemented by gzipt per the blog post.
Here's the solution 'generated' by rfind copying and pasting from the input context, starting from the rightmost occurrence of "MENENIUS:"
MENENIUS:
O, true-bred!
First Senator:
Your company to the Capitol; where, I know,
Our greatest friends attend us.
TITUS:
COMINIUS:
Noble Marcius!
First Senator:
MARCIUS:
Nay, let them follow:
The Volsces
Here's the code for 'rfind' - our complete 'generative algorithm':
def find_candidate_solution_from_context(context, prompt, length):
n = len(context)
i = context.rfind(prompt, 0, n-length)
if i < 0:
return b''
i += len(prompt)
return context[i:i+length]
Can hook it into gzipt.py by adding this line after out is defined, but before the beam search begins
out += find_candidate_solution_from_context(corpus_window, prompt, length)
Read to the end: they aren't actually looking for the best-compressing output, because this quickly devolves into aaaaaaaaaaa. They keep a sliding window over a small portion of recent text and use that.
Basically I think the entire premise falls apart due to that choice--they forced an interesting-looking outcome by adjusting the algorithm until gzip started picking random slabs of letters instead of ever-larger repeating runs.
That's still an algorithm that underwent immense amounts of tuning. The tuning here on gzip is very simple, very few parameters, and generic. There is no reason to reject it.
Also I don't know about calling GPT-2 "really tiny". You can get coherent responses out of 5-10M parameters.
Heck, a few weeks ago someone posted a 25K-ish generator running on an 8-bit machine (ZX Spectrum? BBC Micro?). It emitted semi-plausible random English phrases. So tiny is subjective but I still think GPT-2 qualifies as a tiny model by any modern standard. I could run it on a laptop.
Modern laptops and desktops are so powerful though. That's not a great way to measure tiny.
With some patience you can run huge models directly out of flash. Edge0–35B-A3B, based on Qwen, has 35 billion parameters and will do 15 tokens per second on pretty boring hardware. If you treat Kimi K3 with 2.8 trillion parameters similarly (importantly, cutting the number of simultaneous experts in half) you can get the active weights under 12GB and get just over 1 token per second on a good laptop. Models in between have speeds in between.
The terminology does seem to be all over the place. GPT-2 is definitely a "small" LLM at best, but definitions of "tiny" might cap out at 100M or at 3B...
I think if I wanted to involve computer capability, I would say tiny is what you can train from scratch on a laptop. Not just run.
As AI becomes more and more capable and integrated into our lives, we will see this across many industries.
In theory, as things get cheaper to produce, business profits should rise and governments should be able to raise more taxes. So the government then has more means to provide goods and services for free to people who need them.
It's the snake eating it's tail. For business profits to rise, people need to to have disposable income. If you replace enough people with AI, the average disposable income comes down to a point that businesses can't be profitable.
We are already seeing a localized version of this with restaurants in large cities.
For business profits to rise, people need
to to have disposable income
Does it matter, if the business pays employees who then use their salary to buy goods from the business or if the government collects taxes and uses that to pay for the goods? The government could also give the taxes to the people, so they have disposable income.
Imagine an island with two people on it and there is one tree that grows apples. And every other day, one of the two people climbs the tree and picks apples so they both have something to eat. Then the next day, the other person owes to climb on the tree because they are in debt to the first person.
Now, let's say one day, one of them discovers, hey, we can just give the tree a kick and the apples fall down on their own!
With the perspective you are proposing, the other one would have to say: Oh my God, don't do it! We will be out of work and starve!
Tax rates for wealthy folks are what, 10%? It makes a big difference if the majority of money that is made is distributed to the people via salaries, or whether it's profits and only 10% makes its way to the people.
Problem is there are more people who are not wealthy than there are wealthy people by a couple of orders of magnitude so even if you taxed the wealthy folks at 99%, you would not have enough to go around, if there isn't anyone to tax but wealthy folks. That is unless you think the slice of wealthy folks grows in size.
This is something the "eat the rich" crowd keeps missing.
Sure, you could take wealth away from billionaires, and sometimes there are good reasons to, but it's weird to pretend that it will cover more than a tiny tiny fraction of a government's budget.
Another thing some do is assume wealth accumulation happens on a yearly cycle. Like if you take Musk’s ~trillion today you’ll have another trillion to confiscate next year and the year after that, etc.
That's true locally but not globally - it means the economy will increasingly shift to serve those who still have a reason to bargain with each other, which will be the owners of the AI and other useful capital.
I think you missed the joke that defrost made. Explicitly: The Waymo waits for someone rich to take a ride, then kidnaps them and demands a ransom. That ransom then pays for the cost of the car in less than a month.
It's not using the File System Access API, on Firefox it uses <input type="file"> for file-picking, and the save just downloads it. It's not synchronizing anything with your filesystem.
Firefox unfortunately does not support the File System Access API. You can try by calling the most fundamental function, the one that asks the user to select a file:
window.showOpenFilePicker()
What Firefox supports is a "File System API" which creates something similar to the other old ways of storing data in a browser, like cookies and indexeddb. You cannot use it to edit normal files on your disk.
This is my main gripe with Firefox. They force their users to either store everything in the cloud or go through the arcane "download" workflow where you have to manually save files.
> Firefox unfortunately does not support the File System Access API.
I would not call it unfortunate. Browsers should not have access to the file system, USB ports, etc. Perhaps in "PWA"s, if the user has a way of giving and withdrawing consent.
Why is that true? Some applications require file system access. People would grant the application the permission to access files like any other resource like camera, mic, location.
Because vulnerabilities, coarse access granularity and lazy or ill-informed users. E.g., you now grant cam access per domain. Changing functionality on that domain doesn't revoke permission, so a simple bait and switch is already possible. Now imagine granting access to your file system to some Microsoft domain and finding out that there was a change of heart and some new script has uploaded your files to OneDrive and deleted them from your disk.
Taking that logic of protecting users from themselves to the extreme, a website should not be able to display text either. Because it can use text to ask the user to open their explorer and delete the files manually.
I think the flow of Chrome where the user has to select a file from disk and then acknowledge a prompt that the site will have access to that file until they close the window is fine. But if Mozilla wanted to protect users from themselves even more, they could make it as strong as they like. For example, by requiring to turn the functionality on in about:config.
Not giving the user the choice at all, if they want a cloud only browser or a browser that lets them work with local files is the wrong way.
Iirc the File System Access API should always originate File objects from an input picker so that the user selects the file to be opened and not give more access to apps than users allows?
I believe you are able to connect to a Google Drive account with a purely client side site via google oauth and then using the Google Drive rest api. There was an article in particular that I liked that walked through it. Let me see if I can find it
Yes but Google OAuth is a nightmare if you want to "publish" your client so that anyone can use it. If only you use it, you can add yourself as a test user. Just know your access token expires super fast and you will have to frequently re-auth. Its crazy annoying.
Ease of backup too. One of the issues I take with browsers allowing web apps to save data locally is that they don’t also expose a way to easily locate the data in the filesystem or export it, and to my knowledge on-disk format isn’t standardized and so portability between browsers is also a concern.
The effect of this is that unless the user uses migration assistants or similar when upgrading to a new computer is that they’ll lose all local web app data. To me to this feels like a serious problem but when it’s brought up it tends to be hand waved away.
In that regard AI fits the bill well. Because many of the AI related posts are about tools one can immediately tinker with.
While a new type of laptop cooling might become interesting once the laptops come out, the news is not as interesting to me as a new LLM or agent that I can experiment with right away.
It jumps to the newest story on the frontpage. And when I click the bookmarklet again (or press "n") it jumps to the next. So I just click it until I land on a story I have already seen and know I have seen them all.
If you want to use it, you can convert the code into a bookmarklet with my bookmarklet editor:
My expectation is that AI will give us a way to nicely quantify how productivity is impacted by choice of language. Because we can rerun the same request as often as we like and compare the results.
And I expect that it will turn out Python is the most productive. As it is most easy to reason about. It allows for the most elegant expression of the idea behind a program.
The first tests I have seen seem to confirm this. One recent example:
It is unclear to me though how much of your expectation might be set by the training dataset.
For example, Python and Typescript have the most amount of codebases and training being done on. So I feel as if that plays a part into the overall thing.
Languages which are more niche have genuinely hard times (Try arturo lang for example), so it depends on a lot of things/nuance, or well that has been my experience trying something recently.
My personal opinion is that if each language has the same amount of training. Golang comes close but the first might be Elixir. I have seen Elixir language perform really well with LLM's with magnitudes less training dataset. There have been some studies which had Elixir as the number one language for such tests iirc.
Gleam is a new addition as well and I feel as if it could be good and its another interesting option as well with more type-safety and an interesting language overall.
I've been in elixir for nigh a decade now and the one thing that you can try to pry from my cold dead hands is the BEAM. Elixir and Gleam are my go to languages right now and damn are they fun to write and reason in, but the part that has left me never wanting to leave the ecosystem is BEAM + OTP.
- BEAM makes monoliths sexy. You don't have to worry about a bunch of microservices, just focus on using proper process division for modeling your problem.
- Debugging on the BEAM is first class. Drop into an interactive shell, pull up telemetry, or recon and hammer down on where your live app is slowing down if your metrics have a blindspot.
I could go on and on. I'm constantly blown away every day by the amount of time and effort and all of the sage learnings in distributed computing problems that came out of Ericsson that became the foundation of erlang + OTP + BEAM and in turn elixir + Gleam.
Never tried Elixir myself but came here to say the same thing. Tencent put out this study showing that Elixir seems to reign supreme: https://autocodebench.github.io/
Purely anecdotal, but my experience has been that LLMs generate low quality python code. It's spaghetti code on par with what I've seen when companies I worked at tried offshoring development. It's basically what you get when you give bad or incomplete specs to a team of inexperienced programmers with poor development practices. It's usually good in small chunks, but it gets extremely sloppy as the scope of work increases and more decisions are introduced. Interestingly, I've seen LLMs generate good clojure code.
My guess is it comes down the the training data more than anything else, although I suspect functional languages will fare a little better. At least that's been my experience. There's undoubtedly a ton of python code in the training corpus and portions of it are of dubious quality. Niche functional languages likely have a smaller training corpus where a larger portion of it is better quality.
Python is great as a dynamic language, but I find very few things about are easy to reason conclusively about because the state of the running program can be so crazy (has pros and cons). But it probably depends at what level you are working in python and how deeply you understand it. Type checking and linting help a lot to keep the truly crazy contained, but it's just fundamentally a very difficult system to trust. Not to mention working around the GIL is fairly inefficient.
I think it's far from being this simple. What you're describing is productivity on a greenfield project, but what's really interesting is productivity when working on an existing large codebase, with existing conventions, architecture decisions (or lack of)... How easy is it to do a product pivot, to rearchitect for performance, etc etc etc.
It is actually pretty easy to keep alive URLs if there is a will to do so. Just have tests in place so you can't mess them up accidentally. And convert things that are not changing anymore to static html.
One of my first web projects involved a music forum and I have been keeping the URLs alive for 24 years now:
It's not easy. Part of the instructions would need to contain things like "how to convince your boss to not just delete the old thing" and "what to do when the startup you worked for went bankrupt" among others. Most URLs don't disappear by mistake.
Well, and pay registrar and hosting fees for 100 years, and then just hope the hosting company doesn't fold in the interim after your passing. The problem isn't "can you make sure it stays up while you're alive", the problem is, after you're gone, you're no longer there to keep the flame alive and there are no guarantees anyone else picks up the torch.
Does this suggest a subscription(ish) business where you pay the hosting company for N years and then they ensure your website stays up and unchanged for N years after you die? Quality control issue?
Given how many things want me to pay a subscription while I'm alive, surely somebody will start charging me when I'm dead. It is the logical conclusion of SaaS. I wanted to create an acronym for this, but death as a service didn't seem like the best choice.
Flattening old things down to plain HTML is underrated and important here. Old apps don’t need to be updated or upgraded or maintained or even deployed. It’s way simpler to argue to keep old stuff around if it’s essentially a domain pointing to a static bucket.
> It is actually pretty easy to keep alive URLs if there is a will to do so. Just have tests in place
"Just".
Maintaining and keeping these tests (and the oriinal link) running is also probably easy. "Just" keep maintaining them over changes in technology, hosting providers, DNS registrars...
Because a single autonomous vehicle operating in a shared
fleet can replace multiple privately owned cars, the
widespread adoption of this technology can’t help but
reduce new-car sales volumes.
The old "Thing will become more useful so we'll make less of it" argument. No mention of Jevons Paradox?
If we can travel and send stuff around from point A to point B cheaply and instantly by dropping ourselves or an item into an ocean of cars roaming our streets autonomously, there is a lot more demand for rides.
Also comfortably traveling longer distances might alter where we live. If we can walk out the door, sit down in a comfortable robotaxi right away and exit in the city center 10 minutes later, we might not have to live right in the city center anymore. Another driver for more demand.
I doubt that here. Cars are already near saturation, at least in the US.
Essentially everyone has a car. The car is mostly idle. If car availability starts to approach instant then people don't need personal vehicles that are idle 95% of the time. Car quantity overall goes down unless you can 20x current utilization, which is a lot of trips and fuel.
Not to mention that if anything resembling current quantity of extant cars becomes the current quantity of cars using roadways at a given moment, most cities will gridlock.
If the thesis is "cars will approach 50% or greater utilization" then car numbers must drop barring a massive increase in road capacity for which the land does not exist.
Cars that are idle 95% of the time are replaced less than once in a decade.
Cabs are replaced something like 3x more often than privately owned cars. And when they run 24/7 because of self-driving, that factor will even increase.
> If the thesis is "cars will approach 50% or greater utilization" then car numbers must drop barring a massive increase in road capacity for which the land does not exist.
You can build stacked roads a few levels up. Capacity doubles or triples without any significant land use.
Amsterdam is very dense because historic reasons. Streets are narrow and houses are the same.
Los Angeles on the other hand was built on virtually unlimited land and could expand a lot. I could say LA County is bigger than the whole of the Netherlands.
Both have their charm, but LA is so much better than Amsterdam.
Yeah, the 405 might suck, but at least the weather is better.
> Also comfortably traveling longer distances might alter where we live.
You mean like last time? More cars being the answer to problems created by creating too many cars and reasons to use them is like more people buying guns to counter the gun problem, and I can't think of better "tragedy of the commons" applicable situations.
As I start to get older and I spend less and less of my time in the deep suburbs, I'm starting to be more aware now of the phenomenon for people to get less social and less trusting the further away from a core area (or, arguably also the ground in the case of skyscrapers, but much less so) they live. I don't think it would be a net win to hypothetically encourage further dispersement from one another.
I wish HN commenters would stop bringing up Jevon's Paradox:
1. We see it mentioned all the time now, i.e. When AI makes producing software essentially free, there'll be more jobs. As HN has maybe 75% of the frontpage filled with AI stories, it means we see it almost every single day!
2. It essentially describes outliers. Driving food costs down to a fraction of the peak price (basically down by 90% over the last 200 years) did not result in correspondingly higher food consumption.
3. It only applies when the market is not yet saturated. Making cars more fuel efficient (by going EV) in the last 5 years did not result in correspondingly more miles being driven.
Any time you feel compelled to bring up Jevon's Paradox, ask yourself "Are we talking about energy here?" and if the answer is "No" then it probably doesn't apply.
Keep in mind that even if Jevon's Paradox applies, it does not mean that the society actually benefits. If you drive the value of all human labour to almost zero, you can't use Jevon's Paradox as an argument that the increased efficiency means that we're all living a life of leisure.
We don't need fleets of autonomous vehicles, each carrying two tons of metal for transporting a person or two and clogging up cities. We just need a train network that doesn't suck.
One of the most important ways to make a train network that doesn't suck is to aggressively police the sorts of antisocial behavior on public transit committed by the most marginalized people in society. There are a lot of political barriers to actually doing this, not the least of which is that it necessarily involves incarcerating more marginalized people, using more police violence against marginalized people, and inevitably having the police kill more marginalized people.
If you're reaction to Daniel Penny's killing of Jordan Neely on the New York City Subway isn't "Daniel Penny was a hero, Jordan Neely should have been incarcerated rather than allowed to freely exist on the train, and everyone involved in Penny's prosecution should be thrown out of positions of power", then you can't actually make the train network not suck.
Well if we did that we'd only save 40,000 lives and ~$1T in transit costs a year. Such savings and improvements in quality of life are unthinkable in the US! \s
Say we want to make an icon that when clicked shows how often it was clicked. The webcomponent code seens quite sane to me:
Try it here:https://plnkr.co/edit/0XUOLyM52xfFiIBu?open=index.html&previ...