Hacker News new | past | comments | ask | show | jobs | submit | smilingemoji's comments login

This is false equivalence because machines ingest copyrighted material at a different order of magnitude.

Wikipedia has a nice example of an oil stain vs. oil spill. https://en.wikipedia.org/wiki/False_equivalence


[deleted]


Dark mode causes more issues than light mode for a lot of conditions. Providing only a darkmode is worse than providing only a light mode, IMO.


Every OS has “system” colors. Even with non-native widgets, I have no idea why people don’t use those.


    lynx gopher://hngopher.com


HNcute for chrome still works nicely!

https://caro.io/hn-cute


The Dark Reader browser extension works for HN.


Chrome has a force-dark-mode option in the :config too with heuristics on how to change things with different modes.


Seems a bit over the top when you could also just provide it as a command line argument to sqlite3 which is much more obvious than <<< and works in every shell.

  sqlite3 db.sqlite3 .dump


Review what’s going on. Git gives the file name as the last argument, so you can’t pass .dump as the last argument like that without the contortion of an immediately-invoked function.


I love these sort of articles. No new tools are needed here, it shows you how to get the most out of the tools you already know and use. Awesome!


It still doesn't know about anything that happened in March 2023. It hallucinates instead of saying outright that it doesn't know.

Example: "Many countries had significant political events, whether they were elections, policy changes, or other notable occurrences."


> I really wish people would just stop posting submissions to twitter at this point.

I fully agree. You can also replace twitter.com with nitter.net

https://nitter.net/bagder/status/1709103920914526525?s=46



Mastodon may not require a login, but for some reason it does insist on javascript


  The following example code is a bit hard to read:

  const { status } = await send(capitalize(greeting) + "!")
  console.log(status)
I disagree, I find this example code very easy to read because it reads like idiomatic Javascript. Unlike this library.


Right - because this library tries to fake a new language syntax feature without the actual support for it, it ends up being the worst of both worlds. Even ignoring the lines-of-code explosion, the non-standard use of parens/spacing makes it incredible difficult for me to parse.

Props to the author for trying out something neat, but this is probably a bit to clever for my liking.


Just an FYI to folks, there has been a proposal to add pipes to JavaScript for a few years:

https://github.com/tc39/proposal-pipeline-operator


> the non-standard use of parens/spacing makes it incredible difficult for me to parse.

Same here. Not to mention this wouldn't work in a codebase with an autoformatter.The idea/API is clever. So, a pretty cool experiment I suppose


Author here. Thanks for your nice comment. I added a note to say it does work with autoformatters too. Actually someone in a comment below said he or she prefers the autoformatted syntax.


Oh, that's good to know! I haven't tried it and assumed an auto formatter might misalign some of it or put things on the same line, so the visual "downward arrow" appearance would be lost

Edit: I just checked the docs again and while it does look a bit "misaligned" at the start, I do think it looks more readable with the autoformatted version. Pretty cool!


I agree with the author that it’s a little confusing, but that’s why I wouldn’t write code like that.

    const msg = capitalize(greeting) + “!”;
    const { status } = await send(msg);
    console.log(status);
Now it’s perfectly readable, no weird shenanigans required.


This is clean JavaScript syntax in my opinion and should be what people strive for. It's perfectly readable, it's faster, it does async correctly without any unnecessary computation, can be typed and will have a normal stack trace. Piping is cool when done right, but can introduce complexity fast. Elixir is a good example where it works wonderfully.


But at what cost? You had to name two intermediate variables - and naming things is hard.


In this case the variable is the documentation of the code.

You don't have to write something like "this is the message", you can see it.


What if it isn't a message? What if "msg" is already used for another variable?


This is some wonderful performance art you’re doing here


`greetingMsg`? `greeting`? Naming the other one differently? Splitting the work done with that message and the work done with this message into their own functions?


Frankly, this always sounded like a readability issue seeking a readability problem. Splitting because the names clash, because you decided to name things, because a one-liner was less than ideally readable.


"_msg", then.


Because they provide value and document the chain of events. I fear a long list of piped expressions without any idea of what they are intended to to. Would be like big regexps.


Not hard: msg can be derived from the parameter name of the send() function and status is a fixed attribute of the result.


Even worse - you’re polluting your local namespace with names decided on by other code.

I’m obviously not being serious about naming being hard in this example.

But there are cases where the pattern of using return object property names as variables comes back to bite uou.

Even in this case, what if the response object from ‘send()’ also has a ‘msg’ property?

Changing const { status } into const { status, msg } is an error.

We should be cautious about syntaxes that force us to allocate names. Sometimes.


Still not hard: In that case, instead of msg use sendMsg AND/OR in the second statement use { status, msg: resultMsg }, or just result and later result.msg.


Code is read many more times than it is written. Put in the minute or two to devise good intermediate variable names, and that will pay back manyfold every time someone needs to read and understand it.


Some code. E.g. most of my code was barely read by anyone, as most of it was utilitary or mvp or niche/local enough to never see big light. And when from time to time I read other code, e.g. on github, in projects I’m occasionally interested in, there’s barely anything resembling these high class advices. FOSS with large reach - yeah. But a library that you found for a specific hardware is “just code”. And to be honest, the difference between the two is not that big. Any decent programmer navigates both almost equally fast. As someone who modified Lua internals (typical example [1]) for employer’s needs I can say that I prefer Lua style to ceremony on top of ceremony, to multiparagraph explanations of what should be obvious to a competent developer, and to hundreds of extracted functions for the sole reason of clean-ish scopes or whatever.

But still I’ve done what people advised, for many years. And know what? It never paid back. I’m sort of tired to keep that secret and nod to this obvious overgeneralization and a blanket idea. Pretty sure I’m not alone.

[1] https://github.com/lua/lua/blob/6baee9ef9d5657ab582c8a4b9f88...


I think the implication is that it's difficult to read because it's read non-linearly. You first need to start in the middle at `greeting`, then work your way out to `capitalize` on the left, then to `+ "!"` on the right, then work your way out one more layer to the left with `send`.

Some kind of pipe operator can make this easier to read by arranging the operations linearly from left to right (or top to bottom as is the case with this library). Although in my opinion this library has its own readability issues.


I agree. In the example case, I don't see why left-to-right or top-to-bottom would be more readable.

Sure, it is good most of the time, but operator precedence rules exist for a reason.

I don't want to read

  2.chain(x => x * 2).chain(f)
instead of

  f(2*x)
These patterns have their place for async programming, pure FP, streams and more.

They can also be a distraction.

E.g. the library introduces its own promise-unwrapping semantics and more.

I don't see the use for such a generic implementation, although I applaud the effort.


The strength of the pipeline operators comes when you have to do method chaining things like:

  const foo = capitalize(underline(reverse(exclaim(indent(value)))));
I already forgot the amount of parentheses I needed to close with while typing that.


  value.indent()
    .exclaim()
    .reverse()
    .underline()
    .capitalize()
There’s always the OOP version of method chaining!


This won't look as good when you include all the boilerplate which defines those methods, and which needs to be repeated or otherwise included for every "value" type. You don't have to worry about this when they are pure utility functions.


Which is great until Prettier, in its infinite wisdom, decides it's better to stick four of these function invocations on one line and two on the next, so you have an obnoxious mishmash of tokens!


Which is a problem of Prettier. I wish for the day that someone builds rustfmt but for Typescript, I will happily leave Prettier and StandardJS behind.

I think it could be done today with a (big) number of ESLint plugins.


No worries your ide will help you for the parentheses.


IDEs and linters should not be a crutch methinks because not everyone uses the same IDE or text editor. Either way, it will still be awkward to read.

Better that you either avoid that pattern or at least indent it in such a way that its not so visually confusing. Or yknow use a pipe operator.


People do tend to use the same linter and LSP. That’s why they exist in the first place.


I agree, I really don't understand this library


If you read all the text, it seems like the entire repo is intended to be a satire on https://github.com/tc39/proposal-pipeline-operator.


Is it? I think it's an implementation of the pipe operator rather than satire of it. Javascript doesn't provide the flexibility to extend the language with pipe operators (though tools like Babel will let you use the pipe operator already).

The clunky syntax removes all the benefits of the pipe operator. The entire thing is syntactic sugar, wrapping it in confusing functions just breaks the entire concept.


Unfortunately I’m not getting satire vibes from that blurb. I’m only more scared for JavaScript.

I love JavaScript but this pipe thing is horrific.


Tell that to Unix/FP lovers.


hahaha i mean this implementation. piping things in the shell is great


Ahh OK. Yeah, I always find trying to shoehorn language semantics via functions to be kinda awkward. The best attempt I've seen is this addition of async/await to Lua, which actually looks pretty usable [1].

[1] https://github.com/ms-jpq/lua-async-await


So what exactly does it satirize?


Which supports the age-old notion that readability is in the eyes of the reader.


It's funny that their example is much harder to read


Yeah, it's concerning when even the contrived first example is less clear in the 'solution' than it is in the alleged problem.


Agreed.


The API looks very clean. Today I learned about "..." in Python


It is just a noop, but here it looks very appropriate/readable because it reads as saying "AI will fill this in".


It's a misuse of the Python Ellipsis, though PEP has no opinion on it. The Ellipsis is "Special value used mostly in conjunction with extended slicing syntax for user-defined container data types."

In other words, it happens to work and look neat, but pass is the correct way to do it.


Ellipses is actually used in quite a few places. See the answers and comments on this stackoverflow post[0]. The usage most similar to what I have in the magentic examples is with the `@overload` decorator in the typing module[1].

With that said, you are free to put any code in the function body including `pass` or just a docstring or even `raise NotImplementedError` - it will not be executed. Using Ellipses satisfies VSCode/pyright type checking and seemed neatest to me for the examples and docs. I have some additional notes on this in the README[2].

[0] https://stackoverflow.com/q/772124/9995080

[1] https://docs.python.org/3/library/typing.html#typing.overloa...

[2] https://github.com/jackmpcollins/magentic#type-checking


The same as “pass”?


I took at the look at the SVG smilies, only GPT gets it right (https://benchmarks.llmonitor.com/svg). You can preview the SVGs drawn by the LLMs by pasting this into the browser console

document.querySelectorAll("td pre").forEach((node) => { let code = node.textContent; node.insertAdjacentHTML('afterend', code) })

Or take a look at my screenshot: https://i.ibb.co/Kw0kp58/Screenshot-2023-09-09-at-17-15-20-h...


Clever use of the dev tools console. I think you’re being a little uncharitable, the prompt said “smiley” and not “smiling emoji” and “smiley” was once upon a time used for the whole slew of emoji. With that in mind, several others also pass.


Good point, but you may be too charitable. At least according to Wikipedia, a smiley is supposed to be smiling. https://en.wikipedia.org/wiki/Smiley


I don’t know about Wikipedia but I’m speaking from lived historical experience.

Here’s a throwback for you: https://www.phpbb.com/customise/db/styles/smilies-13

(All “emoji” images were just called smilies in a lot of software.)


Oh neat, thanks for sharing, wanted to add an interpreter to that test


Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: