A Halloween and a half ago, I posted
some scary code in Haskell, Scala, and Python, to take up Joey de Villa's Luhn algorithm challenge (calculate a checksum that is (or was) built into credit card numbers). Here's a translation of that into sorta-dl:
(Luhn.
(do_dig (dig Int) => Int:
=> dig <= 9 ? dig | dig-9 :)
(luhn_sub (nr Int, mul Int) => Int:
.if nr = 0 ? => 0
.else d := mul * (nr mod 10)
=> luhn_sub(nr/10, 3-mul) + do_dig(d) :)
(luhn (nrStr String) => Boolean:
nr := `java.lang.Long.parseLong(nrStr)
lsum := luhn_sub(nr, 1)
lsum % 10 == 0 :)
# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# Above: Luhn algorithm. Below: testing.
# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
(lrange (lo Int, pastHi Int) => List[Int]:
=> lo >= pastHi ? [] |
lo :: lrange(lo + 1, pastHi) :)
(main:
(tens (s String):
.for dig <- lrange(0,10) :
sd := s + dig
prn( "Luhn(" sd ") = " luhn(sd) )
for. :)
tens( "234234" )
tens( "5128960128" )
:main)
.Luhn)
The thing is, that I'd like it to be able to do dynamic type checking when necessary, so that much fewer of the explicit type declarations here would be needed. More like this:
(Luhn.
(do_dig (dig):
=> dig <= 9 ? dig | dig-9 :)
(luhn_sub (nr, mul):
.if nr = 0 ? => 0
.else d := mul * (nr mod 10)
=> luhn_sub(nr/10, 3-mul) + do_dig(d) :)
(luhn (nrStr):
nr := `java.lang.Long.parseLong(nrStr)
lsum := luhn_sub(nr, 1)
lsum % 10 == 0 :)
(lrange (lo, pastHi):
=> lo >= pastHi ? [] |
lo :: lrange(lo + 1, pastHi) :)
(main:
(tens (s):
.for dig <- lrange(0,10) :
sd := s + dig
prn( "Luhn(" sd ") = " luhn(sd) )
for. :)
tens( "234234" )
tens( "5128960128" )
:main)
.Luhn)
Or maybe the programmer still ought to be required to say what kind of thing a given function is returning.