Why Nostr? What is Njump?
2023-12-25 07:26:11

mleku on Nostr: i'm not surprised with the state of the programmer business what a bunch of cowboys ...

i'm not surprised with the state of the programmer business what a bunch of cowboys they all are, with absolutely zero formal training, but it's something i am gonna call out

what prompts this is trawling through 's code

yes i atted him because he should get some feedback and idgaf what anyone thinks of my opinion but it's based on a long time (since 1985) studying programming - no i didn't get a BSc or other but i'm not far from having that level of understanding of the subject

FIRST: stick to a simple, logical structure and don't mix metaphors up for no reason

this one number one reason why Go didn't have generics until last year, and seeing what a hash of it fiatjaf is making by using them willy-nilly for no particular reason when a type specific version takes less space for 2 or 3 implementations than the generic version by itself, because of the fact it's covering all those cases redundantly when they have specifics to them

don't go reaching for type parameters if you only need 3 different implementations of a functionality that only takes a few lines

why?

the very same principle applies to interfaces - some people think they give you organisation to your code but honestly if you are only making two implementations it's not really worth making an interface unless you anticipate making a third later, and it's not difficult to recognise them by the common function signatures

Ctrl-C Ctrl-V are your friends

learn how to use multiple carets

another example i found has a singleton for listeners while the rest of the relay type (in Khatru) is designed to be able to run multiple instances in one application

if one part of it doesn't fit the singleton pattern, don't use it with a component of the first part, what happens when someone naively tries to use your Relay type in Khatru with two independent relay instances as it seems like it's possible?

SECOND: when you use constant number codes, like the event kinds, make them into a type so they are compile time validated and make special ones if you want to use ranges as a typing for them

10000-19999 are metadata events
20000-29999 are ephemeral events

you make your code hard to read and brittle when in the future you change the definitions somehow, maybe add subtypes, for example, and then you are scratching around looking for references to a number that has no contextual meaning

THIRD: think about how the names of your packages look when you use them

nostr.Filter is a very poor context name - where is Filter defined?

oh yes, in NIP-01 - alongside events, for which Filters are search queries

FOURTH: don't mix up directions with comparison operations for no reason

a range boundary check should look like this:

element >= startOfRange || element < endOfRange

if you don't use a consistent ordering it's hard to read what you are saying

30000 <= evt.Kind && evt.Kind < 40000

is not as clear as

evt.Kind >= kind.ParameterizedReplaceableStart &&
evt.Kind < kind.ParameterizedReplaceableEnd

just combining that with the second point because this is what I see in Khatru

just because you can do this in math:

lower < x < upper

doesn't mean it makes sense to try and mimic this in code, it's clumsy and ugly as code without this funny abbreviated notation

the math notation leaves out the implicit separate context of these two comparisons, and flips the precedence of each side - it is neat to write it this way on a whiteboard but to implement it without ambiguity you are breaking the simplicity of the way that the machine does in, and the simplicity of how reading left to right you see "start ... end" which is lexicographic, not telegraphic like so much math notation is

the more people poison models with other models, the more difficult they are to learn and the more difficult they are to build as implementations for dumb, simple machines

computer programs are left to right, top to bottom, infixes are best kept consistent between related, ANDed pairs, names of Go packages are a useful place to put context, and don't reach for convenience tools to abstract a task that has only two or three related instances of, because it's just a waste of space, they are almost never identical across types except in very narrow ways even if they are similar (this is why Go has interfaces, and why generics have been reluctantly and in a very limited way added)

number one problem i see with much of the code i see from amateurs these days is they are just trying to rush things out and the whole thing ends up being spaghetti scripting nonsense with muddled names and poor structure

if you are a bitcoiner, you should understand that taking a little extra time is always better - measure twice, cut once

low time preference is doubly important for programming as it is for life in general, because every bit of code you write is gonna be someone else's problem in the future and you are racking up bad karma by writing shitty code
Author Public Key
npub1fjqqy4a93z5zsjwsfxqhc2764kvykfdyttvldkkkdera8dr78vhsmmleku