HNHacker News
TopNewBestAskShowJobs

consilient

611 karma · joined December 14, 2022

submissionscomments
consilient··on Ham radio enthusiasts vs. High-frequency traders: A battle for the airwaves
That's not what efficiency means in this context. People who say the market is efficient mean one of:

- You can't beat the market

- You can't beat the market without insider information

- You can't beat the market using only information about historical prices.

(Insert "approximately" and "by enough to be worth it" as appropriate)

1 is certainly false, 3 is probably true, 2 is controversial.

consilient··on Ham radio enthusiasts vs. High-frequency traders: A battle for the airwaves
> On the other hand, due to advancements in trading tech, I've seen commissions drop to zero. I've see better price discovery available to professional and retail traders and there has been a lot of people introduced to stock markets because it was accessible via their phone.

Ok, but how much of that is due to HFT specifically? Or more relevantly to the article, ultra-low latency HFT? A bit of the price discovery, maybe, but retail commissions hit zero because Schwab decided to finish turning into a bank and their competitors had no choice but to follow.

consilient··on Crumb,a New Programming Language of No Keywords, and Everything Is a Function
> Strictly no side effects* to help you write functional code

> *With the exception of IO

That's one hell of a footnote.

consilient··on It’s not intelligent if it always halts: A critical perspective on AI approaches
> We are solving the halting problem. We are solving ZFC. That's the entire point of mathematics.

We are not. We're determining whether particular classes of turing machines halt, and we're determining whether particular theorems hold in ZFC (and doing a lot of mathematical work which is neither). This is not evidence that the human brain is super-turing, because these are computable problems.

> It does not, for example, rule out whether you can write a Halt procedure for no-input Turing Machines with N states. In fact we have already written them for N=1,2,3,4.

Turing didn't, but later work does. BB(748) is known to be independent of ZF. The real bound is likely much lower.

consilient··on It’s not intelligent if it always halts: A critical perspective on AI approaches
Of course it's a coping mechanism, but coping mechanisms that get in the way of protecting yourself are bad for you! Being completely fucked if your job gets automated away in a month doesn't have to mean being completely fucked if your job gets automated away in five years, but it's a whole lot more likely if you spend the first four of them being told you have nothing to worry about.
consilient··on It’s not intelligent if it always halts: A critical perspective on AI approaches
Humans can't solve the halting problem or violate the incompleteness theorems either.
consilient··on It’s not intelligent if it always halts: A critical perspective on AI approaches
> I'm not sure this follows. It doesn't halt because the "program" reaches an end, it's halts because the hardware fails.

Ok, but the intelligent entity in question isn't the program, it's the program-running-on-the-hardware. A mere description of your brain is totally inert.

consilient··on If you're interested in eye-tracking, I'm interested in funding you
Yes, and? There is no plausible near future where anyone else (except maybe his heirs) directs how that wealth is used. Better that it go towards socially useful investments than megayachts or land hoarding.
consilient··on Leaving Haskell behind
> I think the JSON.parse() issue is fundamental -- it's not clear what they could have done better, and static languages don't really do better.

The best solution, IMO, is to give up on "no type-directed emit" (which harms the language in lots of other ways as well) and derive appropriate parsers at compile-time. Parsing malformed data should fail immediately, not just when you try to use the broken parts. This is a solved problem in C#, C++, Haskell, and no doubt many other languages.

Failing that, it should return an appropriate `JSON` type. Something along the lines of

    type Field = string | number | boolean | null | JSON
    type JSON = {[key in string]?: Field } | Field[]
consilient··on Leaving Haskell behind
> But code written from scratch doesn't have that issue. I'd be interested in a counterexample -- is there a code snippet that passes the strict mode of the compiler, and doesn't interoperate with untyped code, but produces an unexpected runtime error?

You'd think so, right? But no, typescript is deliberately unsound in ways that have nothing to do with gradual typing. Here are a few examples.

Signatures written in method syntax are bivariant, which is not correct

    interface Unsound {
      f(x: number | string): number
    }
    interface Unsound2 {
      f(x: number): number
    }
    const a: Unsound2 = { f: (x: number) => x }
    const b: Unsound = a
    const c: number = b.f("not a number")
Type predicate results survive mutation

    const hasA = (x: object): x is { a: unknown } => "a" in x
    const deleteA = (x: { a: unknown }) => {
      delete x.a
    }
    const unsound = (x: object) => {
      if (hasA(x)) {
        deleteA(x)
        return x.a
      } else {
        return "no a"
      }
    }
Many stdlib types are incorrect. JSON stuff is particularly bad: JSON.parse and Body.json() both return `any`.

You can spread things that aren't objects

    const unsound = <X,Y>(x: X, y: Y): X & Y => ({...x, ...y})
    const bad: never = unsound(5, 4)
(And even for objects, `X & Y` is not the correct type when you have overlapping keys)

Anything with optional fields can be widened incorrectly

    const unsound = <T extends { x: number }>(t: T): { x: number, y?: number } => t
    const bad: number | undefined = unsound({ x: 5, y: "not a number" }).y
Assignment doesn't handle `readonly` properly

    interface Readonly {
        readonly x: number
    }
    interface Mutable {
      x: number
    }
    const a: Readonly = Object.freeze({x: 5 })
    const b: Mutable = a
    b.x = 4

> The OPERATION is legal, but the data isn't, which isn't something that any type system will tell you.

There are some that will, though unfortunately none that are really production-ready yet.

consilient··on Leaving Haskell behind
> That's a little weird to me ... it seems to be confusing the metalanguage and the language being implemented.

Well, that's sort of the point. It's perhaps a little less important if you're writing a compiler for a separate programming language, but that's a relatively rare use case. GADTs are mainly used for implementing DSLs to be used elsewhere in the same program.

> Is the more abstract GADT solution supposed to "save" you some work of writing a type checker by somehow letting you reuse Haskell or OCaml's type system to express that?

Yes. Writing your own typechecker and integrating it into an existing compiler pipeline is a ton of work, easy to screw up, and a potential compatibility nightmare.

> I also wonder how all that is actually implemented and expanded into running code. The GADT syntax seems to get further and further away from something I imagine can be compiled :)

GADTs are syntactic sugar for constrained type constructors. So this

    data Example a where
         Example :: Int -> Example Int
becomes this

    data Example a = (a ~ Int) => Example a
which is then compiled to a type coercion in the intermediate language
consilient··on Leaving Haskell behind
> AFAIK TypeScript's type system can do everything in OCaml -- it's extremely expressive

Extremely expressive and unsound. And not just in a trivial "escape hatches exist but you should never use them" way - until you've been burned enough it's not at all obvious which operations are unsafe, and there are a lot of them.

consilient··on Leaving Haskell behind
> The community went back to Cabal? What did I miss? :)

Cabal got better, stack stayed the same. It's more a cultural divide than anything at this point.

consilient··on Leaving Haskell behind
> Is all this machinery really helping? Are you sure?

Absolutely: ADTs and general-purpose crud stuff are a perfect fit. It's the delicate numeric stuff where typed functional languages are at their least helpful (though I think still somewhat better than imperative ones, except at the ultra-high performance end).

consilient··on Cosmological time dilation in the early Universe
> it's destructive to the notion of "introduce a coordinate system" because now the phenomena you're describing messes with the coordinate system you picked to describe it!

That's the whole point of GR - coordinate systems aren't physically meaningful.

consilient··on Cosmological time dilation in the early Universe
The volume enclosed by the balloon's surface has a boundary, the surface itself does not.
consilient··on Cosmological time dilation in the early Universe
> As a kid, my notion was that spacetime was "infinite", that galaxies floated in spacetime, and were moving apart. Gradually I became (a bit) more comfortable with the notion that spacetime is somehow created by "stuff", and that a location in spacetime that has never seen a photon isn't a location in spacetime at all.

Neither is especially accurate. Spacetime is not a substance, and it's not created or destroyed. It's the thing physics happens on, for lack of a better non-mathematical description.

> But what does it mean for time to expand? The very idea of expansion is of a thing that grows relative to time.

Same thing as for space: that component of the metric - the shape of spacetime - is an increasing function of coordinate time. But you can always pick a coordinate system where only the spatial components are expanding. It's not physically meaningful either way. The metric is the real object.

consilient··on Leaving Haskell behind
Functional programming is not really a single paradigm. In particular lisps and ML style languages are very different and you should try both. Scala is still a C-style language at heart, it's just much further along the borrowing ML features path than most.

I'm not super familiar with the contemporary lisp landscape but scheme is the traditional choice for teaching.

Among MLs I would definitely pick Haskell.

consilient··on Leaving Haskell behind
It requires changing the places where you instantiate your monad transformer stack, which you should have very few of.
consilient··on Leaving Haskell behind
If you just want to add logging to existing operations, reinterpret them at the call site. Something like this

    newtype LoggedStateT s m a = LoggedStateT (WriterT s (StateT s m) a) 

    instance (Monoid s, Monad m) => MonadState s (LoggedStateT s m) where
        get = LoggedStateT $ do
            val <- lift get
            tell val
            return val
        put s = LoggedStateT $ tell s >> lift (put s)
(which is basically an ad hoc effect system)

If on the other hand you want to reproduce the behavior of other languages, throw everything in `MyAppMonad` give it whatever capabilities you need.

consilient··on Leaving Haskell behind
> And it is not perfect. You will still occasionally have the original imperative problems. But you will have radically, radically fewer of them, so few that the cost/benefit analysis of using the super-strong stuff becomes very difficult to justify, especially over the advantages of being able to use that library you really need.

This has unfortunately not been my experience. Working alone, sure, I can write acceptably pure code in a conventional language. But generally the issue isn't what I can do, it's what my coworkers will do. Even if almost everyone manages to maintain strict discipline without the support of the language, it really only takes one "productive" cowboy to create a disaster. The biggest advantage of pure functional programming is that taking the path of least resistance produces code that's still sort of ok.

consilient··on Leaving Haskell behind
You should generally be writing code against typeclasses, not a particular monad transformer stack. For example:

    fibonacci :: MonadState (Int, Int, Int) m => m Int
    fibonacci = do
        (prev, prev2, n) <- get
        if n > 0 then 
            put (prev + prev2, prev, n - 1) >> fibonacci 
        else
            return prev2

    concreteFib :: ReaderT String (StateT (Int, Int, Int) (ExceptT String Identity)) Int 
    concreteFib = fibonacci
consilient··on Leaving Haskell behind
> Basically, the author's criticism is that the language is too powerful, too expressive, people try very abstract things

I think this is a bit unfair. The author's criticism is that people try very abstract things and don't stick the landing. And to an extent I agree, but the problem isn't that Haskell is too powerful, it's that it's just barely powerful enough for too many things. Contra the author, GADTs are not one of those things, and snoyman can pry them from my cold dead hands. But singletons clearly are. So are impredicativity, open type families, type level arithmetic, and Template Haskell. Idiomatic Haskell practically writes itself, but type-level Haskell is at least as hard as C, and it's almost entirely because of how terrible the ergonomics are.

> Third, about backwards compatibility

Strongly agree here, if anything GHC doesn't break backwards compatibility enough. `Num` is an abomination.

consilient··on Cosmological time dilation in the early Universe
The stress-energy (of which matter density is a component) of a region of spacetime determines its curvature.

In empty space the metric, which tells us how to measure distances between events, is `ds^2 = dt^2 - (dx^2 + dy^2 + dz^2)`. Integrating this along a trajectory tells you the (square of the) proper time experienced by an observer traveling along it. As you can see, the further you move in space in a given amount of coordinate-time, the less proper time you experience: this is the source of time dilation in special relativity.

Around a spherical body of mass M, the metric is (in spherical coordinates, and ignoring some scale factors for convenience):

`ds^2 = (1-M/r)dt^2 - (1-M/r)^-1 (dr^2) - r^2 (dtheta^2 + sin(theta)^2 dphi^2)`

Compare to the flat space metric from before, now in spherical coordinates as well:

`ds^2 = dt^2 - dr^2 - r^2 (dtheta^2 + sin(theta)^2 dphi^2)`

So we pick up some additional time dilation as long as `M < r` (and it always is, unless you're in the interior of a black hole)

consilient··on Cosmological time dilation in the early Universe
> This would mean the universe has positive curvature.

There are several flat compact manifolds, they're just not simply connected.

consilient··on Cosmological time dilation in the early Universe
> today’s observable universe is roughly 13.8B years. By the time you travel to the edge of that universe, others stuff has travel from that edge to even further position at various speed including faster than you do.

This is true but it's not what astronomers mean when they say the universe may be infinite. They're talking about the whole universe, not the just the observable part, and they really do mean actually infinite in extent.

> before/at big bang universe is a single point.

Unlikely. We know that what is now the observable universe was very very very very very dense. Predictions of a literal singular point are the result of extrapolating past the point where we know for a fact that our best physical theories break down.

consilient··on What is narcissism? Science confronts a widely misunderstood phenomenon
> But it's undeniable that the discursive roots of modern psychology come from Freud in particular, and that when we analyze a phenomenon ("treatment" notwithstanding) we owe ourselves due diligence to understand it properly.

Sure, and people analyzing the "discursive roots of modern psychology" - historians of science - do talk about Freud. And Wundt, and James, and Watson, all of whom are of comparable significance in the history of the field. But scientists are not historians; they're interested in analyzing the actual thing out there in the world, not the way we talk about it.

consilient··on People in a genetic database have segments of DNA in common unexpectedly often
It's right there in the article.

> The analysis done by Kong and his student relies on the key idea that a genetic sequence that occurs more frequently in participants than in nonparticipants will also occur more frequently in the genetic regions that are shared by two related participants.

> Put differently, a bit of DNA that is common in the population will show up frequently in the study. But it will still only have a 50/50 chance of showing up in the child of someone who carried a copy. If a bit of DNA makes people more likely to enroll in genetic studies, it will be more common both in the overall data and among closely related family members.

> So they checked the genetic sequences shared between first-degree relatives—either parents and children or siblings (but not twins)—in the UK Biobank.

consilient··on BioWare is laying off 50 employees
Kotor 2 was Obsidian, not BioWare.
consilient··on How to Solve It (1945)
> apostol's calculus

is hard for a calculus book, i.e. is an introductory real analysis book. If you can master analysis at the level of baby Rudin without doing hundreds of problems, you're very talented. If you still don't need to do hundreds of problems by the time you finish papa Rudin, you're a mathematical genius.

← PreviousPage 3 of 11Next →