syntax across languages

C.Reinke C.Reinke@ukc.ac.uk
Mon, 11 Feb 2002 17:33:35 +0000


> > I'm not sure if "iterate" counts as loop forever?
> 
> I don't think there can be a "loop forever" construct in haskell?

why not?

> in OCaml, it is simply:
> let loop(f) = f() ; loop(f)
> and is only useful together with exceptions and side-effects.

and in Haskell, it is simply:

  loop f = f >> loop f 

or, as there is little difference between control structures and
other data structures, you can convert the latter into the former,
using the list version of loop, called repeat:

  loop f = mapM_ id $ repeat f

or simply:

  loop = foldr1 (>>) . repeat 


example (get ready to hit that interrupt key;-):

  loop (putStrLn "hi")


> > I can't remember any %-based sprintf off the top of my head, but hey,
> > who'd want one anyway?
> 
> me! I've always wondered how you internationalize a program without it?
> 
> eg: 
> "This encryption key is too simple (must be at least %d characters long)"
> "The package %s needs to be installed. Do you want to install it?"
> 
> (I agree you don't need the full power of sprintf for this)

indeed not. you only want to factor out the strings, so that they
can be collected in a single space for the translators/customizers
convenience. functional abstraction allows you to just do that 
(then put the functions into a module per language, or collect them
in tuples/records, and link or select as appropriate):

  encryptionTooSimple d =  
    "This encryption key is too simple (must be at least "
    ++(show (d::Integer))++ characters long)"

  packageMissing s = 
    "The package "++s++" needs to be installed. Do you want to install it?"


but if you absolutely want printf-style formatting, Danvy's solution
is very nice and simple (once someone had the idea;-):

  int k r x = k (r++(show (x::Integer))) -- an Integer
  str k r x = k (r++x)                   -- a String

  s x k r = k (r++x)                     -- format String fragment
  nl      = s "\n"                       -- newline

  format p = p id ""


(similar continuation-based functions for other types)

Now you can try it in Hugs:

  Main> :t format $ s "age: " . int . s " name: " . str . nl
  format $ s "age: " . int . s " name: " . str . nl :: Integer -> [Char] -> [Char]

  Main> format ( s "age: " . int . s " name: " . str . nl )  10 "IGS"
  "age: 10 name: IGS\n"

See:

  RS-98-12 
  Olivier Danvy. 
  Functional Unparsing. 
  May 1998. 
  7 pp. This report supersedes the earlier report BRICS RS-98-5.
  Extended version of an article to appear in Journal of Functional
  Programming. 

  http://www.brics.dk/RS/98/Ref/BRICS-RS-98-Ref/BRICS-RS-98-Ref.html#BRICS-RS-98-12

> i don't put any non-simple functions, the main aim is not to show how it can
> be done, but what are the various names used in various languages.

but it is one of the major features of functional languages that 
it is so easy to compose/reuse functionality! this is why Haskell
doesn't need a name for everything - composing the functions can 
be as simple as (and more flexible than) composing the names.

Claus