HNHacker News
TopNewBestAskShowJobs

bcheung

2,193 karma · joined July 7, 2008

submissionscomments
bcheung··on Silicon Valley exodus: Bay Area tech companies leaving for Texas
High taxes are good because people will have less room to live? This doesn't sound like a good justification.
bcheung··on Silicon Valley exodus: Bay Area tech companies leaving for Texas
High taxes, high cost of living, and bad policies were the primary reasons I left CA. Property tax assessment was 1/6th of fair market value (thank you prop 13). Still decided to leave. Got a house almost 3x the size for the same price, and no homeless tents everywhere is a nice bonus.
bcheung··on Silicon Valley exodus: Bay Area tech companies leaving for Texas
They will probably favor them in the beginning but I think a lot of that comes from the SF bay area echo chamber. Getting exposure to different cultures will probably average things out more politically leading to greater acceptance and diversity of thought.
bcheung··on If-then-else had to be invented
To get an intuition for the expressive power you can look up examples of quicksort and factorial in languages that support pattern matching. Haskell is a good example.

It is true that you can always just use if statements, it's more about the convenience and cleaner syntax. You can also do destructuring with pattern matching. Pattern matching is almost a requirement if you are going to use algebraic data types.

As Paul Graham says in Beating the Averages, you have to look at the other language from the perspective of knowing it. Nobody can really explain it. It's just going to seem equivalent or weird syntax otherwise.

bcheung··on If-then-else had to be invented
This is true. In a lazy language it is the same, in imperative languages that do eager evaluation it will indeed have the problem you mention.
bcheung··on If-then-else had to be invented
In regards to global vs local optimum it is useful to look at the alternatives like pattern matching.

For languages that don't support pattern matching or passing in functions as values, "if" is probably the best you can do with. You might be able to do something with boolean short-circuit operators but it's debatable if that that is better than the if statement.

In React, if you are using JSX, they don't have "if" statements within the markup they just use the boolean short-circuit (&&) operator.

For more ML style languages that support pattern matching, it is often easier to express solutions that way than with traditional if statements. In those situations I would say that "if" is less desirable in terms of expressive power and code readability.

Also, "if / else" only supports 2 cases, with pattern matching you can have an arbitrary amount of cases.

Without pattern matching, expressing more than 2 cases becomes a combination of nested if statements combined with "&&" and "||" expressions. This makes it much harder to read and write.

bcheung··on If-then-else had to be invented
"if then else" is indicative of an underlying pattern that exists at a more fundamental level. In that sense, it was "discovered", not invented.

Depending on the language, the syntax of "if then else" is not needed and is syntactic sugar.

In the Lambda Calculus you can implement "if else" using "first" and "second".

Here is something equivalent in JavaScript.

  const trueFn  = (first, second) => first
  const falseFn = (first, second) => second

  const ifFn = (boolFn, first, second) => boolFn(first, second)
  
  ifFn(trueFn,  'yes', 'no')  // returns 'yes'
  ifFn(falseFn, 'yes', 'no')  // returns 'no'
bcheung··on The YouTube ban is un-American, wrong, and will backfire
I generally agree with this but YouTube is a communication channel and has a different set of expectations. Additionally they promoted themselves as an open forum in the beginning.

Ideally, discrimination should not exist in something that is promoted as a public forum.

If YouTube only wanted to serve a certain type of genre or they had the same censorship policies from the beginning then that is one thing. But they promoted themselves as open and free speech and then once they achieved critical mass they changed their mind to push their own agenda.

That is dishonest and an abuse of public trust.

As a contrasting example, censoring porn, while still not free speech, would be fine for YouTube to continue to do since they had this stance from the beginning and people chose to join the platform knowing this.

bcheung··on The YouTube ban is un-American, wrong, and will backfire
I think there needs to be updated thought leadership on what qualifies as "common carrier" and what doesn't.

Whether gov't or private, if a platform is primarily promoted as an open communication channel then I think that some, if not all, aspects of "common carrier" laws should apply.

Social media platforms would not have the trust and would not have been adopted as quickly if they started off censoring as much as they do now. In that regard, they presented themselves as open and impartial, then shifted once they achieved sufficient critical mass.

bcheung··on Oracle Moving HQ to Austin
Short term:

People working remote in other locations will have higher salaries from SV companies since they are used to paying those salaries.

People moving from SV to other locations should expect moderate drops (10-20%). In my own experience moving to a 0% state income tax state, it effectively canceled out the savings from CA tax but the cheaper housing more than made up for it.

Longer term:

Tech salaries will come down as employers hire from a larger talent pool that is cheaper on average. This will make it hard for people in SV to work remote as they won't be as competitive. This probably means SV will become more affordable.

> be compensated the same as those in SV?

Generally speaking no, compensation has an aspect of location. Companies are going to have a harder time paying SV rates if they know you are in a cheaper area.

bcheung··on Cydia, the original app store, sues Apple on antitrust grounds
While I doubt they can do anything in an antitrust case, they are also dragging their feet on implementing web standards (that have existed in Android for years) so that developers have no alternative but to develop native apps for things that can just as easily be web apps and pay Apple their 30% in the app store.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
Appreciation is not rent seeking though. Also, savings is what funds capital investment. There's no capital without previous profit.
bcheung··on Experts are sounding the alarm about the hidden dangers of gas stoves
Stovetop doesn't make much difference. I notice it with ovens though. I favor using countertop electric ovens much more because of this.

I'm much more concerned with central heating. I wish more homes had electric and radiant floor heating.

I have to crack the window in the office and put an electric heater near the window to avoid feeling lethargic from all the oxygen being depleted and replaced with noxious gases.

bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
Every major metro in the US has these things. There's nothing unique about SF/SV in that regard.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
Most CS graduates and interns I have hired and worked with I have been pretty happy with. Granted I'm disappointed CS is turning more into programming as a craft and less on the mathematical thinking necessary for true innovation to happen, but from an economics perspective it makes sense to hire programmers over theoreticians.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
I think for Ops / sysadmin work this is probably more true than general software engineering. Ops people tend to cluster in the bay area more. Probably because Ops work used to be more "physical hands" dealing with physical servers which requires being onsite.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
The formula is different if you are a home owner, at least it was when there was more appreciation. You don't mind paying a higher mortgage as much if you are capturing a huge chunk of your current salary in home equity each year. Bay area home ownership is where a lot of people made their money.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
The bay area is one of the worse places to have rental properties in the country though in terms of ratio of rental income to mortgage costs. If it wasn't for appreciation most would sell instead of try to rent out homes. Landlords aren't making their money from the rents, they are making it from the appreciation.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
It's certainly a factor, but "temporary" concerns are probably not significant enough to cause people to move. Moving is a big ordeal unless you are young and can pack everything you own into a car.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
If you hit <esc> at just the right time you can get it before the article disappears.
bcheung··on Tech elites leaving San Francisco threaten Silicon Valley's supremacy
As a bay area native (since 1980) thought I would add my reasons for moving and my thought process. These are my observations and opinions only. YMMV

I recently sold my house and moved to Las Vegas. It was largely for quality of life and failed gov't policies which seem like they are only going to continue.

I moved from a 1800sqft family home to a 5000sqft fully furnished mansion for the same price. It's actually cheaper when you consider not having state income tax and having roommates brings the cost down even more. Granted I'm currently renting but plan on buying again within the next few years if I decide I like it here.

Once COVID-19 happened it seemed like remote work was going to become the new norm, even after the pandemic passes. I'm predicting downward home price pressure in the SF bay area and a slight increase in other metro areas where tech workers are migrating to (slightly in Vegas but much more so in Austin). I wanted to sell my home before that happened. I also think the suburbs further away from SF but commutable once or twice a week won't be hit as hard as people in SF will get homes still in the bay area but further out.

Within the last year I was seeing a rise of homelessness in my neighborhood. Been woken up in the middle of the night a few times from people yelling and fighting. That never was an issue 2-3 years ago. Local stores had been closing more and more with many prime locations remaining vacant for years. I'm predicting COVID/gov't lockdowns and the homeless situation will only accelerate that.

Politically the bay area is definitely an echo chamber. In Vegas, I have friends who are both extreme left and extreme right and we all get along fine. In the bay area it felt like everyone was far left and anyone moderate or to the right remained silent for fear of being attacked or retaliated against. "Tolerance" and "diversity" seemed like they were in name only, at least when it comes to politics.

The high taxes was definitely a strong motivation for moving as well. Remote jobs don't pay as well and I think over time there will be downward pressure on tech salaries as workers become more spread out but in terms of compensation compared to standard of living I think it is an improvement.

Everything also feels modern and clean compared to the bay area. Roads are maintained, dramatically less traffic, parking is easy to find (especially problematic for those who have a truck in the bay area), utility rates and internet are cheaper. Stores and restaurants are open later. The bay area, especially SF seemed really cramped and kind of grungy in comparison.

It will be interesting to see what happens after the pandemic but my thinking is that there will still be an exodus due to remote work still being common place and accepted.

Socially I was able to make friends and network extremely fast. That might be a Vegas thing specifically though.

After a few months now I have no regrets and am very happy with how things are turning out.

bcheung··on WebAsm: Forth with Lisp Syntax
The purpose of an intermediary virtual machine target is that it abstracts away details like that. It's not that registers won't be used at some point, it is about encapsulation, working at the right level of abstraction, and separating it from underlying hardware concerns.
bcheung··on Exotic Programming Ideas, Part 2: Term Rewriting
I was thinking something close to Haskell pattern matching with some variation.

Ex:

AdditionRule (x :: NumericExpr) + (y :: NumericExpr) = eval(x) + eval(y)

It's been a while but I also remember seeing a concise DSL for tree rewriting in the ATLR compiler. It also had escape hatches for things like context and precedence calculations.

In terms of GUI and clicking, I think it might need to be more sophisticated than that.

What does clicking mean when you are a clicking on a sum type? Is it just that variant of the ADT, the entire type?

What about for complex expressions? Are you selecting just a term in that complex expression or the entire expression?

I suppose if you were looking at a tree visually then you could select a lot easier.

Seeing how other languages do "destructuring" or "pattern matching" might provide other possible alternatives.

bcheung··on Exotic Programming Ideas, Part 2: Term Rewriting
I've recently become very interested in this space and am wondering what resources are out there for people wanting to learn more and implement their own languages/environments that use term rewriting?

Most of the literature I've seen seems to focus more on the typed lambda calculus aspect of things and less on the term rewriting.

I'm planning on going through:

- The Architecture of Symbolic Computers

- Abstract Computing Machines

- Mathematica documentation / internals

bcheung··on Mental models around Ok-Wrapping
Once you know it you see it everywhere. It's kind of amazing how common of a pattern it is without people even knowing it explicitly.
bcheung··on Mental models around Ok-Wrapping
I thought Nil was the answer to not using NULL ;)
bcheung··on Mental models around Ok-Wrapping
The number of variables doesn't matter, as long as they are the same type is the part that matters.

<T, E> can be thought of as a pair, tuple, cartesian product. Likewise you can expand it to as many values as you want.

If type C is just (T, E) then it is really just Result<C> at that point.

The first T can vary but as long as everything after that is fixed to the same type, you can have as many variables/types as you want and it will still be monadic.

bcheung··on Mental models around Ok-Wrapping
> Therefore, to do such thing one has to mentally switch the models to something else and „convert“ the fallible function’s result into a „frozen“ representation.

This is where the concept of lifting comes in.

Take for example a simple function that squares a number.

function sq(n) { return n * n }

Instead of taking something out of a representation (category in math speak), you can instead "lift" your function to be able to work _inside_ the representation.

Here's an example:

const nums = [1, 2, 3]

Now you could write a "for" loop, extract the value from the "array representation" to just the "int" type expected by your "sq" function, call the function, and the push the resultant value into a new array, but there's an easier way.

const squaredNums = nums.map(sq)

Or what about dealing with async values?

fetchNumAsync().then(sq)

Or what about if the value is optional?

maybeNum.map(sq)

Instead of converting from one representation to another back and forth over and over, "lift" your function to be able to work within that representation.

"map" and "then" do the work of lifting a function that doesn't understand that representation and makes it so a much more general function can still do meaningful work within that representation.

This may be a bit advanced, but there's also a special form of composition called "Kleisli composition" that lifts functions that straddle 2 different "representations".

Let's say you have some functions as follows:

processA(value: A) => Result<B,E>

processB(value: B) => Result<C,E>

processC(value: C) => Result<D,E>

How would you go from A -> B -> C -> D?

You could call the function and unwrap it each time and then pass it to the next function.

let b = processA(value)

if b.isErr() { /* abort early */ }

let c = processB(b.unwrap())

...

Or you could do something like:

pipe(processA, processB, processC)(value)

The pipe function in this context would be performing "Kleisli composition" and straddling the 2 different representations for you so you can remove that boilerplate.

In essence, for each function in the pipeline it would check if the returned value was an error, and if it was it would just return that error right away. Otherwise, it would unwrap the result and pass it to the next function.

If you understood that then you have the intuition behind a monad.

The only real difference between a "functor" and a "monad" is that the functor takes functions that return value, and a monad takes functions that return a wrapped value.

Functors lift functions that work within the same "representation".

Monads lift functions that work across 2 different "representations".

bcheung··on Mental models around Ok-Wrapping
Well the other end of the spectrum of surfacing complexity of errors would be idiomatic Golang code. But then half your code becomes "if err != nil" error handling.

In many scenarios error handling can be automated because the essence of what you typically do when there are errors is to short-circuit the rest of the function and surface the error the user. If you are doing it the same way each time, you might as well abstract it.

In some cases you may want to make things explicit and force the programmer to deal with them. But if it is just boilerplate, then it becomes noise, and an excessive amount of noise prevents the programmer from thinking at a higher level of abstraction.

Due to limits of human cognition / mental bandwidth (7 +/- 2 concepts at a time), abstraction compresses the number of concepts you need to concern yourself with, and that means you can focus more on the problem domain and less on boilerplate.

The key to this though is learning new concepts and abstractions. Each abstraction compresses multiple thoughts into 1, freeing up cognitive bandwidth. The more concepts and abstractions you know, the more efficient and higher level thoughts you can have.

But that requires time to learn and master. You might also have lots of junior programmers on a team, in which case they are not familiar with many higher level abstractions and they will not be able to work on a codebase, so you have to keep that in balance.

bcheung··on Mental models around Ok-Wrapping
> I’ve not yet seen an explanation of what a monad is that I could understand. Monads are just too abstract for me to grasp, let alone reasoning about.

I had a similar thought about the Option monad when I was learning Scala at the time. My thought at the time was "why are you making it so damn hard for me to get access to underlying value?". At the time I kept trying to "unwrap" the value and continue using it.

Hang in there. An intuitive understanding of monads is necessary to understand how to work with monads like Result fluidly.

For learning monads the best way is to just read tons of different sources and tutorials on them. A lot of them won't make any sense. You might get a tiny hint each time and then it will just click.

Part of the reason monads are hard to understand is because they are typically taught only at the abstract level. You need to see concrete examples first, otherwise it's just a floating abstraction that you can't ground to existing knowledge.

I recommend finding some Javascript tutorials on monads because in the beginning I think a focus on types creates too much noise. Ignoring types will make the intuition stand out more.

You can also get most of the intuition behind the monad pattern by concentrating on just "functor composition".

Imagine:

fnReturningArray().map(doA).map(doB).map(doC)

Then,

fetchPromiseResult.then(doA).then(doB).then(doC)

What do they have in common?

Now you can create "combinators" to make it simpler:

pipe(doA, doB, doC)(fnReturningArray())

The "pipe" function is a generic utility that will work with any type/abstraction that follows the "functor" pattern.

Once you get familiar with the functor / monad intuition you can use and even build you own higher level combinators.

This is a large motivation behind the Result / Either monad. It creates a common pattern that higher order combinators can reuse. In essence, from the constraint of following the functor / monad laws, you get tons of higher order abstractions for free.

← PreviousPage 3 of 30Next →