
Ask HN: What's the most simple thing you struggle to understand in programming? - betimd
Always there&#x27;s something you struggle to understand and you&#x27;re surprised w&#x2F; yourself
======
mcrider
Testing. I'm a very experienced programmer, and I have written plenty of unit
tests -- but I've never worked in a place with a good testing culture and I've
always struggled to develop a high level mentality of how and why I should be
testing my software. When should I write a test for something and what is the
best way to go about it? Does my code have to be more 'test friendly'? TDD
seems very appealing to me as a way to outline my software before I 'dive in'
but its hard for me to rationalize spending the extra time on building out the
testing framework.

~~~
ferdterguson
I struggle with this as well. I wouldn't say I'm very experienced, but I've
been around the block for awhile. I use TDD successfully, but I always have
problems with edge cases. I think of and try to guard against edge cases, but
I feel like testing in practice is really just preventing regressions for test
cases. Most the bugs I actually see in my software are of things I didn't
think about (obviously).

Sometimes I wonder if I should only write a test when something unexpected
happens (e.g. user has a bug report) instead of wasting time writing tests on
the front end for core features and obvious edge cases.

I mostly work on scientific software, btw.

------
Schwolop
Every asynchronous programming API ever created.

My program spawns and runs in the main thread. It calls the main function. If
it want it to run forever, I'll stick a while(1) loop in that function.

Now I want to have a particular thing go off and do some work in parallel with
that main loop, and when it's done, I want the next iteration of the main loop
to pick up on that fact.

Not once have I encountered a sane API for that use-case as easily expressed
as those sentences of prose above.

~~~
lod723
I can think of a couple trivial ways to express this in Erlang/Elixir. You
should take a look at them.

~~~
Schwolop
I concede I've not studied those languages yet - I do hear good things about
them though, so I'll take a look next suitable chance I get!

------
isuckatcoding
I have a few (mostly silly ones):

• Async/await in C# (I have a pretty good mental model and use it quite often
but honestly have never truly understood how it compares to c/C++ threads)

• async concepts in Java Android. Runnable, future, asynctask, threads
arrghhhh. My head hurts.

• multitable SQL joins (inner vs outer). Someone gave a pretty good
explanation in the comments.

• why do I need to use nginx for my web server? And what is a reverse proxy
anyways?

• how come I can use any smpt client or something like mailchimp or sendgrid
to send an email and specify any email in the "from" field. Can't I pose as
someone I'm not?

~~~
imwally
I can answer your question on nginx. There are multiple reasons why you would
want to use it as the entry point to what you want to serve. As a standalone
web sever if offers a plethora of configuration settings that allow you to
specify how you want to handle the incoming requests.

TLS is one aspect that comes to mind. A certificate and key is not enough. You
must specify the correct parameters such as the cipher suites, DH parameters,
HSTS, and more if you want a secure connection.

You mentioned a reverse proxy. This is the other aspect that comes to mind.
Servers are bound to ports, like 80 and 443. How do you serve multiple
applications on the same port on the same server? A proxy. More specifically a
reverse proxy. It sits between the client and the services as a middleman to
handle and direct requests. Multiple services can run on different ports but
the reverse proxy allows for a single point of entry, such as HTTP requests on
port 80. The proxy will inspect the request and based on certain values, say a
hostname, it will be directed to the correct service. Otherwise you would have
to tell your clients to specify the port the service is running on, ex:
[http://mydomain.com:8080](http://mydomain.com:8080)

~~~
mcrider
This is incredibly useful for performance. If the user is requesting an image
or other static asset, your reverse proxy can detect this and skip making a
request to the actual application. Likewise if you want to go to some sort of
cache based on the type of request.

------
zumu
Basic OOP. What do I make a class?

Functional programming in general clicks with me, however.

~~~
jtolmar
Values that get passed around together go together into a structure, making
code that deals with them more succinct. The functions that care about that
sort of structure go into a class, not because this is inherently better, but
because following this convention solves the "where did I put that function?"
problem for a wider variety of cases than most other conventions.

Values that are supposed to change at the same time (or care about each other,
or would otherwise need to be in sync somehow) would normally have to be
passed around together to maintain that property, but this can lead to errors
because it's the sort of thing people forget. If you put them into a structure
together then hide the ability to actually use them behind functions that
maintain the property you want, you prevent that sort of error.

~~~
zumu
> The functions that care about that sort of structure go into a class, not
> because this is inherently better but because following this convention
> solves the "where did I put that function?"

So you attach functions that operate on a data structure to the data structure
solely for organizational purposes?

Seems almost identical to defining a record and module of functions that
operate on said record. Except that in OO, by attaching the functions you
create new copies of each function with a bound reference to the instance of
data structure. Are there other advantages?

~~~
jtolmar
> Seems almost identical to defining a record and module of functions that
> operate on said record.

OO is mostly that plus the ability to forbid people from using the record
without using the functions.

> by attaching the functions you create new copies of each function with a
> bound reference to the instance of data structure.

Yes, but the compiler won't actually copy the function, it'll implement it as
something closer to the record plus modules approach (for example a record
plus a pointer to the module). This might not be true if you're trying to use
OO in a functional language.

~~~
zumu
Thanks for taking the time to give these detailed responses.

One more question (restated from below):

Coming from FP where immutability is sacrosanct, I often wind up writing
classes that are largely immutable, which doesn't seem like correct OOP. Is
there a proper way to marry immutable data structures with OO?

~~~
jtolmar
The object-oriented world has been moving towards more immutable and mostly-
immutable classes. This is sometimes awkward with large classes, so people use
the builder pattern to get around it. (It's a case of languages having not
caught up with practices.)

------
rrggrr
Lambdas. Monads. Inner & outer joins. Tensorflow.

~~~
dmach
I think of inner & outer joins like AND & OR. An inner join will only return a
result if the value of key that the join is on exists in both tables. An outer
join will give rows for all key values in both tables even if values are only
in one or the other table with null results in the row for the columns of the
opposite table. Inner joins are the default as you are generally interested in
what matches between tables but you have the option of outer if you need to
get the full messy picture or if you are doing ETL and want to ensure no
badish records are missing.

~~~
isuckatcoding
My goodness. Thank you for this explanation. I've always googled the concept
and forgot about it but this sticks.

------
caseymarquis
Lisp continuations! From the name I swear they're just backing up the current
scoped state and returning to it, but I've yet to find an example that clearly
shows what's going on in what order. To be fair I haven't actually used lisp,
just read through the beginnings of the scheme spec.

~~~
Johnny_Brahms
Start with escape continuations (using call/cc to make an early escape) and
work onwards from there.

It didn't click for me until the third tutorial, and there are lots of
resources out there

------
vacri
More 'ops' than 'programming', but: Email.

Email is a real 'devil in the details' thing. Anyone can follow a web how-to
(when they're not stale) and set up a basic server, but it's crazy complex to
understand properly. It's also weirdly both old-as-rocks and at the same time
constantly changing (eg: deliverability scores, major vendors changing how
they accept things, etc). Aliasing and mail flow and MUAs vs MTAs and mailbox
formats and multiple arcane config files and blacklisting and DKIM and MX
records (and TXT records) and etc etc etc... and if you're really crazy, GPG-
signing. I've always got enough to just scrape by, but never actually
comfortably grokked it all at any point. So many disparate spinning plates...

------
cmehdy
I'll risk looking like an idiot: Figuring out the architecture and different
combinations of languages in modern web dev, and what a good solution choice
is for a given need/problem.

From the basic options to set up a server, code deployment and maintenance
using Github, nodejs and similar JS-everything, XML/JSON, how much of what
should CSS take care of, DB access (and which one), structure of a modern
webpage, CDNs, structure scaling, and requirements for browsers and
platforms..

I used to use JS to change some text in html pages ftp'd to a server running a
basic apache. Looking at it now is a big slap in the face. Nodeschool helps a
bit, but it's all pretty blurred still. The more I dig, the deeper it gets
without a sense of direction.

~~~
Johnny_Brahms
Every time I try web development I feel like I have lost every sense of
control. It feels like abstractions upon abstractions that are governed by
conventions hidden from me, and every time I step outside them things break in
weird undocumented ways. And whenever I try any web frontend stuff it feels
like I have taken everything I hate with UI development, squared.

I have however embraced the magic of "no idea how things work under the hood"
and now build things for our intranet in seaside.

I am however a bitter old fart that envy people that can throw beautiful web
pages together in 25 minutes. Most of my work these days are management and
scheme coding,so that is probably.the way it is going to stay.

------
stefanpie
I just figured this out today but the pass by reference and pass by value
thing in Python. I understood that Python variables in the same scope can
refer to the same memory object, just the name is different. However when you
pass the into classes and fuctions, mutable types are pass by reference and
imutable types are pass by value. I just came to this realization after
spending hours looking at gui code trying to figure out why some variables
form a parent object we're not changing when passed into another class and
modified.

~~~
zurn
Everything is passed by reference in Python. But there are no methods to
modify values of immutable objects like strings or numbers.

(Variable assignment, as in foo = bar, always just assigns a reference, it
doesn't mutate objects or copy values.)

------
jtolmar
C++ pointer/reference syntax.

I understand the concepts, and pointers make perfect sense to me when I'm
programming in assembly, but whenever I look at them in C++ it's like & and *
mean the opposite things when used in variable declarations from what they
mean when used as an operator and yet another thing when used to declare
arguments. But I've never seen anyone else acknowledge that they're weird so I
feel like there's some sort of logical connection I'm missing.

~~~
samblr
Second this.

------
homosaphien
This probably is ignorant, But I don't get why we need interface in java/c#.
Why can't a base class with abstract methods be sufficient for that use case?

~~~
Jtsummers
It allows you to compose types and avoid the issues (complications not
necessarily problems) of multiple inheritance.

For example, where in your hierarchy do you stick the AbstractSerializable
class? If it's an interface like ISerializable you just implement it at
whatever level you're at.

With multiple inheritance you don't need interfaces because you can just
inherit from multiple base classes.

------
anothathrowaway
Where to start, and what to make.

------
genkimind
Dependency injection.

~~~
nlawalker
I strongly suggest "Dependency Injection in .NET" by Mark Seemann, regardless
of whether or not you're a .NET dev (if you understand basic OOP, C# syntax is
generally pretty easy to pick up on).

Really the main reason it's "... in .NET" is because there are a few sections
in the book that explain how to achieve DI in some common .NET frameworks,
which you are free to ignore. The first half of the book is a fantastic
explanation of both the problem that DI solves, and how DI solves it.

I felt like I didn't really understand OOP and the real point of object-
oriented design patterns until I read it.

------
jdmoreira
Clean code.

What makes some code better than other code? The understanding of this is
probably a lifelong pursuit.

------
RUG3Y
I guess this isn't "simple" but I'm in a place now where I'm responsible for
"all-the-things" and I'm having a difficult time understanding what makes a
good architecture for a web app.

------
FLGMwt
Right now, Reactive Streams and RxJS in particular, especially around errors.

------
somethingsimple
call/cc. I understand what it is and what it does, but I don't understand how
it's actually used in a practical way (all I've ever seen are synthetic/too
abstract examples).

~~~
Johnny_Brahms
Check out srfi-125 and the make-coroutine-generator:
[https://srfi.schemers.org/srfi-121/srfi-121.html](https://srfi.schemers.org/srfi-121/srfi-121.html)

That is implemented using call/cc, and even though it is mostly a convenience
function, it shows how call/cc can be used.

It should be noted though, that call/cc is extremely expensive and prone to
memory leaks. If you are using racket , scheme48 or guile you should use their
delimited continuations instead.

------
samblr
Initial setup to get started with programming and run a hello world kind of
thing.

With things we do outside of an IDE.

Language specific functions and behaviour.

------
imwally
How to overcome imposter syndrome.

------
drdeadringer
Abstraction.

------
mhh__
Why C++ doesn't have modules yet ;)

------
thdn
Pointers

~~~
imwally
A pointer is a value. That value is a memory location. That memory location
should contain a value too. The value the pointer points to.

Pointers start to make more sense when you take the comment above about pass
by value vs. pass by reference into consideration.

There's a great gif about this where a cup is used as the argument to a
fillCup() function.

[https://blog.penjee.com/wp-content/uploads/2015/02/pass-
by-r...](https://blog.penjee.com/wp-content/uploads/2015/02/pass-by-reference-
vs-pass-by-value-animation.gif)

In pass by value, a second cup is created just for that function and then
filled with liquid. The original cup is left untouched. With pass by
reference, the original cup is being filled, not a duplicate of it. How does
the function know to fill the original instead of creating a duplicate for its
own scope? A pointer.

When calling a function with arguments a few things are happening behind the
scenes. Memory allocation for these arguments is one of those things. This is
where the stack and heap come into play. Memory allocated for the function
call is considered the stack while memory for the entire program (think global
variables) is the heap. Things get even more interesting when you look into
stack frames and step through the execution of a program with a debugger like
gdb or lldb. You'll start to understand how recursion works.

Pointers are also used in certain data structures like a linked list. They
allow you to easily keep a chain of values that contain data and a pointer
which points to the next data, otherwise known as a linked list, or binary
tree, or many other names depending on the structure.

I'm replying on my phone so I apologize in advanced for the formatting. Hope
this helps.

------
aphextron
Haskell.

