This is Leslie Lamport's writing, and he's complaining that nobody uses his TLA+ formal specification language. (Here's the TLA book.[1] Read the introduction, and it's much the same rant.)
I used to work on formal specifications and program proofs, around the time Lamport was developing temporal logic. I took the position that, rather than trying to make programmers learn math, we should automate and divide up the problem so that they didn't have to.[2][3] This meant minimizing the formalism and making the verification information look like ordinary programming. It also meant carving out the harder math problems into a separate system where someone using a theorem prover would prove the necessary theorems in a way which allowed their use and reuse by ordinary programmers. The underlying math is still there, but not in your face so much.
There's a mathematician mindset: Terseness is good. Cleverness is good. Elegance is good. Generality is good. Case analysis is ugly. This is unhelpful for program verification.
Program verification generates huge numbers of formulas to be proven. Most of the formulas are very dumb, and can be dealt with automatically by a simple theorem prover.
Where it's necessary to prove something hard, our approach was to encourage users to write more assertions in the code to narrow the thing to be proven, until they were down to "assert(expra); assert(exprb);" Getting to that point is much like ordinary debugging.
Now they just needed a theorem, independent of the program, that could prove "exprb" given "expra". That job could be handed off to a theorem-proving expert. A library of proved and machine-checked theorems would be built up. Some would be general, some project-specific. This is the software engineer's approach to the problem.
The mathematician's approach is to capture much of the program semantics in mathematical form and work on them as big math formulas. Most of the work is done in the formula space, where mathematicians are comfortable, not the code space, where programmers are comfortable. This seems to hold back the use of formal methods in program verification.
Much effort has gone into trying into trying to find some clever way to make program verification elegant. "A great variety of program logics are in use in computer science for the specification of (software and/or hardware) systems; for example: modal and temporal logics, dynamic logic, Hoare logic, separation logic, spatial logic, nominal logic, lax logic, linear logic, intuitionistic type theory, LCF."[4] We used to call this the "logic of the month club".
You make it sound as if theorists were
inventing logics frivolously.
We have known since the stone age (of computing) that we can reason
about any computation using e.g. ZFC set theory, since we can
formalise the operational semantics of any computation in ZFC. The
problem is that general purpose logics like ZFC are extremely
inefficient (in the sense of having too large a proof search
space). For example ZFC allows you to reason about statements like: 4
\in squareroot(3). But such questions are meaningless in reasoning
about programs. ZFC is too expressive. What all the work on program
logics is about is to find logics that are 'more efficient'. That means they should be
(1) Expressive enough to enable reasoning about program propertise
that we care about.
(2) Make the proof search space as small as possible.
(3) Make specification and reasoning convenient (for computer or
programmer).
All the logics you mention make some progress towards these
goals. Nominal logic for example makes reasoning about programs with
binders more efficient. Separation logic makes reasoning about
stateful computation more efficient. Type theories are progress
towards integrating programming, specification and proving (whether
that's desirable or not is a contentious question). The LCF approach gave use the currently dominant interactive theorem prover architecture. Linear logic has been the single most influential idea in the last 3 decades in the design of typing systems, especially for concurrent systems.
I know I've posted this a few times but I don't think I've ever seen you in a thread about this. Do you have any simple way for a computer scientist to learn about proven methods.
More precisely, how do I engage in the dark incantations required to conjure up my own proven methods? For my critical code, right now I just write unit tests. Do you know some place that can shed some light as to what I actually do? I mean, I can just tell my coworkers "yea I formally proved this, it won't have bugs" but I don't think that's quite in good spirit.
Not the parent, but indeed like you said, writing unit tests doesn't show absence of bugs, but can only show their presence.
To be able to state that a piece of software is bug-free and formally correct, we first need a notion of correctness: that the algorithm follows a [formal] specification.
The first step would be to formally specify what the software/algorithm should do. Then, the next step would be to use formal methods and mathematical tools (e.g. set theory and logic) to prove that your algorithm does exactly as the specification says.
TLA+ is a formal method that can be used for writing specifications and model-checking them. While a big step forward from testing, model-checking still doesn't "prove" anything.
For proving, you can use theorem provers like the Z3 [0] SMT solver (or a formal framework that uses theorem provers) to do proof checking.
The Event-B [1] method is one such formal method that uses SMT solvers and allows you to model systems starting with a very abstract and high-level model, state invariants about your system, and prove that those invariants hold as you refine your models and make them more concrete.
Feel free to shoot me an email if you like to talk more about formal methods :)
You are probably not going to get to the point of being able to tell your coworkers "yes, this is formally verified" unless you are working in a specific domain where you have few/no libraries and very clearly stated and well trusted assumptions about the external environment (hardware, etc).
My next "big" project will be a data visualization system that's probably going to need some Python, JavaScript, and some simple bash piping between the python scripts.
It's not going to be mission critical but it'll be nice to flash and say "I used formal methods to prove this implementation" as it is going to be for an academic's project.
> My next "big" project will be a data visualization system that's probably going to need some Python, JavaScript, and some simple bash piping between the python scripts.
Unfortunately, there aren't great deductive verification tools for either Python or JavaScript.
Perhaps more importantly, there's also not a particularly good understanding of how to formally verify front-end code.
The most important property of a visualization system is something like "the visualization accurately represents the data being visualized", but in a problem domain like this, formalizing the high-level intent is probably harder than actually proving that this intent is achieved.
Additionally, the cost of throwing an exception at runtime are presumably pretty low (unlike in a control system, for example). So once you've formalized your spec, you can just check your specs at run time throw an exception/report a bug instead of or in addition to generating the possibly faulty visualization.
Are there key components of the visualization pipeline that could threaten its correctness? E.g. data reduction, interpolation, fancy graphics code, etc.? If so, I'd focus on those and come up with a good set of formal, checkable-at-runtime contracts that capture your high-level informal specification.
Alternatively, is it possible to do some computation on your output to check that it matches the input data? E.g. you could imagine counting pixels of certain colors on a heat map or pie chart and comparing that to the original data. That way you don't have to verify (or trust) all of the graphics generation code, thus significantly reducing your trusted computing base.
Saying "we have a formal mathematical description of what it means for this portion of the visualization system to be correct, and a way of checking input/output matches that description" is probably a more significant contribution than actually churning through a static verification effort.
> it'll be nice to flash and say "I used formal methods to prove this implementation" as it is going to be for an academic's project.
Are you sure this is the case? Most academics, even within CS, don't care much about formal methods.
If you're just looking to learn formal methods, then I guess it's whatever. But if you're looking to stand out, you might want to figure out what's important to your stake holders and focus on that. I'd be pleasantly surprised if the answer to that question is formal methods.
There are multiple portions of this project only one of which is rendering. The rest is data acquisition, job scheduling, and some other stuff. I've got to sample a source of data and run a lot of code on it.
> If you're just looking to learn formal methods, then I guess it's whatever. But if you're looking to stand out, you might want to figure out what's important to your stake holders and focus on that. I'd be pleasantly surprised if the answer to that question is formal methods.
I was just joking around a bit. I've been interested for some time.
Perhaps its time to rethink the sanctity of mathematical symbolic communication. Seriously, that equation borders on parody in attempting to relay a rather simple concept. We dont expect CS people to communicate concepts through compiled, machine language style syntax (minimum number of bits uber alles) so why not revisit the communication of mathematical concepts with weight given to clarity over compression?
∀+∃+{|} are the epitome of clarity over compression. Mathematicians like them for the same reason why many programmers like sophisticated static typing. They might not always improve the clarity of toy examples to beginners, but they certainly help improve the clarity of untamed, wart-ridden, real life problems to initiates.
I think the first time I truly appreciated the power of ∀ and ∃ was during functional analysis when I found myself juggling an overwhelming number of different notions of continuity, convergence, smoothness and the like. ∀ and ∃ drew out the subtle distinctions that the blurry, imprecise words of the English language conspired to hide. They let me break down logic hairballs completely indigestible to my mammalian intuition into small chunks that I could individually process. Same idea as algebra.
That's their purpose, and they're very good at it. Nothing I've encountered in the world of programming languages really comes close to doing their job. Don't fall in to the trap of assuming they're pointless just because they don't apply to your problems.
I use ∀ and ∃ and so forth, mostly in private notes. It's great shorthand.
On the other hand, in MathLand we have conventions like saying "2x" when you want to multiply x by 2, but if you write "dx" you'd better know if you're doing calculus or not, because it means something totally different depending on context.
Mathematical notation is pretty squishy. There are probably thousands of uses of every greek letter and their italic, bold and variously curlicue'd isomorphs. And it's mostly culture, with a lot of history, personalities and land-grabs thrown in. You can't necessarily crack open a paper without a lot of baggage-level context ("Oh yeah, this community uses brackets for things that community uses subscripts for, okay...")
On the other hand, C++ is complicated and messy and also mostly a train wreck, but at least there's a standard you can go read.
[I once thought it would be worthwhile to learn denotational semantics. The "at least one new hijacked hieroglyph must appear on every page" nature of the reading put me off it in short order. I had no idea where to start interpreting the notation other than maybe attending a class to get the proper starter culture. It was frustrating to see notation go in the "squishy" direction when I thought it should have been using something you could parse and run tools against. Oh well.]
> I had no idea where to start interpreting the notation other than maybe attending a class to get the proper starter culture.
More than anything, I think this is the main reason why studying many subfield of mathematics is so difficult, when we spend more time and effort in things like parsing instead of in the actual subject matter.
Even popular subjects may show similar problems. For example, in Sedgewick's Analysis of Algorithms, he gives the following common definition:
> O(f(N)) denotes the set of all g(N)....
In the next page, he presents an exercise:
> Show that f(N) = N lg N + O(N) implies f(N) = ϴ(N log N)
Reader looks at that "N lg N + O(N)" and tries to make sense of the addition of a number to a set of functions. Note, this is in page 5, so many readers unfamiliar with the culture of the area are likely to just abandon the book (and perhaps the study of the subject) as they could not translate to themselves the very first formula presented by the author.
The only clue to anything that could help the newbie to get some answers lies in a couple of references that point to the historical uses of these greek symbols for computational complexity. Within that reference [1], by no other than Knuth, one can find the explanation for such syntax:
> "1+O(n^-1) " can be taken to mean the set of all functions of the form 1+g(n), where |g(n)| < Cn^-1 for some C and all large n.
And then he goes on about the problem of that syntax in respect to one-way equality:
> we write 1+O(n^-1) = O(1) but not O(1) = 1+O(n^-1). The equal sign here really means ⊆ "set inclusion", and this has bothered many people who propose that we not be allowed to use the = sign in this context. My feeling is that we should continue to use one-way equality together with O-notations since it has been common practice of thousands of mathematicians for so many years now, and since we understand the meaning of our existing notation sufficiently well.
The above is not only a reason for logicians to laugh at the pretense that mathematical language is formal, but also an example of things that are likely not to be in books but in an unwritten culture of a field.
--
[1] - Knuth, Big Omicron and big Omega and big Theta
I think the goal of mathematical notation is precision rather than ambiguity. Yes, the example seems awfully complicated for what simple thing it's trying to state. However, if you read it out loud it still sounds complicated. It's a simple concept, but it's hard to communicate without room for ambiguity.
How do we know if the solution they chose to achieve that goal is the most efficient one? How did that notation evolve? Has it evolved at all?
What if it's just a design by committee, with decisions made in the 17th century still affecting how modern papers are written?
What if we think of the rulebook on "how to write math" as a codebase? Would it be a 3-4 centuries old codebase without any major refactorings done, ever?
This notation is not for relaying the concept of permutations, for that (good) mathematics textbooks would simply write this explanation in plain English.
What the notation is good for is manipulating the notion of a permutation in a greater context, e.g. when you want to show that the functional composition of two permutations is itself a permutation, you can just replace this verbal description with the formal notation, shuffle around the symbols a bit, until you arrive at something that is obviously true.
Try doing that using the verbose English description.
That's a false equivalency. Mathematics, in practice, is more of a domain specific language that encapsulates more and more precise information as you increase the level of abstraction. The levels of abstraction layer upon one another to be able to handle more complex concepts while retaining all of the underlying precision.
> Mathematics, in practice, is more of a domain specific language that encapsulates more and more precise information as you increase the level of abstraction
Isn't that the point of any DSL? Also, wasn't the advent of DSLs meant to make it easier for non-programmers to understand the flow of control in a system?
I think generally the idea was to make things easier to understand by factoring out the complicated bits (implementation) and leveraging abstraction to provide clarity on top of an implementation.
If this is the case for every DSL I and every other CS major designs, why should it not be the goal of every math major? Sure to you and many other math-centrist people these symbols are "how I learned it so it must be the best" but to everyone else it's difficult to grasp and hard to understand.
The lingo is half the battle for most things but for math it seems like the lingo is the entire battle.
> The lingo is half the battle for most things but for math it seems like the lingo is the entire battle.
There's a kernel of truth there.
To abuse the DSL metaphor further, even mildly complicated mathematics concepts are only expressible using layer upon layer of ever-more-abstracted DSLs. Lower-level expansions of the building blocks to improve clarity for reading would be useless in practice, since mathematics is intended to be written and understood by humans and such an expansion would exceed our ability to keep the entire intended concept in our working memory.
Proficiency in mathematics is proficiency with understanding and extending the lingo itself. Mathematics /is/ the lingo, which is why it can't be unraveled from it.
>"how I learned it so it must be the best"
Not at all. It is, however, a very practical approach to getting someone up to speed to be able to do actual mathematics (as opposed to the basic symbol manipulations that most people confuse with actual mathematics.)
You don't need to read or understand (most of) your source code because it is 90% libraries. Mathematics is built based on understanding all the concepts behind a subject, and it's written to express to another human clear rigorous thought.
You cannot just black box everything away and choose to ignore it the way programmers do with source code and libraries.
The metric for success with a program is "does the machine run it properly". The metric for success with a piece of mathematics is "do people who've done some reading in my field understand my new result". You can cheat in one but not in the other.
> You don't need to read or understand (most of) your source code because it is 90% libraries
That's just plain incorrect. I expect all code to be written to standards of which would allow anyone to read.
> Mathematics is built based on understanding all the concepts behind a subject, and it's written to express to another human clear rigorous thought.
Isn't abstraction designed to avoid this? To remove a solution from a problem domain? To work on it without integral knowledge of all; applications? If not then all of Computer Science has been doing it wrong.
> You cannot just black box everything away and choose to ignore it the way programmers do with source code and libraries.
We don't do that. We black box things that aren't related to the problem at hand by referring to them in a terse and understandable way. For instance if I want to use a fork join scheduler for parallel thread scheduler I don't need to write out all the code for a fork join scheduler. I just need to say "You probably know what this is, if not it's called a fork join scheduler and I'll interact with it via sending messages of run, runAll, etc" and be done with it. I wont use an obscure Greek letter to notate a Fork-Join as that's archaic and insane.
> The metric for success with a program is "does the machine run it properly". The metric for success with a piece of mathematics is "do people who've done some reading in my field understand my new result". You can cheat in one but not in the other.
The KPIs for software are as follows: functionality, maintainability, simplicity. In that order. There is no single goal of software but instead a multifaceted set of goals constantly working against each other yet CS people make room for an even balance.
I don't see how this relates to you engaging in proving further information from other information. I don't see why math needs 40 non-terminal characters to type out a proof. I don't see why it can't be written in a way that is more approachable while not detrimental to the performance of current professionals. I also find it unfathomable that someone would think that the current way of doing things is the, all together, best way of doing things because that points a blind eye at the other two things I mentioned: "maintainability, simplicity".
I wouldn't call any of the advanced math world "simple" or "maintainable".
>That's just plain incorrect. I expect all code to be written to standards of which would allow anyone to read.
So you only work on open source hardware, with open source operating systems and open source drivers and open source software? And you've read the code for the libraries you use of course? Please. Unless you're Stallman you're not really assessing how much black boxing you are actually doing.
>We don't do that. We black box things that aren't related to the problem at hand by referring to them in a terse and understandable way. For instance if I want to use a fork join scheduler for parallel thread scheduler I don't need to write out all the code for a fork join scheduler. I just need to say "You probably know what this is, if not it's called a fork join scheduler and I'll interact with it via sending messages of run, runAll, etc" and be done with it. I wont use an obscure Greek letter to notate a Fork-Join as that's archaic and insane.
You do do that. And have you ever really read any mathematics at all? It is literally exactly what you describe. "I am going to use a fiber bundle here, I'll call it (A,B,pi,F), you probably know what this is..." I guess you just hate Greek? The notation is terse and completely obvious to anyone who has the faintiest idea about the mathematics they are reading. Letters are not used to describe abstract ideas (these have English names) they are used to express specific variables. Just like you do in CS. It's hard to type 'alpha' on an English keyboard or programmers would call things alpha as well. The letter notation is essential to express your ideas clearly. The subject material in doing advanced mathematics is much more difficult, abstract and complex than writing code usually, so the notation looks more difficult. That's all.
It isn't simple. Because what it's describing isn't simple. It is maintainable because it's easy to read once you understand it. Understanding is the hard part.
Programmers always think they can "fix math" by swapping notation around. They don't realize that it's as good as it can be until they actually start doing some real mathematics. Notation is really not a problem. It's a tiny minimal bump along the road that massively simplifies the entire endeavor and tries to get out of the way of actually understanding the mathematics, which is the difficult part.
The only objection you're raising that has merit is that a lot of the symbols aren't on a keyboard. Which is why we have TeX. Which is the digital language of mathematics. \pi is really not hard to type.
> So you only work on open source hardware, with open source operating systems and open source drivers and open source software? And you've read the code for the libraries you use of course? Please. Unless you're Stallman you're not really assessing how much black boxing you are actually doing.
And operating system is an operating system. A database is a database. A text editor is a texteditor.
I don't need to know exactly how someone's solution is implemented to understand the concepts and I've written at least one piece of toy software that does everything I do on a day to day. I've done CPU graphics rendering, GPU graphics rendering, web parsing, low level kernel/OS stuff, a lot of things. I'm not an expert. I'm still a student and as such I am and always will be learning. That doesn't mean I'm not a Computer Scientist and that doesn't mean I can't open up documentation on any part of my entire system and get a working facsimile from the ground up. Not to say it will be as performant of course (now that I'm in a computer organization course I can just now realize how horrible my scribbles of a CPU I wanted to build is. No pipelining and everything was going to be hooked up to a huge bus).
Basically, yes anything computer related is something I can sit down and make work. Hardware or software I can design something that will probably work to a degree. Will it work well? No. Will it be the exact same implementation as someone else? Of course not. Will my implementation function the same as whatever I'm replacing? Absolutely.
The black boxing is made in such a way that with basic documentation you can construct in your mind how said box may function.
> I guess you just hate Greek?
No I just like standard keyboard keys.
> The notation is terse and completely obvious to anyone who has the faintiest idea about the mathematics they are reading
The key here is "who has the faintiest idea about the mathematics they are reading". It's not meant for outsiders. It's meant for an in-group. Not for anyone who want's to learn math.
> Just like you do in CS. It's hard to type 'alpha' on an English keyboard or programmers would call things alpha as well
Not anyone who would ever work for, or with, me. I'd replace that code in a hot minute. Anything past a toy you're never going to ever use again NEEDS more then "alpha" or "a". Naming is the most important thing in CS, the runner up is abstraction.
No one worth their salt would ever seriously use single letter variable names outside of maybe the following list:
i, j: Loop variables. Holdovers from FORTRAN.
x, y: Talking about a position in a matrix or in space.
Those are the only 4 I'd ever allow in a professional code base I was getting paid for.
> The subject material in doing advanced mathematics is much more difficult, abstract and complex than writing code usually, so the notation looks more difficult. That's all.
Oh so it's just that mathematics is hard and computer science is easy. That makes sense.
This elitism is part of the issue. I think mathematics is hard but I've worked on many complicated projects and they all don't really seem complicated. We work as a field to tame complexity through understanding a problem domain and abstracting the unimportant implementation details.
It all just turns into operations on data that are (sometimes) sequential. No matter if it is data processing and rendering for an oscilloscope like system, optimizing networking protocols and writing your own stack over UDP to control ordering of packets that are non-essential, or even writing huge orchestration systems that operate on generated statistical models to predict future actions that need to be taken. The simplistic comes from an understanding of how to create interfaces for the complex that are simpler then what they are representing.
> It isn't simple. Because what it's describing isn't simple. It is maintainable because it's easy to read once you understand it. Understanding is the hard part.
It seems like most of the time, when a colleagues explains something to me, I can completely understand the concept but I have no time for the fodder of inefficient notations that are adored by mathematicians.
> Programmers always think they can "fix math" by swapping notation around.
I hardly think I can "fix math". I want someone to fix math so I can learn it and then join in on the party. I want to learn it. It's just overly complicated.
> They don't realize that it's as good as it can be until they actually start doing some real mathematics
You're crazy if you think the current way of doing things cant be improved. Improvements are always happening in my field and I learn and adapt as they they are brought to me. Mathematicians have been stuck with an attitude of "it's different and I don't like it".
> It's a tiny minimal bump along the road that massively simplifies the entire endeavor and tries to get out of the way of actually understanding the mathematics, which is the difficult part
For you it's a tiny bump. For someone who is attempting to learn out of the classroom for their own interests it's the only difficult part. I can go to khan academy and learn about pretty much any college level topic. When I go to take a class at my college (I need to take 3 math courses) I can't learn anything. So much archaic nonsense and a lack of good explanations for new comers.
> The only objection you're raising that has merit is that a lot of the symbols aren't on a keyboard. Which is why we have TeX. Which is the digital language of mathematics. \pi is really not hard to type.
Pi tells you it's a variable, Pi does not tell you why it's a variable. I have no idea how to convey that meaning as I am not in the "cool kids club" that you and your colleagues have built for yourself
To clarify; mathematics talks about objects with increasing amounts of density; as you proceed up the abstraction stack into increasingly abstract topics, you need to be able to efficiently compress the topics you're already supposed to have mastered.
Mathematics is for experts that have mastered the lower levels of the abstraction layer. You cannot study any subfield of math without having understood the basic definitions of the field. No amount of syntax rewriting is going to change that; those definitions are not going anywhere.
"To clarify; software talks about objects with increasing amounts of complexity; as you proceed up the abstraction stack into increasingly abstract topics, you need to be able to efficiently compress the topics you're already supposed to have implemented."
What I'd expect to follow here would be a statement about how your abstractions should be terse and verbose in the right ways. Terse in the implementation specific handling and verbose in the explanation of your abstract solution.
"Software is for experts that have mastered the lower levels of the abstraction layer. You cannot study any subfield of systems programming without having understood the basic implementation of the underlying software. No amount of syntax rewriting is going to change that; those definitions are not going anywhere."
I don't see how that statement would make any sense. I expect to be able to give anyone with the most basic of understandings of computers a piece of any code (from Assembly to high level Lisp code) from widely used software like the Linux kernel all the way to stock trading applications and I expect them to understand it by looking at it for a few seconds, reading the comments, and reading the names of the variables and functions.
If the average person cannot do that, then it's bad code. Understand-ability is the only point of programming. To be understood by the computer and by a maintainer.
I'd never say that obtuse notations for an abstraction should stay around. I'd replace the obtuse notation with a better abstraction.
> I expect them to understand it by looking at it for a few seconds, reading the comments, and reading the names of the variables and functions.
Mathematics also comes with comments, many papers essentially consists of one giant comment for the proof in the appendix. Granted, many variable names could be a bit less terse, but it's just easier to write "let f be an arbitrary function A -> B" once instead of using arbitraryFunctionMappingTheSetOf{DefinitionOfElementsOfA}toTheSetOf{DefinitionOfElementsOfB} every time.
Or there could be a standardized notation for expressing functions and the concept of mapping can be derived from taking a function and applying it to a set of elements.
Function and Map are different concepts that should not be described together.
In CS I'd just say
B = map(some_function, A)
B is the Mapping of `some_function` over the elements in A.
>Function and Map are different concepts that should not be described together
Not in this context. Assuming you are using `map` in the CS sense, B is what is called the "image" of some_function (over the domain A).
In math, a function is a mapping.
Consider the type of `some_function`. In C like notation, it would be `foo some_function(goo x)`. Which indicates that some_function takes an arguement of type `goo` and returns a value of type `foo`. In other words, some_function maps Goo to Foo (where Goo and Foo represent the set of all values of type goo and foo).
That's all fine, but surely there is a middle ground between 'single letter variables or bust' and 'parody of enterprise Java'. It wouldn't kill anyone to use short words instead of re-using phi.
It makes sense to me, although perhaps at a different level --- IMHO redundancy is bad in source code in general, and if you base your development methodologies and practices on assuming that it's not, you end up with things like Enterprise Java and C#: huge, eye-bleedingly verbose monstrosities to perform the simplest of tasks.
Just as with everything there is a sweet spot. I personally feel some things need to stay verbose while some things are implementation and not inherently needed. Before college, I didn't do any python. After touching the language because of a class I like some of the things they do. For instance:
for i in range(10):
print(i)
This is a great way to show a way to print 0-9 to stdout. This is great. Contrary to this, you have a more c-like method of writing this.
for (int i = 0; i < 10; i++) printf("%d\n", i);
This is the same code, but we have a lot more stuff here that convey a lot of meaning. This is fine for me. The construct is dense, but it's not overly dense. It is simple because once you see it the first time, you will understand it and it will always make sense to you no matter how many years pass. I'm fine with this extra verbosity.
On the other side of the spectrum you have this:
map(print, range(10))
This is far fewer characters, but it's more difficult to understand. There are more things to understand if you've never done any functional programming. This sort of dense solution is frowned upon in many cases, especially since this sort of thing rarely scales efficiently in the sense of cognitive load. I did all of my CS labs using map/reduce formulas for CS100 and it did nothing but make things harder and drive a large appreciation for expanding statements into my heart.
It's simpler, much simpler, in this context. It's not simpler when you scale up the implementation being used. After you scale it up it stops being simpler and starts being `clever`.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." − Brian W. Kernighan
Dense and high-level. Like programming languages. You take a group of machine operations and represent those with an operator in a programming language. You take a group of programming statements, expressions, etc and represent them with a procedure. Group some procedures together into a category (or perhaps a 'class' of items.)
Take a few lines of COBOL, compile it, and how much actual machine work does that represent? Lots. Very dense.
> that equation borders on parody in attempting to relay a rather simple concept.
I can assure you the only parody I found was how simple it was compared to how big of a fuss is being made. The notation conveyed the concept of an onto function in exactly the right number of symbols. Every logic step was there, bared to the eye:
A mapping from [1...N] to [1...N] such that for every output, there is an input that maps to it.
As a sarcastic quip, what's so complicated about saying f[x]=y? (Equation wasn't the right word for you to use there).
> We dont expect CS people to communicate concepts through compiled, machine language style syntax
That is a complete misunderstanding of what this is. The symbols (and concepts) on this webpage are roughly equivalent to big-O notation in the Computer Science curriculum, in that they are taught in the first undergraduate course that tries to establish some theoretical basis for the subject.
> As a sarcastic quip, what's so complicated about saying f[x]=y?
IMO that line was the worst offender by far. Just use f(x), especially when you're giving an oral presentation to people who aren't familiar with the context in which the brackets are standards (TLA). Just because your formal system uses brackets for function application don't mean you need to obfuscate your slides.
"I mean who in the hell could call themselves a mathematician without learning how to recognize obscure abstraction principles and language features of Java, something they'll probably never need to use?!?!"
"Some of these people where even smart, I tell you! They are big people who are productive but I have no idea how you could be productive or smart without knowing how to recognize this obscure thing"
Seriously, if you pulled in a bunch of CS people and showed them this:
lambda x: x
And they didn't know what it meant, you have a point. If you pull them in and show them something they don't use often, probably will never really use, and use that as a basis of their worth then I don't feel you have a correct set of KPIs for what makes a good scientist or researcher.
Honestly, this is mostly an issue of syntax (a problem, but one that is remedied with a quick look-up table/cheat sheet).
Giving a legend explaining those symbols would turn the statement into this:
Given a function (f) that maps integers in the range 1 to n onto the same range (1 to n), for every y in that range (1 to n) there exists an x in that same range (1 to n) where applying the function (f) to an input x results in the value y.
(please correct the parts I got incorrect, it's been a while since my last discrete math class).
These symbols are important tools in discrete mathematics, but are easy to forget or get lost in due to the very high information density they achieve. Adding to the complexity, we explain the range of both inputs and outputs before defining the function. Intuitively, I feel CS folks would prefer to define the input range, the function's mode of operation, and finally the mapped output range.
This is especially complex when these discrete mathematics symbols operate upon one another. Throw in some sigmas and boolean operations, and it quickly become very difficult to parse.
The underlying intuition the author is trying to communicate is likely something that entire audience could understand. They simply weren't fluent in the "language" of mathematics. It's like being very articulate in English, and having to defend a thesis in French. Not only do you have to translate your thoughts, many idioms you may usually rely on are no longer valid in a new language.
Finally, why not define that same statement in Python or matlab? It's just as valid in my opinion.
I am a programmer and not a mathematician. I studied more math than typical (almost minored in it) but all of it undergrad and it's been more than a decade since I've done anything formally academic. I read some of the comments here before reading the article, and I was expecting something significantly more complicated and esoteric. Set builder notation, element-of, and quantification - it's practically Python. I find myself genuinely shocked that people here are finding it inscrutable, much less those in the audience at the talk. I can't help but wonder whether most of those with their hands down weren't able to understand but lacking confidence that their read was correct?
I'm npt a CS major, and I also don't have the slightest idea what that formula is about. Don't even know half of the symbols.
Granted, my bachelor's isn't even a scientific degree, I'm an ex-addict turned sysadmin recently turned programmer, self-taught entirely. But I'm freaking sad I was a dumb kid who thought math was stupid once and that our school system (Germany) made it so easy to use my talent for language to average out my dare-I-say intentionally bad grades in the subject.
It's not even that I was bad at it. What drove me to computers, to code or crafting ridiculous zsh scripts in the first place was formulating my own approach to solving a problem. As much as I sucked at "solve these twenty equations like this", I used to love problems stated in natural language and coming up with a solution. Should've built on that.
Anyway, besides the late night regret... Can anyone of you recommend a book for me? Think little to no familiarity with the terminology, many years of only using what math a supermarket or insurance situation entails, eagerness to learn and fascination with the subject. No delusions about becoming a regular mathlete in my early thirties, I just want to fix a lack of knowledge caused by pubescent idiocy.
Alright, hold up a section of C++ or js code and repeat similar questions, and then ask why mathematicians don't learn to code given how relevant computer programming is to applications of mathematics today.
Not that I believe mathematicians should learn how to code as a perquisite for their degree, I don't. I also have similar feelings for CS students and understanding mathematical notation. Yes, if you're headed for grad school or a researcher, then it's a different story (so the grad students/academics should have tried may be). But should knowing that notation, say, be on the same level of importance for understanding programming concepts like cache-locality for someone headed to a typical dev job? Probably not.
I'm surprised anybody calling them self a 'computer scientist' couldn't follow that - developer, sure, but as far as I'm aware everyone on any CS degree programme in the world "learns math"; enough to follow that for sure.
Yes, to me "Computer Science" has always been a branch of (applied) math that deals with mathematical theories that apply to computing - complexity, discrete math, numerical methods, operations research, automata, etc.
It's sort of weird that a mathematician would confuse 'notation' for 'math'.
This is like giving an algorithms class to a mixed group of perl and Haskell programmers, using Haskell for all the examples and wondering why perl programmers don't learn computer science.
If you don't speak the language, It indicates that you never learned the stuff that is spoken in that language. At least well enough to be fluent in it.
> If you don't speak the language, It indicates that you never learned the stuff that is spoken in that language. At least well enough to be fluent in it.
Not true. I learned all the maths necessary to understand that formula and, in fact, have previously seen all the symbols used before. Once I looked up the syntax I had no trouble understanding what was being said.
The problem is that the language is simply bad. I haven't written PHP for years (in fact, the last time I wrote PHP was around the last time I took a math class), but if you give me a snippet of PHP I'll have no trouble understanding it.
Do you think that the people in his room didn't understand the concept of a function mapping over x coordinates whereby the height of each y component equals that of it's position on the x axis?
Or more simply put, do you think these people have never taken a math class in high school that went over
If you study math enough, you learn to read this math notation fluently. From his toy example you can infer that they have not studied much math very deeply. Like topology or advanced algebra.
I think this is exactly correct. When someone explains what that notation is, I understand it, but when it's drawn like that, it's meaningless to me.
As another analogy, it's like an English speaking person taking a french basic-math class. You know like addition, subtraction, etc.. but taught in french.
I loved math and sailed through it in college. Algebra, calculus, linear algebra, theoretical classes- no problem, I never got less than a B+. We had a lot of classes where using the calculator was forbidden and you had to actually know how to break these things down. When I was practicing math I can't understate how easy it was for me.
The problem is that's it's been 12 years since I used a differential equation or any of my other 'hard' math. It's really frustrating that I used to be able to look at these equations and know what they meant and now I can barely make heads or tails of simple f(x) type stuff. I could solve (simple) differential equations without even jotting a note down, I honestly don't know if I could read one now.
I suspect if you wrote some code to solve differential equations 12 years ago, and went back to that code today, you'd understand it without much hassle. This is the failure of maths as a language IMHO.
But you'd be looking at two different things. When looking at a math textbook on differential equations, you're looking at why a class of expressions constitutes a solution to a differential equation. Looking at code, all you'd get is the mechanical how something is computed, and you'd have to take it on faith that what was computed constituted the solution you were looking for.
That's not a fair comparison, since (it sounds like) the parent commenter's been coding for the last 12 years.
The analogy would be more like studying both, writing a formal type system for a programming language, then practising mathematics for twelve years, and still understanding the type system.
He obviously runs though the speech he had ready (there is not half a second of a break at any point) whatever the actual assistance response may be.
Also note that he inundated the audience with a different formula popping in random places of his screen every 5 seconds for at least the previous 2 minutes, with constant more or less related babbling.
It sounds to me like a dishonest behaviour and conclusion. I must say I am neither a mathematician, nor a computer scientist, so I don't have a side to take, and I understand the formula, but I would not have raised my hand due to the fact there was only 5 seconds between the time the formula popped up about at the third of an already filled screen, and the request to raise one's hand. (And also because the one who raises his hand may end up cleaning the toilets. Beware.)
We should rephrase the question as "why don't computer scientists learn traditional math symbols?"
Try writing traditional equations with your keyboard. Try posting your answer online. Modern computer science breaks down these symbols into plain english.
we do have math typesetting you know... With a standard programming language for typesetting handled by all major browsers. Just head over to Mathoverflow and see it in action
Also, when writing code it's not unusual (at least among LISP and Haskell programmers) to have the editor replace a word for its corresponding symbol, the most famous example of which is (lambda -> λ) because some people find it easier to parse e.g. in emacs[0]. You can easily imagine doing that for other expressions, like (forall, there-exists, ...etc).
All in all I think it's a matter of preference which is in turn related to each individual's experiences.
Math notations are so badly designed (if there exists any design) If you'd spoken in plain English, Lamport, most people in the room could have understood the concept of your tedious formula.
So it's not because we don't understand math - it's because the math notations are usually over abbreviated, obscure and inconsistent. Math itself is strict but there's no strict common language to express it, which eventually prevents people from understanding it.
There is a strict common language to express it. The speaker used that language (except for the nonstandard replacement of brackets with square brackets, which was apparently clearly pointed out at the start). The problems start when you speak in plain English: then you get things like everyone using different definitions of continuity and thinking everyone else is just spouting nonsense until someone comes up with epsilon-deltas.
As a CS researcher I probably wouldn't have raised my hand, thinking it was some sort of a trick or that the speaker was making a point about how simple concepts are sometimes conveyed in confusing ways.
I appreciate mathematics, but because I don't use this notation on a regular basis, I wouldn't have been confident enough to raise my hand.
Yeah, I don't judge those in the audience too harshly. I could certainly see, given limited time allotted, thinking "it's probably not that simple, maybe I'm missing something...?"
When I went through Uni we learnt several different types of Math including discrete math, advanced calculus, and probability and stats. The math described in the article falls under discrete math.
The notation used is similar to that used within formal methods.
However, since Uni I have rarely needed to use the math notation, and so I am unable to understand it without "interpreting" it. Such notations have most relevance to understanding database schemas and other set theory type problems, however, generally speaking, in software development using such a notation is unneeded.
In summary, the reason computer scientists don't know math is not because they haven't been taught it, but rather that the notations are not very relevant, and therefore soon forgotten.
It means nothing. Or it could mean anything. The surrounding text is what explains the meaning you're supposed to derive from mathematical glyphs. Of course there are conventions. "x + y" usually means what most people would assume it does. And sometimes it doesn't. Read the paper to be sure.
I haven't finished watching the talk yet, but he seems to be arguing that programming languages aren't expressive enough for mathematical purposes. I suspect he's not counting all of the wordy scaffolding necessary to support those terse equations. Can it all be combined into a formal language that stands on its own? If so, might it look like a programming language?
I was struck by Butler Lampson's observation along the same lines, in 'Programmers At Work', Lammers [0]
INTERVIEWER: What kind of training or type of thought leads to the greatest productivity in the computer field?
LAMPSON: From mathematics, you learn logical reasoning. You also learn what it means to prove something, as well as how to handle abstract essentials. From an experimental science such as physics, or from the humanities, you learn how to make connections in the real world by applying these abstractions.
I have noticed that CS majors tend to be separated into two groups, those who got linear algebra and those who got THROUGH it. Programmers are very logical in their thinking but most are not what I would call traditionally mathematical in their approach to problems.
Put me in the got "through" it camp. To this day my Pavlovian response to any linear algebra is "put it in a matrix & solve", even if I don't have an intuitive understanding of what that means.
Does anyone else feel like the font made it harder to read? It doesn't look like latex. :P I have no problem reading math formulas, but this particular one is harder to read than normal for some reason.
Who am I to argue with Leslie Lamport, but still I reject the premise. Computer scientists do learn math, regardless of whether they read Greek-letter math notation. Write a function with a for loop or array map, and you've used all the same math concepts as this example formula.
For the same reason mathematicians don't learn computer science.
And that answer is: most do. The fields are very complementary.
Set theory? I personally don't have need for that right now. But I've been working my way through https://pomax.github.io/bezierinfo/ which the most complete resource to bezier curves I've seen, including closed-form solutions, analytical methods, and interactive demos.
Slightly off topic, but the video linked in the OP was worth watching for more context. However, he mentions at several points that the Virtuoso operating system for the Rosetta spacecraft was designed using TLA+. That is not the case: http://research.microsoft.com/en-us/um/people/lamport/tla/co...
Maybe the CS people don't know set notation for the same reason that Lamport dismisses Homotopy Type Theory and Galois Connections at the 2:00 minute mark.
At the University of Waterloo a CS degree was a Bmath degree with a CS major up until like 12 years ago, when a BCS was an option with slightly less Math courses. It was so much math I almost dropped out because I hated it, felt like no programming or real world stuff, I just kept waiting for it to get better until I finally realised this is it, it's mostly just math, that's what makes it "computer science". I grunted through it and got my degree and learned everything I use today mostly on my own. There was a good base but I've forgotten most of the math and notation now because it's mostly useless to me and I didn't like it or fully get it. Maybe that was just a UW experience as it was a highly touted math school.
TL;DR Comp Sci I took was all math so I don't get the title!
This is entirely dependent on the program. My undergrad had few set-theoretic math classes. Sure we had to take discrete math and combinatorics, but this kind of notation was lacking. I learned it by way of double-majoring in mathematics.
Conversely, my master's program pretty much assumed you were comfortable with set theory. CS103 is a freshman/sophomore level class at Stanford and is a prerequisite/foundational course for the master's degree. I was out for five years before returning for my master's. It is 100% true that programming skills are more useful in industry, and re-learning the mathematics was the hardest part of returning to school after being out for five years.
With that said, machine learning is eating the world, and it requires a very good understanding of the underlying mathematics.
I certainly learned enough math to understand this when doing my CS degree. The better question is "Why do people who don't use something every day forget the details of how it works?"
When phrased that way the answer is more obviously. I've learned plenty of things I have let myself forget.
CS is interesting because it's about logical expression. You have an idea, now figure out the steps to make that become reality. Sure, some higher maths may be required along the way, but almost always as an ancillary task.
i suppose, but one reason I had no interest in math in school was I saw no practical point to a formula, and less-so for a proof. It may be a personality issue with me, compounded by less-than-engaging math education techniques, but I think a good analogy would be: I always loved legos as a kid, and programming is like grown-up legos to me :)
That kind of math was common on the whiteboards around the MIT AI lab in the early/mid 1980s when I was there. Then again, (to kapitza's comment) ∀, ∃, and ∈ were on the Lisp Machine keyboard (and the KTV keyboards on which it was based).
This is not about mathematical notation. It is about a lot of people working in computing, researchers even, not being able to follow what is going on at what may be the leading edge (cue the arguments that it is not relevant...)
On the other hand, what percentage of physicists understand string theory? I do not know where that figure lies, whether a low number would be a problem, or whether it would be relevant to the computer science case. I do suspect that I would be better at computing if I understood category theory or TLA+ (I would at least be better able to evaluate their prospects for advancing the field), and I am not going to make any excuses for my ignorance.
I would argue that this formulation is outright confusing not because it is so dense but because it has so much unnecessary cruft to misguide the reader.
The entire formula of
{f ∈ [1..N ⟶ 1..N] : ∀ y ∈ 1..N : ∃ x ∈ 1..N : f[x]=y}
could actually be written as
[1..N ⟶ 1..N]
Most CS people myself included will not trust their own senses when confronted with such a tautological statement and continue to search for meaning where there is non because it is so common to encounter cases in your everyday code where something that you thought was dead code has actually semantic meaning.
If by [1..N ⟶ 1..N] you mean the set of functions from [1..N] that have values in [1..N], I think you are wrong. The formula in the post describes a subset, the set of such functions that are surjective.
Yeah I think your right, in this context I saw the case of [ A -> B ] as a function from coimage A to image B which are all bijective. But it is meant as the more standard domain A to codomain B.
His natural language description is somewhat lacking in that aspect
> I had already explained that [1..N ⟶ 1..N] is the set of functions that map the set 1..N of integers from 1 through N into itself,
This feels like naivete and arrogance of the question asker. Why should a group of computer scientists understand a particular equation? What does it mean if they don't?
> Why should a group of computer scientists understand a particular equation?
Because it's incredibly simple, and expresses concepts they should already be familiar with as they're both incredibly basic and plenty relevant to CS. The notion of "one-to-one" and "onto" functions is taught in high-school algebra!
> What does it mean if they don't?
It mostly means they've not been using this notation, which is a problem not because the notation is necessarily perfect (although I dispute those saying what's used here is particularly arcane - this is super basic stuff) but because there is a whole lot of relevant knowledge encoded that way (including plenty of CS papers!) and clearly they haven't been accessing it.
I took a few CS classes while studying engineering undergrad. I also have a grad degree in Industrial Engineering from Columbia U. Now-a-days, I develop software and apps.
The training in mathematics, operations research, and mathematical modeling has been extremely helpful in the way I approach and solve computer science problems. It has helped with everything from smart SQL queries to developing scalable software and enterprise architecture for software.
This post requires some context. This is not about math, which is the field that studies things like stochastic PDEs and elliptic curves. It's about the notation of predicate calculus, which is a somewhat obscure field of logic that used to be in vogue in the early 20th century, and that programmers fixate on for some strange reason.
I'm a computer scientist in France and I think it's weird not to know these symbols, don't you learn how to use them in other countries? I mean, I learnt how to read this kind of formula in high school and used them intensively during my scholarship
We like having small sets of primitive notions ("exists", "for all", "set"). The reason we have words like "surjection" is to abbreviate things which are otherwise unwieldy to state precisely using our small set of primitives. It's analogous to the reason we might program in high-level languages and then compile down to machine code: because the low-level code is much easier to execute directly (analogously, the primitives "forall", "exists", "set" are extremely intuitive and we're nearly all sure that they are non-contradictory).
I wasn't a CS student, but the story at my college seemed to be that if you liked math then you were a CS major, if you didn't then you were an SE major.
I suspect most of the CS researchers in the room were, in a sense, lying. I'm going to guess (a) they could all understand the notation if they tried; (b) they were in fact taught the notation in some undergraduate class, math camp, etc, etc; and (c) what happened is that they intentionally forgot it.
At least, this is the case for me! I think one of the dirty secrets about the CS distaste for many areas of math, including conceptual areas like category theory that are in fact quite closely related to computing and directly applicable there, is that when judged as CS, they don't seem like very good CS.
For example, a programming-language designer who uses symbols that aren't on any keyboard deserves to be laughed out of the room. What are these weird 19th-century squiggles? I see what you're doing, sort of, but why are you doing it?
This is obviously a petty example. But computer scientists, at least ones with a certain kind of systems background, have put a lot of work into designing abstract logical structures for human beings to use. They've learned a lot of rules about how to do this well.
The corpus of pre-CS math that gets applied to CS doesn't seem to care about any of these rules. It takes a lot of work to come up with a CS aesthetic, and when you have one, your brain only has room for "good" systems that play by your rules. If a system doesn't map to your rules, it's almost physically painful to have to contemplate it.
Practicality is not quite the issue. TLA+ seems to be a very useful thing and Lamport has produced a large, large, body of extremely useful work. At the same time, I can't help feeling it would be neat if someone did for TLA+ what Ousterhout did for Paxos.
This! Exactly this! Honestly as a CS person I might be completely biased but, I often hear this quote around the office "The hardest part of software engineering is naming things". We spend a lot of time and effort to name things in a way that a non engineer would understand. I wish people in hard sciences would do the same. I often times understand the underlying concepts described by all these Greek letters and symbols but it gets lost in translation. That is why I love efforts like https://betterexplained.com/ where math is made concrete.
Part of this is because most mathematics is written for mathematicians, certainly not for non-engineers. Another hard part is that the concepts in mathematics are so abstract, and so unprecedented, that "reasonable" words that could be interpreted by non-technical people simply don't exist. This is even true in basic calculus. What is a reasonable name for "the function that describes the slope of another function at every point"? Keep in mind that you have to use that word over and over again for the next 1k pages of the thing you're writing, build up 50-100 other definitions recursively on top of it, and make sure it's relevant for all possible uses of the concept in the future of humanity, even uses that we today cannot possibly conceive.
You might reasonably say, "This is all the more reason to spend a lot of time thinking of a good name!" While everyone else actually doing math would say, "I need to get my work done, so let's just pick a name and get on with it." When math is done right, the concept in your head is concrete and ingrained enough that the particular word your using isn't that important.
That being said, having done math research and software engineering, mathematicians do spend about as much time as software engineers naming things. It's just easier for software engineers.
I was a mathematician and physicist before I went into CS, and when you're doing all your writing on paper and chalkboards, you don't want to write 'code' at all.
The idea of names as power comes from pre-unified Ancient Egypt in which (i may have gotten the kingdoms mixed) the upper kingdom's religious rituals included the use of secret and ceremonial names known to only an elite literate cabal. From there the religion developed to include aspects of secret names for anything and everything and religious texts indicated that people believed once they learned something's secret name they would be able to exert control over them.
In fact, most of the concepts one associates with 'magic' (sigils, astronomical connotations, power words) derive from the Ancient Egyptian religion. See Wallace Budge's "Egyptian Magic" for an excellent treatment on the subject. His book has tons of direct primary source examples that are very entertaining (people turning into crocodiles, priests trying to shape the outcome of wars by creating effigies, lots of fun stuff)
>east ones with a certain kind of systems background, have put a lot of work into designing abstract logical structures for human beings to use. They've learned a lot of rules about how to do this well.
This is very arrogant and wrong. The exact opposite is true. Mathematicians have worked hundreds of years and streamlined notations that can express complect things well.
Mathematical and sheet music are both organically grown. They're like C++ for math and music, but with about fifty times more cruft. Our forebears just kept adding on to and expanding purely crap syntax because getting people to change the existing way they do things is nigh impossible. Going on to hail this as "refined" is beyond me.
EDIT: Sometimes, in maths, different disciplines have conflicting syntax. Rather than fixing this, we just resorted to overloading (see i vs. i in maths and physics). If any programmer encountered that kind of thing in a computer language they would describe it as clearly evil.
Mathematics is organically grown but reinvented every few years or so. Look at a mathematics paper from 50 years ago. Look at one now. Look at one 100 years ago.
Mathematicians aren't dumb. There's some element of tradition (that's a small part of the reason why many mathematicians prefer chalkboards to whiteboards) but most of the reason we use the notation we use is because it's the best way anyone has ever found to express rigorous, technical, creative, abstract thought cleanly and efficiently. Mathematicians routinely do completely /new/ work which requires us to invent entirely new notation out of wholecloth on the spot. The techniques we use are suited to this need. When we find something that's better, we use it. There isn't anything better yet.
Sheet music is terrible until you try to design a better system.
It's easy to design a better toy system. It's very, very hard to design a non-toy system that encapsulates all of the information in a full orchestral score and makes it readable for players of all instruments.
This is dead on, IMHO. I mean, we joke about some language, company, or product being fetishistically backwards compatible, but we've got nothing on music, which is somehow backwards compatability obsessed, but also not actually backwards compatable, because note frequencies have slipped, and most people only know a tiny subset of the actual notation.
Math is even worse. It's syntax piled on top of syntax. It's actually evil.
I am a mathematics student working as a systems software engineer. I find mathematical notation excessively dense and tedious to interpret.
Given the expression:
{f ∈ [1..N ⟶ 1..N] :
∀ y ∈ 1..N : ∃ x ∈ 1..N : f[x]=y}
I can instantly read it in my head as:
The set of all f where f is a function mapping 1..N to 1..N such that for all Y in 1..N there exists an X in 1..N such that f[x] = y.
One might argue that the ability to express such a long definition in such a compact form is a benefit, but I don't think so.
In this particular case the definition is so trivial that it's easy to understand what is being talked about. Anything more complicated than this quickly becomes tedious and boring. I would prefer that mathematicians simply used longer, more verbose, but more clear and explanatory names for quantities and concepts. Just my opinion, though.
I studied math and computer science at university. My personal experience was that if you wrote a long string with quantifiers in your vector spaces or analysis homework or whatever, the professor would ask you why you were acting like you were still in your 'Intro to Proofs and Logic' course and to please rewrite your homework in English. It was assumed that you could translate between quantifier predicate stuff and English, and that you should just therefore stick to English so your professor can actually read it. The CS faculty members were much more fond of writing stuff out in such formal terms like that (especially in the CS-oriented math classes like a general discrete math course, or an automata course) possibly because they thought the CS kids needed more practice with the notation.
My math profs emphasized juggling multiple layers of logical abstraction and omitting all unneeded explanations, while the CS guys wanted everything in excruciating detail and extremely formal language.
I graduated in 1989 with a math degree. For 24 years I didn't look at mathematical notation. Now in grad school for CS I'm seeing a lot of notation like you wrote. Some of it is coming back. But, it has become exceedingly difficult to remember a single Greek letter, embodying a concept, a page or so after it has been defined. The concepts are not especially difficult, but remembering symbols has become frustratingly so.
My current course is Programming Language Semantics. It's all relations, functions, states, predicates, induction, etc. Greek letters are used all over the place. The topic is interesting and I love implementing semantics in Prolog, but the mathematical notation is painful.
The problem is they are used as shorthand for complex ideas that the student is assumed to already know and be aware of. And don't forget upper and lowercase refer to different ideas, and if you are a physicist they will means entirely different things.
If mathematicians used longer notation then "the obscure symbol defined 5 pages back that I totally would remember if it was spelled out" would be more like 30 pages back. Brevity and standard notation are critical for understanding.
> Brevity and standard notation are critical for understanding.
Totally! That's why Perl has taken over the field of software engineering, vanquishing all who came before it.
And for the handful of people who find Perl hard to read and understand: choose another career because brevity and standard notation are critical for understanding, and Perl has that in more abundance than any other language. The problem, as it were, is you.
There's nothing standard about perl (parameter passing via lists, DIY OO, references in a scripting language, and there has to be more that I don't remember anymore - IMO these are the true reasons perl lost its popularity while ruby and python remain lively), nor is perl compact compared to other scripting languages. The parameter passing stuff especially made perl a verbose language.
> IMO these are the true reasons perl lost its popularity while ruby and python remain lively
As a perl cum python developer, no. It's that I had to spend time reverse engineering the code I wrote last week, because of the hundreds of obscure symbols I cleverly used to reduce thirty lines of clear code to five lines of compact code.
Python and Ruby both have to deal with references (though much more indirectly via the concept of mutable objects), as well as arguments coming in as parameter lists (and dicts).
So what in perl made it conductive to that kind of coding? I never worked with perl much but back then I got the impression perl being line-nose or whatever was more legend than reality. Perl's not a different paradigm like APL.
And by references I meant exactly that perl is not pass by reference, unlike just about any other scripting language. R is the only other popular one I can think of that's not. There's shell too but it doesn't count.
> So what in perl made it conductive to that kind of coding?
"Because I could"
More specifically, in very short programs, the shortcut values were actually valuable, and the mental overhead for interpreting them in short subroutines or programs was minimal. The problem is that programs don't stay static, and that single time-saving shortcut becomes two, then four, then eight, then...
Soon, it's an absolute mess.
Even once I realized the cost, I had to follow the coding conventions of those who had come before, at the cost of increasing the cognitive overhead even further. A self-reinforcing loop.
> not pass by reference, unlike just about any other scripting language
As Smaug says, Python is pass by value. The trick is that the value is always a reference to an object, or more specifically “pass-by-object-reference” (“Object references are passed by value.").
This causes a few subtle behavioral inconsistencies, such as the dreaded `def a(b=[]):` bug.
I'm way late to reply, but I never really understood what would qualify as pass by reference according to that logic :D you do have to pass a value eventually, it can't be references all the way
Verbose identifiers in program code are most useful near the top level, where the ideas they give a name to are very specific, while mathematical formulae often concern generalities, so verbose names are not always applicable (or at least not always helpful - even in code, identifiers that try to be too descriptive can make it hard to read, though people rarely err in this direction.)
One of the uses of the notation is to serve as a map for a more long-winded description, as you can lose your place in verbose explanations when they begin to get complicated.
More importantly, perhaps, is their use when you are applying formal manipulations to them. I think author's point is that many computer scientists apparently lack the background to follow or evaluate some of the important current developments in their field.
The notation and its meaning are both pretty clear, but I don't see how it converts to "the set of all permutations from 1 to N". And permutations of what? The integers 1 to N?
You can look at each permutation as a (unique, one-to-one and onto) function from the set [1,2,3,...N] to positions labeled also [1,2,3,...N]. For it to be a permutation, each position needs to contain a single value, and each value needs to be at one single location. Since the domain and range of the function have the same (finite) number of elements, either of these properties implies the other.
I think he was just clarifying a point about the notation.
Given that each f is a function, mapping each member of its domain to one member of its range, and that for each member of the range, there is a member of the domain that the given function maps to it, and that the domain and range are the same size, then there can be no member of the domain not mapped to some member of the range, and each member of the domain must be mapped to a distinct member of the range (or else there would not be enough members of the domain to cover all the members of the range), so, with the domain and range being the same set, each of the given functions is a permutation of the domain, and collectively they must be all of them.
This is a verbose version of the argument for this being the set the author says it is. Arguably, it would be easier to read if I had used x for 'member of the domain', y for 'member of the range' and f for 'the given function'.
I don't really know what you just wrote, but it's not "F is a surjection", which is what the post is capturing. If you're not quantifying somehow, even implicitly, then you're just not giving the same definition.
It can be written with fewer symbols: `f: [N]->[N] s.t. x != y => f(x) != f(y)` is an equivalent formulation, for instance (since f from a finite set to itself is surjective iff it is bijective iff it is injective). The quantification is now implicit in the "implies" symbol. Not sure how standard `[n]` is to refer to {1,2,…,n}; it was used commonly in my undergrad courses.
It conveys ideas well in the level you need to think about them. It's not accurate syntax in CS sense but it conveys ideas well from mind to mind.
I think many CS students have problem with mathematical notation because it can be both accurate and syntactically very sloppy and informal at the same time. It's human language and notation, it's not for computers.
> But computer scientists, at least ones with a certain kind of systems background, have put a lot of work into designing abstract logical structures for human beings to use. They've learned a lot of rules about how to do this well.
You say this like mathematicians haven't been doing this for thousands of years.
Of course, the alternative hypothesis is that they weren't lying and they did forget it. As someone who majored in math quite successfully within the last decade, I can honestly tell you I didn't remember what ":" meant and therefore had trouble parsing the expression. I don't think I forgot intentionally or was lying.
As someone currently majoring in mathamatics, I can honestly say this is the first time I have seen ":" used in this way. The "standard" way I would expect to see that would be for the first ":" to be replaced with a "|", and the second one to be replaced with a "," (or omitted entirely). The third ":" does not look out of place, although I would probably omit it, or right it as "st".
EDIT: for clarity, I would right the set as:
"{f : [1..N ⟶ 1..N] | ∀ y ∈ 1..N , ∃ x ∈ 1..N st f[x]=y}"
The ":" in this case indicates that f has the indicated type.
As long as I am commenting on my sense of "standard" notation, I should also note that the "[1..N ⟶ 1..N]" notation also seems weird (as in, I have never seen it before). I would expect it to be written as [1..N] ⟶ [1..N]. Perhaps replacing [1..N] with Z_n for the appropriate audience; however the speaker seems to be aware that this is a strange notation, as he commented about it in the beginning.
In this particular case, I would probably also omit the entire predicate in favor of writing "onto" above "⟶", which I can do because the particular property being described is common enough to have a name; however this would defeat the point of showing the notion. Once I have entirely omitted the predicate like this, I would probably omit naming f entirely, giving the notation {[1..N] ⟶ [1..N]} (again, with "onto" written above the arrow).
Actually, depending on audience, in this particular case I would replace the entire set with either "The symmetric group of order n", "The symmetric group S_n", or just "S_n".
The f[x] notation looks a bit weird out of context, but does come up when the distinction between a function and a function application is important (often times f(x) is used as a convention to remind the reader that f is a function)
Lamport wrote it the way he did because that's the TLA+ notation, and the talk was about TLA+. That formula is actually parsed by the TLA+ tools. Unlike paper math, TLA+ needs to have a precise grammar. I'm really not sure why `|` isn't used in set comprehensions, but I'm guessing that he wanted to keep `:` as "such that" everywhere. `f[x]` is used b/c round parentheses are reserved for operator arguments, and functions aren't operators (the whole thing is based on axiomatic set theory, and in formal math "function" must be something very specific).
Logic in philosophy is used in a lot of fields of humanities and social sciences too. When you have inductions and deductions based on qualitative axioms what you write is going to take a lot of brainpower to understand. A lot of the academic work in those fields takes thousands of words to explain all the thinking behind something that could be broadly explained in a paragraph.
Admittedly, my exposure was brief and I certainly don't know the notation by any name, but the logic courses used drastically different notation from what I was used to in my math classes. Some of the symbols were the same, sometimes they had the same meanings, sometimes not. Often there were different symbols entirely.
I'm not sure intentionally forgetting something is even possible, but, who would intentionally forget something foundational? Most computer scientists do study math and generally wish they knew more, not less.
Yes, agreed! You'd think most of the CS people in a room listening to a Lamport lecture, of all things, would've at some point in their education taken a theory of computation or similar course. The notation Lamport was asking about is already taught by page 7 of chapter 0 in Sipser [1].
As a mathematician/(ex?-)computer scientist whose area of research is category theory, let me ask: What makes category theory not seem like very good CS?
For what it's worth, it does bother me how much standard CS tooling and the mindset bred from it is stuck in the paradigm of exclusively textual user interfaces. Linear text has its advantages and value, of course, but, like, we know well by now that not everything is best thought of or manipulated this way; that diagrams and other modes of communication and interaction can be useful.
(This has nothing to do with why I'm interested in category theory [it's not that my motivating goal in life was to draw commutative diagrams…], but it's a somewhat relevant thought to the discussion I've had all the same. We as computer scientists talk a lot about trees, and graphs, and this structure, and that structure, and also about human computer interaction, and the importance of design, and yet the only structure we allow ourselves expression via at the end of the day is text, text, text.)
A lot of people draw informal sketches while thinking things through, and there have been waves of enthusiasm for formalizing such things, but except in a few specialized cases (e.g. state transition diagrams) nothing so far seems to have proved useful enough to really take off.
I do wonder sometimes if we are too focused on computer languages, to the detriment of tools (see also Animat's comment.)
I think I remember this particular notation, but only because I beat it into my brain trying very hard to not tank my GPA in a ridiculously useless discrete mathematics class that was required for me to finish my CS minor.
I used to work on formal specifications and program proofs, around the time Lamport was developing temporal logic. I took the position that, rather than trying to make programmers learn math, we should automate and divide up the problem so that they didn't have to.[2][3] This meant minimizing the formalism and making the verification information look like ordinary programming. It also meant carving out the harder math problems into a separate system where someone using a theorem prover would prove the necessary theorems in a way which allowed their use and reuse by ordinary programmers. The underlying math is still there, but not in your face so much.
There's a mathematician mindset: Terseness is good. Cleverness is good. Elegance is good. Generality is good. Case analysis is ugly. This is unhelpful for program verification.
Program verification generates huge numbers of formulas to be proven. Most of the formulas are very dumb, and can be dealt with automatically by a simple theorem prover. Where it's necessary to prove something hard, our approach was to encourage users to write more assertions in the code to narrow the thing to be proven, until they were down to "assert(expra); assert(exprb);" Getting to that point is much like ordinary debugging.
Now they just needed a theorem, independent of the program, that could prove "exprb" given "expra". That job could be handed off to a theorem-proving expert. A library of proved and machine-checked theorems would be built up. Some would be general, some project-specific. This is the software engineer's approach to the problem.
The mathematician's approach is to capture much of the program semantics in mathematical form and work on them as big math formulas. Most of the work is done in the formula space, where mathematicians are comfortable, not the code space, where programmers are comfortable. This seems to hold back the use of formal methods in program verification.
Much effort has gone into trying into trying to find some clever way to make program verification elegant. "A great variety of program logics are in use in computer science for the specification of (software and/or hardware) systems; for example: modal and temporal logics, dynamic logic, Hoare logic, separation logic, spatial logic, nominal logic, lax logic, linear logic, intuitionistic type theory, LCF."[4] We used to call this the "logic of the month club".
[1] http://research.microsoft.com/en-us/um/people/lamport/tla/bo... [2] http://www.animats.com/papers/verifier/verifiermanual.pdf [3] http://portal.acm.org/citation.cfm?id=567074 [4] http://homepages.inf.ed.ac.uk/als/PSPL2010/