Hacker Newsnew | past | comments | ask | show | jobs | submit | zovirl's commentslogin

Additionally, the file size of the sprite sheet image is often smaller than the combined file sizes of the individual images. (I never looked into why but expect it has to do with sharing overhead and the compression dictionary)


Yeah. If your images have similarity at all, being in the same compression container helps a bit; and there is some per file overhead, smallest PNG is reportedly 67 bytes, plus http overhead, and maybe you're serving one request per http connection (but hopefully not for images) . If you're feeling really optimizy, you can probably shuffle the order of the sprites and get bigger or smaller sprite sheets. But then you also need to consider the impact on your css when you shift the sprite sheet around, I don't think that would be big, but it might be.


Can you speak more on why glider pilots need night vision googles to fly at night but single-engine pilots don’t? Is it the risk of landing out? Or are they flying closer to the terrain?


My understanding is that (1) there is, as you say, a very nonzero risk of landing in a field and good visibility of what is _in_ that field is critical; (2) when riding thermals it is traditionally the case that many gliders soar in close proximity close to the core rising air mass, circling at quite a high bank angle – and collisions need to be avoided (many glider pilots wear parachutes for that reason…) and having visual references, particularly to mountains, really helps; and finally (3) it is common to be flying visually as one typically staircases in an altitude profile, as seen here, and go in and out of controlled airsapce (or deliberately avoid bumping into it, as I have done at 10 kft in UK airspace a long time ago).

In contrast, general aviation aircraft:

a) Have bright lights b) Will fly in a straight line at a well defined altitude, meaning that vertical separation is sufficient to deconflict aircraft c) Do not typically land in fields and do instead land on runways which often _also_ have bright lights.


Not the OP, but I'd say both are yes. You will be flying in close proximity to mountains, no way you can do this without actually seeing the mountain.


I agree there aren't very many. I can think of PuzzleScript, Unreal Blueprints, and Machinations (mentioned elsewhere in this thread). Perhaps this dearth is why Blueprints got so popular?

Honorable mentions might go to PICO-8's flavor of Lua (C-like but clearly designed to create a specific type of game and have a specific developer experience) and Excel (used for developing & balancing game mechanics, but usually replaced in the final product).


I was lucky, early in my career, to work at a place which used a lot of Perl and to read Damian Conway’s book, Object Oriented Perl. It was an amazing, mind-expanding book for me. It was filled with examples of different approaches to object-oriented programming, more than I ever dreamt existed, and it showed how to implement them all in Perl.

So much power! And right in line with Perl’s mantra, “there’s more than one way to do it.”

Unfortunately, our codebase contained more than one way of doing it. Different parts of the code used different, incompatible object systems. It was a lot of extra work to learn them all and make them work with each other.

It was a relief to later move to a language which only supported a single flavor of object-oriented programming.


And at the extremes, too much power makes a tool less useful. I don’t drive an F1 car to work, I don’t plant tulips with an excavator, I don’t use a sledgehammer when hanging a picture. Those tools are all too powerful for the job.


planting flowers? trowel

planting foundations? excavator

once you specify "the job", the best tool is "the solution" to that job only. anything else is excess complexity

however if "the job" is unspecified, power is inverse to the length of "the solution"

so is constraint of power bad?

--

a fascinating question

just like music can be created by both additive and subtractive synthesis; every line of code creates both a feature and a constraint on the final program

in which case power can be thought of as the ability to constrain...


that is quite wild...

it implies expressivity is the ability to constrain

it implies drawing on a page, or more broadly, every choice we make, is in equal parts a creative and destructive act

so maybe life, or human flourishing is choosing the restrictions that increase freedom of choice? it's so meta it's almost oxymoronic; concretely: we imprison people to maximize freedom; or, we punish children with the aim of setting them free from punishment

this is the same as the walk from law into grace found in Christian ethics

maybe the ultimate programming language then, provides the maximal step down that path, and this is also the most useful definition of "power"

i.e. place on people those restrictions that increase their ability to choose


http://online-go.com has an interesting anti-stalling feature: If you pass several times it checks with KataGo. If KataGo is 99% sure you will win, either player can click a button to accept that result and end the game.


Sensei's Library is a gem from the non-commercial web! It reminds me of the C2 wiki (https://wiki.c2.com) but for Go instead of software engineering.


Even in situations where this is true, there's almost certainly a better phrasing than "this new policy sucks," which only communicates an emotion. It is imprecise. Listeners will jump to their own conclusions about why you think it sucks.

You can acknowledge the problems more directly: "I get it, we don't have enough chairs so Wednesday is likely to be a challenge." or "I know mandatory 9-5 is going to disrupt your commute."

A bonus of the more precise approach is you can follow up with "do you have other issues with the new policy that I may not know?"


I think the parent was complaining about mentions of CRDTs which don’t acknowledge that the problem domain CRDTs work in is very low level, and don’t mention how much additional effort is needed to make merging work in a way that’s useful for users.

This article is a perfect example: it says syncing is a challenge for local-first apps, logical clocks and CRDTs are the solution, and then just ends. It ignores the elephant in the room: CRDTs get you consistency, but consistency isn’t enough.

Take a local-first text editor, for example: a CRDT ensures all nodes eventually converge on the same text, but doesn’t guarantee the meaning or structure is preserved. Maybe the text was valid English, or JSON, or alphabetized, but after the merge, it may not be.

My suspicion, and I might be going out on a limb here, is that articles don’t talk about this because there is no good solution to merging for offline or local-first apps. My reasoning is that if there was a good solution, git would adopt it. The fact that git stills makes me resolve merge conflicts manually makes me think no one has found a better way.


There is definitely no general solution but for some domains there may be acceptable solutions.

Git is a good example though as we can definitely write merge algorithms that get good results in many more cases than git's default but with something like code it's preferable to let the human user decide what is the correct merge solution except trivial cases. Still, a language aware merge algorithm could do a lot better than git in both automatically merging more cases and refusing to merge nonsensical combinations of commits that don't touch the same lines.


> My problem is that I cannot see how control flow works in Forth, e.g. a simple if-then-else.

What made it click for me was http://www.exemark.com/FORTH/eForthOverviewv5.pdf, specifically sections 2.3 "Loops and Branches" and 5.3 "Structures". With a slight simplification, if/else/then branching is defined in 7 words.

Two primitive words, branch and ?branch (in python because I know it better than assembly):

  def branch():
    """ branch is followed by an address, which it unconditionally jumps to."""
    ip = code[ip] # Get address from next cell in code, jump to it.

  def branch_if_zero():
    """ ?branch is followed by an address. ?branch either jumps to that address,
    or skips over the address & continues executing, depending on the value on the
    stack."""
    if stack.pop() == 0: # Pop flag off stack
      ip = code[ip]      # Branch to address held in cell after ?branch
    else:
      ip += 1            # Don't branch, skip over address & keep executing
Two helper words for forward branching. >MARK adds a placeholder branch address to code and pushes the address of the placeholder. >RESOLVE resolves the branch by replacing the placeholder with the address from the stack.

  : >MARK    ( -- A ) HERE 0 , ;
  : >RESOLVE ( A -- ) HERE SWAP ! ;
And then the actual IF, ELSE, and THEN words. IF puts ?branch and a placeholder address in code. ELSE puts branch and a placeholder address in code, then updates the preceding branch address (from an IF or ELSE) to land after the ELSE. THEN updates the preceding branch address to land after the THEN.

  : IF   ( -- A )   COMPILE ?branch >MARK ; IMMEDIATE
  : ELSE ( A -- A ) COMPILE branch >MARK SWAP >RESOLVE ; IMMEDIATE
  : THEN ( A -- )   >RESOLVE ; IMMEDIATE


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

Search: