HNHacker News
TopNewBestAskShowJobs

haskman

265 karma · joined June 2, 2013

submissionscomments
haskman··on Category Theory Illustrated – Sets
Seems you might have fixed it before I saw it! Thanks!
haskman··on XML is better than YAML – Hear me out
XML semantics, not syntax, are good for configuration too. See https://kdl.dev/
haskman··on Category Theory Illustrated – Sets
Looks fine to me. What's wrong with it?
haskman··on TypeScript please give us reflection/runtime types
A lo of people in this thread seem to be misunderstanding what is being asked for. There is no runtime reflection needed. What is really needed is -

1. A way to get a value that represents the type of any statically known type (i.e. known at compile time). 2. A way to compare two typereps for equality. 3. A way to convert between types if the typereps are equal.

This is basically the equivalent of the `Typeable` class in Haskell and PureScript (https://hackage.haskell.org/package/base/docs/Data-Typeable....). Both Haskell and PureScript erase types at runtime, so it is possible to do without adding a runtime to TypeScript as well.

haskman··on Mediant
How does it follow that the mediant (a+c)/(b+d) is a better approximation than both a/b and c/d? One of the bounds could be very close to the quantity you are trying to approximate already.
haskman··on Rust's Ugly Syntax
Off the top of my head Coffeescript introduced the function arrow syntax to JS, as well as class based inheritence.

Also you don't need to take my word for it, Brendan Eich, the creator of JS himself has said that CoffeeScript had a significant impact on his thoughts about the future of JavaScript (https://brendaneich.com/2011/05/my-jsconf-us-presentation/).

haskman··on Rust's Ugly Syntax
I didn't mean the designers of Rust. I meant the author of the article did not consider a Haskell like syntax.

I completely understand the reasons for Rust devs targeting a C like syntax. Rust had already blown its novelty budget on the borrow checker semantics.

haskman··on Rust's Ugly Syntax
Yup, this could and should be a separate preprocessor step. Changing the syntax of the Rust language itself so drastically would be nearly impossible at this stage.
haskman··on Rust's Ugly Syntax
Why is that hard to comprehend? `do` starts a new block with sequencing semantics (so we don't need the `?` operators) in Haskell.

CoffeeScript can actually be considered very successful, since it influenced the design of a lot of other language features we take for granted. Same can be said for HAML.

haskman··on Rust's Ugly Syntax
I've been thinking about something like this for a while too. Happy to collaborate!
haskman··on Rust's Ugly Syntax
They didn't explore a Haskell (or PureScript) inspired syntax, but I think it could massively improve things without compromising on semantics. The separate function signature itself is a great improvement.

"Haskell flavored Rust" anyone?

    read
      :: forall p
      .  AsRef Path p
      => p
      -> Result (Vec u8)
    read path = inner (as_ref path)
      where
      inner :: &Path -> Result (Vec u8)
      inner path = do
        mut file <- File.open path
        let mut bytes = Vec.new
        read_to_end file (&mut bytes)
        pure bytes
haskman··on Ask HN: Have you stopped reading most news?
I don’t use any traditional sources of news at all. I don’t get newspapers, or watch any tv news. Some time back I made a decision to cut back from toxic twitter and I haven’t used any other forms of social media as well.

What I get in return is peace of mind. I’m able to stay neutral when friends, in person or online, tell me stuff. I don’t feel a need to counter with my own strong preconceived opinions. And I’ve seen that this has a tempering effect on other people too. People are less likely to be vitriolic if they don’t feel they have to make me see the error of my ways.

But what if I am letting “them” brainwash me? By not being fully “pre-informed”, am I opening myself up to misinformation that will eventually convert me into a hateful bigot? I don’t believe that is likely. First, the “them” here is friends and family. I know they come from a good place even if some of their opinions (for some of them, all of their current opinions) may be wrong at times. Being brainwashed by a horde of anonymous trolls on the internet is more likely and much worse. Second, I trust my inner compass enough to know that I’m unlikely to ever become that kind of a hateful person who actively wills harm upon a section of humanity. But I am, like most others, susceptible to being overwhelmed or confused. Opting out of the rapid bombardment of information online helps me avoid that.

haskman··on Duolingo S-1 IPO
I'm currently learning Japanese and I tried playing with this for a bit. I have to say that this looks really nice, and almost exactly what I was looking for. The flashcards are interestingly presented, and the selection of sources is great (Though it doesn't have Minna no nihongo 2 which I'm currently going through).

Great work, and thanks for working on this and making it available!

haskman··on Flame: A PureScript front-end framework inspired by the Elm architecture
Thank you! All the manual wiring in Elm can be very frustrating!

Also not having to expose all the action datatypes when they are only being used in a single place can really improve code structure.

haskman··on Flame: A PureScript front-end framework inspired by the Elm architecture
Well elm architecture is just a pattern in Concur. You don't need to store things globally at all.

Currently the only thing to take care of is - when a child widget returns some value to the parent, if you want to reinvoke the child widget and somehow restore the previous local state of the child widget, you need to have sent that local state out to the parent previously. This means that you either add the local state to the child widget's return value, or use something like a wire to directly send the state to the parent or something else.

I am working on adding automatically persisted local state to Concur which would greatly simplify this. It would provide an API similar to hooks' useState (and the react bindings will actually use hooks for this).

haskman··on Flame: A PureScript front-end framework inspired by the Elm architecture
1. Application wide state is easy since you can always access state from parent components in child components. The problem occurs when you want to update parent state from child components.

Fortunately, you can make your own abstractions in Concur. For example, you can use a "Wire" - which lets multiple child components share and update parts of the parent's state (https://github.com/purescript-concur/purescript-concur-core/...). Note how this abstraction just uses the high level Concur API, and doesn't depend on the UI backend. With a wire the code might look something like this -

  -- A wire into parent's state, accessible using `with`, and updateable using `wire.send`
  counter wire = with wire \i -> do
    button [onClick] [text (show i)]
    wire.send (i+1)
And you can compose several counters that share state like this (the first two counters will increment together -

  -- Parent component creates a wire using `local` and an initial value
  local 0 \w -> div []
    [ counter w
    , counter w
    , some
    , other
    , widgets
    ]
  -- Beyond this point the local state is gone and can't be accessed
  doSomethingElse
2. Concur widgets can perform sync effect as well as async effects using `liftEffect` and `liftAffect`, and the results of those actions are available within the monad just like other widget results. Does that answer your question?
haskman··on Flame: A PureScript front-end framework inspired by the Elm architecture
Purescript-Concur is simpler, and allows you to use elm-architecture as well, but also allows you to use your existing functional programming toolkit to the fullest. It also has react bindings - https://github.com/purescript-concur/purescript-concur-react.

Here's what a counter example looks like -

    counter count = do
      button [onClick] [text (show count)]
      counter (count + 1)
Check out a comparison with elm-architecture at https://ajnsit.github.io/concur-documentation/ch03-01-replic....
haskman··on Proof-of-stake is inherently self-referential
"If the people with the most money start screwing around with other people's money, then everybody will just abandon using money altogether, societal structure will collapse, and they will be left with nothing".

Great argument.

haskman··on Ganja.js: Geometric Algebra Generator for JavaScript, C++, C#, Rust, Python
It's not. Ganja could mean either marijuana or "bald" depending on how you pronounce it. Not offensive or an insult which would "exclude 2 billion people" either way.
haskman··on Linus Torvalds' good taste argument for linked lists, explained
This is exactly the right answer.

There are two cases here (1. when the target is at the front of the list and necessitates changing the head of list, and 2. when the head doesn't need to be changed.) You handle both the cases separately.

Both the classical and the "elegant" versions are worse than this one.

haskman··on Ask HN: Who is hiring? (December 2020)
JUSPAY (juspay.in) | Bangalore or REMOTE | Full time | Functional programming, Purescript, Haskell

JUSPAY is a Payments Exchange connecting merchants, payment providers and banks. With a deep focus on delivering seamless payments UX at scale, we are trusted partners for all major internet companies in India.

We use functional programming (Haskell and Purescript) across our stack. Our Payment page is currently live with 10+ merchants. As we start to scale to 100+ merchants , we are facing some key challenges on building a unified cross-platform configurable payment page. We want to build a team of highly experienced PureScript devs to solve those problems.

Job Description - https://drive.google.com/file/d/1slLlFDc5tZ0qCtQpsCw6AHQYXqM... 1

If you find this interesting and would like to work with us, please get in touch at careers@juspay.in. Or contact me directly for any questions at anupam.jain@juspay.in.

haskman··on The life and death of email read tracking
Thanks! I just disabled external images in gmail after reading your comment.
haskman··on Ask HN: Who is hiring? (June 2020)
JUSPAY | Full-Time | Bangalore or Remote

JUSPAY provides a high throughput transaction processing system built using pure Functional Programming tech - Haskell and PureScript. We have processed over 2Bn payments so far, and currently handle 4M transactions a day. Our SDK has seen over 200M installs and is embedded inside all the top apps in India.

We are looking for Engineers who are interested in learning FP and building UI and backend frameworks to enable our large team of 200+ people.

We are practical people with deep interest in thinking from first principles and in-depth understanding of systems and scaling. FP has done a lot of magic for us. If you are interested in working with us, please drop an email to anupam.jain@juspay.in.

haskman··on React Native for Windows and Mac
Can you clarify the difference between developing "with" vs "on" react-native?
haskman··on Comparing Ember Octane and React
I find all this code so hard to read, because there are very few elements being composed together. It reads like one monolithic chunk of code (and with a global state!).

I find code enjoyable to read and write when it's like Lego. You build small little self contained pieces and join them together. It makes a big difference when building large applications.

I wrote an example in [Concur](https://github.com/ajnsit/concur) to demonstrate what I mean - https://gist.github.com/ajnsit/f0fee9a83480289a5a052273ce21c.... The "app" is composed of self-contained widgets, each of which are short and easy to read, and have a defined purpose (show the searchbox, render a story etc.) In a larger app, they can be mixed and matched together in logical ways.

haskman··on Immediate Mode GUI
I wrote a UI framework called Concur which is very similar to immediate mode UIs and hence very easy to use, but also scales fantastically well to complex UIs. The original code was written in Haskell (https://github.com/ajnsit/concur), and then ported to Purescript (https://github.com/ajnsit/purescript-concur), and even Javascript (https://github.com/ajnsit/concur-js).

There's an introduction/tutorial here - https://github.com/ajnsit/concur-documentation/blob/master/R...

haskman··on SQL: One of the most valuable skills
I am not familiar with R dplyr.

The code snippet I posted doesn't adequately demonstrate it but the DSL is strongly typed with full type inference at every step. So for example, it knows that the type of the table after the "join" is has a field "age" of type "int", and that filtering on it is okay. Trying to filter on a non-existent field will cause a compile (not runtime) error.

Second, the "steps" are actually plain functions. `#` is simply the reverse function application operator defined as `a # f = f a`. Which means you can abstract operations. For example, you can define a generic function that can take any relation with an age field and filters for age > 60. Thanks to strong types, using it incorrectly (i.e. on a relation without an age field of type integer) would cause an compile error.

Also, the language itself is a deeply embedded DSL. So "ordinary" code also compiles down to SQL. You can do things like loops etc. (for example, create a function that filters over a list of age limits rather than just one) and it will try to generate the best SQL possible.

of course the SQL generation is currently not implemented, so all this is theoretical, but I'm getting there!

haskman··on SQL: One of the most valuable skills
Preach! I just started building something like this in Purescript which might interest you - https://github.com/ajnsit/purescript-consequence.

It allows writing things like -

    type PersonRel = Relation (name :: String, age :: Int)
    type EmployeeRel = Relation (employeeName :: String, managerName :: String)

    -- Get all managers older than 60
    oldManagers :: PersonRel
    oldManagers =
      employeeTable
        # renameField (SProxy :: SProxy "managerName") (SProxy :: SProxy "name")
        # join (RProxy :: RProxy (name :: String)) personTable
        # filter (\r -> r.age > 60)
        # project (RProxy :: RProxy (name :: String, age :: Int))
haskman··on JavaScript iterator patterns
I referenced my framework further down the thread as well, but repeating it here since you specifically ask for ease-of-use and React. Please try out Concur-JS which is my async-gen based UI framework that is React based, and designed to be extremely easy to get started with. https://github.com/ajnsit/concur-js
haskman··on JavaScript iterator patterns
You might be interested in a slightly unusual UI framework I wrote that heavily focuses on async generators to define the UI - https://github.com/ajnsit/concur-js.

The idea is that a UI "Widget" is a sequence of UIs (which themselves can be Widgets) generated asynchronously (say when a UI event fires).

A sample widget -

    async function*() {
      // Show a clickable button.
      // All processing is async, this will conceptually block until button is clicked.
      yield* <button onClick>Click me</button>
      // Button was clicked, show text
      yield* <div>Button was clicked!</div>
    })
It uses React and VDOM to diff the UIs generated and update the page slightly more efficiently. As you can see, it also provides JSX support (by overriding createElement calls).

The Widgets themselves can be easily composed, and the entire thing is designed to be extremely easy to get started with. The README on github has more information.

← PreviousPage 3 of 4Next →