178 karma · joined May 15, 2019
Socials:
- github.com/Andrew-Foote
Interests:
Art, Books, Gaming, Music, Programming, Remote Work, Science, Web Development, Writing
---
Having queries return multisets rather than sets "breaks" the relational algebra in the sense that it breaks this correspondence. Results of queries no longer correspond one-to-one to properties, since properties have no multiplicity. To be fair, you can identify the property being true or the element belonging to the set with having multiplicity > 0, and the property being false or the element not belonging to the set with having multiplicity 0, and by doing this you can think of SQL queries as corresponding to sets/properties most of the time. But if you're going to think of them that way, you might as well just have them be sets in the first place. The multisets are just a needless complication. Thinking about SQL queries in terms of multisets seems to only be compatible with a more imperative, non-relational approach to the language, where you still have to think algorithmically about how to assemble the collection of results that you want, rather than just directly characterizing the results in terms of a property.
At some point you have to go into the formalism to really understand it. It's really about an interchange of quantifiers. If you have a non-empty set X that it is true that
[a] (exists x)(x in X)
If you have a family F of non-empty sets X then it is true that
[b] (forall X in F)(exists x)(x in X)
But to say that you have a choice function f for F is to say that
[c] (exists f)(forall X in F)(f(X) in X)
It turns out that the laws of first-order predicate logic and the axioms of ZF set theory do not allow you to come up with a formal proof that [b] implies [c]. You can try to find one, and you will fail. It's like the parallel postulate in Euclidean geometry. There is actually a proof that the axiom of choice is not provable from the other axioms, but it's a pretty deep result. Historically, there was quite a long time between when the set-theoretical foundations for mathematics were developed at the start of the 20th century, which is when mathematicians realized that the axiom of choice was a principle that needed justification, and when Paul Cohen proved that the axiom of choice wasn't provable from the other axioms, in the 1960s.
So if you believe that the implication from [b] to [c] is self-evident, you have to assume
[d] (forall X in F)(exists x)(x in X) => (exists f)(forall X in F)(f(X) in X)
as an axiom, which is the axiom of choice.
I think most people are inclined to agree that [d] is self-evident---that's why it's generally accepted as an axiom, with only a minority of people objecting. However, in the larger context of set theory it makes a lot of sense to minimize the amount of existential assumptions we are making. Historically, set theorists assumed that any set given by a definable formula would exist, but this lead to contradictions (Russell's paradox). So there's some reasonable paranoia about using additional axioms when we don't need to, in case it somehow leads to another inconsistency.
Doubting the axiom of choice means thinking that when you have infinitely many sets to choose from, it is possible that not only is there is no natural choice function, but there is no choice function at all.
Now if you fix a particular formal language for defining real numbers, with a finite alphabet, then the language only has countably many words, hence there are reals not definable in the language. But the notion of "definability" here is not independent of the choice of formal language.
So "choosing an undefinable real number" amounts to "choosing a real number not definable in L", where L is some fixed formal language---and this isn't particularly hard to imagine; given a specific L, you can probably quite concretely construct a real number not definable in L.
I think the writer might have been meaning to imply that there's a spectrum of properties from countably infinite to dense to uncountable, where each property is stronger than the previous one. But this is actually not the case. The Cantor set is uncountable, but nowhere dense. So density is not just something that's in between countability and uncountability---it's an orthogonal thing.
- Sets as fundamental: define ordered pairs via Kuratowski's definition, define relations as sets of ordered pairs, define functions as relations not containing any two ordered pairs with the same first projection but different second projections
- Relations as fundamental: define sets as unary relations, define functions as relations the same way as before
- Functions as fundamental: define sets as functions where the codomain is some fixed singleton (characteristic functions are more appropriate for subsets of a set, rather than sets on their own), define relations as functions whose codomains are power sets
Because of this sort of thing, I don't think any notion of "fundamental" that's purely based on interdefinability really makes much sense.
I personally have a sense that some definitions are "constructive" and others are "destructive" (my use of "constructive" here is in no way related to "constructive" as in "constructive logic", it's just based on the English meaning of "construct"). Of the definitions I gave above, I perceive the definitions of functions and relations from sets, of functions from relations, and relations from functions as "constructive", while the definitions of sets from functions and from relations are "destructive". Since I can't think of any "constructive" definition of sets from functions or relations, while I can think of "constructive" definitions in the opposite direction, I would say sets are more fundamental than functions and relations. Whereas since both relations and functions can be "constructively" inter-defined, I'd say they're both on the same level.
Admittedly, I have no idea how to define "constructive".
All I mean by saying it's a "logical error" is that it's not an argument which is always valid. Of course particular instances can still be correct.
I think a definition of "proof by contradiction" which includes proof of negation is useful if you are reasoning classically (and this doesn't have to be something you always do, or always avoid; you can reason classically some of the time and intuitionistically some of the time). Although the ideal situation to avoid any confusion would be to have three separate terms, one covering both types of proof and two for the individual types.
[1] A > B(assumption)
[2] ~B (assumption)
[3] A (assumption)
[4] B (modus ponens on 1 and 3)
[5] ~A (proof of negation on 3, 4 and 2)
It's only the converse that no longer holds. In general familiar equivalences from classical logic are still valid in intuitionistic logic but only in one direction.1. juxtaposition is shorter than any alternative and hence a natural choice for the most common / only operation on the set in question
2. the operation is roughly analogous to function composition, and when you apply two composed functions it looks like f(g(x)) with f and g juxtaposed (if the functions are among those that have the longest history of being written as prefix operators, e.g. sin, cos, log, you don't even need the paren between the f and the g)
3. juxtaposition is a natural way to express an operation which is just "putting stuff together", such as string concatenation
So while it makes sense to denote string concatenation by juxtaposition in mathematics, I think it's a bit of a leap to go from there to say that A * B is the right notation for a programming language. (Actually using juxtaposition would be fine, but a general-purpose programming language is likely to want to reserve juxtaposition for something else.)
Also if you run with the idea that string concatenation = putting two strings together, well, addition is sort of like putting two numbers together. Rephrasing that in mathematical language: natural numbers can be encoded as elements of the free monoid on one generator, in which case the monoid operation turns out to be addition. I think that might be why the A + B notation is preferred over A * B when we have to choose one or the other.
Perl uses ARC with no tracing GC, so you have to handle cycles yourself: https://www.perlmonks.org/?node_id=1173079
TCL uses ARC, and apparently doesn't need a tracing GC because it is impossible to create cycles in it: https://wiki.tcl-lang.org/page/Garbage+collection