HN user

excessive

178 karma
Posts0
Comments54
View on HN
No posts found.

I don't mean this the wrong way, but since you know one instruction is sufficient, the next smallest number is two. Maybe by RISC, you meant a small orthogonal set? Load/Store/ALU ops separated? So ADD and NAND work on registers with transfers using LOAD and STORE? Seems like you'd need a branch, unless the instruction pointer was one of your registers.

Brainfuck has 8 ops, 2 of which are for input and output. It's Turing complete, and the operations are super simple, but I'm not sure it's RISC-ish.

https://en.wikipedia.org/wiki/Brainfuck#Commands

x86's version of a single "instruction" is frequently a large class of opcodes. It's kind of crazy considering the assembler chooses one of the following numbers for "mov" based on the operand types, not the mnemonic:

    88, 89, 8A, 8B, 8C, 8E, A0, A1, A2, A3, B0, B8, C6, C7
This also ignores all of the prefix bytes.

https://www.felixcloutier.com/x86/mov

A few years back, I re-wired the electrics in my guitar using a semi-complicated setup of a 6 way switch for pickups in-phase or out, and parallel or series, tone and volume pots, and distortion. There was also some choice to be made about what capacitors to use, and picking a diode for passive distortion.

After a first pass trying to just wire it directly, I ended up hot gluing a tiny breadboard into the compartment. That went much better and allowed me to swap candidate parts until it was right.

Here's one you can use with (pretty much) any version of C++:

    __attribute__ ((format (printf, 1, 2))) 
    static inline std::string format(const char* fmt, ...) {
        va_list args;
        va_start(args, fmt);
        size_t bytes = vsnprintf(0, 0, fmt, args);
        va_end(args);
    
        va_list again;
        va_start(again, fmt);
        std::string result(bytes, '\0');
        vsnprintf(&result[0], bytes + 1, fmt, again);
        va_end(again);
        return result;
    }

I'm not the GP, but here's my take on it.

First some good: Python is amazing for how approachable it is. I've tried to teach (non-programmer, but smart) people I know other simpler programming languages, and it doesn't take. For some reason, when I show them Python it goes so much better. Despite the flaws, Guido and crew clearly got this part right. I don't think any other language makes new programmers feel comfortable so quickly.

Ok, for the bad:

Python is a very slow interpreter. If all you're doing is gluing together C/C++ libraries and invoking them from Python, it works just fine. However, my experience writing new algorithms in pure Python is that they run between 50 and 1000 times more slowly than nearly equivalent C.

Python exposed so much of its its internal implementation for making C extensions that the developers hands are practically tied when it comes to improving the implementation. If you look at the Python C API, you'll see most of the structs exposed and 100s if not 1000s of public functions. Important (and complicated) extension modules (such as Numpy) are now dependent on lots of the current implementation details. This is the reason that alternate implementations of Python (such as PyPy) can never really catch up to compatibility. Many other languages provide the same functionality for C extensions/plugins without the same exposure to all of the internals.

Python painted itself into some odd corners by not requiring variables to be declared. Most programmers are surprised by the behavior of this snippet.

    a = 0
    def doit():
        print(a)
        a = 1
    doit()
    doit()
Also, it doesn't happen a lot in my experience, but typos in variables names can be silent errors because it will just introduce a new variable. Similarly, they needed to add a "nonlocal" keyword for when you want to modify something outside your scope. Note, you don't need nonlocal to just read it though.

If there was a "var" keyword required to declare a new variable, you wouldn't need global or nonlocal, you could catch more typos in variable names, and the program above would behave correctly.

There are other issues too, but this post is getting long already, and these are the some of the big ones to me.

I didn't think it worked that way. After that, can I be the Silent/Greatest Generation?

Maybe the word "Boomer" will just get redefined to mean "old people with more money than me". Kind of the same way "meme" got redefined from "idea permeating society" to "cartoon or cat picture with sarcastic text", and how "troll" got redefined from "someone who tries to antagonize" to "someone who says things I don't agree with".

Some boomer should have some “OK SLACKER” t-shirts

As part of Gen-X, I feel like that's appropriating from my culture. I was proudly on the "slackers" mailing list as an adult in the 90s when the millennials were being born. Give millennials a new pejorative, don't steal ours.

Thank you for telling me about this - I didn't know they did that...

My first thought as I started reading the PEP was, "Why did they bother adding the 'bytes' type if 'str' is just going to be able to hold everything anyways?"

After looking at more of it though, it seems like they're storing the binary octets as code points in one of several internal Unicode representations. Moreover, they're abusing (reusing?) the range of code points reserved for 16 bit surrogate pairs, but only using the low half of the pair. This is all clever in the bad way.

This seems like a real lack of taste to me, and I doubt the Guido from 1991 would've found it acceptable to have 'str', 'bytes', and 'bytearray' the way they are. (Let's ignore 'buffer' became 'memoryview' for now...) It used to be a simple and elegant language.

Yes, that's very much what the video goes into. For any rational approximation of 2 pi, say 22/7, you won't get lines at multiples of 2 or multiples of 11.

The first time I saw these, I thought it hinted at some deep insight into the nature of primes. However, after watching the following video, I think it just says something about modular arithmetic and rational approximations of 2 Pi.

    https://www.youtube.com/watch?v=EK32jo7i5LQ
The video is only about Archimedian spirals, but I suspect a similar analysis would apply to Ulam spirals too. We really like to find patterns.

Your proposal only works well for US ASCII users.

No, and I explicitly mentioned UTF-8. My suggestion is that str holds arbitrary immutable binary data and that you have a method which can interrogate whether that binary data is valid UTF-8.

Yes, real world text is messy and there are lots of encodings, compression schemes, and exceptions (UTF-8 with byte order marks, overlong encodings, or surrogate pairs, as examples). If your main task is converting text between outdated or broken encodings, I don't have any problem saying you need a separate library and shouldn't burden the rest of the user base. Despite it's flaws, the majority of the world has settled on Unicode with a UTF-8 encoding.

"Special cases aren't special enough to break the rules."

There were some intractably difficult, "rip-the-band-aid-off" types of changes that had to happen at some point.

I suspect you're referring to Unicode here. In that case, I think they could've just added a flag to Python 2's str type to indicate "is UTF-8" and deprecated the old unicode object. Then add some functions to extract code points or grapheme clusters or whatever else you need from the old school str object.

I might be in the minority, but I really like that Python 2's str could hold arbitrary binary data, of which UTF-8 is just one possibility. It had good interop with C, which I think is fundamental to a glue language like Python. I'd rather have fewer string types instead of more (one of my complaints about Rust too).

If you meant the print function, there were other ways to solve that too. The simplest might be to create a new name for the function and deprecate the print statement. So old code uses the statement "print 123" while new code is encouraged to call the function "echo(123)" or "ouput(123)". Bikeshed the actual name...

Note when I say "deprecate", I mean provide a timeline over several releases where it continues to work. Then issue deprecation warnings which can be silenced.

All of the newer features in Python 3 (@ operator, async/await, type annotations, etc...) could've been added in a mostly backwards compatible way. (Note: adding async wasn't really backwards compatible even in Python 3).

Anyways, hindsight is 20/20, but I really do think the path for Python 3 was a poor choice in comparison to other options.

Thank you for your reply, it does actually change how I see the prior art thing played out.

Often, folks think that they've found prior art if they find one thing in one document and another thing elsewhere. Nope.

Still, I think there must be something profoundly broken if you find the exact math in an old book, and the new patent basically says, "do that math on a computer".

Here is one in Python. Uncomment the if statement if you want it to terminate.

    def sin(x):
        def recur(x, n, s, p, f):
            #if n > 9: return s;
            return recur(x, n + 2, s + p/f, -p*x*x, f*(n + 1)*(n + 2))

        return recur(x, 1, 0, x, 1)
Of course maybe it's cheating from your intent because it's really just implementing the Taylor series, and it has too many arguments. I believe any analytic function could be defined this way if you can figure out the pattern for its derivatives.

The plaintiffs certainly had a larger legal team. We brought our patent attorney and a trial lawyer on our own dime, and we managed to get some time from the chief patent counsel for a very large company because he had a relationship with one of our investors.

The plaintiffs managed to get jurisdiction in their own city (across the country from ours), and the general belief was that the judge granted this because he wanted a change from the drug trials he normally dealt with. This made it very expensive for us, and they definitely had the home court advantage.

I could whine about a lot of other things. For instance the plaintiffs removed every juror candidate who had any college, leaving only locals who I don't think even understood trigonometry. The fact that you're not supposed to be able to patent math, but somehow math on a computer gets through the patent process, etc...

ex post facto analysis

I'm not sure what definition of "obvious" survives then. I was out of college for less than 2 months, and I wrote the code in a single evening. The "infringing" algorithm was less than 10 lines.

When you go to court, the presumption is that the patent is valid. The judge is unlikely to be technical, and he must assume the experts at the patent office did their job. Since the patent office basically rubber stamps anything you send to them, it's a very uphill battle to start with.

In my case, we submitted lots of prior art (some over 100 years old) to the court, and of course they shared this with the plaintiffs. I was certain we should be in the clear. However, in the time between receiving those documents and the actual court date, the plaintiffs submitted our list of prior art to the patent office as some sort of addendum. The patent office re-rubber stamped the new stack of paper, and the judge disregarded it during the trial. We lost. I doubt the patent office bothered to read, much less understand, any of it.

I feel very strongly that their patent was not novel, and since I wrote the algorithm which got us sued from scratch as a new college grad with only a bachelors degree, I doubt it was non-obvious to one skilled in the art. Maybe we could've won with better lawyers, but as a small startup, we didn't have that kind of money.

Is that what it's about?

I'm pretty sure most people who strongly like OOP are sure their particular definition is the correct one. I haven't seen many people agree about what that definition is though. I generally dislike OOP, but perhaps that's because my definition is "encourages implementation inheritance". As you're keen to note, the standard list of other things (encapsulation, message passing, dynamic dispatch, interface inheritance, and even "establishing protocols") are available in a lot of other languages which people don't generally consider OO.

Perhaps I'm ignorant, but I like my way of doing things, and a.f() is less attractive to me than f(a) for all the reasons I listed.

Heh, this is really a matter of perspective. If you think the rest of the web was wonderful, then Flash was a turd floating in a swimming pool. If you think the web is a poorly designed shoddy mess, then you might think Flash was a raft keeping you afloat in the sewer.

HTML and JavaScript are so sloppy and incrementally improved by accretion rather than taste, I lean towards the sewer point of view.

As consumers, most people probably only care about what modern browsers can do. As a developer, the mechanisms become front and center. Modern web development is a Rube Goldberg kluge of things glued together with duct tape. Flash was much more coherent and imposed less cognitive burden of tying it altogether.

I was never a Flash developer, but I certainly admired it in its prime. The early versions could be installed simply by putting a 47kb DLL in the plugins directory, and in a time well before the HTML canvas or JavaScript with good performance, this brought dead web pages to life in a way that was very portable across browsers and operating systems. It was much better (lighter, simpler, quicker to load) than Java applets from the mid 90s.

It's easy to imagine the various security vulnerabilities could have been fixed by a more responsible/responsive company, and the abuse by advertisement companies should've been solvable with an ad blocker.

JavaScript, CSS, and HTML have come a long way in capability, but the mashup is much more distasteful to me. Flash was elegant despite its frequent misuse.

Show HN: Bel 7 years ago

This one seems backwards to me:

    (2 '(a b c))
In addition to being data structures, I like to think of lists/arrays as functions which map integers to the contents. This nicely generalizes to hash tables / associative arrays, and then further to actual functions. If that's all reasonable, then
    ('(a b c) 2)
is the right order for application.

However, maybe pg is just thinking of 2 as a shorthand for cadr or similar.

I prefer looking at in months. If you make a grid 36 across and 30 tall, those are the months of a 90 year life. Much easier for me to fit in my head.