Quite ironic coming from the creator of Go. Algebraic data types, anyone?
Quite ironic coming from the creator of Go. Algebraic data types, anyone?
You can argue that advanced language constructs will make it easier to write correct code to implement data structures, but it's not a magic bullet.
The Go authors argue that a simple programming language with loops, pointers and arrays is all you need to implement any data structure you need.
I find this a good example of a data structure for which I see little or no benefit in being modeled as an ADTs:
http://research.swtch.com/sparse
Even simple things like doubly linked lists are complicated with ADTs. On the other hand I don't know about good examples of ADTs used outside of the context of functional programming, do you have some pointers?
There is nothing advanced about ADTs.
"The Go authors argue that a simple programming language with loops, pointers and arrays is all you need to implement any data structure you need."
It's all about increasing the level of abstraction. There is a reason we don't code in assembly anymore. Of course machine code is all you need to implement any data structure, but how convenient is it?
"I find this a good example of a data structure for which I see little or no benefit in being modeled as an ADTs:"
So you found a single counterexample which (according to you) would not benefit from ADTs.
" On the other hand I don't know about good examples of ADTs used outside of the context of functional programming, do you have some pointers?"
I dislike pointers (a necessary evil if you have mutation I guess...), but here is one example:
data Gender = Male | Female vs type Gender int; const ( Male Gender = iota; Female )
Combine the first with pattern matching and you find yourself in awesomenessland (ie. code becomes readable, type safe).
Perhaps there was a misunderstanding. I asked you if you had some links to some interesting examples of ADT outside the context of functional programming. Because I was assuming that this wasn't a discussion about Go vs purely functional data structures.
Your example clearly shows the benefits of strong typing with fully described types. My point that this is orthogonal with Rob Pike's position about the importance of data structures.
Data structures exist independently on how we represent them. I don't see any irony or conflict in highlighting the importance of data structure vs. implementing language features that make it easier to write correct implementation of them.
Rules of abstraction: https://pbs.twimg.com/media/BqkVxmrCUAEZSTZ.jpg
Back in my university data structures class, an Abstract Data Type was just the collection of "a data structure and its operations". For example, a tree ADT could be a struct of two pointers and some value, along with operations like addNode, removeNode, findNode, copy, create, destroy, etc... We wrote lists, stacks, trees, hashes, and graphs in C as self-contained ADT libraries. This wikipedia page [1] explains the differences in approach.
The concept of data+operations was a lead in to objects for us, and seems very simple. Is the ADT idea in functional programming inherently more complex? I see from that page that it is intended to be immutable, which is certainly a difference.
1. http://en.wikipedia.org/wiki/Abstract_data_type#Imperative_v...
The middle brow dismissal is apt/damaging in these situations because it saves everybody a lot of time by quickly demonstrating that the author ignored those pesky real world facts and complexities that spoilt the ideological narrative.
This probably isn't worth the debate, though.
Edit: since when having ADTs are so taxing for the machines? I did a quick search and I found no source saying they are expensive to implement.
Developer time is often more expensive, but it's always a one-off cost. Machine costs are ongoing. Machines can also impose hard limits on scalability.
In the real world, software optimisation is often necessary. Ever play a computer game? Those have pretty hard limits on much time they can spend processing. You can't just throw hardware at the problem to make it go away when you don't control the client.
"Just add more hardware" is also an ecologically unsound and unsustainable approach. Ever wondered about the carbon footprint of the average data centre?
Maybe one day we'll have optimising compilers so good that thinking about machine-level data structures won't be necessary. They've come a long way in the last 20 years, but aren't quite there yet. In the meantime, if you ever find yourself actually needing to make something run within some hard limits on CPU time, RAM, etc., listen to people like Rob Pike: he know's what he's talking about, even if you don't like what he's saying.
In the meantime if you're working on an MVP, by all means optimise for developer time. In that context it's almost always the right decision.
I hope I don't prove to be too detrimental to your health.
"Developer time is often more expensive, but it's always a one-off cost. Machine costs are ongoing. Machines can also impose hard limits on scalability."
A one off cost? I have never seen a codebase which gained consciousness, became self operating, fixed the bugs in itself and implemented new features, I hope I will, that's gonna be a truly glorious moment for humanity.
"Ever play a computer game?"
I did, but Go is rarely used for creating games. Typical use case: backend server services.
"In the meantime if you're working on an MVP, by all means optimise for developer time. In that context it's almost always the right decision."
Yes! On this site most people are working on some startup which will fail in 2 years. Performance is barely an issue.
No, but I've seen lots of projects who were completed, shrink wrapped, and shipped, with the team disbanded or moving on to other projects (sometimes with a few people left behind for bug fixing).
Especially most large scale enterprise /government / organisational projects are mostly one off, fire and forget affairs. A large team is assembled to create them, and then the support is offloaded to smaller team for fixes (and some tacked-on new features), and they run for decades on end.
>I did, but Go is rarely used for creating games. Typical use case: backend server services.
Which is bedide the point. The discussion was about those "programming principles" Rob Pike put forward, and the costs of developer vs machine etc -- not about Go in the least.
Bear in mind that opportunity cost is an unrecoverable loss. Game programming where you press a DVD is an exception, but in the majority of areas the greater cost is actually in maintenance.
Machine time eventually translates to user time. Slow code leads to poor user experience and if your product is successful, wasting the time of millions of people.
There are many problems that require some efficiency to solve effectively, especially in pike's field of systems.
PS: Coding go is my day job.
Go was designed as a system's language, I think it just eventually went in a different direction when people realized it would never match C++ or even Java in performance.
BTW, if you want to gain an understanding of this stuff, the difference it can make and why, I'd recommend reading basically anything by Michael Abrash.
No compiler optimization is going to get you a 100 to 1 improvement with a conventional language, but choosing the right data structure and algorithm for a task certainly can.
Now scale this to a situation where solving the problem requires ten thousand machines for each developer working on code, and where each minute of time spent writing code translates into two days of machine time running that code, and the numbers start to look different.
Meanwhile I just want to deliver the features for my product owner as quickly as possible! So we can both go home to our families in time and still deliver tons of business value.
I think it is a question of how far you're willing to take generalization over how easy it is to come up with a reasonable concrete solution to a concrete problem.
See eg: https://groups.google.com/d/msg/golang-nuts/DLxFvfdRKBY/NDkW...
The c mindset of unions/structs coupled with functions doesn't contradict the idea of "chose the right data structures".
[edit: It appears others have made this point better while I was typing. The gist seems to be (to paraphrase another comment): (abstract) data types and types are not the same thing. types can help with the implementation of ADTs, but that's not really relevent to the 5th rule.]
"data types and types are not the same thing. types can help with the implementation of ADTs"
Can you please show me how can you implement a language (type system) feature without touching the compiler source?
Type safety (checking that all integers pushed to the "record-of-type-library-card stack" are in fact valid pointers to valid library-card-records) can be helpful, but not needed to implement ADTs.
Am I close to clearing up what I was talking about above?
[edit: typo, also: you mis-quoted me, dropping the "abstract" in "abstract data type" -- which might be the source of the confusion?]
As to the meat of the discussion, algebraic data types imply that you can apply algebraic operators to types. Since this is traditionally a purely compile-time feature you can imagine why the parent comment is incredulous that you could implement this without language support.
Your specific statement, "data types and types are not the same thing," is particularly confusing. You are making assumptions that aren't warranted, for example that "data types" encompass both a compile-time type check and an interface allowing abstract operations, while "types" are simply static type guarantees on values. In fact, both terms can refer to either.
Anyway, I think we've cleared up what I apparently didn't put very clearly in the first place: Algebraic Data Types can help with implementing Abstract Data Types, but one doesn't need the former for the latter -- and I suspect the data structures of "Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming." are indeed closer to using the right simple data structures along with the correct abstract data types -- so there's no direct contradiction between the 5th rule and Go not having (proper) Algebraic Types.