Believe it or not, it gets worse. The authors of this paper are the same folks who came up with this particular dating technique. And I can't find any evidence the technique has been independently validated. Not that that should count for much from this layman.
HN user
dpratt71
I don't think you can "debunk" something merely with strong evidence.
Besides that, I wasn't aware of this codex, so I'm glad you shared it. Has anyone suggested that (assuming there is a relationship) the arrow of causality might go the other way? That perhaps this image was a reference for the shroud itself?
If you have a goal of being able to confidently reason about your code, such as to be confident it won't go "wrong", then making it more math like would seem to make a lot of sense.
As far as the IO thing is concerned, one could use pure functions to construct a model of an imperative program. Then you just need something to run it... There is a sense in which this is exactly what is done in practice.
The word "suspected" does not appear on the report you linked. Rather it says it is a "possible" carcinogenic. Moreover
The committee therefore reaffirmed that it is safe for a person to consume within this limit per day. For example, with a can of diet soft drink containing 200 or 300 mg of aspartame, an adult weighing 70kg would need to consume more than 9–14 cans per day to exceed the acceptable daily intake, assuming no other intake from other food sources.
It sounds like we'd be better off not knowing about this law. Thanks.
Turkeys can fly, though. Just not the domestic ones :)
Rust is more restrictive than it needs to be, in this case. What matters is whether it's possible to have a situation where the value of a variable or parameter is not concordant with its type in a given context and what it takes to make that happen.
Of course it's possible to tell the TS type checker to sod off in a given context (cast, use the "any" type, etc.), but without doing that, I think it's hard to contrive a situation such as I described above.
https://www.typescriptlang.org/play?#code/C4TwDgpgBAsiAq5oF4...
In your example, '3 | "foo" | false' is the type of the variable. What is the argument for this being a bad idea in general? You imply it's unsafe. How?
Stupid question: Why isn't such logic incorporated into the call itself?
Some ideas that I suspect are true do indeed scare me. But I'm more scared of ideas that I strongly suspect are false, but I think other people may not agree.
Fyi, "Alcohol distributes into water spaces, not fat" https://sites.duke.edu/apep/module-1-gender-matters/content/...
Whether it's a single company (or product) or multiple is beside the point. If a technology is only available to (say) 1% of the population, I don't think that qualifies as being widely available.
I will also note that my original comment was in response to someone who is "more interested in tech for the other 95%".
Penicillin, maybe? But I wonder how quickly it became readily available outside of the Western world.
And I see that Nintendo has apparently sold an extremely impressive number of consoles (https://www.nintendolife.com/news/2019/11/nintendo_has_now_s...). But even if everyone only bought one console each, that's only about 10% of world population.
This may be a little unfair, but I do wonder if there isn't a tendency to consider a technology to be widely available when it becomes available to you and the folks farther back in the line don't count or aren't relevant.
Is it not the case that having access to a machine capable of running either Minecraft or Linux in the early days of each (if not now) means you are (or were) fairly affluent?
What is an example of important technology that did not start as something only available to the affluent/connected?
I don't understand why Haskell gets brought up in the middle of an otherwise interesting and useful article. This sort of thing cannot happen in Haskell. And while Haskell is not universally admired, I can't recall seeing Haskell's flavor of type inference being a reason why someone claimed to dislike Haskell.
It's really too bad that the only way we can be sure rich folk pay their fair share is to charge them twice for private education. Otherwise, my mother may not have felt it necessary to work the overnight shift at the local factory for decades in order to provide us with the basic necessities and a private school education.
It's an abstraction to facilitate writing do blocks. Mostly tongue in cheek.
There are no guarantees in life, but the reason we don't have global pandemics constantly is that mutations that make a virus as dangerous as SARS-Cov-2 are quite rare.
I'm fairly out of my depth here, but it's somewhat relevant to my personal situation:
When this came up for discussion on HN a few days ago, I was initially confused, as some of what I read seemed to suggest that taking e.g. lisinopril could possibly increase the risk of an infection because it seems to increase the expression of ACE2 receptors that are used by the virus to infect cells.
On the other hand, some of what I read seemed to suggest that ACE inhibitors (e.g. lisinopril) could have a therapeutic benefit. The virus is going to inactivate a bunch of ACE2 receptors through the course of infection. Since ACE2 receptors inactivate angiotensin, that would leave a lot of active angiotensin floating around, which is potentially very bad. ACE inhibitors would seem to help here because they inhibit the active form of angiotensin from being created in the first place.
Now I'm wondering: Is it possible that taking lisinopril could increase the risk of serious infection for those of us not yet infected, but also could reduce the severity of an active infection?
Small nitpick: some statically typed programming languages have optional type annotations.
Yeah, you're right, I muddied the waters a bit with that example. I was just trying to think of examples of persistent data structures being used in a concurrent context, but you had in mind a situation where multiple agents could be updating the same data structure independently.
Your example is much better. I also was thinking of maintaining an account balance with a log (vs. synchronising updates to a stored amount), but it's not much different from your example.
And of course this "eventually consist" strategy is generally how things happen "at scale", persistent data structures or not.
Oh goodness :) OP has conceded the point, but you're still down to argue on the basis of what a person may or may not believe is the main strategy to handle serialization. I give up. You win, I guess.
Regards your other question(s), I will just add that I answered many similar questions for myself (as well as disabusing myself of a lot of misconceptions) by undertaking to get a basic understanding of Haskell.
Whether the "merge" implementation is costly or complicated very much depends on exactly what it has to do. The git example is pretty much a worst case example in this regard.
An easier example could be that you have a tree structure that represents a mathematical expression. The evaluation of every node could proceed on its own lightweight thread. The merge strategy would be to simply perform the appropriate operation on the results produced by the threads evaluating the child nodes.
You could, as per your example, use locking as part of a resolution/merge strategy to combine the results of two separate computations running on two separate threads. Or you could use some strategy that does not involve locking. Either way, it does not support the original claim I disputed that "Immutable structures still require locking".
In brief, these sorts of conflicts simply do not arise in a fully persistent data structure. You may have a situation where you have a persistent data structure together with one or more mutable references, each to some version of the data structure. Yes, a modification to one of these mutable references would need to be synchronized, but they are separate from the persistent data structure itself.
Again using git as an example, there is the persistent data structure, aka the commit graph, as well as mutable references to commits, aka branches. A change to what commit a branch references needs to be synchronized.
This is not how persistent data structures are used in practice. There is no "the" new version of a persistent structure. The best analogy I can think of is to compare it to a VCS (e.g. git). There is no need to lock any existing commit in order to create a new commit (which together with prior commits, represents a new version of the code).
This is a sad reminder to me that the tooling story around Haskell seems to be perpetually almost really good.
Case in point, the core toolchain (e.g. the compiler itself) supports "typed holes". Basically, you drop a placeholder somewhere in an expression and the compiler will infer and report the type of the sub-expression. There are also tools to search either within a program/library or e.g. the entirety of the Hackage package database for functions matching a certain type. It seems like a relatively short distance from there to having an IDE or code editor that can list possible expressions/functions that could satisfy a particular placeholder. And to me, having e.g. a list functions that transforms the input(s) I have to the output I need seems much better than e.g. a partial list of all the functions that relate to a particular type.
And maybe such a thing exists today, but I have had really bad luck trying to get Haskell tooling that works well and is easy to set up.
There's a lot here I would like to respond to, but I'll limit myself to a couple points:
The whole POINT is that there are complex language features which have to be enabled if you want them
Yes, "if you want them". If you value having a simpler language, don't use them. And Haskell is hardly unique in this regard. You've mentioned GCC, but I think the Babel transpiler is another good example.
You have mastered Haskell and forgotten what lack of complete understanding means to anyone else.
I've managed to teach my daughter some Haskell, who had no prior exposure to programming languages whatsoever, so I doubt your assertion is entirely true.
The hardest programming language I ever learned was the first one. Each one after that was easier than the one before...until I got to Haskell. It was so different that I was forced to go back to a more fundamental understanding of the nature of code and computation and start from there. It felt pretty challenging, especially at first, but I think that had more to do with my perspective and experience coming into it than the language itself (and the fact that I had a family and career at that point didn't help).
I can only directly address the examples you've given. If you disagree with how I've characterized those examples, I'd be interested to know why. If you have other examples, I'd be interested to hear them.
Haskell has its weaknesses, e.g. the lack of quality tooling available as compared to mainstream programming languages.
But I disagree that Haskell is complex, at least as a criticism. When expressing concepts of a similar complexity, I find Haskell to be particularly concise and expressive as compared to most other programming languages I am familiar with.
And if Haskell undervalues consistency and standardization, I would like to know as compared to what? The only programming languages that I know of where there are not many reasonable choices for e.g. a testing framework are those that either (a) haven't been around that long, or (b) haven't seen wide adoption.