Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Brain Candy
May 18, 2006

tef posted:

that took longer to write than i thought it would and tbh i think i answered your question with a complete tangent :confused:

i wanted to answer with something more complete than good luck but tbh i don't think i've ever gotten it right the first time

Adbot
ADBOT LOVES YOU

Arcsech
Aug 5, 2008

tef posted:

let's try to make code easy to delete

step 0: don't write code

the number of lines of code doesn't tell us much on its own, but it's magnitude does 50, 500, 5,000, 10,000, 25,000 etc

a million line monolith is going to be more annoying than a ten thousand line one and significantly more time, money, and effort to replace.

this is facile, but generally the more code you have the harder it is to get rid of. saving one line of code saves absolutely nothing on its own.


step 1: copy paste more code

lines of code is a good approximation for the maintenance burden of code, but some lines of code cost more than others. it's sometimes to copy paste a couple of times before making code reusable.

when you avoid copy paste and go for code reuse, you introduce dependencies upon the library you have created. building reusable code is something thats easier to do in hindsight with a couple of examples of use in the code base, than foresight of ones you might want later.

it's much harder to delete code that's used in multiple places. it's much harder to delete code that's been reused, and the more it has been reused the more accidental and implicit behaviours will be relied on.


step 2: don't copy paste code

when you copy and paste something enough times maybe it's time to pull it up to a function. you know the code won't be going away any time soon: this is the "save me from my standard library" stuff, the "open a config file and give me a hash table", "delete this directory". a lot of this code is stateless, or at least the state they are relying on is things like environment variables. the stuff that ends up in a file called "util".

each of these things should generally stand on it's own give or take a couple of helper functions, so my advice is this sort of code should live in it's own file, rather than in one shared util file with a bunch of methods. make a util directory and stick them in there. a single file util will always grow until it is too big and yet too hard to move out, putting them in individual files makes it easier for them to grow as time goes along. some of the time this code is a wrapper around a third party library, or error handling code.

like the one shots, they are more about dealing with the computer than your application or business logics like file handles, or processes. stuff that is just going to be platform detail. other good examples of code you're not going to delete are lists, hash tables, and other collections. not because they often have very few methods, but because they don't grow in scope over time.


step 5: write more boilerplate

despite writing libraries to avoid copy pasting, with very simple interfaces we often end up writing a lot more code but we call it boilerplate as you usually change some of code in a different place each time, rather than the same bit over and over. it's like a more frustrating copy paste that's less obvious on how to lift out.

it is not that you are making code easy to delete, but you are consolidating something that is hard to delete and keeping it away from the rest of the code lest it be contaminated with business logic. stuff like network protocols, wire formats, parsing libraries, stuff where it's hard to interweave policy (what a program should do), and protocol (what a program can do) together without limiting the options.

like with copy paste, we are duplicating parts of code to avoid introducing dependencies, gain flexibility, and pay for it in verbosity. with these libraries, when you change your mind about what you want them to do, you can change one part and continue on. although the total lines of code never really goes down, it never really grows that quickly.

again, this is not an exercise in code reuse but trying keep the parts that change frequently from the parts that are relatively static. it's not so much deleting code but being able to replace parts of it without interruption.


step 5: don't write boilerplate

boilerplate works best when it's invoked for one off situations or to cater to all tastes, but sometimes you end up doing the same things over and over. despite urlib2 being flexible, it's still awful to use. you can layer on a library atop that handles the details for you. this isn't as uncommon as you'd think: requests is an successful example of providing a simpler interface for common tasks built over a complex library which can be assembled into shape (urllib3).

what we are doing is structuring our code into layers atop each other: starting at the bottom with the things that change the least (platform, runtime), and slowly adding a layer as we deal with a new concern, like protocol, or policy. i'm not advocating you go out and create a /protocol/ and a /policy/ directory but you do want to try and keep your util directory free of business logic, and build simpler interfaces out of wrappers around more flexible but verbose ones, and layer your software to manage change: things that don't need to change shouldn't rely on things that do.

it isn't a clean separation between "absolutely inflexible" "every project" and "this project" every time but it's a corner that's relatively expensive to cut in large code bases and one that's hard to fix later. layering is about not making your code easy to delete but making the most of what you have with the code you have got: the code you're going to change is the code you should focus on making it easy to delete, but a healthy system always has some redundancy.

it really isn't about code reuse.


step 6: write a big ball of mud

eventually you have to deal with your business logic somewhere, and once you've isolated the other parts of your code that are unlikely to change in scope you're actually going to have to make the program do something. remember that one big poop emoji vs 19 small tangled poop emoji? sometimes it's easier to delete one big mistake than try to delete 18 smaller mistakes one at a time.

this works well when your software is disposable but all of the moving parts look the same each time even if it does look a bit different. one off client sites, event web pages, homebrew content management systems. when you work in a factory line you don't really care about the lifecycle that far after release. i've seen mobile games companies operate around this principle: make a bunch of fire and forget demo games out of a shared toolkit and maintain the ones that people like. this often involves punching things into a template or framework, well the sort of framework that's a big ball of mud but it has handy gaps left for your things.

when you know what code is going to be deleted soon or easily replaced you can cut a lot more corners, especially when you've isolated the other parts. it isn't so much about code reuse but making it easy to prototype without too much investment.


step 7: don't write a big ball of mud

on the other hand, some of us are not so lucky and we must live with our mistakes for a lot longer. the problem with big balls of mud is that the short term gains are fantastic but eventually they become a very very big poop emoji. although the layers i've talked about above work with a very thin veneer of business logic atop a bunch of domain and platform specific things, this breaks down when you have an awful lot of business logic.

before we talked about layering state, logic, protocol, and policy above more simpler lumps of code, we change that and begin first with a shared layer. out software starts to resemble multiple processes sharing the shame file system. they don't care what filesystem it is as long as it as the files it expects to be there. another example is dependency injection, whereby a hidden namespace is populated with objects and hopefully most of the code to glue it together is handled for you.

other examples involve a twitter engineer wrote something about how they've introduced namespaces into their rpc toolkit, to let them control how the system in a similar means to how other people have used dns. the trick with having 18 small balls of mud is keeping the ways in which they depend on each other to simple contracts, although it's a rough ride even for well established things like filesystems.

uniformity of interface, like file systems or wsgi, is one thing that makes code easy to delete: there is code re-use in things like rack/wsgi/*, but what they enables you do is to pick and choose your http server and middleware and make it easy to change your mind and delete the code that made those choices.

it isn't so much that you can split your software into smaller parts, but a uniform interface makes it easier to delete the code you depend on and replace it. a uniform interface is not just how the system works, but how it breaks too. it can be better to have an honest interface (i might be slow) vs one that assumes (i will always return quickly) because computer networking is terrifying.


step 8: loose coupling

it isn't so much the size of your code base, or how cleanly you've split your software into layers, or how uniformly your components communicate and share with each other, these are just as much approximations of what it means to write code that is easy to delete. it is not having few dependencies, making them explicit or implicit, but how you isolate and compose these dependancies together, and how you can change them over time.

when your code is loosely coupled together, it's easy to delete it. a healthy code base has some verbosity, some redundancy, and just enough distance between the moving parts so you won't trap your hands in it.


tl;dr if you want to write code that is easy to delete, repeat yourself to avoid creating dependencies, but don't repeat yourself to manage them. layer your code apart to make it easy to change your mind and isolate the bits of your code that are fast moving and/or hard to write from each other. don't try to do all of these things at the same time. or just don't write so much code

I'm the two step 5s

Also the lack of steps 3 and 4

(cool post tho)

MeruFM
Jul 27, 2010
maybe it's metacommentary on bugs and boilerplate

the only languages i've had a "utils" library directory and not just a couple extra functions in a class or module are C and Golang and i'm trying to never write in those 2 ever again

tef
May 30, 2004

-> some l-system crap ->

Arcsech posted:

I'm the two step 5s

Also the lack of steps 3 and 4

(cool post tho)

those steps are only available for yospos gold™ members

tef
May 30, 2004

-> some l-system crap ->
but yeah those are artefacts of editing :shobon:

i've never been great with numbers. when i was much, much younger i would copy work down from the blackboard, misread a + for a -, and solve a completely different problem. i guess i was a programmer because i was told "well, it's not what i asked for but it is correct" before i started using computers.

but yeah, counting is hard for me. i don't tend to write bugs when i write things around iterators, or list operations, but if i write x+=1/ x++ / x-- anywhere odds are i've hosed something up

Bloody
Mar 3, 2013

MeruFM posted:

maybe it's metacommentary on bugs and boilerplate

the only languages i've had a "utils" library directory and not just a couple extra functions in a class or module are C and Golang and i'm trying to never write in those 2 ever again

idk I have a growing collection of c# extension methods I like

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Bloody posted:

idk I have a growing collection of c# extension methods I like

same and also swift operator overloads etc

a lot of that stuff feels like configuration. I know what I want NSDecimalNumbers to do most of the time in this app, so I specify that as implicit when using +/-*

but once I was in a panel with someone on the .net framework who got asked if X feature was ever going to be in the library because dude "kept having to implement it himself"

the framework guy looked kind of confused for a minute and asked "why have you had to implement this more than twice at most?"

MeruFM
Jul 27, 2010
going into new projects without explicitly loading in your bespoke utils file or even all your MUST-HAVE 3rd party libraries is a good way to re-evaluate the language holistically because you might have been doing something wrong the whole time

or the language is poo poo

Bloody
Mar 3, 2013

I can't name a single must have lib for c#

leftist heap
Feb 28, 2013

Fun Shoe

tef posted:


but yeah, counting is hard for me. i don't tend to write bugs when i write things around iterators, or list operations, but if i write x+=1/ x++ / x-- anywhere odds are i've hosed something up

because imperative code is fraught with peril

triple sulk
Sep 17, 2014



Bloody posted:

I can't name a single must have lib for c#

json.net

pseudorandom name
May 6, 2007

:siren:Shaggar:siren:

Jerry Bindle
May 16, 2003

rrrrrrrrrrrt posted:

because imperative code is fraught with peril

iawtp. java 8's functional interfaces decrease the number and severity of bugs i write AND they make me feel super smug. win win win.

Jerry Bindle
May 16, 2003

Bloody posted:

I can't name a single must have lib for c#

is this because everything is in the standard lib already?

FamDav
Mar 29, 2008
my most frequently used convenience lib in Java is a cli parser. I'm surprised there isn't a standard lib for that.

Vanadium
Jan 8, 2005

today i was allowed to add a utility methods to our stringutils.pas that adds a bunch of zeroes before a string

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde
:aaaaa:

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer
wow, i didn't think id ever see pascal being used for anything other than teaching high school computer science

brap
Aug 23, 2004

Grimey Drawer
kotlin is a good language. it makes android dev more tolerable.

Bloody
Mar 3, 2013

Barnyard Protein posted:

is this because everything is in the standard lib already?

yeah probs

Shaggar
Apr 26, 2006

Barnyard Protein posted:

is this because everything is in the standard lib already?

yes except for json.net which should be but isn't.

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde
oh is JavaScriptSerializer not good enough for you, ingrate?

Vanadium
Jan 8, 2005

Delphi 5 is a perfectly adequate development environment for Windows applications.

JewKiller 3000
Nov 28, 2006

by Lowtax

Vanadium posted:

Delphi 5 is a perfectly adequate development environment for me to poop on.

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

JewKiller 3000
Nov 28, 2006

by Lowtax
when the mumps programmer is talking poo poo about your programming language, you know you've hosed up bad

JawnV6
Jul 4, 2004

So hot ...
we're definitely in the wrong universe because pascal strings are Obviously better than c-strings

Soricidus
Oct 21, 2010
freedom-hating statist shill

FamDav posted:

my most frequently used convenience lib in Java is a cli parser. I'm surprised there isn't a standard lib for that.

it's because there's a bunch of other stuff you also probably need to do to run a thing, like set up the classpath and other jvm params and maybe identify the entrypoint to use

so in general people won't want to run it directly, and if you're providing a wrapper script anyway then you can just parse the command line args in that and have your java code read system properties

at least I think that's the reasoning idrk

Shaggar
Apr 26, 2006

Gazpacho posted:

oh is JavaScriptSerializer not good enough for you, ingrate?

from the JavaScriptSerializer docs

quote:

Json.NET should be used serialization and deserialization. Provides serialization and deserialization functionality for AJAX-enabled applications.

lol.

Emacs Headroom
Aug 2, 2003

Soricidus posted:

at least I think that's the reasoning idrk

probably originally it was "they can implement that themselves" and now it's more that java stuff gets used as a back-end language where people are using DI from a config or reading in parameters from the DB or whatever that works well with continuous deployment

bomb
Nov 3, 2005


Shaggar posted:

from the JavaScriptSerializer docs


lol.

:dukedog:

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

JewKiller 3000 posted:

when the mumps programmer is talking poo poo about your programming language, you know you've hosed up bad

Hey... I wrote some vb6 and xslt today. Xslt might be the worst God damned poo poo I've ever worked with.

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde

Shaggar posted:

from the JavaScriptSerializer docs


lol.
what a strange recommendation, when i've found JSS to work just as well without adding a dependency

Sapozhnik
Jan 2, 2005

Nap Ghost

LeftistMuslimObama posted:

Hey... I wrote some vb6 and xslt today. Xslt might be the worst God damned poo poo I've ever worked with.

:twitch:

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde
xsl-fo is worse

Jerry Bindle
May 16, 2003
i'm sure xsl fo makes sense for someone otherwise it wouldn't exist, right? i came across it while evaluating docbook and i couldn't make any fuckin sense of it.

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

Barnyard Protein posted:

i'm sure xsl fo makes sense for someone otherwise it wouldn't exist, right? i came across it while evaluating docbook and i couldn't make any fuckin sense of it.

assuming well-formed xml, you can really easily translate raw xml data into basic but presentable html+css. this, of course, naively assumes that anyone has every written xml that's not totally hare-brained. i could rant all day about the horrifying xml we use for our release note portal and the 20k line xslt-foreach soup used to turn it into something displayable, but that poo poo is proprietary and there's no way to convey the horror without breaking confidentiality.

comedyblissoption
Mar 15, 2006

xslt is essentially a programming language with its syntax based on xml

a programming language whose syntax is based on xml is basically a much more un-readable lisp

what im trying to say is xslt is some garbage poo poo

Soricidus
Oct 21, 2010
freedom-hating statist shill
I tried to use xslt to convert some xml to html once. then after about an hour I stopped tearing my hair out and used a real programming language instead.

Adbot
ADBOT LOVES YOU

b0lt
Apr 29, 2005

comedyblissoption posted:

a much more un-readable lisp

isn't that the point

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply