Hacker News new | past | comments | ask | show | jobs | submit login

Whenever I hear "Socratic dialog", I reach for my revolver. Is there any other form of teaching so irritating and patronising? You might have a brilliant store of insight to impart, but if you insist on trying to do so via a twee, affected and unbelievable conversation with a Mary Sue wise professor, I'm going to write you off as insufferable before the fawning moron you have as proxy for your audience utters their first "Oh, wow! So you mean that straw-man you just put in my mouth isn't true?"



Could it really be that bad?

    I followed the link, it's so much worse.
Worse?

    Yes.
How much worse?

    So much.


How much?


Much worse


So much!

Egad you’re right Socrates!

PS: Sherlock Holmes was based partly on Socrates


The only thing more annoying is when people ape Why's (Poignant) Guide to Ruby and you have to follow the adventures of some tedious otter as it meets the rabbit people who ultimately explain pointers in a way which takes a thousand too many words.


Have you ever come across anything that explains why pointers are hard for some people?

I find it difficult to explain pointers to people because I don't understand what they are missing. I could use some help understanding their lack of understanding.

When they don't get "indirect reference to the address of a data structure or object in memory", I'm stuck on how to proceed. Pointing people to the very elegant treatment of this topic in the old K&R doesn't always do the trick. Somehow.


> When they don't get "indirect reference to the address of a data structure or object in memory", I'm stuck on how to proceed

That's because to them, _everything_ is an "indirect reference". Every time they use a variable it feels like an indirect reference, so what the hell is so special about a pointer?

Took me an intro class in computer systems before I could really understand pointers, because nobody wanted to bite the bullet and teach me about the stack. Pointers don't make sense if you don't know that the stack and the heap exist.


> Pointers don't make sense if you don't know that the stack and the heap exist.

Now, THAT's interesting...


What I see is two types of people, people that understand basic computer architecture and those that don't.

The C memory model and pointers come easily to those that understand what a memory address is and how long one is on their favorite architecture.

In my experience, people without this knowledge might understand how to use pointers, but not really why they are. And the answer to the "why pointers" question is _not_ "Imagine you want a function that swaps two parameters" nor "because they you would have to copy structs all of the time"


Honestly, I think the answer to "Pointers, WTF?" is simply describing how data is stored in memory. This concept is important not only for how pointers work but even how data is stored on a hard drive. You don't have to go into great detail. All you need to do is say this is a number, it takes n number of bytes to store (Most people who haven't been living under a rock have a knowledge of bytes, just explain it to them using their phone data plan). Draw a picture showing one set of bytes next to another. Write 0x100 at the first set, 0x100 + number of bytes you put in at the second.

Then, it is simply "0x100 is what's in a pointer".

I don't think that is complex (it shouldn't be). It is intuitive to most. Seeing a picture should solidify things. And finally, it is semi-accurate to how a pointer actually works. Getting into the mud of "A pointer is like a reference in a scholarly paper" or "A pointer is like a link on a webpage" simply confuses what a pointer actually is.

And, if that isn't enough, simply write a program using pointers and print out pointer values. It really is a crazy simple concept that doesn't need a whole lot of metaphors.

What's worse is when the authors of "what's a pointer" don't know what a pointer is themselves. I've seen that far too often.


I agree completely.

The correct simplification to make is not explaining virtual memory or MMIO. Pretend we have nicely-acting linear address space. The computer is a mail-sorting octopus and when it runs out of hands it only has mailboxes to put things in. Still not a great analogy.

Everytime I start to hear "addresses are like real addresses, ways to find where something lives" I know it will be an explanation for people that want to understand them well enough to not use them.

It is also rough because some people try to explain pointers with Java. AP CompSci in american high schools is happy to try to explain pointers to Java users, it's not surprising people have a rough time!


> Pretend we have nicely-acting linear address space.

I feel like the prevalence of linked lists in discussions wrt pointers is proof that nobody is understanding these analogies.

At least there should be some regular pushback from beginners who conceptualize the linear addy space and say, "Hey, what is the distance between this item and the one I just inserted into the list?" Or, "Does it take time to jump around among all these links?"

Edit: And, "How does the time moving among links compare to the time iterating over an array?"


Honestly, I think the answer to "Pointers, WTF?" is simply describing how data is stored in memory.

So is this not how it's explained nowadays? No wonder there's people that doesn't get it. So many concepts, not only about programming, I have learnt in my life first with "this is what happens", then with the precise definition...


I think part of the problem is that many popular languages now default to using two very different behaviours for elementary tasks like passing variables or parameters around, depending on whether the variable is a "reference type" or a "value type". Simple things like numbers have value semantics. Objects and whatever else works a bit like an object in your language have reference semantics. If you want a reference to a simple value like a number, you box it so the basic type is now wrapped in an object, or something equivalent. Maybe that's even a semi-automatic process that is done for you in some cases. Anyway, that's just how variables work, and the idea that in principle you could have a value of any data type or a reference to any data type doesn't even occur to someone who has learned this way.

Then you get to data structures, and you're trying to explain the fundamental difference between dense, buffer/array-like structures and sparse, graph/pointer-like structures, and there might be no concept of an underlying memory model where the difference is clear.

This has always seemed like a horribly ambiguous and inconsistent mental model to me, and there must surely have been quite a few bugs caused by programmers not clearly understanding the differences between value and reference semantics and exactly when each applies in their chosen language(s). And yet for reasons I can't understand, many of the popular languages today do seem to follow something close to this model.


Assembly was fun, but I understand it would be cruel and not so useful to teach it to today students, but I can't figure out how someone can learn some concepts whithout the "memory is an array" model.

My favourite book at college about (the real) data structures started building the array, even if it was already implemented in the language.


I think learning some assembly is essential for any student that wants to use a low level programming language. It's a good way to learn not only about pointers but also the stack, registers, etc. I don't mean they need to be able to manually create a full program in assembly but doing simple exercises can be enlightening on their own.

Of course you also have to mention that even assembly is an abstraction. Memory isn't really a big array, cpus have caches and all that jazz. This matters when writing performant algorithms.


It is not necessary to go right down to assembly level to introduce these concepts, though. Just a language with a transparent memory storage model and explicit reference vs value distinction is enough. C is still the lingua franca of the programming world and IMHO it is useful to know basic C for these reasons even if you rarely write much code in it.


At least in my college days, it didn't seem like it. It felt like a lot of professors jumped straight to the analogies rather than taking a second to just draw things out.

edit that being said, after your comment I went out and looked up "What's a pointer" to see how it is taught. Pretty much every web page I hit does exactly what I described, so, awesome :).


Pointers now belong in a weird territory where you can be a perfectly fine programmer without ever having explicitly used a pointer. So most people who have worked with pointers either did it because they cut their teeth on it in school or needed to use C/C++ for hobby/work.


I've taught pointers to multiple people who struggled. C makes pointers difficult by having some syntax oddities that seem to mainly be intended to save a few characters of source code. The biggest trouble is that C often gives you a free ampersand ("&") when you need one.

Consider that p=f and p=&f both can be used to assign the address of a function f to a function pointer p. To a beginner it could look like p takes either type, or that the & really serves no purpose.

Consider these four lines of code:

    char *p1   =  "hello";
    char  a1[] =  "hello";
    char *p2   = &"hello";
    char  a2[] = &"hello"; // only this one is junk
For the assignment to p1 you get an implied & effectively added into your source code. It may be convenient, but it leads beginners astray with muddled thinking about types.

A little-known limitation of C is that you can't really pass arrays to functions. You get that free & again, meaning that you end up passing a pointer. We should need to do printf(&"hello world\n") but that would be inconvenient, so instead we have a language that appears to behave in inconsistent ways.

Array dimensionality plays a role here. A real X by Y array, with two dimensions X and Y, can syntactically be used in the same way as an array of pointers to arrays. After being passed to a function, the sizeof operator breaks for both (since now you have just a pointer) but the 2-dimensional nature is lost for only one of the styles.

Even the bracket notation is trouble. It is why cute stuff like 4["foo"] can be used to mean 0. That seems harmless enough, but the oddities extend well beyond syntax that nobody should be using. Other issues are pointer arithmetic being surprising and some people being surprised that pointers have types beyond simply "pointer".

I find that the best hope for a clear understanding is to constantly remind the student of the above, right from the start. This is slower going, but it prevents serious misunderstandings from persisting and building on each other.


So ... the problem with understanding pointers is C syntax? That sounds ... plausible.


Yes, I know about the off-by-one. I can't edit it now.

3["foo"]


I didn't understand pointers until I understood all variables were all a certain size and stored in a specific place in memory. Which I didn't really understand until I'd been programming for a while.


I don't think I understand pointers. Maybe we can help each other. My mental model of pointers is a map: lat/long identify the object of interest (the local coffee shop), but not what is interesting about it (their menu and hours).


When learning abstract programming concepts, I think it is important to have some practice operationalizing that knowledge. Precise definitions are important, but by themselves aren't enough because it doesn't guarantee you'll understand the implications of that definition.

Analogies seem like they help, but often lead to error when you reach a point where the analogy is stretched to far.

To see if you understand pointers, try exercise #3 here: https://www.joelonsoftware.com/2005/12/29/test-yourself/ . Just step through the code in your head, and then use your mouse to highlight the text in the box below it. Hopefully that helps you to get started in the right direction.


Hmm, your mental model possibly could use a tweak. Yes, a pointer is like a map. It tells you how to get to the thing but it isn't the thing. It is a reference point, a pointer to the thing. The thing that it points to might be a library, a museum or a place to pick up more maps. Irrespective, the thing to remember is it something to takes you there it is not the place.

You may also pass around the map to your friend in effect showing them how to get to the place, without possibly even having seen the place yourself.

And if you are a bad person, you could share maps that lead to dead end dumps


Hmmm. Interesting. I'm going to have to roll that around in my brain for a day-or-so to see if I can make that compute for me. (Which means I may be back here in a day to check back in!)

Maybe it's because I started in assembly language, but to me, data exists at an address in memory. Or starting at an address in memory. That data might be on integer, a float, a character, the beginning of a string, the head of an object/data-struct, OR an address of data somewhere else (which may be any of the above again). Pointers, to me, are simply an address of an address of a data thingie.

Why would you want to use these? One reason is that pushing large data-objects back-and-forth across function calls is expensive (pointers are usually just 32-bit or 64-bit numbers). Another is that one can have a pool of resources (think polygons in a large 3d scene), that are marked "used" or "unused". This gets a large performance boost from not having to do the whole malloc/free thing on lots and lots of small objects. Another (this is related to the first), the function can receive a data-structure, and modify it (side effects!) without having to copy it and pass the modified copy back.

I'm intrigued by your mental model. Having not thought it through - it seems as if lat/long is appropriate, but maybe even the idea that it is a coffee shop that you will find there is undetermined. (That is: the fact that it is a coffee shop is one of the things that is interesting about it, like the menu and hours. Again, I need to think this through).

Thanks!


So, I'd like to point out that some of your assumptions about performance may no longer be true. Optimizing compilers are REALLY good now-a-days, but one thing you can do to really trip them up is introduce a bunch of pointers.

It takes very little time to allocate space on the stack and not too much time to copy data from one register to the stack or another register. Very often, if you don't use pointers, the compiler will take your data and throw it into a register and reference that register directly in the method you just called (free).

Now, if you are going to allocate on the heap anyways, then sure, it makes sense to start looking into things like object pools. But that wouldn't be a baseline I'd start with.

Objects with a few ints or longs in them can be passed around free or nearly free with modern compilers.

Here is an example of that concept in action

https://godbolt.org/z/G6r0X6

You really don't get much faster than that.


Note that your model is also an abstraction. Modern architectures move data around between a variety of memory locations (and store it in multiple locations) which are all addressed via the pointer ‘transparently’. It’s not really a memory address anymore and hasn’t been for some time.

That’s not to say your model is bad, it’s the same one I have in my head. But it’s no more ‘real’ than coordinates or library cards or P.O. Box number.


Isn't it still the model that is exposed to the programmer, even though internally all kinds of things are going on to make it all go faster? For example, nowadays many/most processors have separate caches for instructions and data, meaning that they strictly speaking don't conform to the Von Neumann architecture. But the programmer doesn't see the different caches, ideally doesn't even see the cache at all.

It's like the execution model, where processors do a lot of out-of-order execution, but do a lot of work so they can present a model to the programmer as if everything happens in-order.


That depends on the architecture, the os, the compiler & the runtime.

Part of the confusion in teaching pointers (I think) is that we act like they are a lower level abstraction than they are (because they used to be). On modern commodity hardware with mainstream languages pointers have very little to do with memory addresses. Accessing memory via them will not happen in constant time, they may or may not perform better when used, even if the language doesn’t copy them on use the OS or processor might etc.

I just find when I try to teach people the memory address model of pointers there are so many exceptions that the model isn’t helpful. Like the OP I struggle with an alternative.


Agreed. But it depends on the computer. On the old vectorized machines like the Cray Y-MP, it was always just a mental model. On even modern embedded systems w/o virtual memory, it's pretty close to being really real.

(I find that the P.O. Box number thing to be a useful general abstraction for me, but it doesn't seem to convey the concept well to people who are confused. Hence the intent behind the intent of my question: "Does anyone know how to effectively teach pointers?")


I'm semi-convinced the reason many people have a problem understanding pointers is because C makes them needlessly confusing. Or at least in my experience people struggle more with C pointers than they do with learning assembly.


FWIW I struggled with pointers in Pascal before struggling with pointers in C.

I do think one area that causes issues with C is any sort of string manipulation requires a reasonable understanding of pointers, and most introductory programming classes tend to focus on things like string manipulation.


To use that analogy: The coordinates tell you where the restaurant is (pointer), but you still have to go to the actual restaurant to get some food (data).


A better analogy would be the coffee shop (as a physical building) versus the street address of the building. If you want to do anything in the coffee shop you have to go there, the pointer (address) tells you where to go.

And just like real world street addresses, you can't make blind assumptions about pointers.

The value may make logical sense, or it may be completely meaningless and you require direction from someone to find it.

You can't just write down a random address and expect a building to exist at it.

You can hold onto the street address for a coffee shop, put it in a notebook, then one day go to the address to find that the coffee shop was torn down and the street address is invalid.


Do you know what an array is?

If so, then you can think of memory like as a giant array of bytes and a pointer as the index in that array.

Hurray, you now understand pointers :)

Don't muddy it up beyond that.


There are different notions of what an array is.

In some languages, an array is dynamic. You don't have to declare the size. You can just put stuff at any index you desire, and the array will grow as needed. For example, just set foo[1000000000] to 42. That might take a gigabyte or more of RAM, or just address space, or neither.

The indexes might not be required to be numbers. Some languages allow strings or even arbitrary objects as indexes. You could index by a JPEG or a device handle or a float.

The values might not be required to have a consistent type. Some languages would let you throw random different-sized things into an array.


* In some languages, an array is dynamic.

Doesn't really matter for the general concept.

* The indexes might not be required to be numbers.

In most of those languages, that data type is called a map, dictionary, or even associative array. I've seen few languages actually use the phrase "associative array" primarily because it is confusing.

But, to be clear, I'm talking about the common "array" definition. That is, a value indexed by a number.

* The values might not be required to have a consistent type.

Yet, I was clear in saying "a byte array". A pointer points to the byte address and doesn't care about what type is ultimately represented. That is why void pointers are a thing. It is a language level action to reinterpret the pointer into a concrete object type.

But again, that confuses the issue of what pointers are with concerns like memory layout and object sizes. To be clear, you don't need to those concepts to understand what a pointer is.

* Some languages would let you throw random different-sized things into an array.

I specifically said "array of bytes". It does not matter what a language lets you do. A pointer is the head of a byte address and the interpretation of that byte and subsequent bytes are a language level concern. All unneeded information for a discussion on "what is a pointer".


Add to that: you store the index in another cell in the array.


I started to understand pointers easily because I was told variables were mailboxes that held data/stuff (like numbers). A pointer was just another variable (mailbox) that held the address of a different mailbox.

There you have it. Pointers in two sentences.

The "indirect reference" yada yada is too technical, requiring your audience to already understand those terms. It also ends up leading to cyclical definitions if you try going too much into detail (because data structures can hold pointers).


> I find it difficult to explain pointers to people because I don't understand what they are missing. I could use some help understanding their lack of understanding.

Maybe they don't know what they are missing.

When I was learning C two decades ago, my first thought was that pointers were solving no real problems, and that I will be able to do without them. Then I had to implement the "swap" function.


I feel an urge to tell somebody a monadic astronaut burrito story.


it's not for you.


Is there any other form of teaching so irritating and patronising?

It's only patronizing to people who are motivated self-learners, such as you. To people who are unmotivated and/or struggling with the concepts (such as high school students), it works better than most other styles I've tried.

I've spent a lot of time tutoring high school and elementary school students. Many of them are so frustrated that they just want you to give them the answer. But then if you do they write it down and declare "problem solved." In the long run, students who continually weasel the answers out of their tutors end up far, far behind those who work with a Socratic teacher and are persuaded to try to think of the answers for themselves.


The problem here is that this is a piece of opinion, presented as a lesson, implying that the author is the master and the readers the apprentices.


Can author imply anything else? If reader knows better, why reader reads at all? Actually, before reading nobody can know what's in the writing, so author is naturally more knowledgeable.

Lesson is just a transfer of knowledge - which may turn out to be useless, but only after the fact.


Can author imply anything else?

Of course.

If reader knows better, why reader reads at all?

Because the reading, as you yourself said:

...may turn out to be useless, but only after the fact.

I don't find it wrong, just irrelevant.

Oh, and using "data structure" to mean a "struct" is annoying for us old farts that learned the standard meaning, it's causing people to get confused. Actually, since classes are a data structures (in the old sense), the very title sounds like nonsense.

Nothing too bad, every day people does much worse in the Internet, but add the μαιευτικη´ and it comes out as inappropiate.


The author could acknowledge the trade-offs between their preference and anothers.


Is there a difference between using the Socratic method interactively and transcribing a socratic discourse that never occurred?


A huge difference. Interactively, you can both ask and answer questions and you can steer the dialogue toward the pupil's areas of ignorance.

As a form of writing, you're left to guess at what your pupil might be thinking. Apart from Plato, few people have ever managed to succeed at this.


Plato succeeded if you judge by his historical rep, but I can't stand the guy, for reasons not entirely unlike the complaint starting this thread. Though good dialogs do exist (I like Raymond Smullyan's).


Plato didn't imagine his audience to be idiots. He really debated with himself or with questions he'd probably heard other people actually make (since he was with lots of other philosophers). He's harder to appreciate if you don't think like him or his companions and thus don't follow his line of thought.

In a way though, Plato tries to tell a story rather than blabber away facts. It allows for the introduction of stupid or "less-intelligent" questions rather than setting up obvious straw men.

.02


I completely understand and almost always share your reaction. Socratic CAN be done well - The novel Starship Troopers is actually like that...the arguments may not be your first pick, but you consider them all reasonable, and then you discover you're supporting fascism! It requires you to back up and find where you made a false connection.

Unfortunately, the most common usage is at best ineffective, for as you say, they will dictate some logical jump I don't agree with, so when they disprove it in favor of their point I remain unconvinced as my own argument hasn't been addressed at all.

At worst, it's infuriating.


Socratic method is supposed to be done in person, between professor and students, with professor choosing next question based on student's answers that typically reveal gaps in their knowledge. Doing it in form of made-up conversation in a book is a travesty.


Have you read Starship Troopers? It's one of Heinlein's finest novels.


As a teacher, it's a necessary tool. But you are right that it can be abused by teachers who are both attempting to inspire critical thinking AND trying to navigate their students to the "correct" answer at the same time.

If a teacher wants to convey a specific opinion or viewpoint, they should just share it. But if a teacher is genuinely willing to listen and wants to get their students to think critically about a topic -- without a desire to navigate the students in a specific direction -- then the Socratic method is very useful. But the teacher has to be truly willing to listen to their students. And that is hard for some teachers.


To be fair, actual Socratic dialogue can be very effective and rewarding, without being patronizing. What you're describing there -- what the blog post is like -- that's just as awful as you said, or worse.

I couldn't get much further past this:

What is an object?

    An object is a set of functions that operate upon encapsulated data elements.
...what?


Maybe we should try to be patient here and assume some valid point of view - even if possibly unusual for a personal experience. That is, can we try to justify this approach?

It's like HN guidelines - "assume good intent".


We can try, but we won't get as far as you might like. I gave the post a second chance and pushed myself past the point I originally criticized and past all such points.

I could write an in-depth critique of the whole post, but it's 5:30 pm and I would rather focus on finishing my work so I can go home and be with my family.

So instead of that, I'll just give you a summary of what I think about the post:

1) The post essentially compares two different approaches: a specific variant of object-oriented programming and a specific variant of functional programming.

2) There are various points in the post where the author plays fast and loose with definitions of certain concepts, in order to make them fit his narrative.

3) The Socratic dialogue format does not help make the reasoning clearer, it just makes the readers uncomfortably aware that they're being railroaded into reaching certain conclusions.

4) The conclusions reached in the post are a mixed bag of: a) useful and interesting, b) correct but incomplete, and c) correct only under very specific circumstances, rendering them potentially dangerous.


You're not Socrates, Uncle Bob.


I'm going to write you off as insufferable before the fawning moron you have as proxy for your audience utters

You must admit, you're throwing stones from a glass house when you write like that :p


When Socratic dialogue is done well, it is pretty helpful. When I read some article, I have questions in my head as the author makes her points. If the author is good enough, they can anticipate the reader's questions and write directly to the internal dialogue occurring in my head.

Plato merely makes this process explicit in his Socratic dialogues.

So, the existence of poorly thought out or agenda driven dialogues do not in themselves show the method is a bad one, just like bad musicians do not discredit music as a whole.


Yeah, I actually was convinced that it was a great idea and tried to apply it a bunch of times when trying to help teach others. It always worked out really badly.

The Socratic approach can be great when everyone's on the same page, but if you are teaching people from the ground up then all you'll really do is come off as a jerk.


I got a few lines down and couldn't keep going. It's such an irritating way of making an argument.


I've read all, and got both interesting points - useful to me angles of view - and certain statements and conclusions from then which I don't agree with.

1) Author says object and data structure are different things basing on stated difference, but doesn't explain why this couldn't be a different point of view on the same thing.

2) When author says "adding a class is easy when you need a new entity, while adding a function is easy when you deal with data structures" he doesn't mention that only "packaging" of code - into switch cases or separate methods - is different. To add Triangle, one still has to add both fields which contain Triangle data and all the methods which work with that data - area, perimeter, center. Similarly, adding data structure "Triangle" also needs all those additions - and only them - but in a different form.

And many derivations from this perceived difference are, um, questionable.

Yet I like author's explanation of impedance mismatch. True, data storage has to satisfy many needs (roughly, we don't want to copy data - normalization), while logic may focus on specific goal at hand.


You have a revolver? That's awesome!




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: