For the best experience on desktop, install the Chrome extension to track your reading on news.ycombinator.com
Hacker Newsnew | past | comments | ask | show | jobs | submit | history | jose_zap's commentsregister

No, it can be any pure function or IO. Both will get interrupted.


Haskell would be one of them. It features transactional memory, which frees the programmer from having to think about explicitly locking.


That was definitely true many years ago. Nowadays Haskell has some really good tooling.

It has a feature-rich LSP, code formatter, package manager, dead-code checker, configurable linter, thread debugger, memory debugger, vulnerabilities checker, and much more.

That’s just what is provided by external tooling. Then, it also has everything the compiler has to offer, which is bit more than what most languages do. For example, you can now compile to JavaScript or WASM.


> Postgres offers strictly serializable isolation indeed, but IIUC it's basically a form of read locking so will tank performance.

It will not. We use it at work for all transactions and its is very performant.


Interestingly, the naive solution presented in this article is O(n) thanks to laziness.


It’s O(n log n). If the strings contain the same letters then you end up fully sorting both lists, and there’s no magical way of doing that in O(n) time with a general purpose sorting algorithm.

The article is just saying that the best case performance improves because you don’t have to fully sort both lists in the case where the two words are not anagrams.

There are other cases where laziness works its magic in relation to sorting, though. For example, “sort the list and then take the first element” is (with a suitable implementation of ‘sort’) an O(n) implementation of “find min/max element of list” in Haskell.


That’s floating point, though. Not Double. Floating point has the same gotchas in all languages because it is a defined standard.


That list is of type (Fractional a, Enum a) => [a], but ghci defaults to Doubles, as you can see from

    ghci>  [0, 0.3 .. 2.0]  :: [Float]
    [0.0,0.3,0.6,0.90000004,1.2,1.5,1.8000001,2.1000001]
    ghci>  [0, 0.3 .. 2.0]  :: [Double]
    [0.0,0.3,0.6,0.8999999999999999,1.2,1.5,1.7999999999999998,2.1]
Exceeding the upper bound by 0.1 is not due to a general floating gotcha, but a specific choice in the definition of typeclass method enumFromThenTo for both Floats and Doubles.


Haskell has & which goes the other way:

    users
      & map validate
      & catMaybes
      & mapM persist


Yes, `&` (reverse apply) is equivalent to `|>`, but it is interesting that there is no common operator for reversed compose `.`, so function compositions are still read right-to-left.

In my programming language, I added `.>` as a reverse-compose operator, so pipelines of function compositions can also be read uniformly left-to-right, e.g.

    process = map validate .> catMaybes .> mapM persist


Elm (written in Haskell) uses |> and <| for pipelining forwards and backwards, and function composition is >> and <<. These have made it into Haskell via nri-prelude https://hackage.haskell.org/package/nri-prelude (written by a company that uses a lot of Elm in order to make writing Haskell look more like writing Elm).

There is also https://hackage.haskell.org/package/flow which uses .> and <. for function composition.

EDIT: in no way do I want to claim the originality of these things in Elm or the Haskell package inspired by it. AFAIK |> came from F# but it could be miles earlier.


Maybe not common, but there’s Control.Arrow.(>>>)


Also you can (|>) = (&) (with an appropriate fixity declaration) to get

  users
    |> map validate
    |> catMaybes
    |> mapM persist


I guess I'm showing how long it's been since I was a student of Haskell then. Glad to see the addition!


The screenshot looks like a copy of the hasura web console. The same looks also similar to Hasura’s internal RQL. I wonder if this is just a coincidence.


Not a coincidence. I was a big Hasura fan when I created that landing page.


Yes, it is possible to linearize it. You can, for example use do notation:

    result <- do
        a <- someEitherValue
        b <- anotherEitherValue
        return (doStuff a b)
In the above example the do notation will unwrap the values as an and b, but if one of the results is Left, the computation is aborted, returning the Left value.

This is one just of the many techniques available to make error checking linear.


We do that at our company, it's been great


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

Search:

HN For You