HNHacker News
TopNewBestAskShowJobs

chombier

303 karma · joined June 30, 2014

submissionscomments
chombier··on The Lazy Monad
> but List operations cannot.

They can, the effect modeled by the list monad is non-determinism.

chombier··on The Lazy Monad
> Is Maybe/Option an effectful computation

Yes, Maybe/Options are a way of encoding partial functions/exceptions.

List is a way of encoding non-determinism.

chombier··on The Lazy Monad
A monad is for composing effectful computations.

Effects are encoded using a polymorphic type with a `map` operation (called a functor), and effectful computations are functions `a -> E b` for some types `a, b` and effect `E`.

A monad is exactly the plumbing you need for composing effectful computations: it turns a computation `b -> E c` into a `E b -> E c` so that you can compose `a -> E b` with `E b -> E c` to get a composed computation `a -> E c`.

It does so in a way that makes effectful composition associative (i.e. the way you'd expect)

chombier··on Rust Is Hard, Or: The Misery of Mainstream Programming
Can one really escape clone hell afterwards, though?
chombier··on What was wrong with SML?
I think this refers to a system of types in which for any two types there is also an union type and an intersection type in the lattice.
chombier··on What was wrong with SML?
> Scala has a very different solution to this problem, called covariant and contravariant traits.

I thought Scala had an even stricter value restriction than ML, where only function/methods may get a polymorphic type?

chombier··on Functional programming with bananas, lenses, envelopes and barbed wire [pdf] (1991)
If you're going to introduce a generic functor fixpoint then you'll probably want to define

     type Tree a = Fix (TreeF a)
so that `toTreeF` is just `unfix` (and is effectively free, as I mentioned above)
chombier··on Functional programming with bananas, lenses, envelopes and barbed wire [pdf] (1991)
I also remember struggling with this paper quite a bit at first. This is how I would explain catamorphisms to past me:

Suppose you have a recursive `tree` data structure, and another one `tree' x` where `tree' x` is just like `tree`, but with recursive occurrences of `tree` replaced with type x. So maybe something like, in Haskell-ish syntax:

    type tree = Leaf int | Node tree tree
    type tree' x = Leaf int | Node x x
Then one can easily write a `fold` over trees with type

    fold: tree -> (tree' x -> x) -> x
where the second parameter (called an algebra) evaluates the result over a tree' assuming recursive subtrees have been replaced with the result of their evaluation (this is the key).

Now the beauty of recursion schemes is that whenever `tree'` is a functor, you can get `tree` (as a fixpoint: `tree = tree' tree`) and `fold` for free (generally called `cata`), which can be seen by rewriting `fold` above using just `map`.

This skips a fair amount of boilerplate code you no longer have to touch when modifying recursive types.

chombier··on Crimes with Go Generics
> not actual runtime variables/parameters/return types/struct fields.

Is it possible to church-encode these with Go generics?

chombier··on Chris Lattner on garbage collection vs. Automatic Reference Counting (2017)
Thinking about it, my guess is that properly scoping the variable does not really prevent the user from leaking the value anyway:

    with context() as foo: 
        leak = foo
This is unlike list comprehensions, where it is syntactically impossible to bind the comprehension variable to a new name accessible outside the comprehension.

So maybe the reason is that it is not really worth the trouble.

chombier··on Chris Lattner on garbage collection vs. Automatic Reference Counting (2017)
I always wondered why does this variable leak outside the `with` scope, because this is really the one place where it should not.

IIRC python3 fixed scope leaks in list comprehensions, does anyone know why they didn't fix this one as well? Or does it have actual uses in practice?

chombier··on Python’s “type hints” are a bit of a disappointment to me
I generally force it on a per-file basis by adding

     # mypy: disallow-untyped-defs 
on top of new python files.
chombier··on Exponentially Better Rotations
I found this nice accessible proof for the interested: https://planetmath.org/slnrisconnected
chombier··on Exponentially Better Rotations
Yes, SLERP is commutative along one-parameter subgroups by definition. The problem arises as soon as more than two quaternions are to be averaged using the above procedure.

Again, using 3 quaternions and uniform weights with the above algorithm gives slerp(slerp(a, b, 1/2), c, 1/3) but medians in a spherical triangle don't cross at 2:1 ratio in general.

chombier··on Exponentially Better Rotations
This wikipedia page has some, e.g. https://en.wikipedia.org/wiki/Comparison_of_vector_algebra_a...
chombier··on Exponentially Better Rotations
> As far as I can tell he just takes weighted averages, which is a commutative operation.

It works when doing LERPs (linear interpolations) but the algorithm above uses SLERPs (spherical interpolations) which can be expressed with quaternion products/exponentials/logarithms, so I think the order does matter.

A quick numerical check with 3 quaternions and uniform weights seems to confirm this.

chombier··on Exponentially Better Rotations
Except the quaternion product is non-commutative, so the result of your algorithm will depend on the ordering of your `quaternions` array (which may be acceptable in practice), whereas Karcher mean does not.
chombier··on Exponentially Better Rotations
> Quite bluntly, this all sounds like an attempt to reinvent euclidean geometry following a convoluted way

I think that's the idea.

> I mean, what does all this buy you that applying a subset of affine transformations (scaling, translation, rotation) to an orthogonal coordinate system doesn't give you already?

Well, algebra: with the geometric product one can solve geometric equations in a nice, unified way.

chombier··on Exponentially Better Rotations
Thanks, I just realized I was also assuming exp to be surjective as well, I stand corrected.

The Wikipedia page[1] mentions the issue briefly but I was curious of the counter-examples. IIUC, matrices in SL(2) with trace < -2 have two distinct eigenvalues, one of which is negative[2], and such matrices cannot be reached by exponentiating elements of the Lie algebra sl(2) (traceless matrices).

[1] https://en.wikipedia.org/wiki/Exponential_map_(Lie_theory)#S...

[2] https://en.wikipedia.org/wiki/SL2(R)#Classification_of_eleme...

chombier··on Exponentially Better Rotations
What made the Lie exponential click for me is the definition of exp as a limit: exp(x) = (I + x / n)^n when n goes to infinity.

A tangent vector x at the identity is split in n chunks, each chunk is added to the identity to get a matrix (I + x / n). Each of these matrices gets increasingly closer to the group as n increases, and these n matrices are composed together to approximate exp(x), in a similar fashion to forward Euler integration with n iterations and integration step 1/n.

The actual formula ends up being the usual power series and is useful for computations, but I find the limit above really captures the essence of how the exponential works.

chombier··on Reasons to not use PCA for feature selection
> so you can stop collecting the unnecessary data

I think that's the key, thanks.

But still, if some inputs are redundant shouldn't this be somehow apparent in the eigen-vectors/values of the covariance matrix (making PCA an indirect feature selection algorithm)?

chombier··on Go 1.18
Maybe the addition of generics could enable Concurrent ML-style composable channels?

This wouldn't solve the performance issue, but at least it would provide a nice abstraction for protocols.

chombier··on Go 1.18
Because of lifetime of captured variables in closures, mostly.

You can't really pass around functions freely like you would in Haskell/ML unless you start Box-ing/Rc-ing everything. But then it's not really idiomatic Rust anymore, IIUC.

chombier··on Ask HN: What's the Deal with HN and Rust?
> strcpy in C is Turing complete

I was curious too, but my google-fu did not succeed. The closest I found is about printf being Turing-complete [1], which is also new to me.

[1] https://www.ioccc.org/2020/carlini/index.html

chombier··on Quaternions
"Geometric Algebra is just a Clifford algebra over an Euclidean space, what's the problem?"
chombier··on Quaternions
Exactly, in fact I'm always surprised so many people still claim GA is better for practical implementations after all these years.

My impression is that if you want something compact that you'll need to either give up on performance (type erasure) or separate compilation (track every type).

GA is great for pen and paper proofs though.

chombier··on Quaternions
> It's a real shame that people continue to focus so much on quaternions in this day and age.

No really, unit quaternions are nice because it's pretty clear they belong to a sphere, therefore you can fairly easily extend geometric methods on the usual sphere to perform filtering, averaging, interpolation etc on rotations.

With GA it's not so obvious.

chombier··on Quaternions
See "A General Construction Scheme for Unit Quaternion Curves with Simple High Order Derivatives" (Kim, 1995) for a simple extension of Hermite splines to Lie groups, including unit quaternions.
chombier··on What's next for language design? (2017)
It may not be exactly what you're looking for, but "The History of Standard ML" published last year has a nice section on ML modules with design considerations.
chombier··on The Rise of Meson
I really want to like Meson, but with the lack of user-defined functions [0, 1] (even restricted) it seems difficult to use for larger projects.

How do people handle repetitive patterns in practice? By extending Meson itself?

[0]: https://github.com/mesonbuild/meson/issues/3234

[1]: https://mesonbuild.com/FAQ.html#why-doesnt-meson-have-user-d...

← PreviousPage 3 of 7Next →