Retrograde morse (d)e(n)coder
Perl 5: too long to care (740 though)
Just wanted to see if it will be possible to write this in a language with non single character statements. The result is not pretty, but works. Most of the code is used in both decoder and encoder, but the eval+'{code}' trick shows a loophole which could be used to write completely separate code for decoder and encoder.
Fixed all known problems. Supports both lower and upper case input with all punctuation characters mentioned on the page linked in the question.
Encoder:
;;$^;s,.*,reverse+uc,e;
tr,+?.(),+~=&lt;&gt;,+rt;
1while+s/E/#_/s+s/T/`_/s+s! !{_!s+elihw1;
1while+s/A/`#_/s+s/N/#`_/s+s/I/##_/s+s/M/``_/s+elihw1;
1while+s/O/```_/s+s/D/##`_/s+s/R/#`#_/s+s/S/###_/s
      +s/G/#``_/s+s/U/`##_/s+s/W/``#_/s+s/K/`#`_/s+elihw1;
1while+s/B/###`_/s+s/C/#`#`_/s+s/P/#``#_/s+s/Q/`#``_/s
      +s/F/#`##_/s+s/H/####_/s+s/V/`###_/s+s/J/```#_/s
      +s/X/`##`_/s+s/L/##`#_/s+s/Y/``#`_/s+s/Z/##``_/s+elihw1;
1while+s/1/````#_/s+s/2/```##_/s+s/3/``###_/s+s!&lt;!#``#`_!s
      +s/4/`####_/s+s/5/#####_/s+s/6/####`_/s+s/7/###``_/s
      +s/8/##```_/s+s/9/#````_/s+s/0/`````_/s+s!/!#`##`_!s+elihw1;
1while+s/~/##``##_/s+s/=/`#`#`#_/s+s/,/``##``_/s
      +s/:/###```_/s+s/'/#````#_/s+s/&quot;/#`##`#_/s
      +s/-/`####`_/s+s!&gt;!`#``#`_!s+elihw1;
tr,+{`#_,+/\-\. ,+rt;
;;$^;s,.*,reverse,e;
s/ //s

Decoder:
s// /s
;e,esrever,*.,s;^$;;
;tr+, .\-\/+,_#`{+,rt
;1while+s!_`#``#`!&gt;!s+s/_`####`/-/s+
s/_#`##`#/&quot;/s+s/_#````#/'/s+s/_```###/:/s+
s/_``##``/,/s+s/_#`#`#`/=/s+s/_##``##/~/s+elihw1
;1while+s!_`##`#!/!s+s/_`````/0/s+s/_````#/9/s+s/_```##/8/s+
s/_``###/7/s+s/_`####/6/s+s/_#####/5/s+s/_####`/4/s+
s!_`#``#!&lt;!s+s/_###``/3/s+s/_##```/2/s+s/_#````/1/s+elihw1
;1while+s/_``##/Z/s+s/_`#``/Y/s+s/_#`##/L/s+s/_`##`/X/s+
s/_#```/J/s+s/_###`/V/s+s/_####/H/s+s/_##`#/F/s+
s/_``#`/Q/s+s/_#``#/P/s+s/_`#`#/C/s+s/_`###/B/s+elihw1
;1while+s/_`#`/K/s+s/_#``/W/s+s/_##`/U/s+s/_``#/G/s+
s/_###/S/s+s/_#`#/R/s+s/_`##/D/s+s/_```/O/s+elihw1
;1while+s/_``/M/s+s/_##/I/s+s/_`#/N/s+s/_#`/A/s+elihw1
;1while+s!_{! !s+s/_`/T/s+s/_#/E/s+elihw1
;tr+,&gt;&lt;=~+,)(.?+,rt
;e,cu+esrever,*.,s;^$;;

Usage
$ perl -lp retr.pl &lt;&lt;&lt;&quot;(Morse) Code?&quot;
-.--. -- --- .-. ... . -.--.- / -.-. --- -.. . ..--..
$ perl -p0e '$_=reverse' retr.pl &gt;rter.pl
$ perl -lp rter.pl &lt;&lt;&lt;&quot;-.--. -- --- .-. ... . -.--.- / -.-. --- -.. . ..--..&quot;
(MORSE) CODE?

Explanation:
;;$^;s,.*,reverse+uc,e; # parses as $^; s/.*/reverse uc/e
                        # and in decoder as e; cu + esrever; *.; s/^$//
                        # reverse and uppercase input, no-op in decoder
tr,+?.(),+~=&lt;&gt;,+rt;     # parses as tr/+?()/+=&lt;&gt;/ + rt
                        # in decoder as tr/,&gt;&lt;=~/,)(.?/ , rt
                        # equivalent to y/?.()/~=&lt;&gt;/ and y/&gt;&lt;=~/)(.?/ in decoder
1while+s/T/`_/s+elihw1; # parses as while(+s/T/`_/+elihw1){1}
                        #        =&gt; while(s/T/`_/s+0){}
                        # equivalent to s/T/`_/g and s/_`/T/g in decoder
s/ //s                  # remove leading space / add leading space