HNHacker News
TopNewBestAskShowJobs

sirclueless

1,803 karma · joined June 4, 2010

submissionscomments
sirclueless··on The Problem with Friendly C

    I don't have anything to say about races, but OOB array
    accesses should simply do what you'd expect the hardware
    to do: attempt to access memory at the location the array
    indexing equation gives. It may segfault, or it may
    access some other contents in memory. That's what any C
    programmer would probably expect.
The problem is that defining OOB array access this way means throwing out pretty much every semantic guarantee from the rest of the language. There is really no friendly way to define writing an arbitrary value to an arbitrary location. By way of example, pretty much every (non-embedded) C implementation since 1972 supports recursion by writing an address of code to execute to memory. If you have semantics allowing a programmer to write to that location, then you can start executing literally any piece of code you want to. On some platforms like x86 you can execute starting in the middle of an instruction.

For example, "return" would stop meaning "execution resumes at the callsite of this function" and instead mean "execution resumes at the callsite of this function or maybe somewhere else if someone wrote to arr[-5]". The article makes a big point about the controversy of giving memcpy() the semantics of memmove(); how would you like the semantics "memmove() unless a concurrent thread is running, in which case anything might be written to dest and src might be overwritten."

sirclueless··on Why Johnny Still Can't Encrypt: Evaluating the Usability of a Modern PGP Client
Did you guys read the paper, or even the abstract? This whole paper is about Mailvelope and the difficulty people had using it.
sirclueless··on Show HN: Pyexperiment
I want to voice my support for keeping the driving use case "experiments".

I'm coming from the perspective of a software engineer here. To a software engineer, a "program" is a collection of stateless routines and behavior. Data is external and separate, the same program should be able to process a wide range of data. "Reproducibility", as much as that matters, is having a tested system that responds in a predictable and reliable way to inputs, and data is one such input.

When I first worked extensively with a scientist on an experiment, I was shocked how much common wisdom from computer science was turned on its head. One is expected to load up a Matlab workspace with data and code all in the same file? Scripts irreversibly mutate data, and often run exactly once? How could one possibly keep track of such an environment? How does one fix bugs in a series of commands typed into an interactive prompt? Reproducibility to a scientist is a log of actions that could be repeated by another human, but the environments used often just dropped such things on the floor, to be caught only by the most diligent researcher with an unusually well-kept notebook.

I think there is definitely a happy medium somewhere. Reproducibility as a scientist understands it; interactivity in a way that makes sense to a scientist writing a one-off script. Program state stored easily so that the scientist doesn't feel lost every time they restart their environment, as I imagine they must do when editing python scripts in vim as a software engineer might. But all this in a world where scripts can be maintained and versioned and fixed without their hair catching fire.

sirclueless··on Learn Chapel in Y minutes
It's easy enough to skip ahead. I like that it doesn't leave any of that out; it's not so tedious that you can't scan for interesting bits, with the rest as reference material. Maybe I am biased from reading on a laptop where scrolling and scanning is easy?
sirclueless··on What is Ethereum?

    Contracts that are mutually beneficial typically
    don't need to be enforced because they are not
    often broken.
This is a fundamental misunderstanding the purpose of contracts. Contracts are almost by definition mutually beneficial, at least nominally. Otherwise the only reason parties would enter into them is under duress or out of ignorance. And in fact, contracts backed by a legal system are routinely struck down if either of those cases occur.

What you are describing is a situation where neither party has an incentive to defect or default on the contract. And if that is the case then there was no need for a contract in the first place. For example, you and I agree to meet Friday night for dinner. This is a beneficial arrangement for both of us, neither of us need sign anything.

The purpose of contracts is to solve a game-theoretic problem: it is to our mutual benefit to cooperate in some way. But if we cooperate, then one of us can do even better by defecting. For example, it might be mutually beneficial for me to give you $1,000 today, and for you to give me 100 widgets on Thursday. But if I give you $1,000 today, you can do better than the original agreement by keeping the money and the widgets. So the only reason I would ever give you $1,000 is if there was some way to enforce that you give me 100 widgets. That can be by legal means, or technological means. The threat of punishment under a legal system is one traditionally effective way to incentivize you to hold your end of the bargain, and in many ways is at the very heart of what makes modern society work. A technological solution, that avoided law enforcement and judiciary systems, has the potential to be even better because there are obvious negative effects to having a large and over-reaching police force, for example.

TL;DR The enforceability of the contract is the whole point. The only reason you need a contract in the first place is because someone has an incentive to defect.

sirclueless··on The Universal Data Structure
That comment was responding to a comment about PHP and JS, both of which do not make such a distinction.
sirclueless··on Mystery Man Moving Japan Made More Than 1M Trades (2014)
Even day traders have their capital in some instrument, be it cash, real estate, stocks etc. It's not unlikely that in addition to day trading, this trader invested a large amount of money into the stock market (and indeed, we have been told he did not invest in real estate).
sirclueless··on Cancer reproducibility effort faces backlash
I disagree here, because the inevitable result of a highly visible series of failed reproductions is a big media hit. The scientific community may be able to poke holes in the reproduction attempt and sort through the damage, but the media and the court of public opinion certainly can't. Not until long after the reputations of possibly faultless scientists have been ruined irreparably.

So it's important for the reproduction attempts to be as high quality and rigorous as we would hope the original studies were. And it behooves scientists to make sure that these attempts are legitimate, unbiased and equitable, and to investigate any experimental flaws and biases of the experimenters before the results.

Misgivings about a reproduction attempt don't indicate denial of the validity of the scientific process, but recognition of the volatility of scientific news media. The unfortunate reality is that both sides of this effort, both original researchers and reproduction attempts, are subject to a great number of biases and restrictions. Subjective opinion does deeply affect the lives of scientists, and it's not possible for even the best scientists to live in a bubble of scientific purity and assume things will work out.

sirclueless··on Early vs. Beginning Coders
I don't think these things are all that different, in the very early stages.

The very first part of computational thinking is understanding that you can make a very specific and precise procedure to accomplish a task. If a student is at an age where reading and writing is easy, then learning the syntax of a language is a fine way to accomplish this. The student will spend a lot of time with each finicky word and symbol to make the computer behave, and while they may not recognize that they are defining an abstract procedure, the result is hopefully some intuition that the computer is a very predictable and reliable machine that does exactly what the code says, even if it's not what you meant. With exposure to more languages and by writing more programs, hopefully a student begins to recognize patterns and abstractions in their code, and that's the point at which they become real computational thinkers.

If a student isn't ready for that, there are still fun things to try. One cute one I've seen is "program your parent" exercise at a workshop. The child can make their parent move one step forwards or back, turn left or right, pick up and put down an object, and put one thing inside another. Can they make their parent pour a glass of juice? Or put a lego back in the box?

I don't think there is a chicken and egg problem here, because learning to make a dumb machine perform a task by following a procedure is the essence of computational thinking. Learning the basic syntax of a language is probably the most efficacious way to experience this for many students of many ages, even if the explicit goal is "do well on an AP test" or something mundane.

sirclueless··on Solving the Traveling Tesla Salesman Problem with Python and Concorde
Not to mention the situation in New Mexico, which is trivially suboptimal by the triangle inequality.

I think there was either some kind of rounding error getting data into the TSP solver, Concorde is just giving an approximate solution, or the data preparing code in python has a bug.

sirclueless··on Key for chromium's encrypted cookies store in Linux is “peanuts”
It's a good software development principle. Make things that are secure look secure. Make things that are insecure look insecure. This is going to be insecure no matter what precautions are taken, because the source is open and the key is part of the binary, so it should look exactly as insecure as it is so no one assumes anything untrue about this code.
sirclueless··on Node9: Inferno kernel with LuaJIT instead of the Dis virtual machine
Just a side note, because it's not directly relevant to this conversation, but I love how useful and powerful libuv has become. I'm not a huge fan of JavaScript or Node, but the Node project's work on libuv is a great boon to a large number of projects, for which it is the perfect level of abstraction between raw non-portable OS interfaces and opinionated, performance-sacrificing language APIs.
sirclueless··on The male suicides: how social perfectionism kills
Are they? To me it seems obvious that if one is seeking those emotions actively, then one will be disappointed or worse if they prove unattainable.

For whatever reason, be it psychological or physiological, it is clear that humans cannot maintain a perpetual high. The serotonin is expended, the stimulant wears off, unhealthy dependencies on emotional states are created. An even keel is worth any number of highs in my opinion. The goal should not be an emotion or a high-water mark, but rather to make progress. Progress is tangible, you can hang your hat on it and be proud of it, and most importantly it's available to you no matter how poor your circumstances or station in life are.

sirclueless··on New Debian project leader talks open source careers, PPAs and more
Not really an answer for packages that need configuration in /etc, add desktop entries to user's menus, or should be discoverable for example by systemd.

Adding to everyone's PATH is invasive and not really an option for most multi-user systems.

sirclueless··on Show HN: Deck of Cards – A playing card API
I wonder if you could do most of this cryptographically. If you did, you could make a client that could do all of this peer-to-peer. I think you would just need the following to make a wide range of games (many popular ones, perhaps most?):

1. Client can produce a signature that it drew the k'th card from the deck for any k.

2. Client can produce a signature that the k'th card is X if it drew the k'th card.

3. Client can produce a signature that card X came from any arbitrary set of card indices containing k if it drew the k'th card. (This is the hardest one.) If it's easier, you could get most of this even restricting it to sets of cards that the client has drawn.

With just that, I bet you could make a protocol for most card games where no one can cheat, where the central server's role is only to give out information about k'th card one and only one time. Certainly it's enough for blackjack, most forms of poker, hearts, and go fish. Anyone have a game that would be difficult? Maybe one where hidden cards get passed from player to player.

sirclueless··on Show HN: Deck of Cards – A playing card API
Appears to be python's random module, so not very secure if that's what you're after but it's probably correctly pseudorandom: https://github.com/crobertsbmw/deckofcards/blob/master/deck/...
sirclueless··on The Discovery of Apache ZooKeeper’s Poison Packet
This looks wonky. Why are you writing a loop here?

    if (potentially_large_value >= 32) bit_pattern = 0;
    else bit_pattern = bit_pattern << potentially_large_value;
That does the same thing in constant time, and doesn't loop 2^27 times on bad input.
sirclueless··on Why Lisp?
You can get this in other languages too. For example, Flask (a Python web framework) has a fantastic debug-mode error page that totally changed the way that I think about web development. Any time an exception is thrown in a view function (and this includes the exceptions that you idiomatically throw for HTTP 4xx and 5xx errors) the debug-mode error page would have a stack trace (obviously), but also an interactive REPL that could be opened at any stack frame in that trace. It wasn't necessary all that often, but when it was, boy was it a fantastic way to work.
sirclueless··on Why Lisp?
Calling log.debug() with and argument of `false` is a no-op? That sounds like someone bending the language to fit an idiom, because it doesn't sound like a sane API except that it enables this use case.
sirclueless··on Postgres gets support for upsert
Sequences in Postgres are updated even if a transaction is rolled back. It's pretty easy to see why that's important, especially when dealing with concurrent transactions.

You can't give out the same number to multiple transactions without causing a bunch of unique constraint violations. And you can't retroactively decrease a sequence number without affecting all the other transactions currently executing. You could in theory go back and plug in the gaps in a sequence, but it's more important to guarantee that a single thread of execution will always see increasing numbers than it is to guarantee that all numbers will eventually be handed out to a successful transaction.

sirclueless··on Pre-Pooping Your Pants with Rust
I think you need to split the unsoundness bug, which happens because thread::scoped uses unsafe code, from the "you can write mem::forget in safe code" bug, which is arguably not a bug but is at least an enormous footgun waiting to happen.

When the footgun goes off in unsafe code in the standard library, you get use-after-free and memory unsoundness. When the footgun goes off in safe code written by mere humans, you leak arbitrary resources.

sirclueless··on Pre-Pooping Your Pants with Rust
Scrapping the guarantee that destructors will be called is tantamount to scrapping RAII. thread::scoped made the assumption that destructors were called before a borrowed value was returned, and it led to a memory-safety error. If you don't use unsafe, you won't get memory-safety errors, but you can get plenty of other nastiness.

The guarantee that destructors are called when values leave scope is fantastic. It means that one can leverage memory-safety into arbitrary-resource-acquisition-safety. It violates the principle of least astonishment in a brutal way if Rust's borrow checker can statically guarantee that a value no longer exists, but can't know whether or not its destructor has been called.

sirclueless··on Automated code review for Python, Django, etc.
Is there a way to silence particular errors (i.e. false positives). For example, the python linter is unhappy that I have the following in my code:

    ParticipantFormSet = modelformset_factory(Participant, can_delete=False, max_num=8, extra=8,
                                              form=ParticipantForm)
It claims that this is a violation of the naming convention for variables, but in this case ParticipantFormSet is actually a python class, albeit created with a factory function.

This is just one example, but I would think long-term that it would be a great annoyance to deal with persistent misapplication of rules.

sirclueless··on Pre-Pooping Your Pants with Rust
Putting stuff in a HashMap that you'll never ask for again is a kind of leak. Allocating stuff on the stack and then looping forever is a kind of leak. The case where you put it on the heap and forget to ever free it is a specific kind of leak that people seem particularly terrified of for whatever reason.

I too am particularly terrified of this kind of leak. The reason is that it is the only kind of leak mentioned that is not clearly a programmer mistake.

C++ has a whole class of "mistakes" that one cannot be aware of simply by reading the language specification. Common ones such as writing a constructor and destructor but not a copy-constructor are now compiler warnings, but many will pass under the radar. As a result, to write correct code one needs to be aware of multiple conventions and rules and patterns that are external to the language. When reviewing code one needs to do more than observe that it compiles and accomplishes its stated task, there are probably several organizational standards that need to be satisfied as well to be safe.

This is precisely the kind of thing that Rust was supposed to solve. The goal was to have a language that didn't require an "Effective <xyz>" book to be memorized to do code review. A language where any rule like "You should always free resources in advance in case the destructor doesn't run" is captured statically by a compiler error.

So yes, I am particularly put off by this error.

sirclueless··on No Longer an Inspiration
I think the timeline is correct and the article is about 2015. The Most Inspirational of the 2015 event, which was held April 11, 4 days ago, involved a Wix website. Neither of the other years appear to.
sirclueless··on Parallel Map in Elixir
Is this piece of code idiomatic Elixir/Erlang?

    receive do { ^pid, result } -> result end
Without looking up what the "receive" procedure does, it suggests that the current ("main"?) process is going to block waiting for an incoming message that matches the pattern. Done in a loop as I presume the Enum.map function does, it looks like the main process might be blocked waiting for the matching message while some internal mailbox fills up. In the worst case I would expect this to have an O(n^2) running time unless there is something fancy going on when pattern matching against a full mailbox.

Please correct me if I'm wrong. This looks elegant, but I would expect it to be considerably less performant than, say, the equivalent Go program which would issue a select on a channel of incoming messages, thus only blocking until any message is received, rather than a specific message in series.

sirclueless··on The Cryptographic Doom Principle
Did you edit your post? I'm not the only one who misread it. If KC is applied first to the plaintext, then assuming you didn't flub anything in implementation the combined scheme won't be less secure than KC, I agree. Applying CC effectively becomes security through obscurity, which is admittedly sometimes helpful.
sirclueless··on The Cryptographic Doom Principle
This is not a true statement. CC may leak information about the plaintext in ways that KC can't handle, even without breaking it. For example, applying CC might deterministically affect the message length.

One of my favorite cryptographic attacks ever was of this form, known as the CRIME attack [1]. It was a "partial plaintext" attack, where the "CC" in question was plain old gzip. Basically the attackers controlled a small part of the plaintext (for example, a field in an HTTPS request they could send with CSRF) and they were able to use known properties of the CC to get some information to leak into the message length -- namely, if the message fragment they controlled appeared elsewhere in the request, the gzip encoding would be shorter, and hence the encrypted request would be shorter. This is something that happens even with a "perfect" KC that no one could break.

[1]: http://en.wikipedia.org/wiki/CRIME

This is one of the defining characteristics of cryptography to me -- there are no perfect cyphers, there are only good systems. Littering extra cryptography around nearly always decreases security. The most secure system is the simplest system that works.

sirclueless··on Asteroid Database and Mining Rankings
There's no good model out there I know of for the rate of innovation. Massive availability of a resource should spur innovation around its use. It's very difficult to predict the future demand for a resource beyond a timescale of decades.

A good historical parallel for this kind of situation might be aluminum, which was a precious metal for many years. When it suddenly became available in large quantities due to new chemical processes for extracting it, supply skyrocketed and led to whole new industries. I don't think anyone in 1890 could have guessed what the ultimate demand for aluminum would settle at, even though it was clear the price was dropping precipitously.

sirclueless··on Announcing Rust 1.0 Beta

    I'm genuinely curious because, as far as I know, none of the
    major languages were designed to be usable...

I think that's a little narrow-minded. Of course languages are designed to be usable. "Usable" is almost meaningless on its own, as every language is intended for use by developers to solve problems (toy languages notwithstanding).

As for your specific goals, "package management, interoperability, docs, and error messages," I think there are in fact major languages designed with very specific goals in those areas. Node.js for example was designed to leverage the immense popularity and familiarity with JavaScript, and it has a clear story for package management that has enabled an enormous ecosystem. Go is a language that from the get-go was designed with a coherent story of how to build large and maintainable systems, encompassing package management and the module system, language features chosen for their simplicity such as interfaces and the lack of generics, and a canonical source formatting tool to attempt to make the whole ecosystem more readable and understandable.

Rust of course has its own answers for usability. They too have a package system that can enable a thriving ecosystem. Their approach to memory management is a naked attempt to make their language "usable," an attempt to make programming more user-friendly language in contexts where interpreted languages, bytecode and even garbage collection are untenable. Their docs are coming along nicely, their error messages perhaps less so.

To say that no major languages are designed for usability is laughable. In fact, I would say that every major language since and including x86 machine code has been designed with usability concerns front and center. The more recent wave of languages especially -- practically no one is trying to beat C and C++ on technical capabilities. They are trying to beat them on ergonomics.

← PreviousPage 6 of 23Next →