Squawk as an replacement to Java (2000)

In the October 1999 Communications of the ACM Lutz Prechelt
had a spirited article entitled Evaluating
Java vs. C/C++ Effectivity Disorders to Interpersonal Disorders
requested 38 programmers to implement variations of a program in C, C++, or
Java. The conclusions showed that Java used to be 3 or 4 instances slower than C
or C++, nonetheless that the variance between programmers used to be greater than the
variance between languages, suggesting that one can are also searching for to reveal
more time on coaching programmers in area of arguing over language
need. (Or, suggesting that you just ought to rent the exact programmers and
steer clear of the injurious ones.) The variance for Java used to be decrease than for C or
C++. (Cynics can also reveal that Java forces you to write uniformly gradual
capabilities.) I applaud this line of work, and hope that more be taught of
this kind will seemingly be carried out.

It turns out my hopes possess been answered. First, Prechelt printed one more
that covers Tcl, Python, Perl, and Rexx. Additionally,
Ron Garret (nee Erann Gat) did
apply-up stamp
in which he requested programmers to write Prechelt’s
take a look at
in Squawk. His outcomes advise that the resulting Squawk
capabilities ran sooner on moderate than C, C++ or Java capabilities (even though
the quickest Squawk program used to be no longer as fleet as the quickest C program),
and that Squawk capabilities took much less model time than the other

I did no longer elevate part within the stamp, nonetheless after I observed it, I wrote my
model in Squawk. It took me about 2 hours (when compared to a vogue of two
to eight.5 hours for the other Squawk programmers within the stamp, 3 to 25 for
C/C++ and 4 to 63 for Java) and I ended up with 45 non-statement
non-easy traces (when compared with a vogue of 51 to 182 for Squawk, and 107
to 614 for the other languages). (Meaning that some Java programmer
used to be spending 13 traces and 84 minutes to develop the efficiency of
each and each line of my Squawk program.)

Right here is my program:

;; Peter Norvig - Programming Challange from Erann Gat:
;; Given a list of phrases and a list of cellphone numbers, win all the systems that
;; each and each cellphone number would be expressed as a list of phrases.
;; Jog: (main "notice-list-file-title" "cellphone-number-file-title")

(defvar *dict* nil 
  "A hash desk mapping a cellphone number (integer) to a list of phrases from the 
  enter dictionary that develop that number.")

(defun main (&no longer obligatory (dict "dict") (nums "nums") (dict-measurement 100))
  "Be taught the enter file ¨DICT and cargo it into *dict*.  Then for every and each line in 
  NUMS, print all the translations of the number real into a sequence of phrases,
  in accordance to the foundations of translation."
  (setf *dict(load-dictionary dict dict-measurement))
  (with-delivery-file (in nums)
    (loop for num = (read-line in nil) whereas num attain
          (print-translations num (opt-if-no longer #'digit-char-p num)))))

(defun print-translations (num digits &no longer obligatory (delivery up 0) (phrases nil))
  "Print each and each doable translation of NUM real into a string of phrases.  DIGITS
  wants to be WORD with non-digits eradicated.  On recursive calls, START is the
  area in DIGITS at which to leer the subsequent notice, and WORDS is the list
  of phrases found for (subseq DIGITS 0 START).  So if START will get to the cease of
  DIGITS, then now we possess an answer in WORDS.  In every other case, for every prefix of
  DIGITS, glimpse within the dictionary for notice(s) that plot to the stamp of the
  prefix (computed incrementally as N), and for every and each such notice strive to elongate
  the solution with a recursive name.  There are two complications: (1) the
  suggestions reveal that apart from dictionary phrases, you would possibly perchance perchance well perchance expend a single 
  digit within the output, nonetheless no longer two digits in a row. Additionally (and this appears to be like 
  silly) you would possibly perchance perchance well perchance no longer possess a digit in a area the place any notice can also seem.
  I take care of this with the variable FOUND-WORD; if it's miles misguided after the loop, 
  and the latest notice isn't very any longer a digit, are attempting a recursive name that pushes a 
  digit. (2) The opposite complication is that the obtrusive design of mapping 
  strings to integers would plot R to 2 and ER to 02, which clearly is 
  the same integer as 2.  Due to this truth we prepend a 1 to each and each number, and R 
  becomes 12 and ER becomes 102."
  (if (>= delivery up (measurement digits))
      (structure t "~a:~{ ~a~}~%" num (reverse phrases))
      (let ((found-notice nil)
            (n 1)) ; main zero place
        (loop for i from delivery up beneath (measurement digits) attain
              (setf n (+ 10 n) (nth-digit digits i)))
              (loop for notice in (gethash n *dict*) attain
                 (setf found-notice t)
                 (print-translations num digits (+ 1 i) (cons notice phrases))))
        (when (and (no longer found-notice) (no longer (numberp (first phrases))))
           (print-translations num digits (+ delivery up 1) 
                               (cons (nth-digit digits delivery up) phrases))))))

(defun load-dictionary (file measurement)
  "Develop a hashtable from the file of phrases (one per line).  Takes a hint
  for the preliminary hashtable measurement.  Every secret's the cellphone number for a notice;
  each and each stamp is a list of phrases with that cellphone number."
  (let ((desk (make-hash-desk :take a look at #'eql :measurement measurement)))
    (with-delivery-file (in file)
      (loop for notice = (read-line in nil) whereas notice attain
        (push notice (gethash (notice->number notice) desk))))

(defun notice->number (notice)
  "Translate a notice (string) real into a cellphone number, in accordance to the foundations."
  (let ((n 1)) ; main zero place
    (loop for i from 0 beneath (measurement notice) 
          for ch = (char notice i) attain
          (when (alpha-char-p ch) (setf n (+ 10 n) (char->digit ch)))))

(defun nth-digit (digits i) 
  "The i-th part of a character string of digits, as an integer 0 to 9."
  (- (char-code (char digits i)) #.(char-code #)))

(defun char->digit (ch)
  "Convert a character to a digit in accordance to the cellphone number suggestions."
  (ecase (char-downcase ch)
    ((#e) 0)
    ((#j #n #q) 1)
    ((#r #w #x) 2)
    ((#d #s #y) 3)
    ((#f #t) 4)
    ((#a #m) 5)
    ((#c #i #v) 6)
    ((#b #okay #u) 7)
    ((#l #o #p) 8)
    ((#g #h #z) 9)))

Two notes: (1) In the muse, I belief I had crushed the other Squawk
programmers (and each person else) by finishing in 1.5 hours, nonetheless then I
realized that I had cheated: the instructions mentioned to code as you would possibly perchance perchance well perchance
professionally, and which approach I ought to statement my work. It took 30 minutes
more to set aside within the feedback and clear up a minute bit. (2) I used to be
lucky in that after I used to be nearly carried out, I observed that I had a computer virus: I
would possibly maybe well not distinguish between the number 123 and 0123. I used to be about to
alternate numbers to strings (that is, 123 to “123” and 0123 to “0123”),
which would possess taken 15 minutes or so, when I observed that I’m in a position to also
repair the computer virus with a one-character alternate: alternate the initialization of
n from 0 to 1, so that 123 is represented as 1123 and 0123 as
10123. With that repair, the whole lot perceived to work ravishing.


This text is on hand in Czech, which strategy of Daniela Milton.

Peter Norvig

Related Articles

Back to top button