HN user

peterevans

406 karma

https://www.modul8r.com/

Posts4
Comments102
View on HN

Assembly is a type of programming that is unlike most programming languages, and as such, would be a really tough introduction to the field.

Can you explain a bit more about how you became interested in assembly and programming the Apple II? And specifically, why you want to start the journey towards programming there?

The original magic system from Final Fantasy 1 (you can only cast N spells per magic level, maximum of 9) is a copy of the system from Wizardry. The only difference you have to type the spell name to cast it in Wizardry, and you get a menu in Final Fantasy.

Freshpaint is hiring! We're a YC- and Intel-backed company SaaS platform that provides a codeless customer data platform that is default-safe for companies that need to work with sensitive data, like protected health information.

We're looking for software engineers and others to join our team: https://www.freshpaint.io/about

I like the idea of deliberate learning! I also really like the idea of focusing on how to maximize the amount of learning you do, and choosing when to strategically focus on that. So this is really cool general advice, and honestly the feedback that is outlined really could apply to any raiding guild, whether casual or not. Or also just, you know, people. Any people. It's good advice.

I had to set aside the framing device of a raiding guild, though, because the way it's used isn't realistic. It seems to me there's an assumption that learning is happening in a closed system, where learning can only happen through experimentation. That's not how MMORPGs work--people share experiences all the time, both inside and outside the game. People also raid outside of their own guild, which means that raid attempts can include people who've done this before, and can essentially help your guild by talking you through how it's done in-game.

So, in the general case, any attempt at learning within some reasonably closed system in which no learning can happen outside of experimentation, and when experiments are limited in quantity, certainly _must_ try to maximize what you can learn for every experiment. But casual raiding guilds do not fall into that category.

A lot of advice I've seen (such as this) postdates much of the standard library implementation by quite a bit. I could not, however, suggest that the current design for crypt is good or bad, for I have not used it often enough to offer a worthy opinion.

People seem to really click with the net/http design, and that does seem well done, but I imagine the standard library itself is a bit unevenly architected.

Abstractions are not a bad thing, but early abstraction often lacks understanding of the problem to solve. Abstraction is complexity. We often need complexity, but we should not add complexity without cause.

And I don't think this is a Java vs. Go thing. Let the program, or the problem if you will, prove to you where you need abstraction.

It would be neat if MachineBox could sense whether log noise would be useful in other contexts--e.g., as a metric that can be graphed. Or whether your logging is lacking something that might be useful, or just lacking signal at all (hey, user, your logs are just noise!).

I mean, I guess it's the best thing if you want to wreak havoc and chaos? Which, perhaps, you do!

Your suggested dichotomy is, of course, a little bit false. But I'm sure you knew that when you wrote it down.

It's entirely possible to write secure programs in C, even with standard functions. Writing your own code does not somehow confer a level of security-consciousness that you lacked when sticking to strings.h. (It does give you a wonderful opportunity to write your own security holes that no one has discovered yet!)

I mentioned this somewhere else, but we're in a pretty good place right now with languages; we finally have really solid alternatives to C that can compile to machine code, in both Go and Rust.

The main issue is that there's already a lot of standard library support for classical strings--things that are just a pointer to a chunk of bytes, and no more; rewriting those functions would be destructive. The C standards group could add to the standard library, I suppose, but generally they are a bit reticent to do so.

It is not the case that C has a benevolent dictator with a particular vision and drive for the language. It's more like a small group of people who don't want to mess things up. And so not much changes. This is neither good nor bad to me--it simply is; and anyway, these days, you have quite a few options that do offer automatic strings that can also compile into machine code (Go, Rust I suppose?).

I highly recommend the Static Analyzer that clang already uses. I use this frequently in the C project I am currently working on, and it's very good at spotting memory leaks and other potential issues. I've had more than one occasion where I've looked at an issue it's reported and said, nah, this is a false positive...oh, no, wait.

Ah-ha, well! There are actually two Apple IIe models. (Well, there was a third "platinum" one too, but let's not talk about that.) One would have shown "Apple ][" at boot time, and this was the original model with a 6502 NMOS-based chip. But they later released an "enhanced" model, which had a 65C02 CMOS chip. You could tell the difference because the later model would have instead shown "Apple //e" when booting.

It's quite possible (perhaps because you typed it as Apple //e!) that you were actually working with that 65C02 variant, and thus, your janky stuff was forgiven by the Gods of Early Personal Computing (blessed be).

(See: https://en.wikipedia.org/wiki/Apple_IIe)

My understanding is that in the 6502 (NMOS) chip, those other opcodes had undefined behavior, and you might crash if you executed one. So you'd need to know who was the manufacturer to be certain that opcode X was available.

In the CMOS version (65C02), illegal opcodes are treated similarly to NOPs--they don't crash, and don't do anything other than spend cycles--with the caveat that certain of these "illegal" opcodes have specific numbers of cycles and bytes that they consume which are different from other illegal opcodes. More confusingly, there is an actual proper NOP instruction (0xEA), which consumes the one opcode byte and two cycles, which exists in both the CMOS and NMOS version of the chip.

So some of the illegal opcodes are just like NOP, and eat one byte and two cycles; some eat two bytes, and 3 or more cycles; and there's at least one which not only eats 3 bytes, but eight (GASP!) cycles.

Source: if it's possible for one to consider MOS emulation a hobby, then let's say it's a hobby of mine.

I suppose time will tell whether generics are added or not. I'm--not exactly buying your argument that Go's compiler is badly written, or itself the reason that generics can't be added. But god bless ya for having an opinion.

Sort of--you get dynamic types, so you can stuff whatever you want into your collections. You can do that in Go, too--just use interface{}. Sadly, that has not quieted the Generics Brigade.

If you used arrays in PHP, or Ruby, or Python, you can get those--with static typing!--in Go, either with slices for sequential arrays, or maps for associative arrays. I think that satisfies the vast majority of collection use-cases that arise in practical applications of those three languages.

(Note: I think generics would be a Good Thing for Go, and I think they'll probably happen at some point. They keep doing user surveys, and the user surveys keep bringing up the lack of generics as one of if not the number-one issue that users would like to see addressed.)

Huge caveat: This article was written in 2012. So do yourself and fellow reader a favor and not argue over content that is now six years-old.

Obviously, Go has not replaced C++ usage. And, these days, I would see Rust as the more likely step from C++.

(Although, I still feel that it remains to be seen whether Rust will make a huge dent there; is memory-safety the killer-app feature that makes people want to use Rust? Do enough people feel that they Need To Use Rust to make it stick? I'm interested to see how that plays out.)

What Go has done, I think, is replaced interpreted language use (PHP, Python, Ruby) in backend code. Which makes sense, to me--those are already GC languages, so you're pretty familiar with the lay of that land. Generics may not make a huge deal for you because there were no generics to use in those other languages. And Go is quite a bit faster than any of the aforementioned interpreted languages.

Expressiveness is not always a pure ideal; reducing your business logic to two lines of code comes with tradeoffs. The ways your code work within the frameworks you choose is not always obvious, and when something goes wrong, it's harder to point at one place within your two lines of code and say: this must be it.

The opposite is not, and should not, necessarily that you write your own versions of things; after all, if you did so, you'd still have as deep of a stack trace as you do with the third-party code!

I guess, if I encountered this stack trace, I might say there's something of a code smell there. But, hey--this is also fairly old code, and I suspect things are Better Now, so let's not be so quick to cast stones!

"Almost never."

In my experience, the code you write within a third-party framework rarely works the way you expect it to the first time. So you often do "debug" the framework, just to see where your code goes while in the framework to see what you missed.

That's not a bad thing, though--it's a great way to learn any new framework!

To me, this essay read more like a troll; a mish-mash of complaints and anecdotes that don't frankly make any sense when put together. But the author succeeded in getting to the first page of HN, so–congrats?

As such, it's hard for me to bring myself to respond to any one point in the piece. It'd be quite easy for most of us to do so, but I suspect that was the intention.

I recall reading something from some of the language developers who had indicated that their worry with generics was whether they could do it right. I inferred that to mean, whether they could do it in a way that felt as simple as the rest of the language does.

I would guess generics, when it lands, would look syntactically similar to the way channel type declarations look; you can have "chan int", so perhaps you would have "vector int". That feels the most intuitive and Go-ish to me. Channels require special syntax to work with, but with generics, I imagine you'd want to make use of interfaces.

I can see a bunch of ways of doing it—but none I could guarantee would end up in the finished product! But I do think generics land at some point. The unfortunate thing is there's a sense going around that Go doesn't have generics because the language authors somehow know better than everyone else; if anything, I think they have an abundance of caution that some other language developers have lacked.

I am afraid I don't exactly agree. If you are publishing a library, for one, it's best not to include any vendored dependencies to begin with. But, ideally, no one should include vendored dependencies, whether a library or executable; those are things that can be fetched at build time. ("But, what if the dependencies disappear?" you may ask—this would be handled through the caching proxy in Russ' proposal.)

The additional tool you would need to build your software would be vgo.

I'm really excited about all this! No more GOPATH, no need for vendor directories; I think this is a positive step forward for Go, and package management in general. I'm also interested in seeing if there's any wider adoption of these ideas in the larger package management ecosphere.

One thing I've been mulling is whether this setup makes more sense in compiled languages than it would with dynamic languages. In the latter, your code base is your executable, so there may not be much difference between this and having a traditional vendor directory.

Of course, using semantic import versioning is something that can stand alone.

As I said: gofmt is not a pretty printer.

It may help if you decouple the goal (increased readability of code) and the action (application of a style to code). Pretty printers—and gofmt—apply a style to code. That is their only job; in a traditional pretty printer, you could configure a terrifyingly awful style of code, and it would apply it happily and correctly. The readability of that style is a subjective judgment to others, but this is in no way a concern of the pretty printer.

You may not like the style of code that Go uses. That is a perfectly valid viewpoint, and I encourage you to develop it as you see fit! It is also perfectly valid to criticize the style choice of having an undefined maximum line width.

The problem gofmt solves is not "how do we allow you to style Go code", but more specifically, the problem it solves is "how do we encourage the community to adhere to one style of code for Go?" And it is successful in that. It is obviously unsuccessful in applying a style that you find aesthetically pleasing—alas!

Also, I am afraid that I did not claim indent does not allow for a maximum line width! I said that indent (like other pretty printers) allowed you to define a style "with a specific indent level" and that "you could mix in your own preference for indent level".

A pretty printer, historically—going all the way back to indent—allowed the user to define a bespoke style guide, with a specific indent level, with one way to align braces, etc. You could implement GNU-style C code with indent; you could implement Allman-style C code; you could mix in your own preference for indent level.

As such, I think your complaints are misplaced. gofmt is not a pretty printer. It's designed to implement a single standard format—one which does not define a maximum line width—but nothing more.

I should note I am fine with lockfiles myself, so I can only speculate as to what RSC/others feel. It is fair to say that lockfiles are not Go—they would be another set of syntax that has nothing else to do with the language aside from their use in package management. So one might argue that it would be desirable to have a solution to Go's package management that was achieved using Go, which are what the module files are written in.

The proposal doesn't seek to guarantee reproducible builds; it merely seeks to enable them, through the methods they outline.

If you did want to guarantee reproducible builds with SHA-1 hashes, one way would be to introduce those into the .mod files they outlined. But that'd be clunky; it's much easier to reason about a version number than it is a digest hash.

Another method would be to introduce a lock file where those details are kept from plain view, but my sense was that they wanted a little more openness about the mechanism they were using than a lockfile provides (which is why .mod files use Go syntax, save the new "module" keyword they would introduce). After all, that's how dep works right now: they might as well just keep the lock file.

Cases where tags are being deleted, or worse—where accounts are deleted, then recreated with (other? same?) code, may be said to break the semver contract the library or binary author someone has with their users. As such, it may be seen as outside of scope for what they are seeking to accomplish with vgo.

I agree with you that the name itself (kanban) does not preclude one from having those regular times to get together.

People joke that nobody actually follows "Scrum" or "Kanban"; it's interpreted differently everywhere. I personally think that's a good thing, if it is done so in a directed fashion. (E.g.—don't estimate hours if that's not a useful thing to do for your team.)

Kanban and Scrum are themselves starting points, and perhaps a statement of where you align philosophically; in the end you are either using an agile process, where you kept what was useful or added what was needed, or you are in a muddle, where inefficient processes have crept in that are frustrating to the team.

It kinda depends!

If you have a small team, kanban is really great. It's easy to communicate what goals are; everyone's pretty aware of what is going on, development-wise, company-wise. You just need a good workflow, and that is what kanban is.

I like scrum more when you have a larger development team, because it's much harder to communicate what goals there are. People are less aware of what's going on in the platform, in the company, etc. The start and stop points in scrum are great times to reconnect and allow that communication to happen.

But, there are lots of contexts, and lots of ways to solve communication problems, so it's really difficult for me to tell you what you should or shouldn't be using. It's almost more important to just have a process that is clear to everyone so they know what their expectations should be.

I'm pretty sure I'm not confusing it with Rust!

That said, I don't think there's anything more I can say which can add to the conversation. I'm happy to allow what I have said to stand.

I love C. It's the language I used when I first "got" programming, and it's stuck with me, even though I don't use much professional use for it. I don't think you can count me among those who "love to bag" on it.

I don't think Go needs to be a like-for-exact-like analog of C to be a valid replacement. For many C programs, the memory management pattern they use is something that could be handled just as easily with GC, and done so in such a way as to lift a significant burden on the programmer.

I mentioned this in another comment, but definitely, if you need to manage your own memory—don't use Go. I must disagree that GC disallows Go as a replacement for the language. But I will respect your opinion if you think it does!