Mathematica is not strongly typed. If you provide arguments that match the structure of the definition, so that the function as used does in fact match the definition, then the function will evaluate as expected. If the form of the arguments as used does not match the definition, the rule which was established by the function definition will not apply, and Mathematica will just return the input. You can restrict the match by using Conditionals in the function definition.
For example, here are a few lines of code that define our own complex numbers, as ordered pairs, by rules for adding and multiplying them. No type restrictions were needed:
In[1]:= complexPlus[{r1_, i1_}, {r2_, i2_}] := {r1 + r2, i1 + i2}
In[2]:= complexTimes[{r1_, i1_}, {r2_, i2_}] := {r1 r2 - i1 i2,
r1 i2 + r2 i1}
In[3]:= (* argument structure does not match definition *)
In[4]:= complexPlus[a, b]
Out[4]= complexPlus[a, b]
In[5]:= (* this matches *)
In[6]:= complexPlus[{x, y}, {u, v}]
Out[6]= {u + x, v + y}
In[7]:= c1 = {x, y}; c2 = {u, v};
(* so does this *)
In[9]:= complexPlus[c1, c2]
Out[9]= {u + x, v + y}
Look at documentation for Pattern (and follow the related links). There are several ways to restrict your functions to specific argument “types” (i.e. make the pattern matching more restrictive).
For example:
In[1]:= mySum[a_Integer, b_Integer] := a + b
In[2]:= mySum[1.1, 2.2]
Out[2]= mySum[1.1, 2.2]
In[3]:= mySum[1, 2]
Out[3]= 3
Or
In[4]:= myPositiveSum[a_?Positive, b_?Positive] := a + b
In[5]:= myPositiveSum[1.1, 2.2]
Out[5]= 3.3
In[6]:= myPositiveSum[-1.1, 2.2]
Out[6]= myPositiveSum[-1.1, 2.2]
Or
In[7]:= myOrderedSum[a_, b_] := a + b /; a > b
In[8]:= myOrderedSum[1, 1]
Out[8]= myOrderedSum[1, 1]
In[9]:= myOrderedSum[2, 1]
Out[9]= 3
And yes, Mathematica is not strongly typed, but the interesting question is “how does strong typing benefit me?”. Having answered that question, look for ways that Mathematica can provide those same benefits. Mathematica actual does have powerful facilities for helping you attain correctness in your code. While I personally think it’s unhelpful to try to mimic object oriented programming with Mathematica (and, yes, that can be done), you can get similar benefits by using more Mathematica-natural idioms. For example, using custom symbols as heads for data structures allows you to define functions that apply to only those data structures. You can then create custom constructors, accessors, etc. You won’t get compile time type mismatch errors (that doesn’t even make sense with Mathematica), but you will get un-simplified expression, which in some ways is actually better, because you can inspect exactly what the expression is that didn’t get pattern-matched to anything. (This is exactly what happened in the example in your previous post that was missing the comma–something pretty easy to detect once you’ve worked in Mathematica for awhile.)
Thanks. I know that as one gains experience in a new paradigm, it becomes more natural. I’m an “old-timer” - started in FORTRAN II - migrated through Fortran versions, assemblers (VAX, 8080 family),Pascal, Modula II, LISP,C, (even a bit - ashamed to say- COBOL), C++, HTML, and was just getting into JAVA and the use of programmer’s GUI interfaces when I retired. When I first encountered “object-oriented” programming I was stumped as well, but learned the benefits - as I will do with MMA. Good community and very helpful. I’ve actually got some problems solved now!