HNHacker News
TopNewBestAskShowJobs

thinkpad20

2,032 karma · joined April 1, 2013

Software developer in Chicago. Interested in functional programming and related topics, such as logic, type theory, programming language theory, and such-like. Haskell-phile but I try not to be douchey about it :)

http://github.com/adnelson

submissionscomments
thinkpad20··on Functional Programming in OCaml
I did one small pedagogical project in PureScript. As a language, I really like it; in fact I'd prefer it to Haskell in many ways. The compiler experience is good, if not great. Compile times are a lot slower than Bucklescript but a lot faster than ghcjs. Performance is definitely worse, but for many apps I think it'd be fine (and you can always FFI out...). There is a webpack loader for it, although I've had some issues trying it. I've found the syntax to be quite confusing though, even coming from a Haskell background. Parser messages are vague and tracking down the bug can be very frustrating. Also not supporting things like trailing commas is lame (but the same in Haskell). Type errors are also often difficult to understand (even compared to Haskell).

I think overall it needs more development, in particular in regards to UX and integrating into a modern development workflow. I'm excited to see its progress :)

thinkpad20··on Functional Programming in OCaml
Hah, no I don't have a blog, but I'm glad you enjoyed reading it! :)

I touched on this a bit, but the main thing is the compiler experience. I've written apps in Haskell compiled to JS before; specifically I was using Miso. While I very much enjoy writing Haskell -- that part was great -- the compiler is very slow, the binary is huge, and the generated code is completely incomprehensible. There are a few other disadvantages, such as runtime bulk, speed, laziness and the multitude of string types as well. Bucklescript is _so_ much faster than ghcjs and the tooling fits neatly into an established workflow (i.e. webpack, create-react-app etc). It compiles almost as fast as ES6, it has a built in code formatter, it supports JSX natively, etc.

That, plus I had been curious about trying OCaml for a while and I figured why not.

thinkpad20··on Functional Programming in OCaml
I'm currently developing a web app with a Haskell backend and a ReasonML (OCaml with a different syntax) frontend. I'd been interested in ReasonML for a while and so far it's been a great experience, but overall I wouldn't say I prefer it to Haskell. I've been using Haskell for many years and so the simplicity advantage isn't there for me. I also miss strongly some of the major Haskell conveniences like generic programming, type class derivation, higher kinded types, and yes Monads. I'm not a huge fan of the OCaml record system as it frequently gets confused and requires type annotations. In fact I've generally found OCaml to be substantially worse at type inference than Haskell, requiring frequent type annotations and cluttering up the code. Haskell's learning curve is steeper, but it is simpler in some ways, especially once you're familiar.

I think where ReasonML/OCaml wins hands-down is its compiler. Bucklescript (and I've heard similar things about other compilers, but can't vouch for it) is lightning quick, and the community has gone leaps and bounds to make it super easy to bootstrap (including with create-react-app). GHC can do amazing things but it's not the fastest out there, and the compiler for the JS backend is abysmally slow. The code Bucklescript produces is very high quality and performant. The library ecosystem is reasonably strong and I expect (but haven't done much testing) that because of the strictness and relative simplicity of the language, library code would tend to be pretty performant and easy to use. I've never found myself in OCaml wondering what string type I should use, or attempting to parse some absurdly complex type hierarchy in a library.

I think for a frontend project, to most programmers I would recommend ReasonML. For one thing, I think even most without experience with FP would find ReasonML to be a giant improvement over Flow (which infuriates me as a type checker), and it doesn't take a ton of time to learn. ReasonReact is a pretty sweet library and I prefer it to React even setting aside language choice. Compared to Haskell, its strictness means it doesn't require a special runtime, generate slow/impenetrable code, or hog tons of resources -- all things that are issues in frontend Haskell. For those who really want to use Haskell on the frontend I'd recommend PureScript instead (also you get the bonus of a kickass record system).

For backend, I think OCaml will get you up and running sooner, but in the long run you're going to find yourself missing the type system and language features Haskell has. GHC's speed on the backend is tolerable (especially if you use nix), and I think Haskell is competitive in performance to OCaml (perhaps better with optimization). Most importantly, I think Haskell is second to none when it comes to correct implementations of business types and logic, creating powerful and reliable abstractions, and eliminating boilerplate, and I think that forms a greater advantage in backend code.

EDIT: this turned into quite the essay...

thinkpad20··on Blue Apron becomes a penny stock, trading under $1 for the first time
Not a stock market expert by any means, but human psychology has a major impact here. That’s why stocks tend to find floors/ceilings at nice round numbers like multiples of ten or whatever. Likewise to a machine a number is a number but to a human who’s evaluating the stock, seeing something less than $1 is a red flag. Someone please correct me if I’m off!
thinkpad20··on Prions, Nearly Indestructible and Universally Lethal, Seed the Eyes of Victims
To be precise, these aren’t really analogies, they are in fact similes. :)
thinkpad20··on Raising of Chicago
I'm not 100%, but I don't think that's an example of the effects of the raising of the city. For one thing, the address is quite removed from the downtown area, but beyond that you can find these kinds of buildings all over the city, so I've always figured they were just built that way. Here's an example of a clearly recently-built building which has a similar design, in Wicker Park:

https://www.google.com/maps/@41.9092286,-87.6725628,3a,34.8y...

thinkpad20··on Acquiring absolute pitch in adulthood is difficult but possible
I think it's overly simplistic to group people into those who have perfect pitch and those who don't. Of course, I don't know if the article makes this claim, but I think a lot of people tend to view perfect pitch as a binary ability -- either you have it or you don't. But speaking personally, I have "sort of" perfect pitch (imperfect pitch? semi-perfect pitch?), by which I mean that I can sing and/or recognize the pitch of certain notes from memory, but not any arbitrary note, not under all circumstances, and not instantaneously. If I'm not right on the money, I'm usually at least within a semitone or two. I can do it reliably enough that I'm convinced it's not just a fluke when I get it right, but on the other hand it's not at all "perfect." Moreover, the recognition happens too slowly to be practical in real time; usually it involves audiating part of a song that I know has certain notes, and using them as reference pitches. Perhaps if I dedicated more time to it I could get it more accurate or faster, and maybe even develop proper perfect pitch.

All that being said, while having true perfect pitch would probably open up new ways to appreciate and understand the music I'm listening to, I think that relative pitch is a far more useful skill -- nigh essential for many genres.

thinkpad20··on Go hits the concurrency nail on the head
Well, there are trade offs in both directions. Haskell has a steep learning curve and no clear one choice for concurrency, while Erlang is more approachable, has a built-in answer for concurrency, and well-established patterns for building fault tolerant applications at scale.

On the other hand, Haskell’s system has more flexibility, offering a few powerful primitives which can be used as building blocks for higher level abstractions. On top of that it is a general purpose language capable of implementing traditional imperative patterns, etc, so you only need to use the concurrency when it makes sense, rather than using it for all stateful and IO operations as in Erlang/Elixir. Its performance ceiling is certainly higher. I don’t think monads in Haskell are a problem except in terms of the learning curve.

All in all, which one to use, if either, will depend on the circumstances. But both of them should be a part of any thorough discussion of languages which are “good at concurrency”. ;)

thinkpad20··on Go hits the concurrency nail on the head
True, but I think that the "mainstream-ness" of Go (debatable as it is) was of secondary importance to the article, which didn't even mention that there are other languages out there which solve the concurrency problem in other/better ways. Whether or not a language is mainstream is more or less a matter of opinion, in any case. Certainly Haskell, Rust or Erlang (to name a few) are probably less widely used than Go, but none of them are obscure, so to not mention them at all suggests that the author is either being disingenuous, is not aware of those languages' capabilities, or simply forgot.
thinkpad20··on Go hits the concurrency nail on the head
I think the author might be overstating how unique Go’s position is in terms of making concurrency easier. Haskell has the best concurrency story of any language I’ve used. Super lightweight green threads, simple concurrency primitives like MVar and STM, good performance (possibly requiring tweaks, but not bad out of the box). Referential transparency (by which I basically mean immutable data) makes sharing data across threads much easier and in some cases more performant by allowing you to avoid copying. Plus, you have a type system which makes it much easier to reason about your code.

All that being said, I haven’t written Go and can’t compare the two. Also, Haskell doesn’t support the actor/message passing model out of the box (although libraries exist for it) or prevent deadlocks (although the immutability helps a great deal here). BEAM languages, clojure, rust, pony and others all have their strengths here — again, this doesn’t discredit the article at all but the idea that Go is the clear winner is debatable.

thinkpad20··on Chrome 69 will keep Google Cookies when you tell it to delete all cookies
> They apply at some other company comparable to Google, uproot their family, move across country, and get a job somewhere else?

Not all job changes are so drastic. Refusing to implement this behavior might be as simple as just requesting to switch teams within Google. If one chooses to leave, finding another high paying job in the same area is not typically a great challenge for a Google engineer. No uprooting necessary...

thinkpad20··on Pocket’s 30M Users Are Great for Publishers
Not having read the article, I’ll just chime in and say anecdotally that since I use Firefox on my iPhone I’ve clicked on numerous Pocket articles suggested on the new tab screen. Even though they only show two suggestions at a time, they tend to be really interesting reads and fit in well with my interests. Clearly they have a good algorithm.
thinkpad20··on If monads are the solution, what is the problem?
> These bigger, more useful programs you can write with Haskell are pretty much unreadable though.

This seems somewhat baseless. Unreadable according to whom? There are many large and complex programs written in Haskell by large teams of developers (open source or otherwise). It’s the nature of software in any language to become difficult to manage as the code base becomes large; I don’t think Haskell is an exceptional offender in this category.

> There is a reason everyone is not jumping into the functional programming bandwagon, despite mature languages being available for 30+ years.

There certainly are reasons for that, but not the ones you laid out.

thinkpad20··on Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation
How does this compare to the Yew framework?
thinkpad20··on Letter from Shenzhen
> Sorry but just because an article or opinion piece does not make censorship the central point of an article does not mean it is a piece of propaganda.

Very true. However, I didn't claim that censorship should be the central point of the article. I simply noted that it was barely mentioned at all.

> Rarely have I seen someone go into a lengthy speech about government overreach or free speech.

I'm not really sure what this demonstrates -- this can hardly be surprising in a country which provides no way for ordinary citizens to participate in government, has no history of its citizens doing so, and actively discourages them attempting to. That being said, it's certainly believable that freedom is not high on the list of priorities for the average Chinese citizen, but again, I never said that it was.

> We should allow people to talk about the Chinese tech ecosystem without having to pay their due to Western audiences in the foreword.

Another refutation of a claim that I never made.

As to the rest of your post, I agree! I've spent some time in China and was really amazed at how connected it was and how much could be accomplished with just a phone. I was mostly in the cities, but I also went out to the countryside and for the most part everything just worked, and everyone had WeChatPay and AliPay :)

thinkpad20··on Letter from Shenzhen
The sarcasm here isn't necessary. I wasn't claiming that it was the author's duty to educate the reader about the Great Firewall, government censorship and invasion of privacy, copyright law in China, or anything else. Obviously, most everyone reading this is aware of those things at least to some degree. But leaving them out of any serious discussion of the differences between the technology economy of China versus the US is a glaring omission.

This is especially true when it seems to be simply ignoring elephants in the room, such as in the oblique references to security/privacy or copyright law, or claiming that talking about censorship is "unfashionable". For another example, the article spends a good deal of time talking about WeChat, one of several unicorn technology companies which, while certainly it's been very innovative in its history, likely only exists in large part due to the blockage of Facebook and Twitter.

This isn't knee-jerk sinophobia, this is pointing out some pretty obvious holes in the discussion here and speculating as to the reason for them. Of course, the overall tone of the article is rather fawning, but this is Hacker News so that's nothing out of the ordinary.

thinkpad20··on Letter from Shenzhen
This article honestly reads a lot like propaganda from the Chinese government.

It never even mentions the Great Firewall (unless I missed it?) and only barely mentions the security and censorship issues involved in writing software in China, even claiming that the reason it’s difficult to talk about security and privacy is because “so much of the grand technological experiment in China is still unfolding.” Right; I’m sure that’s the main reason.

The article also breathlessly mentions that “there are still parts of the rural US without cell phone service, places where you feel untracked and like you might disappear. Yet even in one of the poorest provinces in China, QR codes will follow you from towns to villages.” Even if you assume that’s something that everyone wants, to ignore the implications of having that technology available in a highly invasive police state is irresponsible (in my opinion).

Finally, I thought the line that “its strength is in extreme open-source, which stands in stark contrast to the increasingly proprietary nature of American technology“ is completely laughable in a country as notoriously insecure as China and in an era when use of open source software is probably at an all-time high in the US.

(Edit: added newlines for clarity)

thinkpad20··on Futhark 0.6.1 released – High-performance functional programming on the GPU
This project is super cool. I wish that I had a use case for the stuff in here, but I dont really do any high performance or GPU programming. Maybe I will one day, but in the meantime keep up the good work!
thinkpad20··on Lyft and Uber Won’t Be Happy Until They’re Your One-Stop Transit Guide
I think your point about operations and verification is spot on. However, it’s worth noting that Japan (less familiar with other countries) has tremendous cultural advantages over the US when it comes to privatizing infrastructure. Punctuality, cleanliness, attention to detail, engineering prowess, safety, collectivism — many things that lend themselves to a well-functioning transit system — are all deeply interwoven into Japanese history and culture in a way that is difficult to imagine being the case in America. Which isn’t to say that it couldn’t be successful here, but it’s not an equivalent set of circumstances.
thinkpad20··on React from zero: a simple tutorial for React
Hahaha, “props”. Badamp-tssssh
thinkpad20··on Short-Termism Is Harming the Economy?
Not a terminology I’m familiar with. What does “submarine story” mean?
thinkpad20··on Microsoft Is Said to Have Agreed to Acquire GitHub
I switched jobs and went from Github to Bitbucket about 6 months ago. I've found bitbucket to be consistently and noticeably slower than github both in its web UI and in pushes/pulls, with more downtime. You pay for those private repos one way or another.
thinkpad20··on Conversations with a six-year-old on functional programming
If you’re interested in the subject, look up Adam Neely on YouTube. A great channel with a series of 10-minuteish videos on various interesting topics in music, from theory to history to physics and beyond. Not so much a “course” in music theory, morning e of a series of one-off topics mostly accessible by a lay audience. Might be good conversation starters with your son :)
thinkpad20··on Dark side of ergonomics in Rust
On the contrary, I think that’s an argument against implicit conversions. u8 and usize have wildly different ranges, and treating them as the same could cause some maddening bugs. I can’t imagine there are that many places where you’d need to use a u8 as an index; if there were you could either wrap your data structure in a struct which accepts u8 instead, or use usize more instead...

(Not that I’m claiming to know your code base or specific challenge or anything; I’m just speaking generally)

thinkpad20··on Guido van Rossum: Python 2 end-of-life will be on January 1st, 2020
That list was a little surprising to me. Simplejson at the top, a library I’ve never used which seems to be obviated by the presence of json in the standard library (similarly argparse). Surprised to see pymongo above Flask. Also surprised to see Django having 10m more downloads than Flask.
thinkpad20··on Pearsons, Who Pledged $100M to UChicago, Want Their Money Back
As a UChicago alum I'm somewhat bewildered by their actions, and saddened for the bad press and more importantly what seems to be a missed opportunity to take advantage of an unprecedented gift. I'm curious how this will be seen to reflect on Robert Zimmer. Although he may not have been directly involved in the project, I'm sure he had a lot to do with the arrangement and negotiations, and the buck ultimately stops with him -- assuming, of course, that UChicago screwed up as they are accused of having done.
thinkpad20··on Containers won the battle, but will lose the war to serverless
When someone speaks in the style of this guy — absolute certainty of the superiority of their chosen technology, dismissive of or glossing over its disadvantages, condescending to those who use or advocate other technologies — it makes me very dubious of their claims. It also makes me assume they’re trying to sell me something.
thinkpad20··on Nix 2.0 Released
Yeah, and I use cleanSource, but I find it to be pretty obtuse and full of edge cases.
thinkpad20··on Escaping Hell with Monads (2017)
There are two answers I can think of:

1. You know what the code is doing to the extent that you know how monads work. As in, you know that you’re going to do some monadic action that returns a, then another one that returns b, etc. The code as written is generic so it’s not specified what the actions are.

2. And this is the much more common case; the code in question is being used within a particular context (I.e. for a particular monad that the programmer is working with) and the context makes it obvious what is actually being done by the monadic actions. Here the genericness is not in writing a function that can be used in multiple places, but in having a portable concept of “a pipeline of actions that return things and could fail” which you can use wherever you need it.

thinkpad20··on China's Xinjiang surveillance is the dystopian future nobody wants
Poverty exists within cities and without. I’m not sure how suburban sprawl is helpful to those in poverty.
← PreviousPage 2 of 20Next →