As far as I know, in a nutshell, if for a formal system $\mathcal{F}$ we have $\vdash_\mathcal{F} \exists! y \ \phi(y,x_1,\cdots,x_n)$ then we can safely introduce a new formal system $\mathcal{F}'$ that differs from $\mathcal{F}$ because it has a new function symbol $f$ and a new axiom $\vdash_\mathcal{F'} y=f(x_1,\cdots,x_n) \iff \phi(y,x_1,\cdots,x_n)$. More precisely, the new system $\mathcal{F'}$ is a conservative extension of $\mathcal{F}$.
However, sometimes it happens that new symbols are introduced even if the existential premise "$\exists! y \ldots$" is only "partial". For example, by studying $\mathcal{ZFC}$, I noted that usually intersection is only "partially defined", namely I have only $x\neq \emptyset\vdash_\mathcal{ZFC} \exists! y \ \forall u(u\in y\iff \forall v\in x(u\in v))$. By "partial", I mean that the case $x=\emptyset$ is escluded. In this case, the above scheme is not fulfilled, and I cannot introduce the new function symbol $\bigcap$ since this is not defined for $\emptyset$. Therefore, here is my first question. 1) Is there a more general scheme? Namely, is there a more general way to conservatively extend a system involving partial definitions? (I think the answer is no, but I need a confirmation)
An other common way to define intersection is to use separation, union and extentionality axioms to prove $\vdash_\mathcal{ZFC} \exists! y \ \forall u(u\in y\iff u\in \bigcup x \land \forall v\in x(u\in v))$. This solution produces a complete definition, and therefore I can extend $\mathcal{ZFC}$ introducing the new function symbol $\bigcap$ by exploiting the scheme reported above. However, this solution has different drawbacks, due to the fact that it imposes $\bigcap \emptyset=\emptyset$. For example, it is not true that $\vdash_\mathcal{ZFC} a\subseteq b \implies \bigcap b \subseteq \bigcap a$. But, this seems an apparent limitation, because I can state all the theorems (properties) about a certain $\bigcap x$ by simply adding the hypothesis $x\neq\emptyset$. For example, I can state $a\neq\emptyset,b\neq\emptyset\vdash_\mathcal{ZFC} a\subseteq b \implies \bigcap b \subseteq \bigcap a$. Actually, for this case, I could omit the hypothesys $a\neq\emptyset$, but the sense is to eliminate any occurrence of $\bigcap\emptyset$ from any reasoning, since I accept this patological definition only because I need to define the symbol $\bigcap$ for any member of the universe, not because I actually want to use it for patological cases. Therefore, here is my second question. 2) Is this way to procede correct (in general, not only for the intersection symbol)?
Thank you!
You're right to be careful, but this isn't a serious issue. Below I've outlined three basic approaches which all work.
The simplest approach is to work with relations instead of functions, conflating the function $f:X\rightarrow Y$ with its graph $G\subseteq X\times Y$. So e.g. "$\bigcap x=y$" would be shorthand for "$Intersection(x,y)$," and "$\bigcap\emptyset$ is undefined" would be shorthand for "$\forall y(\neg Intersection(\emptyset,y))$." We could in fact go right back to the set-up of first-order logic and drop functions entirely, since we truly can do everything with relations (even if sometimes it's annoying), and this gets around partiality concerns once and for all.
In practice, this is what logicians tend to do "under the hood" in my experience.
"But that's a really silly and unnatural thing to do!"
Yes, there is that. Well, in this case the fix you mentioned in the second part of your answer works perfectly well: define a "total version" of the partial function you want! No problems arise this way, as long as you're careful to keep track of the hypotheses needed to make your "totalized" operation behave as intended.
Sometimes there is a reasonable "default" to set our functions to (like $\emptyset$ in set theory or $0$ in arithmetic); a universally-applicable approach, while annoyingly arbitrary, would be to just make the function behave as the identity on a "bad" input (or be projection onto the first coordinate in the case of a multi-ary function). The details are left to the reader and are also silly.
"But that still doesn't feel right, and if our logic framework is making it hard to do math then there's something less-than-optimal with the logic side."
Honestly, I agree with this sentiment (which I'm rudely attributing to you). There are features of first-order logic I tend to (I'm inconsistent) dislike - most loudly, the restriction to partial as opposed to total functions. So let me outline how you can restructure first-order logic to allow partial functions.
There are four features we need to pay attention to:
What is a language?
What is a structure?
How do truth evaluations work?
How do proofs work?
I'm going to talk about the first three, and punt on the fourth.
Languages: Exactly the same. I have function symbols, relation symbols, and constant symbols, just as before. Syntactically, there is no difference.
Structures: Here's our first taste of freedom. A structure will now be allowed to use partial functions: e.g. if $f$ is a unary function symbol, then an $\{f\}$-structure $\mathcal{A}$ is a nonempty set $A$ together with a partial function $f^\mathcal{A}:\subseteq A\rightarrow A$.
Truth evaluations and satisfaction: Now we need to give a Tarski-style inductive definition of truth. The issue is that terms no longer need to refer to things. The most natural (in my opinion) fix is the "call-by-value" approach: as soon as you try to do something undefined, BOOM. Specifically, we'll leave all other clauses of the usual truth definition unchanged, but modify the atomic clause to say that any atomic formula involving a term which is not defined is automatically false - and a term with an undefined constituent is undefined. For example, if $f$ is always undefined and $g$ sends everything to $0$, then the sentence $g(f(a))=g(f(a))$ is false: it doesn't matter that both sides are literally the same expression, or that $g$ "doesn't need to look at" its input in order to decide what to output, the mere presence of the poisonous expression "$f(a)$" (either one) kills the whole setup immediately.
Proof system: There is as before an appropriate (= sound, complete, and recursively enumerable) proof system corresponding to the modified semantics above. Finding such a system is left as an exercise. (It is actually a good exercise, and basically involves closely reading the proofs of the soundness and completeness theorems and modifying them appropriately.)
At this point, once the above have been checked carefully, we have a basically satisfying approach; that it is satisfying for this particular context comes from further checking that adding a function symbol $f$ and the axiom "$\forall x_1,...,x_n,y[y=f(x_1,...,x_n)\iff \varphi(x_1,...,x_n,y)]$" always yields a conservative extension, regardless of what formula $\varphi$ (in the original language) you use.