Archive for the 'Health' Category

Can an entrapment neuropathy of the superficial peroneal nerve cause foot drop?

Sunday, August 29th, 2010

Of the 26 medical doctors I have met in the last couple of years, about 10 of them had this question before them in some way. All of them answered “no.” I am very confident this tiny sample set extrapolates — I doubt there is a doctor who would not say no.

They are all wrong.

Entrapment neuropathy of the superficial peroneal nerve is not a common condition, but one which I had after an ankle inversion sprain. The entrapment was 10cm proximal to the lateral malleolus at the deep fascia exit behind the peroneal muscles.

In order to achieve resolution of this problem, I had to publish an essay with citations and present it to several surgeons. My citations include every case study of this condition that currently exists and several orthopaedic text books.

My insistence that this was causing a significant problem and that I also had incomplete foot drop was met with deep scepticism. After all, the superficial peroneal nerve (SPN) is a cutaneous nerve that does not supply motor control. I knew this too of course, but I had no explanation. It is the deep peroneal nerve (DPN) which supplies motor control — the guy next door. Foot drop is often caused by an entrapment below and behind the knee before the nerve splits into these two branches, but I knew this was not the cause.

A marcaine/steroid injection into the SPN entrapment site immediately (within seconds) relieved some amount of foot drop. This too, was met with scepticism (?placebo), but I was adamant — there was an effect including a functional improvement.

An entrapment neuropathy of the superficial peroneal can cause foot drop by extending the nerve, and placing traction on the L5 nerve root. This will result in the expected fibrillation of the foot extensor muscles. Further, this is an extremely painful and distressing condition resulting in symptoms that can be very distracting from the actual etiology.

I am not a medical expert, just an independent thinker who owns too many medical text books.

Doctors

Sunday, April 11th, 2010

Debut with a Catamorphism

Wednesday, December 2nd, 2009

Hello everyone,

Many of you know I have been battling health problems for the last 2 years subsequent to a sporting injury. After a total of six surgical procedures, my most recent about 3 weeks ago, I am glad to be almost completely cured. Today I lodged a formal complaint to the Medical Health Board of Queensland against six doctors (coincidentally, the same number of operations — there were a total of 19 doctors mentioned).

As a result of the aforementioned, I haven’t written in a while, so I plan to return to my usual from now on.

I thought I’d write a little about a pervasive problem on the Scala mailing lists. Specifically, the misunderstanding of the purpose of static typing. Of course, there will always be lots of myths and proponents willing to ensure their survival, however, I am a strong believer that education is the only means by which we can advance the software development industry, despite the task often appearing insurmountable (ala Scala mailing list).

Some discussions recently on the Scala mailing list include the relationship between scala.Option data type and null and another discussion about documentation and types that are once-inhabited such as forall a b c. (a -> b) -> (b -> c) -> a -> c

I thought I’d propose a small piece of code and leave any potential insights unstated so as not to destroy anything for the observer. There is a Haskell version toward the end.

I propose the following data type:

trait MyOption[+A] {
  // single abstract method
  def cata[X](some: A => X, none: => X): X
}

Astute observers will notice that the cata method is similar to a combination of the map and getOrElse methods on scala.Option. This topic has also arisen on the Scala mailing list in the past. In other words, I could have written this:

trait MyOption[+A] {
  // two abstract methods
  def map[X](f: A => X): MyOption[X]
  def getOrElse[AA >: A](a: => AA): AA
}

…and I’d have a data structure that is exactly the same as the previous one. What may not be obvious is that MyOption is also exactly the same as scala.Option. The correct term for “exactly the same” is isomorphic. Yes, this is despite not using case classes or subclasses — coincidentally, another area where much mythology is prevalent.

I could also write construction functions that are akin to scala.None and scala.Some:

object MyOption {
  def none[A] = new MyOption[A] {
    def cata[X](s: A => X, n: => X) = n
  }
 
  def some[A](a: A) = new MyOption[A] {
    def cata[X](s: A => X, n: => X) = s(a)
  }
}

As an exercise, I propose filling out the Option API, however, using the single abstract method cata and the none/some constructor functions for additional convenience. I promise you it can be done and that anything scala.Option can do, MyOption can do also (and vice versa), since they are isomorphic.

trait MyOption[+A] {
  // single abstract method
  def cata[X](some: A => X, none: => X): X
 
  def map[B](f: A => B): MyOption[B] = error("todo")
 
  def flatMap[B](f: A => MyOption[B]): MyOption[B] = error("todo")
 
  def getOrElse[AA >: A](e: => AA): AA = error("todo")
 
  def filter(p: A => Boolean): MyOption[A] = error("todo")
 
  def foreach(f: A => Unit): Unit = error("todo")
 
  def isDefined: Boolean = error("todo")
 
  def isEmpty: Boolean = error("todo")
 
  // WARNING: not defined for None
  def get: A = error("todo")
 
  def orElse[AA >: A](o: MyOption[AA]): MyOption[AA] = error("todo")
 
  def toLeft[X](right: => X): Either[A, X] = error("todo")
 
  def toRight[X](left: => X): Either[X, A] = error("todo")
 
  def toList: List[A] = error("todo")
 
  def iterator: Iterator[A] = error("todo")
}
 
object MyOption {
  def none[A] = new MyOption[A] {
    def cata[X](s: A => X, n: => X) = n
  }
 
  def some[A](a: A) = new MyOption[A] {
    def cata[X](s: A => X, n: => X) = s(a)
  }
}

If you get stuck, the answer is base-64 encoded below, however, I encourage you to follow the types and to the extent that there may be ambiguity, follow the existing Scala API specification for scala.Option. If need be, please ask questions. Best of luck!

dHJhaXQgTXlPcHRpb25bK0FdIHsKICAvLyBzaW5nbGUgYWJzdHJhY3QgbWV0aG9kCiAgZGVmIGNh
dGFbWF0oc29tZTogQSA9PiBYLCBub25lOiA9PiBYKTogWAoKICBpbXBvcnQgTXlPcHRpb24uXwoK
ICBkZWYgbWFwW0JdKGY6IEEgPT4gQik6IE15T3B0aW9uW0JdID0gY2F0YShmIGFuZFRoZW4gc29t
ZSwgbm9uZSkKCiAgLy8gQWxzbwogIC8vIGRlZiBtYXBbQl0oZjogQSA9PiBCKTogTXlPcHRpb25b
Ql0gPSBmbGF0TWFwKGYgYW5kVGhlbiBzb21lKQoKICBkZWYgZmxhdE1hcFtCXShmOiBBID0+IE15
T3B0aW9uW0JdKTogTXlPcHRpb25bQl0gPSBjYXRhKGYsIG5vbmUpCgogIGRlZiBnZXRPckVsc2Vb
QUEgPjogQV0oZTogPT4gQUEpOiBBQSA9IGNhdGEocyA9PiBzLCBlKQoKICBkZWYgZmlsdGVyKHA6
IEEgPT4gQm9vbGVhbik6IE15T3B0aW9uW0FdID0gY2F0YShhID0+IGlmKHAoYSkpIHNvbWUoYSkg
ZWxzZSBub25lLCBub25lKQoKICBkZWYgZm9yZWFjaChmOiBBID0+IFVuaXQpOiBVbml0ID0gY2F0
YShmLCAoKSkKCiAgZGVmIGlzRGVmaW5lZDogQm9vbGVhbiA9IGNhdGEoXyA9PiB0cnVlLCBmYWxz
ZSkKCiAgZGVmIGlzRW1wdHk6IEJvb2xlYW4gPSBjYXRhKF8gPT4gZmFsc2UsIHRydWUpCgogIC8v
IFdBUk5JTkc6IG5vdCBkZWZpbmVkIGZvciBOb25lCiAgZGVmIGdldDogQSA9IGNhdGEoYSA9PiBh
LCBlcnJvcigiTm9uZS5nZXQiKSkKCiAgZGVmIG9yRWxzZVtBQSA+OiBBXShvOiBNeU9wdGlvbltB
QV0pOiBNeU9wdGlvbltBQV0gPSBjYXRhKF8gPT4gdGhpcywgbykKCiAgZGVmIHRvTGVmdFtYXShy
aWdodDogPT4gWCk6IEVpdGhlcltBLCBYXSA9IGNhdGEoTGVmdChfKSwgUmlnaHQocmlnaHQpKQoK
ICBkZWYgdG9SaWdodFtYXShsZWZ0OiA9PiBYKTogRWl0aGVyW1gsIEFdID0gY2F0YShSaWdodChf
KSwgTGVmdChsZWZ0KSkKCiAgZGVmIHRvTGlzdDogTGlzdFtBXSA9IGNhdGEoTGlzdChfKSwgTmls
KQoKICBkZWYgaXRlcmF0b3I6IEl0ZXJhdG9yW0FdID0gY2F0YShJdGVyYXRvci5zaW5nbGUoXyks
IEl0ZXJhdG9yLmVtcHR5KQp9CgpvYmplY3QgTXlPcHRpb24gewogIGRlZiBub25lW0FdID0gbmV3
IE15T3B0aW9uW0FdIHsKICAgIGRlZiBjYXRhW1hdKHM6IEEgPT4gWCwgbjogPT4gWCkgPSBuCiAg
fQoKICBkZWYgc29tZVtBXShhOiBBKSA9IG5ldyBNeU9wdGlvbltBXSB7CiAgICBkZWYgY2F0YVtY
XShzOiBBID0+IFgsIG46ID0+IFgpID0gcyhhKQogIH0KfQoK

For Haskell users:

{-# LANGUAGE RankNTypes #-}
 
-- Data.Maybe
newtype Option a = Option { cata :: forall x. (a -> x) -> x -> x }
 
-- Just
some :: a -> Option a
some a = Option (\s _ -> s a)
 
-- Nothing
none :: Option a
none = Option (const id)
 
-- fmap
map' :: (a -> b) -> Option a -> Option b
map' f m = error "todo"
 
-- (>>=)
flatMap :: (a -> Option b) -> Option a -> Option b
flatMap f m = error "todo"
 
-- fromMaybe
getOrElse :: Option a -> a -> a
getOrElse = error "todo"
 
filter :: Option a -> (a -> Bool) -> Option a
filter m p = error "todo"
 
-- mapM_
foreach :: Option a -> (a -> IO ()) -> IO ()
foreach m f = error "todo"
 
-- isJust
isDefined :: Option a -> Bool
isDefined m = error "todo"
 
-- isNothing
isEmpty :: Option a -> Bool
isEmpty m = error "todo"
 
-- WARNING: not defined for None
-- fromJust
get :: Option a -> a
get m = error "todo"
 
-- mplus
orElse :: Option a -> Option a -> Option a
orElse m n = error "todo"
 
toLeft :: Option a -> x -> Either a x
toLeft m x = error "todo"
 
toRight :: Option a -> x -> Either x a
toRight m x = error "todo"
 
-- maybeToList
toList :: Option a -> [a]
toList m = error "todo"
 
iterator = error "bzzt. This is Haskell silly."
ey0jIExBTkdVQUdFIFJhbmtOVHlwZXMgIy19CgotLSBEYXRhLk1heWJlCm5ld3R5cGUgT3B0aW9u
IGEgPSBPcHRpb24geyBjYXRhIDo6IGZvcmFsbCB4LiAoYSAtPiB4KSAtPiB4IC0+IHggfQoKLS0g
SnVzdApzb21lIDo6IGEgLT4gT3B0aW9uIGEKc29tZSBhID0gT3B0aW9uIChccyBfIC0+IHMgYSkK
Ci0tIE5vdGhpbmcKbm9uZSA6OiBPcHRpb24gYQpub25lID0gT3B0aW9uIChjb25zdCBpZCkKCi0t
IGZtYXAKbWFwJyA6OiAoYSAtPiBiKSAtPiBPcHRpb24gYSAtPiBPcHRpb24gYgptYXAnIGYgbSA9
IGNhdGEgbSAoc29tZSAuIGYpIG5vbmUKCi0tICg+Pj0pCmZsYXRNYXAgOjogKGEgLT4gT3B0aW9u
IGIpIC0+IE9wdGlvbiBhIC0+IE9wdGlvbiBiCmZsYXRNYXAgZiBtID0gY2F0YSBtIGYgbm9uZQoK
LS0gZnJvbU1heWJlCmdldE9yRWxzZSA6OiBPcHRpb24gYSAtPiBhIC0+IGEKZ2V0T3JFbHNlID0g
ZmxpcCBjYXRhIGlkCgpmaWx0ZXIgOjogT3B0aW9uIGEgLT4gKGEgLT4gQm9vbCkgLT4gT3B0aW9u
IGEKZmlsdGVyIG0gcCA9IGNhdGEgbSAoXGEgLT4gaWYgcChhKSB0aGVuIHNvbWUgYSBlbHNlIG5v
bmUpIG5vbmUKCi0tIG1hcE1fCmZvcmVhY2ggOjogT3B0aW9uIGEgLT4gKGEgLT4gSU8gKCkpIC0+
IElPICgpCmZvcmVhY2ggbSBmID0gY2F0YSBtIGYgKHJldHVybiAoKSkKCi0tIGlzSnVzdAppc0Rl
ZmluZWQgOjogT3B0aW9uIGEgLT4gQm9vbAppc0RlZmluZWQgbSA9IGNhdGEgbSAoY29uc3QgVHJ1
ZSkgRmFsc2UKCi0tIGlzTm90aGluZwppc0VtcHR5IDo6IE9wdGlvbiBhIC0+IEJvb2wKaXNFbXB0
eSBtID0gY2F0YSBtIChjb25zdCBGYWxzZSkgVHJ1ZQoKLS0gV0FSTklORzogbm90IGRlZmluZWQg
Zm9yIE5vbmUKLS0gZnJvbUp1c3QKZ2V0IDo6IE9wdGlvbiBhIC0+IGEKZ2V0IG0gPSBjYXRhIG0g
aWQgKGVycm9yICJOb25lLmdldCIpCgotLSBtcGx1cwpvckVsc2UgOjogT3B0aW9uIGEgLT4gT3B0
aW9uIGEgLT4gT3B0aW9uIGEKb3JFbHNlIG0gbiA9IGNhdGEgbSAoY29uc3QgbSkgbgoKdG9MZWZ0
IDo6IE9wdGlvbiBhIC0+IHggLT4gRWl0aGVyIGEgeAp0b0xlZnQgbSB4ID0gY2F0YSBtIExlZnQg
KFJpZ2h0IHgpCgp0b1JpZ2h0IDo6IE9wdGlvbiBhIC0+IHggLT4gRWl0aGVyIHggYQp0b1JpZ2h0
IG0geCA9IGNhdGEgbSBSaWdodCAoTGVmdCB4KQoKLS0gbWF5YmVUb0xpc3QKdG9MaXN0IDo6IE9w
dGlvbiBhIC0+IFthXQp0b0xpc3QgbSA9IGNhdGEgbSAoOltdKSBbXQoKaXRlcmF0b3IgPSBlcnJv
ciAiYnp6dC4gVGhpcyBpcyBIYXNrZWxsIHNpbGx5LiIK

Third World Medicine

Saturday, February 14th, 2009

I’ve had two operations on my right ankle and both have failed to correctly diagnose and address the underlying symptomatic complaints that have existed for over 18 months. I am now aware of what the correct diagnosis is, verifiable with historical and radiographic evidence and repeatable symptomatic observations.

The surgeons are cautious given that I’ve already used up two of my available surgery cookie quota and hesitant to go again. This is despite having an exact pinpoint of where the problem is and published literature of what procedure is required. I simply have no rational explanation for this and, if it weren’t for my discomfort, it would leave me in awe.

The diagnosis is anteromedial osseous impingement of the right ankle visible on CT, verified by a radiologist and repeatable on dorsiflexion. This has come about from repeated trauma and in particular, a grade 3 inversion sprain in July 2007. I require a resection of this excess ossification.

I am asking (begging) my international audience for recommendations of a surgeon who is willing to perform this procedure as soon as possible in any part of the world. I suspect, only because I have no other explanation, that there is some bureaucratic restriction preventing me from making progress with surgeons here.

Suggestions please?

Pan-pan medico

Monday, January 19th, 2009

Pan-pan medico Pan-pan medico Pan-pan medico.

I’ve been stuck in my house for weeks. Help!
http://ankle.tmorris.net/

Posterior Tibial Tendon Impingement

Sunday, August 3rd, 2008

July 2007

  • Right ankle sprain
  • Fifth life-time occurrence
  • X-Ray reveals no fracture (Royal Brisbane Hospital)
  • Zero weight bearing for 6 days

January 2008

  • Certain movements cause swelling and discomfort
  • Movement is restricted in bending the knee with the foot flat on the ground (name?) — can get the knee vertical with the tip of the foot, but no further
  • MRI ordered by local GP (see below)
  • Radiography report is unremarkable and states no anterolateral abnormality (even though the pain is posteromedial?)

February 2008

  • Local GP administers cortico-steroid injection. Due to the swelling, the exact site of the pain cannot be accurately located. Since swelling has stopped (I have ceased rigorous activity), I estimate that the injection missed by about 2cm.
  • Improvement over the following 3 weeks and flexibility increases, just a little (I can get my knee 3cm passed the tip of my foot vertically)

May 2008

  • Ceased all sporting activity, in particular squash (3 times per week, including A1 grade competition)
  • This was due to this injury and one other; scapholunate ligament tear resulting in instability

June 2008

  • Subcutaneous atrophy from steroid injection begins to subside
  • Further injections are advised against by local GP
  • Arthroscopy of the wrist for scapholunate ligament repair (Dr. Peter Rowan, BOSMC)

July 2008

  • Wrist Arthroscopy has failed (reconstruction pending?)
  • HELP!

04 August 2008 (update)

  • Appointment with Greg Sterling on 30 September
  • YAY! 57 sleeps to go

Photos

  • Taken 2 August 2008
  • Red mark denotes site of impingement
  • Note atrophy below the mark

Ankle 1

Ankle 2

Ankle 3

Ankle 4

MRI

Radiographer Report (Transcribed)

Images (DICOM)

All DICOM images (tar.gz) 71MB

MR000000 MR000000 MR000000 MR000000 MR000000
MR000001 MR000001 MR000001 MR000001 MR000001
MR000002 MR000002 MR000002 MR000002 MR000002
MR000003 MR000003 MR000003 MR000003 MR000003
MR000004 MR000004 MR000004 MR000004 MR000004
MR000005 MR000005 MR000005 MR000005 MR000005
MR000006 MR000006 MR000006 MR000006 MR000006
MR000007 MR000007 MR000007 MR000007 MR000007
MR000008 MR000008 MR000008 MR000008 MR000008
MR000009 MR000009 MR000009 MR000009 MR000009
MR000010 MR000010 MR000010 MR000010 MR000010
MR000011 MR000011 MR000011 MR000011 MR000011
MR000012 MR000012 MR000012 MR000012 MR000012
MR000013 MR000013 MR000013 MR000013 MR000013
MR000014 MR000014 MR000014 MR000014 MR000014
MR000015 MR000015 MR000015 MR000015 MR000015
MR000016 MR000016 MR000016 MR000016 MR000016
MR000017 MR000017 MR000017 MR000017 MR000017
MR000018 MR000018 MR000018 MR000018 MR000018
MR000019 MR000019 MR000019 MR000019 MR000019
MR000020 MR000020 MR000020 MR000020 MR000020
MR000021 MR000021 MR000021 MR000021 MR000021
MR000022 MR000022 MR000022 MR000022 MR000022
MR000023 MR000023 MR000023 MR000023 MR000023

Images (PNG)

All PNG images (tar.gz) 23MB

MR000000 MR000000 MR000000 MR000000 MR000000
MR000001 MR000001 MR000001 MR000001 MR000001
MR000002 MR000002 MR000002 MR000002 MR000002
MR000003 MR000003 MR000003 MR000003 MR000003
MR000004 MR000004 MR000004 MR000004 MR000004
MR000005 MR000005 MR000005 MR000005 MR000005
MR000006 MR000006 MR000006 MR000006 MR000006
MR000007 MR000007 MR000007 MR000007 MR000007
MR000008 MR000008 MR000008 MR000008 MR000008
MR000009 MR000009 MR000009 MR000009 MR000009
MR000010 MR000010 MR000010 MR000010 MR000010
MR000011 MR000011 MR000011 MR000011 MR000011
MR000012 MR000012 MR000012 MR000012 MR000012
MR000013 MR000013 MR000013 MR000013 MR000013
MR000014 MR000014 MR000014 MR000014 MR000014
MR000015 MR000015 MR000015 MR000015 MR000015
MR000016 MR000016 MR000016 MR000016 MR000016
MR000017 MR000017 MR000017 MR000017 MR000017
MR000018 MR000018 MR000018 MR000018 MR000018
MR000019 MR000019 MR000019 MR000019 MR000019
MR000020 MR000020 MR000020 MR000020 MR000020
MR000021 MR000021 MR000021 MR000021 MR000021
MR000022 MR000022 MR000022 MR000022 MR000022
MR000023 MR000023 MR000023 MR000023 MR000023