Recent submissions

Comment · 8 years ago
I don't understand your example. What does compile-time computed stuff have to do with readInt()?

I get that it might be possible to do that, use a Maybe Maybe T. But it's like an optional<bool> in C++. It can be done, it's just not a good idea. So if you design your system not to allow that in the first place, nothing of value was lost.

If you have specific error cases that you want to communicate, like "what was read from the console didn't parse as an int" as opposed to "the computation didn't find a result", then using the two values "Nothing" and "Just Nothing" as the two distinct values to encode that is not a sound design. Either you have meaning, or you have Nothing. Nothing shouldn't have any meaning attached to it.

Comment · 8 years ago
So you're saying that the one Nothing has a different meaning than the other Nothing, and that this is something that anybody would want? Or that we have a Nothing and a Just Nothing? I'm sorry, but I don't get how that would be considered good design in any context. Do you have any example where this would be considered sensible?
Comment · 8 years ago
Thanks dang
Comment · 8 years ago
First I want to thank you for your honesty. It is so refreshing to read, in this sea of self-promotion of Medium posts that go around here.

You may want to talk to a coach about this. I'm sure you can find someone specialized in finding jobs. You make it sound like you somehow let yourself down, and if that shimmers through in an interview, you won't leave a good impression. I think you need somebody to help you with finding a good way to frame this time in a better light. Not only for your next application, but also for yourself. What started as time off might have turned into involuntary unemployment, with all the negative weight that this brings.

Comment · 8 years ago
My understanding is that this is only about memory access patterns, and has nothing to do with multithreading. The basic example being matrix multiplications C=A∙B. If the matrices are too big to fit in the L2/L3 cache, you have to think about how to optimize memory access. So instead of having the compiler just generate instructions to read/write memory, you want it to interleave instructions to prefetch memory, ahead of time. But how do you do that? What is the best point in time to prefetch?

Another optimization is locality: The basic algorithm is to loop over i and j, then multiply A's row i with B's column j. You do that with another loop over k to compute the sum over Aᵢₖ∙Bₖⱼ, then store the result in Cᵢⱼ. But what if one row or column is already too big for the cache? Also, once you invested into loading the data into the cache, you want to make the best use of it. You don't want to load it again if you can avoid it. So what you do is you limit the loop ranges for i, j, and k such that the overall memory accessed fits into the cache. But what are the optimal loop sizes?

The answers depends on the CPU architecture (cache sizes) and probably also the memory that you're using.

Comment · 8 years ago
> NOTE 2: Depending on the shape of your head the head band of the earmuffs can make the crown of your head hurt – though this is not limited to earmuffs as may headphones have this undesirable feature.

I tied a piece of memory foam that I salvaged from an old mattress to the head band, using two strips of velcro tape. Looks ridiculous, works really well.

Comment · 8 years ago
Comment · 8 years ago
Because Starcraft is 1v1 and LoL is 5v5. Poker AIs also focus on 1v1 as opposed to full ring games. It's easier.

Also because Starcraft has three races, i. e. 9 matchups. But if you pick one race for your AI, you only have three matchups to worry about. LoL on the other hand has about 500 champions (give or take), whose strengths and weaknesses are vastly dependent on the current patch. LoL is less about skill or strategy, and more about picking the champion of the week.

Starcraft works because they have such a small number of matchups that balancing them is possible. Certainly not easy, and players keep figuring out ways to evolve the meta game. Maybe an AI could even find interesting new strategies. But LoL has so many matchups that their balancing team has an absolutely impossible task of trying to catch up. It's so complex that they can't just think about in theory, but they have to look at win-rate statistics, over different skill ranges. At this point it's more a problem of data science. And the number of champions keeps growing, because that's how they make money.

Comment · 8 years ago
Oh, alright. I thought the "it" would refer to the question, not the whole review process.
Comment · 8 years ago
Comment · 8 years ago
> If they had a question on a change, it would add two days latency

Wouldn't that be just one day? You ask the question while they sleep, they answer while you sleep, you get the answer the next day.

Comment · 8 years ago
Does the compiler build the initial AST based on a grammar, before the transformations happen? That would mean you can't expand the grammar with user-defined rules. The reason you can "implement for loops in user land" is because they're already part of the grammar, is that correct?

How abstract is that initial AST? Can you use these rewriting transformations to expand the grammar?

Comment · 8 years ago
Ben, could you go a little into detail on what you had in mind with the term rewriting system? The sin/cos example seems a little underwhelming, since these should be evaluated at compile-time in the first place.

They seem like a variant on C macros, but without the restriction on function syntax. Maybe one could implement Python's with statement in userland, which is very nice.

It also seems to me that you could replace C++ templates, yet you do have generics. How come? What's the difference?

My intuition is that ambiguities are at least possible, so what about precedence, which AST term is evaluated first? I'm thinking of some situation where two subtrees match the rule, but you end up with different results depending on which is transformed first. E. g. if you were to define a cross product rule, and apply it to a × b × c.

What about infinite loops in rule sets? What about recursion?

What about a situation where multiple rules could be applied? Is there any way to debug the transformations? Is that what the `using` scopes are for? If the compiler was to detect ambiguities, that seems pretty expensive, because it would need to match every rule to every subtree, right?

This thing seems very, very powerful, I just find it a bit hard to grasp what you can do with it in practice, and what the limitations are. I would be very interested to hear what you ran into so far.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton