12 ms·
Understand Go pointers
- pavlov 9y agoAre there actually programmers who need to be explained the following: "...memory is just a series of numbered cells, and variables are just nicknames for a memory location assigned by the compiler." What kind of programming can one do without even that level of mental model of what a computer does?
- danielvf 9y agoActually you don't need to know about numbered memory cells for most modern languages that aren't C, C++, or assembly. It's a good thing. Most of the time for most of the people, it's better to work closer to your problem domain than to the CPU.
- nottorp 9y agoYeah, that's why we have chat programs taking 5-10% of the CPU when idle and in the background. The developers worked "closer to the problem domain".
- 0xelectron 9y agoIs it their fault that we still haven't been able to find an elegant solution to this problem?
- TeMPOraL 9y agoThere are many elegant solutions; they're not JavaScript on Electron.
- dualogy 9y ago> It's a good thing. Most of the time for most of the people, it's better to work closer to your problem Having a rough understanding of what memory is at a very rough high-level grasp ("numbered byte-size cells" isn't very in-depth after all) doesn't preclude one from working "closer to one's problem domain", likewise lacking such grasp doesn't bring one any closer to one's problem domain.. what am I missing?
- aninhumer 9y agoThe parent just said that it's a good thing that these languages don't require an understanding of memory, not that such an understanding is not valuable. If you need to understand memory to use a language, then it's not abstracting well enough.
- deleted 9y ago[deleted]
- danielvf 9y agoIt's not that such an understanding precludes a person from working close to the problem domain, it's just that that knowledge is not necessary most of the time. In the book, "Mythical Man Month", Fred Brooks talks about the two kinds of complexity in solving problems with computers. There's the "essential complexity" that's there because the problem you are solving is actually complex, and then there's the "accidental complexity" that's not actually required to solve the problem, but to make the computer happy. Let's compare C arrays and Python/C# Lists. For my pretend problem, I need an ordered, index-able set of things. With the C array, I need to know how big to make it before I create it. I need to allocate the memory that is used before I use it, and I must deallocate that memory when I'm done with it. I might underflow or overflow the array and allow Eastern European hackers control over my server and data. Even if I checking for overflows and underflows in all the proper places, I also have to add code to every one of those places handle each possible error. Whereas in C# and Python, I just make a new list and stick things into it. When it goes out of scope, it disappears automatically. Python and C# move me closer to the actual problem being solved by removing this "Accidental Complexity". When complexity removing is done well, it also removes the requirement for the programmer to know about numbered cells of memory, because numbered cells of memory is "Accidental Complexity" for the problem domain. Now when I know how the computer is actually working, it does bring benefits. Today, in fact, I'm writing C code for an embedded ARM chip. Knowledge of memory numbers is a little required here. But for most software developers, knowing how memory works is not a requirement for working software. Even memory-as-a-numbered-set-of-cells is still just a huge abstraction from how the memory is actually being handled by the hardware.
- problems 9y agoJust people who are new to it mostly, this must be aimed at people who haven't done any low level development at all. Some people seriously struggle with it though, I don't think I had a truly full grasp until I started reverse engineering and saw the memory first hand and how it was accessed with different instructions.
- jayflux 9y ago> What kind of programming can one do without even that level of mental model of what a computer does? JavaScript? Python?
- pavlov 9y agoSurely you need to have some kind of idea of what memory is just to write: var a = 1 var b = 2 You have to know that these values are stored in working memory, not on hard drive or Google's servers or Martian stone tablets.
- aninhumer 9y agoNo? All you need to understand to program are the assignment semantics. Understanding the implementation details is valuable, but I'm not sure why you think it's necessary to program?
- pavlov 9y agoI just don't see what kind of useful programming you can do without knowing anything about the machine it runs on. If "a = b + c" takes a second to execute, you have to take that into account. The programs that people wrote for 1950s computers were very different from today, even though the language semantics might be essentially the same. On the other hand, this discussion is helping me understand why the web development world is full of weird database-backed Rube Goldberg machines that can spend milliseconds to access a few bytes of data that were already in RAM.
- aninhumer 9y ago>If "a = b + c" takes a second to execute, you have to take that into account. But it doesn't, so you don't. Sure understanding performance is necessary to build more complex or higher usage systems, but not understanding it does not preclude "useful programming".
- 9y ago
- taneq 9y agoBack in my uni days I met a few people who found this confusing. It's one of the basic concepts of programming that, believe it or not, some people just aren't mentally equipped to grasp.
- GoToRO 9y agoNew people are born, every day...
- mikeash 9y agoDid you never go through the beginning phase where you didn't understand pointers? That's usually a breakthrough moment, not something you start out with.
- simias 9y agoDepends where you start from, really. If you come from the "bare metal" side of things (electronic work, microcontrollers etc...) then work your way "up" then the memory model is all you think about. I learned pretty much that way so I never really had much of an issue understanding these concepts (conversely, it took me a while to get used to things like dynamic typing). That being said nowadays I'm sure many more coders start with something like Javascript instead of 8bit controllers, so I'm sure these types of articles are very valuable to many.
- pjmlp 9y agoNo, because the languages I had available to me were Timex 2068 Basic and Z80 Assembly. Maybe the first couple of hours when I still hadn't read the DIM, DATA, READ, POKE and PEEK manual pages. Just like on Dave Cheney's post, seeing a few box examples was enough to get it.
- mikeash 9y agoSo you benefitted from exactly the sort of explanation you now seem to be questioning?
- pjmlp 9y agoNo, because I never had a "breakthrough moment". It just felt natural on how a computer was working, typing example after example, to a 10 year old version of myself.
- int_19h 9y agoThere's a certain distinction to be had between understanding memory addresses, and understanding pointers as part of a type system. I remember the former was very straightforward in various BASIC dialects running on DOS, and it never really confused me. C pointer types, on the other hand, did. Sure, there's an obvious mapping between the two... in the retrospect. But it wasn't obvious at first.
- zabana 9y agoMost (keyword: Most) self-taught programmers / hobbyists start with high level languages like Python, Ruby, PHP, JS etc and work their way "down" out of interest and intellectual stimulation (like myself). It might be counter-intuitive to those with CS backgrounds but the truth is for most things, you don't really need to know the implementation details of variable assignement if you're only interested in scraping the NYT. Believe or not, pointers can be difficult to grasp as a concept for people who aren't used to this type of mental model. If you didn't struggle with it, good for you. But there's no need to look down on others who are trying to learn. I should also add that Software Engineering and Programming aren't necessarly synonyms. Some programmers aren't SWE and that's OK. If you're a "fake programmer" like the parent is trying to imply, don't lose hope. Continue to learn at your own pace and you'll eventually catch up.
- pavlov 9y agoI can see that pointers are conceptually difficult (the passage I quoted was not about pointers). I'm not even looking down on anyone. I'm just honestly surprised that programmers might not know what RAM is.
- JustSomeNobody 9y ago> If you're a "fake programmer" like the parent is trying to imply... You probably shouldn't put words in other people's mouth. I don't think he was calling the people fake, but merely asking how effective they could be at programming without an understanding of memory.
- zabana 9y agoI admit it was a bit harsh but the parent comment sounded a bit too condescending.
- luckydude 9y ago(I upvoted you, I think your question is fine FWTIW) Sadly, yes. Universities have moved away from teaching C. In ancient times, when I went to school, you'd start with an intro class in Pascal, then you'd take a data structures class in Pascal, and then you'd take some harder class in C. About half of the people in the C class would drop out of Computer Science when they hit pointers. As someone who gets pointers pretty much instinctively, I didn't get it, the concept seemed really intuitive to me. But apparently that's not true for everyone, some people really struggle with it. I think it really doesn't help that CS has moved away from C as a teaching language. C can be viewed as a pleasant, portable, assembly language. As such, it lets you "feel" the bare metal, much more so than a scripting language like Python or Javascript.
- pjmlp 9y agoWe had pointers already in Pascal.
- throwaway18917 9y ago> C can be viewed as a pleasant, portable, assembly language. Do I have to buy what you're on from some guy on the street or is it available as a prescription? > As such, it lets you "feel" the bare metal, much more so than a scripting language like Python or Javascript. C hasn't been bare metal since the PDP-11. There are like eight layers of abstraction between char *foo = "bar"; and the "bare metal"; I don't know why people are desperately clinging to this "C is basically portable assembly nonsense".
- akubera 9y agohttps://godbolt.org/g/q01z7n https://godbolt.org/g/q01z7n I'm not sure what you mean by layers of abstraction (type checking? optimization?) but C code often does have a pretty straightforward translation to assembly. Perhaps you had a bad experience and can clarify what you mean?
- chousuke 9y agoEight layers? That made me curious about how many are there really, though? My understanding is rather vague at this level, though hopefully good enough to know when I need to look deeper. So the compiler is obviously one layer. Then there's the assembler and the linker. Does the C runtime count too? You think you have a "string", but it's actually just an address to a (hopefully) nul-terminated chunk of "contiguous" virtual memory. If you wanted to read the first byte of that array, it would first go through the OS's virtual memory system, so that's one rather large abstraction. (I'm lumping in the hardware's virtual memory support here, too) Then when you actually access a piece of "real" memory, there are a number of caches between your data and the request to fetch it. And what about the DRAM itself? Can it access only a single byte of memory at a time, or is that too an abstraction? Instruction decoding is one or two layers at least, since chances are the processor doesn't actually execute x86 opcodes directly. And when you run out of software abstractions, how many levels of abstraction is there in the actual hardware? I only have vague ideas of what actually happens at this level, and whenever I stop to think about it, it's pretty amazing our software stacks work at all...
- paulddraper 9y agoHuh? You need a mental model of your language and runtime. If your language treats things in terms of numbered cells and nicknames, then you need a mental model of that. If your language treats things in terms of reverentially transparent values, then you need a mental model of that.
- TeMPOraL 9y agoThat's programming eqivalent of giving someone an axe and telling them to go chop some trees. For non-early-apprentice-level programming, one could also use the mental model of what's below the language runtime.
- paulddraper 9y agoWell, it's really all quantum wavefunctions.
- waxjar 9y agoIt seems that some languages provide a pretty good abstraction, memory-wise ;)
- deleted 9y ago[deleted]
- nottorp 9y agoI clicked the article thinking that Go pointers are something special... but this seems targeted at the "programmers" who only know javascript...
- lclarkmichalek 9y agoProgrammers who only know javascript are, controversially, still programmers.
- leshow 9y agoEven if you're a JS programmer, having no knowledge of pointers just shows you've never dug very deep into how your language works. Does JS pass by value? by reference? does it pass references by value? These are all things a JS programmer should know, and requires some knowledge of pointers.
- bsaul 9y agoDon't understand the downvote. Understanding javascript's closure (which is a core js feature even on the client) properly without understanding pointers seems like an impossible task to me.
- inimino 9y agoThe idea of reference is necessary, but pointers are an implementation detail. If you don't come from C, you can understand everything in JavaScript without knowing what pointers are. Many languages have references to mutable state without the peculiar details that make pointers what they are.
- EdiX 9y agoRegardless of whether they can be called programmers, we can not deny that they exist.
- akuji1993 9y agoI'm really tired of people bashing Javascript to death. It's here, it's being used, wether you like it or not. Stop whining about it, please.
- tapirl 9y agoThe word "Go" is not essential in the title.
- BoorishBears 9y agoIf it didn't include Go, this would barely be scratching the surface (pointer arithmetic) I see Go's pointer as closer to C#'s ref/out than anything
- jerf 9y agoI personally (emphasis intentional) consider the core distinction between "references" and "pointers" to be whether you can do pointer arithmetic on the pointers. Pointers without pointer arithmetic aren't hardly scary at all, especially in languages where there is no way to deallocate the underlying value but leave the pointer behind such that it may point to the wrong thing later, be that due to something like Rust or with GC like Go. So personally, I think of Go as having references, but not pointers (outside of unsafe). Of course every language community uses those terms its own way, but that seems to me to be the most broadly useful way of looking at it.
- steveklabnik 9y agoI've spent a lot of time on this, working on Rust's docs, and the way I see it is that "pointer" is the most generic concept, with "reference" being a more restricted form. So all references are pointers but not all pointers are references. Words are hard.
- ptero 9y agoI agree, Go in the title is irrelevant. Otherwise, it is a decent overview of the notion of pointer, although there are many of such overviews around. My other objection is with using code like * b++ in a text that aims to be crystal clear about a single concept (pointers). That can bring totally irrelevant questions on operator precedence and right / left associations. It would be better to say * b = 201. My 2c.
- sddfd 9y agoThis is a good explanation of what happens on the machine. However, most languages (C, C++, etc) have different definitions of what pointers are, and many operations that seem reasonable on the machine model are in fact undefined behavior. In C, for example, you cannot reference one object from a pointer to another object (there is one exception to this rule).
- weberc2 9y ago> In C, for example, you cannot reference one object from a pointer to another object (there is one exception to this rule). I'm confused about what this means--can you explain?
- Arnavion 9y agoYou can't both cast a double* to an int* and then dereference the int* , expecting to read an int-sized chunk of the double. It's called strict aliasing and there are defined scenarios where it is allowed (one is that char* is an alias for all pointers).
- int_19h 9y ago> In C, for example, you cannot reference one object from a pointer to another object (there is one exception to this rule). I'm not sure what you mean by this, but if it's a reference to strict aliasing rule, then it's about types, not object identity; and there's more than one exception to it.
- Aardwolf 9y agoLooks the same as C pointers. Maybe the title is more clear if it would be: "Understand pointers, using Go". Then for a C programmer it's clear from the title that "pointers" is the same concept, and Go doesn't have a different type of "Go pointers". Or instead of starting with: "This post is for programmers coming to Go who are unfamiliar with the idea of pointers or a pointer type in Go." It could start with: "This post is for programmers coming to Go from a language without pointers or a pointer type."
- kazinator 9y ago> Then for a C programmer Maybe that's not the target audience? Tutorials targetted at C newbies have been about "C pointers" for eons; why would Go tutorials refer to a different programming language? What that program is doing would not be well-defined in C; you cannot increment a pointer from the address of one local variable to point to another, without leaving behind the ISO C standard dialect. I haven't seen any compiler-specific document which "blesses" the practice. If that is well-defined in Go, that would be an excellent reason why the article really is specifically about Go pointers and not C pointers.
- echlebek 9y agoThey're not the same. Go doesn't have pointer arithmetic, and Go functions can safely return pointers to values that aren't created via new(). https://play.golang.org/p/m3OdaXH98_ https://play.golang.org/p/m3OdaXH98_
- pjmlp 9y agoYes it has, via unsafe package. Which ANSI C example should I write for you in Go?
- echlebek 9y agoPackage unsafe is in the spec, but converting unsafe.Pointer to uintptr (which is how I'm supposing you'd do your pointer arithmetic) is implementation-defined. This means I could create a perfectly legal implementation of Go where such things result in complete nonsense. I don't think package unsafe "counts".
- agentgt 9y agoI am still not sure why the language creators of Go decided to make pointers explicit (syntactically) instead of making references the default like most other languages. That is you still have pointers but you don't have to put "*" all over the place. I suppose it is because the language designers came from C or maybe they wanted to be that explicit? I understand the value of having pointers even in a GC but I'am actually more concerned with the resource I'm pointing to and its lifecycle than that is pointers. That is there should be different types of pointers depending on where the data is stored and how it is reclaimed (something Rust does nicely with generics). I'm not trying to bash Go rather I must be missing something (I don't know the language that well).
- omginternets 9y agoI always assumed it was because passing by copy was useful in highly concurrrent environments. It's essentially pseudo-immutability, if you will.
- steveklabnik 9y agoRust does not use references by default either, so I wonder why you don't mind it there but mind it in Go.
- agentgt 9y agoBecause Rust is not a GC language. I should have perhaps explained that better. My round about point mentioning Rust was that instead of putting "*" all over the place you could just have types that represent such (pointers) or the opposite (ie value types) depending on what the language defaults to. I mean the pointer in some senses is effectively abstract wise Pointer<SomeType>. However I suppose this is difficult with out generics. That is I don't mind the explicitness of Rust because I guess I expect it just like C/C++ but I probably incorrectly expect it with Go lang. This is mostly because I come from a JVM background where I expect the VM to figure out what is more optimal and consequently also have very little experience using in/out parameters.
- 9y ago
- dmix 9y agoThe article referenced 'Cuneiform' which I had to Google. It's neat to see that languages evolved the same way math was developed and similar to how software programs grow as a series of expanding abstraction: > Emerging in Sumer in the late fourth millennium BC (the Uruk IV period), cuneiform writing began as a system of pictograms. In the third millennium, the pictorial representations became simplified and more abstract as the number of characters in use grew smaller (Hittite cuneiform). Software is very much a natural extension of the brain and how we processed the world around us.
- twic 9y agoMy favourite bit of ancient writing is the Kushim Tablet. It's a clay document, written in pre-cuneiform archaic Sumerian. It was written in Uruk, about halfway between Baghdad and Basra in modern-day Iraq, in the 31st century BC - five thousand years ago. On it is are the oldest examples of two things fundamental to human civilisation: a person's name, and an industrial process. It's a receipt for ingredients for a brewery: http://www.schoyencollection.com/24-smaller-collections/wine-beer/ms-1717-beer-inanna-uruk http://www.schoyencollection.com/24-smaller-collections/wine...
- ohstopitu 9y agoThank you! This is extremely useful! I've always wanted to break into Go, but pointers scare me after my experience in C in University. While I got the usefulness and it's functions (and usage), it was not something I felt comfortable with. This definitely it easier!
- lspears 9y ago"Understand Go pointers in less than 800 words or your money back" There are multiple pictures each of which is worth 1000 words. Where is my money?