As with most CS stuff there's the standard split here: type theory, languages and grammars and pumping lemma on the theoretical side and recursive descent, lex/flex/yacc/bison, programming language exposure lisp, prolog, assembly, etc on the practical side. Dominance frontiers and register allocation algorithms were some of the places where they really started to intersect for me. I guess also regular languages, regular expressions and balanced parens is another place where they intersect.
So in my CS program, those were split into several separate courses.
You had an (mostly theoretical) Automata and Formal Languages course, which had regular/context free languages (including regexs), grammars, and pumping lemma.
lex/flex/yacc/bison, recursive descent, and LL(1) LR(n), LALR were in a Compilers course.
Programming Language exposure to a functional language (ML) and a logic language (Prolog) plus some other stuff was the Programming Language course.
Type Theory, lambda calculus, and so on is relegated to advanced graduate courses that are given when a faculty member feels like it.
You realize lisp is based on the lambda calculus and prolog is based on formal logic, right?
The theory and practical realms are very tightly intertwined in programming/computer science/whatever you want to call it as long as it isn't "information technology".
On the other hand, the portion of "math" that is applicable computer science/software development/whatever is pretty distinct from much of the "math" in math departments.