
Frequent versus infrequent developers, in languages and so on - simula67
https://utcc.utoronto.ca/~cks/space/blog/programming/FrequentVsInfrequentDevs
======
tzs
The thing that always get me when doing infrequent development is the
differences in how languages handle common tasks.

For instance, if I have a string and need to get its length. Do I call a
length() function passing the string? Or is a string an object and there is a
.length() member function? Or maybe its an object but the length is a
property?

Not a super big deal...but it is an annoying interruption when I realize I
don't remember which this particular language uses, and have to either go
Googling or start looking around the code to try to find an example. There are
a whole bunch of these.

Is it "elseif", "elif", "elsif", "else if", or sometime else?

Is the "for" loop like C, or does it take some kind of iterator object? Is it
"for" or "foreach"?

Null, nil, undef?

How to break an outer loop from within an inner loop? How to continue an outer
loop from within an inner loop?

Variable scope is a whole can of worms. In some to access a global from inside
a function you have to explicitly say you want the global. In others variables
in functions are global unless explicitly marked otherwise. Is the scope of a
variable declared in a nested block just its block, or the whole function? Is
it lexically scoped?

(The scope ones are particularly treacherous, because getting those wrong
often won't cause a compile or run-time error. You might just end up creating
a global when you thought you were creating a local, or changing a local when
you thought you were changing a global).

How do I do multi-line string literals? How do I concatenate strings? Parse
strings as numbers? Apply regular expressions to strings? Find substrings?

~~~
tomc1985
Classic polyglot problems :)

I really, really resent how every language seems to use the same concept but
slightly different wording. The elif/elsif/'else if' distinction is a
particularly annoying one. Same for null/None/nil

~~~
52-6F-62
And camelCase or not to camelcase:

    
    
        foreach(...)
        /* OR */
        forEach(...)

------
carlmr
I'm also an infrequent developer in many languages. I find this is a really
important article especially for new languages (Go, Rust, F#).

If your language has less adoption _most_ of your developers will be
infrequent developers. There won't be many companies purely building on this
one technology. You will have a lot of people dabbling in small side projects
to see whether the language fits their needs.

So it's important to have an easy way to update your whole toolchain or
install the toolchain easily whenever needed. E.g. updating my Rust toolchain
means runnning rustup update and updating VSCode (the RLS extension updates
automatically) cargo does everything automatically for builds with a very
simple project structure.

It's also best if you can avoid the need for specific tooling (I use VSCode as
my main editor anyway).

Another thing that should be thought of is that commands should do similar
things like in other languages in order to not surprise people unnecessarily.
If you want to go against the flow, you should have a good reason for it.

~~~
tonyedgecombe
I sometimes wonder if the tooling should be different for infrequent tasks. I
might update the build scripts for my desktop software just once or twice a
year, given the infrequent use it would make sense to use a GUI for this
rather than a text editor.

~~~
pjc50
Indeed - infrequent tasks should be low-friction, or infrequent turns into
"never".

~~~
carlmr
I'd say low friction tooling even helps a famous language. It's essential for
convincing the dabbler though.

------
segmondy
If you infrequently use a language and you are not planning on writing write-
once/throw-away code. Then don't use any library/framework. The overhead of
development today as I see it is not just the languages, but the cognitive
overhead of having to learn gigantic libraries and frameworks. I'm seeing
libraries/frameworks that are 20x-100x times as complex as the language. Shed
those bloat and free your mind. If the language is also fairly large,
constraint yourself and restrict yourself to a subset of the language. It's
not a must that one must use every feature of a language. The suffering of
developers that use an infrequent language is self inflicted. Hell, don't use
a language that you don't plan to use often unless it truly offers something
that other languages don't, which is rarely so.

~~~
jakevn
I also recommend avoiding unnecessary libs/frameworks for any code that you
expect to run for a long time without change.

I do this at work when writing small services in Go and it works out well.
Some have been running for three years now without being touched yet there is
no code rot and anyone can easily pick it up.

~~~
kstenerud
Absolutely this. Even the base dev environment is often an exercise in
madness. I loathe every new iOS version because Xcode will break my code in
new and interesting ways, requiring me to recheck every single library I've
developed to make sure they still compile (often they don't) and run (almost
always they don't).

And then, once I've got that headache handled, I update the version number,
type 'pod lib lint', and watch all the new and interesting ways that cocoapods
has broken things since I last used it.

Every 3rd party component you rely on is something that WILL break as soon as
you need to rebuild your project.

~~~
oblio
Not necessarily. People make fun of Java, but any half decent Java place,
especially the ones using Maven, won't have this problem.

Maven is quite verbose and it forces you to pin a lot of things down. Where it
doesn't outright force you, the general practices are to pin them regardless.

All the dependencies are in the same immutable Maven repo (or your own
proxy/cache), all the build tool extensions/plugins/etc. are there as well.
Java is generally very good at backwards compatibility, as is Maven itself.

So you can come back a few years later and do a :

mvn clean install

and things will work.

Of course, humans are fallible and things could still break due to various
factors, but in this sense the ecosystem helps you and either offers stability
already bundled it or guides you towards achieving it.

The downside: Maven is boring. Developers don't like boring :)

~~~
zamber
In JS world we got a package lockfile fairly recently. Locking your own
package.json version wasn't enough because packages have deps too.

Beforehand running npm install on newly checked out repos was a gamble,
especially given that we have packages for every minute "feature" like leftpad
(which is a horror story of its own).

------
ToJans
As an "infrequent developer", I usually piggyback on others to find best
practices, in case I have a bigger project. For the tiny ones it simply
doesn't matter.

The advantages of being an "infrequent developer" is that you grow an
intuition on how to get started with something completely new (cfr. Taleb's
anti-fragile), and that you learn a lot from cross-contamination.

Also, others might refer to frequent/infrequent developers as specialists and
generalists.

(Edit: reformulation of some Dunglish sentences)

~~~
GuB-42
I don't think that the "infrequent developers" they are talking about are
necessarily generalists.

For example, you may be an expert in Python and need to write a bit of C code
for now and then. It makes you a frequent Python dev and an infrequent C dev.

In fact, good generalists should be able to fit the "frequent developer"
pattern more closely for any language, at a reduced efficiency of course.
"infrequent developers" are more likely to be specialists that are out of
their specialty.

~~~
RobertRoberts
I find this issue with Node.js stuff. I can't count the times where I found
some software that looks great, would really help development, but then it's
based off of Node (which we don't use at all), and it requires 3 build tools
(none of which we use) and a pile of dependencies... :(

~~~
thriftwy
I think node of all things have no excuses. They're javascript all the way
down, why don't they have one command to download, build and deploy
everything, including any build tools that come to need? Instead they seem to
have a baroque setup

~~~
zamber
Well maintained packages do have that:

    
    
        npm install
        npm run (dev|build|deploy)
    

Poorly maintained ones don't have these run command set and instead rely on
pages upon pages of crap in README.md or do have a subset hacked together from
whatever the dev needed for their FUD-driven development workflow.

Edit: as an afterthought: maybe the infrequent developers are to blame for not
reading about what npm provides?

Edit2: another, I guess inexperienced, developer type I've seen in the wild is
"I did some jQuery 5y ago, React probably is as easy to pick up and spaghetti
out". For these: stick to what you know and don't play the hype game.

------
hkon
Web Development in recent years has made being an infrequent Web developer
unnecessarily complex, to the point that only frequent developers can perform
tasks

~~~
LandR
Absolutely, I tend to stay away from web development, but when I have to do it
it's just seems so unecessarily complex and painful.

~~~
danieltillett
Only if you are using the latest hipster JS framework. I write only vanilla JS
(infrequently) and things have been getting easier and easier as browsers (and
JS) advance.

~~~
thriftwy
jQuery seems to be an underrated gem. It's just as good as 10 years ago.

~~~
iopuy
It's not that it is underrated, the paradigm has moved past manually grabbing
bits of the DOM and updating them. Today, it is all about two way databinding.
You have a variable that lives in your controller and when he is updated so is
the DOM, automatically. I'm glad jQuery has been put to pasture because you
end up writing way less code which is way more maintainable.

------
alexandercrohde
I'd like to make explicit what the author made only implicit, that languages
are just one example of many. For me, setting up an apache server used to be a
task that took 2 hours, even when I was an engineer with half a decade of
experience (mostly windows).

I view this as a major failure. In fact, if your open source software takes
many hours to set up, it's costing hundreds of dollars of effort to learn the
unnecessary quirks every time.

(Example issues: permissions, conf file failing silently, server installing in
multiple distinct places leading to multiple installations, .htaccess ignored
due to config setting, config settings including directories of other config
settings, logs going to different places, OS security setting screwing up
server. )

~~~
liveoneggs
I like to defend apache a little bit here since you can actually do a lot with
no config file or even a very small one. :)

It's your crazy (I mean really crazy on debian/ubuntu) distro who made it so
scary.

[https://wiki.apache.org/httpd/Minimal_Config](https://wiki.apache.org/httpd/Minimal_Config)

------
foxhop
Some cool insights in there that I have not had the ability to articulate
myself but I have been feeling for maybe 5 or so years.

The biggest hurtle is that a "frequent dev" isn't always the best at
remembering the sum of everything needed and so it takes an "infrequent dev"
to write the docs and outline the helper tools and environment setup and
common gotchas.

Which if done for a certain amount of time the "infrequent dev" will gain
enough insight and mastery until they move into the "frequent dev" category.
As a result they will become blind to the pitfalls. They become the blind
"expert".

This is why I'm completely fascinated with teaching and knowledge transfer and
I feel like there is huge advances that can be done in this field.

Here is the catcher, this isn't just limited to computers or programming! In
fact it isn't even limited to spoken language.

This "blindness" to detail applies to all of reality!

If you want to read more checkout:
[http://johnsalvatier.org/blog/2017/reality-has-a-
surprising-...](http://johnsalvatier.org/blog/2017/reality-has-a-surprising-
amount-of-detail)

~~~
jt2190
> As a result [the now frequent developer] will become blind to the pitfalls.
> They become the blind "expert".

This is known as “The Curse of Knowledge”:

[https://en.m.wikipedia.org/wiki/Curse_of_knowledge](https://en.m.wikipedia.org/wiki/Curse_of_knowledge)

------
kstenerud
Another major source of frustration for infrequent developers is tools &
commands that cater to the 10% first and the 90% second (commands that require
a bunch of flags/configuration to be set for the 90% use case).

If your tools/frameworks don't do the 90% use case by default, you're doing it
wrong.

------
thriftwy
I was trying to be an infrequent user of OpenGL. People were totally not
understanding why amn't I "just writing a shader".

Modern 3D environment is hostile to infrequent developers now that drawing a
simple sphere suddently needs a page length blob of code. Or a "model".
Exported from "3D editor".

~~~
andrewmcwatters
I frequently imagine the terror that junior computer graphics devs encounter
when they realize you can't just "draw lines" in OpenGL.

~~~
thriftwy
...and there's no good reason why you can't, other than that in some iteration
of API, frequent developers could not imagine why would anybody need that.

~~~
iopuy
Isn't it because everything is represented as triangles? That is fundamental
to how openGL works I believe.

~~~
thriftwy
Everything can be represented in terms of everything else. It's a matter of
caring, or not caring, about convenience.

------
zimbatm
Go is actually a pretty good language for infrequent developers. There isn't
much to is so it's easy to pick it up again. The language is largely backward-
compatible so it's easy to pick the latest version and get up and compiling.
It also encourages low levels of abstractions which in my mind is the biggest
scourge against infrequent programmers. Now if only dependency management was
solved...

~~~
oddthink
I agree that Go makes infrequent use easy. That was part of why I went for
python over perl; I just didn't use perl often enough for it to stick in my
head. There are similar issues with Haskell, just because of all the many
libraries of abstractions and operators to memorize.

I still don't see why dependency management has everyone so up in arms for Go,
though. Especially for infrequent use, it's hard to beat just copying the lib
into your source tree and re-fetching from git every now and then.

~~~
oblio
> I still don't see why dependency management has everyone so up in arms for
> Go, though. Especially for infrequent use, it's hard to beat just copying
> the lib into your source tree and re-fetching from git every now and then.

That's not "dependency management", that's step 1 of any development
environment setup ever made. It's basically giving up on dependency management
and doing everything manually.

The correct way to do dependency management:

Have a config file with all the dependencies, clearly specified, including
versions.

Have a tool that has a standard command (mvn install, gradle build, npm
install, etc.) without parameters that brings the dependencies locally and
makes them available for your local environment.

For the standard command, depending on your environment and philosophy, either
fetch sources or fetch sources and compile them or fetch binaries.

To upgrade a library, change the version in the config file and re-run the
tool. To add a library, add the library info in the config file and re-run the
tool. To remote the library, remove the library info from the config file.

The cognitive overhead is much, much smaller with a well designed dependency
management setup. I just run the standard command and it does what I need, no
rummaging through Github repos to find what I need.

~~~
oddthink
Me, I long for the days when I could just download a tarball and be done. :-)

Seriously, as a mostly C++/python/R developer, maven was a PITA to set up for
experimenting with Java, and I still don't feel like I entirely understand the
npm/bower/yarn ecosystem. (Will they install globally or locally? What
permissions do I need? etc. etc.)

It's certainly not something that I can't learn, or something that's really
all that complex, but it's another barrier to just messing around with a new
project. It's better for the frequent-users than the infrequent.

As an infrequent user of Java/Javascript, I'm fine with just downloading a
tarball or cloning a single all-inclusive repo, and dealing with it being
harder to update or to push a change back to the source project.

Even in python, I just maintain a local global install and occasionally update
numpy/scipy manually. I'm not saying it's the best setup, but it's pretty easy
to download verson X.Y.Z, config/make/make install, and done.

~~~
oblio
I imagine the pain is setting the environment variables? This thing:
[https://maven.apache.org/install.html](https://maven.apache.org/install.html)

After that you run mvn install and things should just work. If not, the
project maintainers have bigger issues :)

------
logicallee
I don't find that this hits home.

Instead, I find that nobody on planet Earth is as disrespectful of your time
as programmers.

Imagine the slowest waiting room for some government office. You might be
stuck sitting there for 5 hours.

To a programmer, that's nothing! You'll be up and running the same afternoon.

They routinely send you off to RTFM, and if it will only take you two or three
days that's nothing. It's like programmers live in a magical land where time
is free, and they just don't understand why it's an issue for anyone.

It's about time as a resource.

~~~
cakebrewery
That's a very black and white point of view. There's lots of grey areas and
varying urgencies for problems. I'm sure most respectable programmers would
take care of matters as fast as they could, even if it isn't that urgent.

If it takes me an hour to take systems back up after things go bad during the
after-hours, it's not because I was purposely not doing my work. It's because
that's literally what took me to fix the problem.

Programmers aren't magicians and we certainly aren't out there to get you and
waste your time on purpose.

~~~
logicallee
Tangent

\--------

>Programmers aren't magicians

All right, so this part is tangential but after I posted my (GP) comment I
realized that in one sense programmers _are_ magicians. I had left the
following aspect out of my black-and-white comment:

(I hadn't considered that) some of the best programmers I know don't REALLY
read every word, the way you read my comment or I read yours. There's just no
way there's enough time, given the speed of use of totally new information in
totally new documentation that I've seen. It would be inhuman if they really
read every word.

I think they must skim and scroll and use magical ways of picking out just
what they need.

So when someone links a 500-page specification and tells you to "read it"
(which might take, say, two weeks of an hour a day to read, starting at the
first word and ending on the last -- perhaps they legitimately expect you to
"read" it in 1 minute 48 seconds, since that's how long it takes to "read" it.

Back on topic

\---------------

You've directed most of your response to how long it takes to do something.
But I had actually directed my comment at how long, when designing
(documentation/installation/whatever) you _expect_ people to spend doing
something.

With the tangent I just added, I realize that perhaps some of it is
misleading. If you direct someone to do something that takes 15 hours, that
doesn't mean you don't expect them to be done within 3-10 minutes. Because
programmers have magical abilities at times.

So it is far from as certain as I had said.

------
erokar
Elixir got a lot right with regards to the infrequent developers -- the
tooling and the package management is very nice and low-friction.

------
crdoconnor
Even for non-infrequent developers, an automated dev environment set up is
welcome.

------
voidhorse
As an infrequent developer, dabbler, and amateur in a vast number of
programming languages, I think a great deal of the difficulties that arise
when plodding around between different languages stem from a great number of
design decisions that prioritize elegance, abstraction, terseness, and library
economy over user experience. What results are a number of extremely powerful
language features that are useful to _everyone_ but remain inaccessible to
anyone uninitiated into the cabal of that language's practitioners.

While we're on the subject of cabals, I think Haskell is a paragon case of
this type of situation. Haskell is a phenomenal language and has the potential
to be incredibly expressive and useful when it comes to accomplishing tasks
that require one and done programmatic solutions. However, the language
ecosystem refuses to abandon a great number of practices that, while they are
historically and conceptually justified given its relation to category theory
and mathematics, will ensure haskell never sees the same degree of general
purpose adoption other languages do. For example, the following function is
one I came up with on the spot for illustrative purposes:

folds :: (b->b->b)->[b]->[b]

folds f x = map (\n -> foldl f n x) x

It's not immediately obvious what this does unless you have basic knowledge of
functional programming. Part of the difficultly stems from my choice of names,
but I'm sticking with the convention to use single letters in the majority of
cases that capture abstractions.

If I have obtained the prerequisite knowledge of haskell necessary to quickly
read the above simple function and tell what it does it's incredibly powerful
and easy reading, however, if I'm just picking things up for a small project
there is waaaaaay to much learning overhead for me to even consider using
haskell. Compare the haskell function with the same function expressed in
javascript:

function folds(f, items){ return items.map(x => items.reduce(f, item)); }

If you are familiar with haskell, the haskell version is probably faster to
read and comprehend. However, if you don't know haskell the js is probably
easier to come to grips with based on its lingual contents.

The there's common lisp, which _almost_ reads like English if it were't
drowning in parens and quote weirdness:

(defun folds (f items) (map 'list (lambda (item) (reduce f items :initial-
value item)) items))

The keyword arg goes a long way in helping the code read like a sentence,
which is a good thing. In fact, that's the sort of syntactic support of
semantics swift promotes using parameter labels:

func move(from start: Point, to end: Point)

x.move(from: x, to: y)

It's immediately clear to a caller what purpose each of the arguments of that
function serve.

Obviously this is a huge, complex issue, and I'm never going to do it justice
in a hackernews comment, but in general I think if library designers and
developers focused more on user experience and usability we'd have more
pleasant code to interact with. User experience isn't a concept reserved
strictly for graphical applications--any tool, no matter what it is, has a
user experience, and it's important to consider the user up front when we go
about designing technology.

In this respect I think Knuth's concept of literate programming has a lot of
worth, as it can cut down on research time tremendously and increase ease of
use--if the code itself can provide _all_ of the contextual information I
need, there's no reason for me to go scouring the documentation, which--
another issue--is frequently spotty, unclear or confusing, and on some
occasions incomplete.

~~~
oblio
I wish this had more upvotes. I agree. That's one of the reasons Python is so
popular, despite its many flaws. It's just easier to grok for newcomers. And
overall it is quite consistent and usable.

