Now I have been intending to pick up a functional language and I seem
to be unable to choose which one to use. Hence would like to clear a
few things up
1) Which would be the easiest language to learn ? (given my
background.) Anecdotal experience with the many functional languages
would be more welcome than real highly complex theoretical explanation
as i prolly wont understand them anyway :(
2)In addition will learning one language help in learning other
languages in reasonably short time ?(i.e are there major fundamental
difference between the different functional languages or is it mostly
the syntax which is different ? )
3) is there any site or reference contaning survey of which of the
languages are more commonly used ?
Thanks,
Abhijit
You've skipped the single most important piece of information: why do you
want to learn a functional language? Is it purely out of academic interest
or would you like to have a new language in your arsenal and, if so, what
tasks do you want it to help with?
Also, what OS? OCaml has great support under Linux, ok under Mac OS X and
not great under Windows. Clean is the other way around.
> 1) Which would be the easiest language to learn ? (given my
> background.) Anecdotal experience with the many functional languages
> would be more welcome than real highly complex theoretical explanation
> as i prolly wont understand them anyway :(
You'll probably benefit from some basic classifications:
Eager: Lisp, Scheme, SML, OCaml.
Lazy: Haskell, Clean.
You're used to eager languages so you might find it more academically
interesting to learn a lazy language. Practically, eager languages
typically have more predictable behaviour, particularly with respect to
memory usage.
Statically typed: SML, OCaml, Haskell, Clean.
Dynamically typed: Lisp, Scheme.
If you only know a sucky statically typed language like C then you're likely
to learn a lot by using a statically typed language with a more expressive
type system. SML has the simplest type system of those languages, so it may
be easier to learn. OCaml supports some more exotic features (e.g.
polymorphic variants and objects) so there is more to learn. Haskell has a
very funky type system. I don't know about Clean.
Static and dynamic typing both have their applications. Basically, static
typing is only useful when you can leverage the static type system to
perform checks on your code that catch bugs. Static typing is useless when
the data structures that you are dealing with are fundamentally type less.
For example, if you're rearranging XML documents and only use one type
(XML), then static typing isn't going to help. Under such circumstances,
you might as well use dynamic typing. There are allegedly applications (or
patterns of usage) where static type systems can be a hindrance. However, I
have yet to see one. Conversely, I often spent a week redesigning
complicated code to leverage static type checking and I end up with code
that passes all tests first time. I've done that with GUI code, graphics
code, net code and compilers/interpreters.
Essentially, in the presence of type inference, static typing is beneficial
for the vast majority of applications.
Lisp and Scheme are still interesting languages, however, because they
provide first-class code and EVAL. This lets Lisp and Scheme programs
generate, compile and execute code on-the-fly. For example, a Lisp program
that gets a regexp from its user at run-time can compile up some optimised
code implementing a matcher specifically for the given regexp. This can
lead to drastic performance improvements but is rarely useful in practice.
MetaOCaml tries to add first-class code to OCaml but it conflicts with
static typing. IMHO, you're trying to write a type-safe compiler when the
back-end of a compiler needs to be type unsafe in order to generate
efficient code, i.e. my MetaOCaml code always ends up doing unnecessary
boxing of intermediates. Anyway, I digress...
So the trade-off is checking of your program at compile time (SML, OCaml,
Haskell, Clean) or run-time code generation (Lisp, Scheme). For production
code, I'd say that the former is more useful because it eliminates so many
errors.
Perhaps the main downside of static typing is having to learn how to make
good use of it. This requires you to know something about what it is doing,
IMHO. For example, there are some valid programs that do not type check
under some languages, e.g. the OCaml:
# let rec f x = x f;;
This expression has type ('a -> 'b) -> 'c but is here used with type 'a
Most such code is not useful in practice. Read Chris Okasaki's thesis/book
for more information on code (polymorphic recursion) that doesn't type
check in SML/OCaml but is useful.
There are also the pedagogical applications of generalised algebraic data
types (GADTs), such as the evaluator:
let rec eval = function
| Lit n -> n
| Plus(a,b) -> eval a + eval b
| True -> true
| False -> false
| And(a,b) -> eval a && eval b
| If(p, t, f) -> eval(if eval p then t else f)
http://www.haskell.org/ghc/docs/6.4/html/users_guide/gadt.html
> 2)In addition will learning one language help in learning other
> languages in reasonably short time ?(i.e are there major fundamental
> difference between the different functional languages or is it mostly
> the syntax which is different ? )
All programming languages are related and functional languages are no
exception. Lisp and Scheme are similar. SML and OCaml are similar. Haskell
is like a distant cousin of SML's.
For example, here is code to define and insert elements into a red-black
tree, first in OCaml, then in SML:
type 'a t = E | B of 'a t * 'a * 'a t | R of 'a t * 'a * 'a t
exception Found
let rec ins x = function
E -> R(E, x, E)
| R(a, y, b) ->
if x < y then R(ins x a, y, b) else
if x > y then R(a, y, ins x b) else raise Found
| B(a, y, b) ->
if x < y then match ins x a, y, b with
R(R(a, x, b), y, c), z, d -> R(B(a, x, b), y, B(c, z, d))
| R(a, x, R(b, y, c)), z, d -> R(B(a, x, b), y, B(c, z, d))
| a, x, b -> B(a, x, b) else
if x > y then match a, y, ins x b with
a, x, R(R(b, y, c), z, d) -> R(B(a, x, b), y, B(c, z, d))
| a, x, R(b, y, R(c, z, d)) -> R(B(a, x, b), y, B(c, z, d))
| a, x, b -> B(a, x, b) else raise Found
datatype 'a t = E | B of 'a t * 'a * 'a t | R of 'a t * 'a * 'a t
exception Found
fun ins(x, E) = R (E, x, E)
| ins(x, s as R(a, y, b)) =
if x < y then R(ins(x, a), y, b) else
if x > y then R(a, y, ins(x, b)) else raise Found
| ins(x, s as B(a, y, b)) =
if x < y then
case (ins(x, a), y, b) of
(R(R(a, x, b), y, c), z, d) => R(B(a, x, b), y, B(c, z, d))
| (R(a, x, R(b, y, c)), z, d) => R(B(a, x, b), y, B(c, z, d))
| (a, x, b) => B(a, x, b) else
if x > y then
case (a, y, ins(x, b)) of
(a, x, R(R(b, y, c), z, d)) => R(B(a, x, b), y, B(c, z, d))
| (a, x, R(b, y, R(c, z, d))) => R(B(a, x, b), y, B(c, z, d))
| (a, x, b) => B(a, x, b) else raise Found
You can see the similarity.
> 3) is there any site or reference contaning survey of which of the
> languages are more commonly used ?
I don't think anyone knows which languages are most commonly used.
Worldwide, Lisp and Scheme are very common because they are taught a lot in
the US. In Europe, more modern languages (e.g. SML, OCaml) are often taught
instead. In terms of industrial use, I have been involved with several
companies that use OCaml and one that uses SML. However, that is
self-selected because I am an ML programmer.
If you're interested in OCaml then read the freely-available first chapter
of my book (link in my sig).
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/ocaml_for_scientists/chapter1.html
Abhijit> First some background. I have done little bit of prolog
Abhijit> long time back ( approx 10 years back) and I am more or
Abhijit> less comfortable with C, perl ruby.
Abhijit> Now I have been intending to pick up a functional
Abhijit> language and I seem to be unable to choose which one to
Abhijit> use. Hence would like to clear a few things up
Abhijit> 1) Which would be the easiest language to learn ? (given
Abhijit> my background.) [...deleted....]
Abhijit> 2)In addition will learning one language help in learning
Abhijit> other languages in reasonably short time ?
Abhijit> [...deleted...]
If you are truly interested in learning about *functional programming*
(you know what that means, right?) I would strongly suggest learning
Haskell.
Haskell is a purely functional language, and IMHO is the best one to
learn concepts about functional languages. Being purely functional it
has a bit of steep learning curve to get to where you can write "real
world" programs (you can't escape into the familiar imperative style
as easily as with some other functional languages).
Cheers!
Shyamal
Warning: I have never really tried Haskell myself (but I would like to).
On the topic: "escaping to imperative style":
When I first encountered a functional language, it was through the book
"Structure and Interpretation of Computer Programs" available at
http://mitpress.mit.edu/sicp/full-text/book/book.html
In c it is normal to use variables like "int i = 3;". In this book the
first two chapters treat procedures and data whereas the concept of
c-like variables is not introduced until chapter 3(!). (In the cplusplus
book I have here, variables are introduced first, followed by
if-statements, and only much later does one learn about functions.)
When I arrived at the section
"3.1.2 The Benefits of Introducing Assignment", I was VERY astonished
by the programming way thay needs a discussion of its benefits before
introducing the concept of c-like variables.
If you would like to understand this difference, then I would think
looking at Haskell or some other more pure language might be good, or at
least using a book that is centered aroud the pure aspects of a
functional programming language.
On my choice;
I now use SML (when I program) because it works for me and programs
execute fast for me, but if I was not only doing numerics and if I would
program for fun instead, I would try Haskell. My SML code is (for
speed) in some parts (conceptually) fairly c-like, but I would not
recommend this to learn the benefits (and fun) of functional
programming, (unless you are impatient and want speedy programs fast,
but then you miss a lot).
I have chosen language based on speed and efficiency for me, and for
this I think the MLton compiler is good, but there are good arguments
for compilers of other languages as well, and I would not recommend
choosing only based on the compiler, unless you know what your criteria are.
By the way, I would imagine it is much easier to learn SML/OCaml if you
know c and Haskell or Clean than to learn Haskell if you know c and SML,
but I have not tried.
If I would start trying to learn functional programming now for fun, I
would try to get a good book on Haskell.
But these are only my ompinions.
/ johan
this was a good overview on the FP-languages.
I want to add some things:
Jon Harrop wrote:
> avi...@gmail.com wrote:
>
>>First some background.
>>I have done little bit of prolog long time back ( approx 10 years back)
>>and I am more or less comfortable with C, perl ruby.
>>
>>Now I have been intending to pick up a functional language and I seem
>>to be unable to choose which one to use. Hence would like to clear a
>>few things up
[...]
> Perhaps the main downside of static typing is having to learn how to make
> good use of it. This requires you to know something about what it is doing,
> IMHO. For example, there are some valid programs that do not type check
> under some languages, e.g. the OCaml:
>
> # let rec f x = x f;;
> This expression has type ('a -> 'b) -> 'c but is here used with type 'a
>
OCaml has a "rectypes" option:
====================================================
first:~ oliver$ ocaml
Objective Caml version 3.09.0
# let rec f x = x f;;
This expression has type ('a -> 'b) -> 'c but is here used with type 'a
# ^D
first:~ oliver$ ocaml -rectypes
Objective Caml version 3.09.0
# let rec f x = x f;;
val f : ('a -> 'b) -> 'b as 'a = <fun>
#
====================================================
So, if it really should be necessary, one can also compile
such functions.
>>3) is there any site or reference contaning survey of which of the
>>languages are more commonly used ?
>
>
> I don't think anyone knows which languages are most commonly used.
> Worldwide, Lisp and Scheme are very common because they are taught a lot in
> the US. In Europe, more modern languages (e.g. SML, OCaml) are often taught
> instead. In terms of industrial use, I have been involved with several
> companies that use OCaml and one that uses SML. However, that is
> self-selected because I am an ML programmer.
It's interesting that you say, there are "several" companies that use
OCaml. I've heard of a few that use (or had contact with ;-)) OCaml.
"Several" sounds much.
Can you give an estimated number of how much "several" is?
Ciao,
Oliver
> I have chosen language based on speed and efficiency for me, and for
> this I think the MLton compiler is good, but there are good arguments
> for compilers of other languages as well, and I would not recommend
> choosing only based on the compiler, unless you know what your criteria are.
>
> By the way, I would imagine it is much easier to learn SML/OCaml if you
> know c and Haskell or Clean than to learn Haskell if you know c and SML,
> but I have not tried.
[...]
But that is what I experienced. Also OCaml was easier to install.
Haskell is good for learning the pure FP, but IMHO OCaml is more
real-world ;-) in a sense that it is not as narrow focussed ("dogmatic"
;-)) like a pure language: it offers many possibilities. Which you
choose is up to you. Also Haskell seems to lack on performance.
But performance is not all!
I like Haskell's list comprehensions and it is very elegant and
powerful, has a straight mathematical-like syntax (e.g. list
comprehensions) and offers a powerful concepts (Monads).
In OCaml I like the syntax, the powerful module system, quite
good performance, that it comes with bytecode and native code
compilers for a huge amount of platforms (and a toplevel to try some
code without seperate compilation steps (and as a simple calculator like
bc ;-)). (But there are also scheme-interpreters and Hugs
(Haskell-interpreter) to sdo some things without compilation,
so this allone could not be a reason.)
IMHO the four FPLs one should think about to use are
Lisp, scheme, Haskell, OCaml/SML. These are the most
often used languages and the best - each in it's own way.
I use OCaml (have tried Haskell and scheme also (LISP was intended,
but the problem was that the Lisp-books that were recommended, were out
of print for more than a year (I then put my Lisp-attempts into the
Trash; OCaml for me was the best way).
Ciao,
Oliver
P.S.: Would be good to know what reasons are to learn an FPL for the
original-poster (OP). (BTW: Ruby was mentioned; it has some
FP-functionality inside, so some concepts may already known
by the OP.
and
> P.S.: Would be good to know what reasons are to learn an FPL for the
> original-poster (OP). (BTW: Ruby was mentioned; it has some
> FP-functionality inside, so some concepts may already known
> by the OP.
My initial reason was to just to learn a new way of programming, so if
in future I come across problems where functional programming is the
way to go, then I would be better prepared.
So with this in mind, I searched a bit and selected Haskell just off
the top of my head and downloaded the "Yet another haskell tutorial". I
did try out the few of the examples in the initial chapters.
Then I downloaded (without functional programming in mind) the lecture
videos of
"structure and interpretation of computer programs" and in the first
lecture they did a brief summary of LISP. Now that to me looked very
simple to pick up. I mean the guy(in the lecture video) claimed that
almost all of LISP can be explained in a very short time.
So anyway now I was kind of tied between haskell and lisp .so decided
why not here from experienced people !
--
back to the original question ..I would presume each language would
have its pros and cons. Hence would also like if anyone can explain in
layman terms under what circumstances a particular language is more
suited , like for example from what i gathered from the discussion so
far OCaml would be more suited if performance is critical etc etc.
Indeed. Someone recently asked me how they could type a callback that
returns a value and a replacement callback. The type would be something
like:
$ ocaml -rectypes
Objective Caml version 3.09.1
# let rec f x = x+1, f;;
val f : int -> int * 'a as 'a = <fun>
But you don't want to compile your code using rectypes because it obfuscates
many error messages (it effectively "weakens" the type system by allowing
recursive types to be inferred for functions when they were not intended).
An alternative is to wrap the result in a polymorphic variant (thus keeping
type inference) and unboxing the result:
# let rec f x = x+1, `F f;;
val f : int -> int * [> `F of 'a ] as 'a = <fun>
# let unbox (`F f) = f;;
val unbox : [< `F of 'a ] -> 'a = <fun>
Note the inferred recursive type.
A more commonly encountered set of useful type errors is polymorphic
recursion. This is where a function calls itself recursively using two
different types. Ordinary SML and OCaml type infers using the first
recursive call and then gives a type error on the next recursive call. For
example, we want "val f : 'a -> unit" here but we get:
# let rec f _ = f 3; f 'a';;
This expression has type char but is here used with type int
This can be worked around using recursive modules and explicit type
declarations:
# module rec A : sig
val f : 'a -> unit
end = struct
let rec f _ = A.f 3; A.f 'a';;
end;;
module rec A : sig val f : 'a -> unit end
But recursive modules are still an "experimental" corner of the OCaml
language. You can also implement polymorphic recursion using objects, which
is stable but probably slower:
# class a = object (self)
method virtual f : 'a. 'a -> unit
method f _ = self#f 3; self#f 'a'
end;;
class a : object method f : 'a -> unit end
I have never needed to circumvent the type system in this way. I can only
remember one instance where I had to sit down and think about how to
refactor my code in order to get it to type check and that was a "big
picture" problem, trying to avoid lots of mutually recursive modules. I
chose to use an object and the result is clear and simple and it allows the
rest of the program to be factored cleanly.
>> I don't think anyone knows which languages are most commonly used.
>> Worldwide, Lisp and Scheme are very common because they are taught a lot
>> in the US. In Europe, more modern languages (e.g. SML, OCaml) are often
>> taught instead. In terms of industrial use, I have been involved with
>> several companies that use OCaml and one that uses SML. However, that is
>> self-selected because I am an ML programmer.
>
> It's interesting that you say, there are "several" companies that use
> OCaml. I've heard of a few that use (or had contact with ;-)) OCaml.
> "Several" sounds much.
>
> Can you give an estimated number of how much "several" is?
Wolfram Research:
http://www.wolfram.com
http://forums.wolfram.com/mathgroup/archive/2004/May/msg00061.html
XenSource:
http://www.xensource.com
http://lists.debian.org/debian-ocaml-maint/2006/03/msg00045.html
Merjis:
http://merjis.com/
Flying Frog Consultancy:
http://www.ffconsultancy.com
http://www.ffconsultancy.com/products/presenta
Jane St. Capital
http://www.janestcapital.com
http://www.janestcapital.com/ocaml.html
Studio Baretta
http://studio.baretta.com/
Also, look at the list of institutions that have purchased my book:
http://www.ffconsultancy.com/products/ocaml_for_scientists
You've got Apple, Sun, Microsoft, Philips, Burnham, Intrech, DV Studio,
Hubbard One, Starkmann, LMS Deutschland, Softship and Open Fuel. We haven't
updated that page for a while so there are many more not yet listed...
Ah, I cherish the days when I was the only OCaml consultant. ;-)
On AMD/AMD64, yes. On IA32, SML compiled with MLton is likely to be faster
than OCaml. Have a look at the performance results (and code) of my ray
tracing benchmark:
http://www.ffconsultancy.com/free/ray_tracer/languages.html
Also, it depends what kind of code you're writing. OCaml is good for
floating-point-intensive numerical code. MLton is good for symbolic code.
Lisp and Scheme have many practical disadvantages:
1. Dynamic typing => slow, buggy code.
2. No standard pattern matching => poor for data structures.
>>>>> "Jon" == Jon Harrop <use...@jdh30.plus.com> writes:
Jon> Lisp and Scheme have many practical disadvantages:
Jon> 1. Dynamic typing => slow, buggy code.
Jon> 2. No standard pattern matching => poor for data structures.
This is a - well - rather lopsided comment on common lisp and scheme.
As you can see by using either cmucl or sbcl, idiomatic cl is usually
neither slow nor buggy. It is not an ML, that's all. And if you really
need the last ounce of numericxal performance you know where to find it:
it is called Fortran.
'Andreas
--
Wherever I lay my .emacs, there's my $HOME.
Johan> I have chosen language based on speed and efficiency for
Johan> me, and for this I think the MLton compiler is good, but
Johan> there are good arguments for compilers of other languages
Johan> as well, and I would not recommend choosing only based on
Johan> the compiler, unless you know what your criteria are.
I have not written performance intensive code in a purely functional
language in the "real world" but AFAIK Haskell has some very good
implementations. The Glasgow Haskell Compiler (GHC) has always
surprised me, and here is some data compared with MLton
http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=mlton&lang2=ghc
Of course simple tests like this are hardly conclusive of much except
that performance is not a really good reasons for skipping out on
Haskell.
Cheers!
Shyamal
3. Verbose.
> As you can see by using either cmucl or sbcl, idiomatic cl is usually
> neither slow nor buggy.
You mean the compilers themselves are bootstrapped, fast and reliable?
As for speed: SBCL is ~3x slower to compile my ray tracer than ocamlopt and
the resulting program runs ~2x slower. Lisp also requires a lot more code
and a lot more optimisation-related knowledge to produce fast code. That's
performance on numerical code. I don't have results for symbolic code but I
expect SBCL-compiled Lisp to be slow there too, especially compared to
MLton.
I think there's no question that Lisp is generally slow compared to SML and
OCaml. Indeed, it is difficult to find examples where SBCL-compiled Lisp
outperforms MLton-compiled SML or ocamlopt-compiled OCaml.
In terms of reliability, unit testing is much more common in Lisp
development than in ML development. This requires the programmer to invent
tests and try to catch their own code out.
Stalin-compiled Scheme certainly brings run-time performance up to par.
However, it is vastly slower to compile and only supports a subset of
Scheme.
> It is not an ML, that's all. And if you really
> need the last ounce of numericxal performance you know where to find it:
> it is called Fortran.
You might as well learn assembler...
Indeed, Haskell certainly used to be a slow language (as ML was 10 years
ago) but GHC gives excellent performance on a variety of tasks now.
I'd like to see my ray tracer written in Haskell... :-)
In my opinion, some dialect of ML is a good place to start with is you
want to study the basic concepts of functional programming as well as
to write something "real-world" in that style.
LISP/Scheme has somewhat weird syntax (made of parenthesis) and to
understand it´s real power you´ll have to understand macros (however,
Scheme is my personal language of choice). Languages of this family, as
other posters already noted, also lack the strong typing, so if you´re
comfortable with dynamic typing languages like Python or Ruby it may
also be a good place to start.
Haskell has a funky concept of monads, which is both required to write
some real-world app in that language and a place to stuck for a long
time when learning Haskell. It´s good area for further study.
However, to get the best understanding of functional programming, it´s
good to learn all three languages to see three different approaches of
writing programs in non-imperative style.
Ivan.
Ivan> avi...@gmail.com wrote:
>> Now I have been intending to pick up a functional language and
[..deleted...]
Ivan> LISP/Scheme has somewhat weird syntax (made of parenthesis)
Ivan> and to understand it´s real power you´ll have to understand
Ivan> macros (however, Scheme is my personal language of
[..deleted...]
Note that Lisp is *not* a functional language. It can be used to
program in a functional style but common usage (with setf, setq, loop
macros etc.) is certainly imperative style.
But I'd still recommend learning Lisp just for the "mother of all
languages" experience you get :)
Cheers!
Shyamal
I have seen this, and been impressed. Looking at the OCaml results in
the shootout also gives the impression that OCaml is also good at
optimizations. I had a reason for writing "efficient for me" in teh
quoted passage above.
MLton versus OCaml:
In fact, for my numerical code, I switched from OCaml to MLton for
performance reasons, but I would certainly not say that Ocaml is always
less good at optimizations than MLton. As far as I understand, however,
Ocaml is not an optimizing compiler in the sense MLton is a
whole-program, optimizing compiler. In my numerical code, I used the
module system, and other constructs to make my code more readable. These
did not slow things down with MLton but it is definitely my impression
that they did so with OCaml.
Haskell:
Considering Haskell, it has often been said that it requires more
thinking to write efficient code in Haskell than in SML, and therefore I
chose SML. I so not program a lot, and learning how to optimize Haskell
code did not seem to pay off quickly enough for me at the time I made
the choice.
But given enough time for programming, I would perhaps have chosen Haskell.
/ johan
But note this: you haven't "learned Lisp" when you know how
to program in Lisp. You need to extend it and change it to your
particular needs, to grasp its spirit.
The real strength of Lisp is the ease of changing it into what is
nowadays called a "domain specific language". I am quite puzzled
when I hear Lisp illiterates talk about dsl as something new... it
has been part of Lisp programming for 35 years or so, yet mainstream
software developers never cared to pick up what was under their
nose - it seems to have been associated with an AI geek smell.
Interestingly, when dressed up in XML, the same ideas and
techniques suddenly make sense to the mugglers.
The way to learn Lisp is to build a language on top of it - and
this is not as far fetched as it seems.
Ole Nielsby
[...]
Some years ago, when I found my first way to functional languages,
I started with scheme. Some things I tried, and looked for a compiler
that creates extremely fast code.
I later looked at OCaml and Haskell, and had decided for OCaml then.
One of the reasons, to let scheme go was, that the compiler I chosed
(because of performance as well as that it had a C-interface) was,
that it could not do tailrec-optimization.
As far as I understand the ChangeLog, this problem should be
no more a problem (I will ask the developer if it now is completely
tailrec-optimising).
The compiler was "bigloo", and it seems that it is even better than
the years ago, where I first looked at it.
It now has interfaces to a lot of other languages/APIs, and if I
understand correctly the words on the omepage of bigloo, it now compiles
scheme as well as SML?! (*)
And seems to be one of the best optimising compilers now...
(it even was some years ago high-performance, but maybe it's
even better now?!)
So, I think during the next time (when i have time for such
things... I hope so), i would do some experiments with bigloo.
Bigloo is not 100% R5RS compliant, but nearly ("mostly" they say on the
homepage).
Well, it seems, that scheme then could come back to my mind now. :)
This might be interesting for you:
http://www-sop.inria.fr/mimosa/fp/Bigloo/bigloo.html#Bigloo-homepage
and especially:
http://www-sop.inria.fr/mimosa/fp/Bigloo/bigloo-1.html#Features
http://www-sop.inria.fr/mimosa/fp/Bigloo/bigloo-5.html#Papers-&-Reports
Ciao,
Oliver
(*) "Bigloo is the first compiler for full Scheme and full ML, and for
these two languages, Bigloo is one of the most efficient compiler
now available (Bigloo is available by anonymous ftp on
ftp.inria.fr)."
(found this here:
http://www-sop.inria.fr/mimosa/fp/Bigloo/bigloo-5.html#Papers-&-Reports)
[...]
Well, the Changelog seems to have irritated me?!
I looked into the documentation (from 2006) and found this:
"Bigloo produces C files. C code uses the C stack, so some programs
can’t be properly tail recursive. Nevertheless all simple tail
recursions are compiled without stack consumption."
So... the tailrec-problem seems not to be solved?! :(
:(
Well....
Ciao,
Oliver
That isn't even true anyway, you could implement tail-recursion in C by
using it like an assembler, i.e. by emitting "goto"s.
Thank you for the links. If it is as good as you seem to indicate, I
would be interested.
As I said, the code governing my language choice was doing numerical
simulations, but using higher-level constructs. When looking at the
shootout mentioned earlier, on two of the floating point tests, bigloo
seems not to optimize very well compared to MLton
On "Mandelbrot", MLton is 83 times faster, and on "n-body", it is 73
times faster according to:
http://shootout.alioth.debian.org/sandbox/benchmark.php?test=all&lang=bigloo&lang2=mlton
Those results are for the AMD machine. On pentium, bigloo is not one of
the languages.
Do you have any reason to believe that bigloo is better than that?
From the shootout results, I think I would rather stay with MLton now,
and try Haskell as a next step, when I have more time for learning to
optimize Haskell.
/ johan
http://www.codepoetics.com/wiki/index.php?title=Topics:SICP_in_other_languages
As spare time allows, I've been slowly grinding away on the project.
The first chapter of SICP is done for OCaml, Oz, Alice ML. Other than
a couple of lines here and there, the Alice code is mostly using the
Standard ML susbset. The Haskell code is barely started, so it needs a
lot more work.
>Oliver Bandel wrote:
>> Well, the Changelog seems to have irritated me?!
>>
>> I looked into the documentation (from 2006) and found this:
>>
>> "Bigloo produces C files. C code uses the C stack, so some programs
>> can?t be properly tail recursive. Nevertheless all simple tail
>> recursions are compiled without stack consumption."
>>
>> So... the tailrec-problem seems not to be solved?! :(
>
>That isn't even true anyway, you could implement tail-recursion in C by
>using it like an assembler, i.e. by emitting "goto"s.
Goto can't cross function boundaries. A multiple function tail
recursion (one that "loops" through a chain of functions) is not
easily expressible in C. To handle a tail recursion involving
multiple functions, you need to fuse all the HLL functions involved
into a single C function while preserving all of their independent and
mutual behaviors. While this is technically possible it is rarely
done because it can be very difficult to do.
So some tail recursive programs in your favorite language won't be
tail recursive when compiled to C. If this bothers you ... write a
better compiler.
I've occasionally wondered about using the exception mechanism in C++
to implement multiple function tail recursion, using exception
parameters to pass back the arguments to the recursive calls. I've
never bother to develop the idea, though, because it seems like it
would be complex to automate.
George
--
for email reply remove "/" from address
The Chicken Scheme compiler does something similar to this, only it
uses setjmp/longjmp in C instead of C++ exceptions. It compiles to
CPS, and implements functions with regular C functions. When a series
of tail calls hits the stack limit, it will longjmp back, clearing
the stack of useless frames.
--
Neel Krishnaswami
ne...@cs.cmu.edu
Is there an overview on different scheme implementations?
If there is one that looks interesting I would like
to do some scheme-stuff.
Which compiler could you recommend?
Is there an overview doc somewhere?
Ciao,
Oliver
Oh, that is very interesting.
> Those results are for the AMD machine. On pentium, bigloo is not one of
> the languages.
>
> Do you have any reason to believe that bigloo is better than that?
No. It's long ago since I looked for scheme implementations.
And at that time I didn't knew about MLton (maybe it was not existent
at that time?). I doubt the shootout existed at this time; it's
some years ago.
What in the bigloo-abstracts of the paper's page
was mentioned was, that it does a whole-program optimization.
If you do not compare simple benchmarks but whole applications,
then the bigloo way might outperform MLton.
Or does MLton also make optimization on the whole
program code?
I didn't used MLton, but one reason is, that OCaml
is quite fast and I didn't felt the necessity to have
it faster.
Compared to some Perl-stuff it is amazingly fast
(even in bytecode!).
So when I really would have such performance problems,
only than I would try it.
In my daily work since some months I do some Perl scripts
and do documentations in LaTeX, and I have to document VisualBasic
code (ugly written). This is such an ugly language... and then
also ugly code... well... :(
I would be happy to have a project where I have to look at
performance. (And more happy, when using OCaml would be no problem.)
Documenting code of others, written in ugly languages
is not my favourite thing... but doing it with LaTeX makes fun. :)
Some things I wrote a while ago where fast in OCaml
(logfile analyzers and some other nice things). I first
started with a Perl-implementation (of this logifle analyzer),
and at a certain point I saw that for the complex stuff it would be
better to re-implement the nearly
complete Perl program in Ocaml - better than to crap around with
Perl... "use strict" is necessary, but nothing compared to
strictly typed OCaml. :)
And the abstract features... well....
...and the result was quite fast (even if I today would
implement it otherwise, but also with OCaml, and I think
it would be again faster. But the necessity for another
language instead of OCaml was not there. Optimizing
the code/algorithms and maybe compiling to native code,
this are the things I would try first).
But scheme is interesting nevertheless; before I switched to
OCaml I started with scheme.
Lisp would be interesting, if the literature would be available now.
But then also there are different implementations - which one is really
good?
>
> From the shootout results, I think I would rather stay with MLton now,
> and try Haskell as a next step, when I have more time for learning to
> optimize Haskell.
Why MLton?
I don't know much about it; but the last piece of
performance hit.... well performance is fine,
but not all.
Haskell is always fine, because of it's mathematical-like
syntax (list comprehensions) and because it is pure and
elegant.
Even if you don't know to optimize it, it would be good to learn it.
But it's harder to get than ML-languagesm when you come from the
imperative world.
But there are more books on Haskell than on OCaml.
Are there any on MLton?
Ciao,
Oliver
Indeed it does. A quick glance at http://mlton.org/ reveals this. My
experience is that MLton trades speed for space, but boy is the target
fast.
It would also most likely be rather inefficient.
C++ compilers have become a *lot* more efficient with exceptions, but
they still don't assume that exceptions are a normal return path, so
exception efficiency takes a back seat whenever it conflicts with
another design goal. That's bad if you want to implement tail recursion,
which would be one of the more important FPL optimizations (if it's not
*the* most important one).
Regards,
Jo
Well, it certainly doesn't make sense to *me*, whether it's in the
disguise of XML or Lisp.
Give me a well-crafted set of library routines, and I'll drop
domain-specific languages any day... (yes they can be useful, and they
are nearly indispensable when giving marginally programming-literate a
language that they can program in - but for any serious project, there's
almost inevitably a seam between the DSL and the base language, or the
DSL and another DSL, so the application programmer needs to know not
just the DSL but the base language, too - and at that point, I don't see
much of an advantage anymore.)
Regards,
Jo
...well... really seems to be interesting... :)
I may try it also. :)
(Even if I - for myself - prefer systemy like Linux and Unix-systems,
OCaml's binaries for M$ Win. have the advantage that I could also
use my scripts on computers that are not mine (which means, that
this has an advantage in a job-setting, where I can't change the
environment like Operating System. MLTon does not seem to have
Win-standalone binaries?! And has it a module system, similar to
OCaml's?...well, I might see, if I explore the mlton-pages, but if you
know it, you may answer, please.)
Ciao,
Oliver
I doubt you can re-program a well written DSL with a common programming
language in a way that it makes sense. This would be stupid in most
cases. You would have to use too much time, and also would have the
problems of any software development. You would re-invent the wheel
while driving with your car through the valley.
Or would you prefer using a common programming language instead
of using specialized tools like TeX/LaTeX, m4, gnuplot, graphviz,
SQL-databases, make, metapost, R, matlab/mathematica/..., postscript
and the many other tools around ?!
I also doubt, that Lisp would be the ultimate tool to implement
such languages, even if I think it will be very powerful here.
But other FPLs are also powerful and has their advantages.
(But I'm not a Lisp-er (but maybe one day I would try it... if the
necessary literature is available again (and I have some leisure to
learn it).)
Ciao,
Oliver
Well... it has the Standard ML module system.
It is described in Harpers book:
http://www.cs.cmu.edu/~rwh/smlbook/online.pdf
>> http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=mlton&lang2=ghc
> I have seen this, and been impressed.
One thing the shootout doesn't tell you is the effort spent to achieve
the results. I know some of the Haskell benchmarks deserve a
"closed course - professional driver" subtext (you can see some of the
development process at the haskell wiki). In all likelyhood, many
other benchmarks haven't received the same level of attention.
(The flip side of the coin is that in those cases you either have a
very small community, or one that doesn't care about performance. Or
one where the programmers are in such demand that they have no time
for toys like the shootout :-)
Anyway - the important message is that it is certainly *possible* to
optimize Haskell programs. In many ways, that is all you need, you
can quickly write a working and correct, but possibly inefficient
prototype, and then apply optimization efforts where it counts.
-k
--
If I haven't seen further, it is by standing in the footprints of giants
There are several things that a DSL can do that you can't get from a
set of library routines, no matter how well crafted:
- A syntax designed for the problem domain.
- Static validation of domain-specific properties and constraints.
- Compile-time error messages stated at the level of the problem
domain.
Note that DSLs embedded in Lisp or similar can only to a limited
degree do the avove. Lisp macros may be very well, but you don't
avoid Lots of Irritating Silly Parentheses, and static validation can
be difficult.
Torben
The MLton wiki has a page about OCaml, that tries to sum up the
differences (http://mlton.org/OCaml).
At my level of programming, the language features do not make a
difference. The module is indeed similar.
I feel one drawback of using SML is that as MLton does not run
interactively, if you want to have both an interactive and one with the
performance of MLton, you would have to use two implementations of SML.
These will probably (I think) have different FFIs and different
libraries available. OCaml solves this by having just one
implementation, adn Haskell seems to have a (somewhat) standard FFI.
I think the Windows version of MLton needs cygwin.
> Lisp would be interesting, if the literature would be available now.
The following two books are especially good for learning programming in
Common Lisp:
Paradigms of AI Programming, Case Studies in Common Lisp, Peter Norvig
Practical Common Lisp, Peter Seibel
Both are available from bookstores.
The ANSI CL Spec is available as html.
Other older books I often order used through Amazon or similar online
bookstores.
Some of the used books you can get are really in excellent condition.
> But then also there are different implementations - which one is really
> good?
Depends on what is 'good' for you.
Commercially: LispWorks and Allegro CL. They also have no-cost versions
for learning.
But there are others like Scieneer CL.
Otherwise: SBCL, CLISP, GCL, OpenMCL, ...
I put a lot of effort into improving many of the programs (particularly in
OCaml), only to have them rejected for spurious reasons or ignored.
Worse, they designed a test (sieve-bits) that OCaml cannot implement as
specified but refused to do the opposite for binary-trees by making them
polymorphic. Many of the implementations use wildly different hacks to
improve their apparent performance.
IMHO, the most interesting benchmark on the shootout is still my ray tracer,
(although it isn't listed):
http://shootout.alioth.debian.org/debian/benchmark.php?test=raytracer&lang=all
In short, take the performance results from the shootout with a big pinch of
salt...
Caveat 1: It's hard to design a good language. A lot of effort would
have to go into that.
If the same effort went into library design, I suspect that many DSLs
would become unnecessary.
> This would be stupid in most
> cases. You would have to use too much time, and also would have the
> problems of any software development. You would re-invent the wheel
> while driving with your car through the valley.
Caveat 2: I think that many DSLs reinvent the wheel of general
programming, and with less competence in, um, programming language
ergonomy. (That doesn't mean that many mainstream languages are much
better.)
> Or would you prefer using a common programming language instead
> of using specialized tools like TeX/LaTeX, m4, gnuplot, graphviz,
> SQL-databases, make, metapost, R, matlab/mathematica/..., postscript
> and the many other tools around ?!
Indeed.
Under the precondition that the base language uses minimal syntax. E.g.
similar to Haskell's syntax (which is remarkably slim). In fact I have
seen references to Haskell being used as a DSL substrate, where the
DSL's elements are just calls to ordinary Haskell functions.
TeX is an excellent example how to *not* do a DSL.
It has an excellent internal library (or so I hear). However, it's
syntax already is quite horrible, and its semantics is a real mess. (I
have tried to achieve a few things in TeX, so I have the bruises to
demonstrate the point. It doesn't even have a reliable way to quote things!)
TeX is also an excellent example where programming languages indeed have
limitations; you'd probably want different rules than the usual
delimit-a-token-and-ignore-comments scanner for a programming language.
(Well, maybe not. Designing a lexical syntax that's suitable for writing
instead of programming could be a challenge, but I suspect it would be
nearer to ordinary programming languages than many would expect.)
> I also doubt, that Lisp would be the ultimate tool to implement
> such languages, even if I think it will be very powerful here.
AFAIK it's widely used for that purpose.
However, Lisp's macro facilities are "too powerful" and can change too
many rules of the language IMHO.
Regards,
Jo
Usually not a serious problem. The DSL designer often doesn't know
enough about programming language design, and a programming language
designer often doesn't know enough about the domain language to design a
good syntax for it.
You forgot this:
- A semantics designed for the problem domain.
Though the reply would be the same. (I was just remembering some of the
weirdnesses that are in Mathematica's language, for example.)
> - Static validation of domain-specific properties and constraints.
>
> - Compile-time error messages stated at the level of the problem
> domain.
Agreed with these two. A good static type system (Hindley-Milner or
stronger) can get you quite far with the first point, but there's always
the odd condition that's difficult, awkward or plain impossible to
express; and it doesn't address the second point (unless error reporting
is really, really good at translating the intermediate HM-inferred types
back to high-level types).
I have some ideas how to address these concerns, but they haven't been
put to practice in any language that I'm aware of.
Regards,
Jo
> TeX is an excellent example how to *not* do a DSL.
> It has an excellent internal library (or so I hear). However, it's
> syntax already is quite horrible, and its semantics is a real mess. (I
> have tried to achieve a few things in TeX, so I have the bruises to
> demonstrate the point. It doesn't even have a reliable way to quote
> things!)
I tend to agree with you. TeX has a lot of warts and strange
limitations, so I would really like to see a replacement designed by
people who know programming language design, preferably declarative
language design (I wouldn't want something looking like C++ or Java).
> TeX is also an excellent example where programming languages indeed
> have limitations; you'd probably want different rules than the usual
> delimit-a-token-and-ignore-comments scanner for a programming
> language. (Well, maybe not. Designing a lexical syntax that's suitable
> for writing instead of programming could be a challenge, but I suspect
> it would be nearer to ordinary programming languages than many would
> expect.)
Probably. You need to delimit scopes, you need to name things, you
need to make parameterised definitions, etc., all very much familiar
from programming languages.
In terms of lexical rules, these should be fairly flexible --
sometimes we want spaces and newlines to be significant, other times
we won't. Sometimes we want to treat consecutive letters as a single
unit, other times not. Sometimes you would want to treat characters
that normally delimit scopes etc. as literals instead (as in LaTeX
verbatim mode), and so on. At the same time, you would probably want
to see from the place where you write text which is the case, i.e., a
macro (or whatever it is called) should not be able to specify how its
input is scanned, it should be the input itself that applies the
proper level of "quoting". I.e., you don't want LISP-style Fexprs but
rather something like backquote/comma.
Another question is scoping. You would normally want a macro to use
style parameters from the place it is invoked rather than the place it
is defined, unless you specify otherwise in the macro. So either you
need dynamic scoping or you postpone application of style parameters
until all macros are expanded. Exactly how to handle scoping will
probably require serious thought.
And I would want static typing (but mostly implicit, with type
inference), so sizes, numbers (for enumeration), colours, etc. have
different types and macro definitions etc. would be checked at time of
definition rather than at time of application.
Torben
> Torben Ægidius Mogensen schrieb:
> > There are several things that a DSL can do that you can't get from a
> > set of library routines, no matter how well crafted:
> > - A syntax designed for the problem domain.
>
> Usually not a serious problem.
Depends on who is the user of the DSL. Programmers can get used to
any syntactic oddities, but non-programmers would want concrete syntax
that looks familiar. So no OO-style value.method notation nor
LISP-style (function arguments) notation.
> The DSL designer often doesn't know
> enough about programming language design, and a programming language
> designer often doesn't know enough about the domain language to design
> a good syntax for it.
It requires dialogue, like design of any software that is used by
others than the designer.
> You forgot this:
>
> - A semantics designed for the problem domain.
Indeed. A set of library routines will not change the scope rules and
evaluation order of the language.
> Though the reply would be the same. (I was just remembering some of
> the weirdnesses that are in Mathematica's language, for example.)
There will always be examples of bad designs.
> > - Static validation of domain-specific properties and constraints.
> > - Compile-time error messages stated at the level of the problem
> > domain.
>
> Agreed with these two. A good static type system (Hindley-Milner or
> stronger) can get you quite far with the first point, but there's
> always the odd condition that's difficult, awkward or plain impossible
> to express;
Such as linearity. Several DSLs I know of use linear types to
constrain use of resources. That's not easy to express using
Hindley-Milner, even with phantom types or popular extensions like
GADTs or existential types.
> and it doesn't address the second point (unless error
> reporting is really, really good at translating the intermediate
> HM-inferred types back to high-level types).
Indeed. H-M-style error messages are notoriously bad, and C++
template error messages are even worse.
> I have some ideas how to address these concerns, but they haven't
> been put to practice in any language that I'm aware of.
Details?
Torben
> I tend to agree with you. TeX has a lot of warts and strange
> limitations, so I would really like to see a replacement designed by
> people who know programming language design, preferably declarative
> language design (I wouldn't want something looking like C++ or Java).
Any thoughts on http://www.it.usyd.edu.au/~jeff/nonpareil/ ?
It's OO, but rather functional.
-- Mark
Most people use SML/NJ interactively and compile using MLton for
speed. Both MLton and SML/NJ support NLFFI (although I believe there
are some minor differences).
Sure. I'm just expecting that DSL designers will usually do even worse
than programming language designers. (I may be wrong with that.)
>>> - Static validation of domain-specific properties and constraints.
>>> - Compile-time error messages stated at the level of the problem
>>> domain.
>> Agreed with these two. A good static type system (Hindley-Milner or
>> stronger) can get you quite far with the first point, but there's
>> always the odd condition that's difficult, awkward or plain impossible
>> to express;
>
> Such as linearity. Several DSLs I know of use linear types to
> constrain use of resources.
Any URLs? (Preferrably informal ones.)
>> and it doesn't address the second point (unless error
>> reporting is really, really good at translating the intermediate
>> HM-inferred types back to high-level types).
>
> Indeed. H-M-style error messages are notoriously bad, and C++
> template error messages are even worse.
There seem to be different levels of badness to H-M-style error messages.
Early compilers tended to emit the end point of their reasoning, leaving
the programmer with lots of unintelligible constructed types. However,
it seems that some compilers do a fairly good job at translating these
back up to programmer-specified types. (Just hearsay though.)
>> I have some ideas how to address these concerns, but they haven't
>> been put to practice in any language that I'm aware of.
>
> Details?
Something along the lines of:
* Use general boolean expressions (actually first-order logic) to assert
program properties.
* Use a inference engine to take 90% of the proof burden from the
programmer.
* The inference engine must not be too smart, otherwise the programmer
won't be able to interpret error messages.
This covers type checking, resource constraints, and invariants. It also
gives domain-specific properties and invariants a place to specify
inside a library (e.g. Eiffel has a rather limited assertion language,
yet it was very helpful in codifying domain-specific limitations).
Combine syntactic simplicity as in Haskell, assertion semantics as in
Eiffel/Spark, a strict formal semantics as in Haskell/Spark, and
assertion validation, and the result should be able to serve as a
substrate for implementing most DSLs in the form of libraries.
The only thing that I don't see easily embedded in a standard
programming language environment is lexical conventions. Stuff like TeX,
even if given a saner syntax and semantics, would probably still require
a special scanner.
Regards,
Jo
Yes!!
I have read a little about the NLFFI but I never thought much about it,
because my guess would be that it is fairly low-level and c-like in style.
Now, however, I realize that this should mean that I can interface the
c-library of my choice (the gsl with cblas) using the NLFFI, and then
write a nice interface to use sml-style syntax, interfacing with that!
This should then be usable in both MLton and SML/NJ, right?
Is this how libraries are usually ported to SML?
Excellent!
I have just printed an NLFFI paper, and will start trying to figure out
if I can do this.
I apologize for noting the differences in FFI between MLton and SML/NJ,
but failing to realize this way of doing things using the NLFFI.
If this works, the only thing I miss is a debugger.
Thanks!
/ Johan
What most slows exception handling is the requirement to clean up
automatic objects as the stack unwinds. If you don't use auto objects
... essentially writing C code in C++ ... then exception performance
is reasonably close to setjmp/longjmp. Longjmp will always be faster
because the jump target is provided and there is no need to resolve it
at runtime.
> I put a lot of effort into improving many of the programs (particularly in
> OCaml), only to have them rejected for spurious reasons or ignored.
>
> Worse, they designed a test (sieve-bits) that OCaml cannot implement as
> specified but refused to do the opposite for binary-trees by making them
> polymorphic. Many of the implementations use wildly different hacks to
> improve their apparent performance.
There was a discussion on the Erlang list about the sieve-bits
benchmark. Erlang's entry was pitiful - it timed out. A few versions
were proposed that put Erlang at roughly the same order of magnitude
as Perl and Python, but then Kostis Sagonas wrote one version using an
obscure feature called hipe_bifs:bytearray(). It's essentially an
Erlang binary that's destructively updated.
I fully expected that implementation to be rejected, as it uses
wholly undocumented black magic for the HiPE compiler, but -
there it is, making Erlang look quite spiffy on this kind of problem.
I thought this kind of thing violates the spirit of the benchmark
(as expressed by the maintainers), but perhaps we're not worse
culprits than anyone else? ;-)
As large Erlang binaries are passed by reference to other processes,
you can write very un-Erlangish programs with the bytearray, as
illustrated by Matthias Läng in
http://www.erlang.org/ml-archive/erlang-questions/200605/msg00013.html
I expect the BIF to remain undocumented...
BR,
Ulf Wiger
--
Ulf Wiger, Senior Specialist,
/ / / Architecture & Design of Carrier-Class Software
/ / / Team Leader, Software Characteristics
/ / / Ericsson AB, IMS Gateways
I briefly scanned some of the articles, and it does look interesting.
I don't like the OO notation, though, and would much prefer something
like Haskell's type classes.
Torben
> Torben Ægidius Mogensen schrieb:
> >> Though the reply would be the same. (I was just remembering some of
> >> the weirdnesses that are in Mathematica's language, for example.)
> > There will always be examples of bad designs.
>
> Sure. I'm just expecting that DSL designers will usually do even worse
> than programming language designers. (I may be wrong with that.)
>
> >>> - Static validation of domain-specific properties and constraints.
> >>> - Compile-time error messages stated at the level of the problem
> >>> domain.
> >> Agreed with these two. A good static type system (Hindley-Milner or
> >> stronger) can get you quite far with the first point, but there's
> >> always the odd condition that's difficult, awkward or plain impossible
> >> to express;
> > Such as linearity. Several DSLs I know of use linear types to
> > constrain use of resources.
>
> Any URLs? (Preferrably informal ones.)
http://springerlink.metapress.com/openurl.asp?genre=article&issn=0302-9743&volume=2986&spage=204
http://www.diku.dk/undervisning/2006f/213/PSIpaper.pdf
> >> I have some ideas how to address these concerns, but they haven't
> >> been put to practice in any language that I'm aware of.
> > Details?
>
> Something along the lines of:
> * Use general boolean expressions (actually first-order logic) to
> assert program properties.
> * Use a inference engine to take 90% of the proof burden from the
> programmer.
> * The inference engine must not be too smart, otherwise the programmer
> won't be able to interpret error messages.
>
> This covers type checking, resource constraints, and invariants. It
> also gives domain-specific properties and invariants a place to
> specify inside a library (e.g. Eiffel has a rather limited assertion
> language, yet it was very helpful in codifying domain-specific
> limitations).
>
> Combine syntactic simplicity as in Haskell, assertion semantics as in
> Eiffel/Spark, a strict formal semantics as in Haskell/Spark, and
> assertion validation, and the result should be able to serve as a
> substrate for implementing most DSLs in the form of libraries.
Sounds interesting. Maybe extending to linear logic or modal logic
would be useful.
> The only thing that I don't see easily embedded in a standard
> programming language environment is lexical conventions. Stuff like
> TeX, even if given a saner syntax and semantics, would probably still
> require a special scanner.
Indeed. But lexers/scanners are fairly easy to make using generator
tools, so I don't think it is too much of a problem to use alternative
lexers.
Torben
MLton does it.
> If this bothers you ... write a better compiler.
Just use one of the many decent compilers that already exist, albeit not for
Lisp/Scheme.
An important problem in designing TeX Done Right<tm> is to keep the
basic structure that the source file mostly is just a manuscript with
markup added _and_ the ability to define new markup which trigger
special processing, on the fly. The "Done Right" part entails that
the language for special processing should be reasonably wart-free
with sensible scoping and binding rules, and still allow defined
markup to be viewed as something _injected_ into the manuscript
structure.
Such issues do not appear to be addressed in the Nonpareil paper I
downloaded and briefly flipped through.
For example, the syntactic structure for marking up the text of a
chapter ought to follow the same principles as marking up a few words
of emphasized text. LaTeX uses \begin{chapter}{title}...\end{chapter} and
\emph{...} basically in order to work around having to slurp the
entire chapter into memory before beginning to typeset it.
Memory is much more abundant today than when TeX was designed - with
16-bit address spaces long gone and virtual memory available
everywhere, there is no intrinsic reason not to read the entire
chapter souce before processing it, provided some location information
was preserved for use in error reporting - but the "we're not reading
large amounts of text in one go anyway" assumption led to other warts
(such as early but customizable tokenization) that still make it
undesirable in LaTeX to let the contents of large structural elements
be macro arguments.
A design for TeX Done Right<tm> ought to be rooted in some
considerations about how the "manuscript" and "programming" levels
should interact in order to make all the things one resanably wants to
do doable without sacrificing the sanity of the programming level.
For example, a design that rigidly enforced a separation between markup
definitions and manuscript text (by requiring them to be in different
files) could preserve the programming-language purity very well, but
would also make the system so cumbersome to use when you wanted
anything out of the ordinary that very few people would want to switch
from TeX anyway. It would just be an exercise in l'art pour l'art.
(Surprisingly many people who otherwise grok the importance of local
definitions seem to think that it is OK for a document processor to
require that all markup elements _must_ have global scope and have a
definition that is lexically remote from their perhaps specialized
use).
--
Henning Makholm "Nej, hvor er vi altså heldige! Længe
leve vor Buxgører Sansibar Bastelvel!"
>>> Though the reply would be the same. (I was just remembering some of
>>> the weirdnesses that are in Mathematica's language, for example.)
>> There will always be examples of bad designs.
> Sure. I'm just expecting that DSL designers will usually do even worse
> than programming language designers. (I may be wrong with that.)
I don't get your distinction. A non-trivial DSL is a programming
language, so its designer is, by definition, a programming language
designer. Of course the designer should either be someone with good
knowledge of both programming language design and the domain in
question, or a well-functioning team that includes experts in both
fields.
--
Henning Makholm "Vi skal nok ikke begynde at undervise hinanden i
den store regnekunst her, men jeg vil foreslå, at vi fra
Kulturministeriets side sørger for at fremsende tallene og også
give en beskrivelse af, hvordan man læser tallene. Tak for i dag!"
Thanks.
FWIW, Wikipedia gave me the link
http://homepages.inf.ed.ac.uk/wadler/topics/linear-logic.html , which
has a *lot* of interesting material.
>>>> I have some ideas how to address these concerns, but they haven't
>>>> been put to practice in any language that I'm aware of.
>>> Details?
>> Something along the lines of:
>> * Use general boolean expressions (actually first-order logic) to
>> assert program properties.
>> * Use a inference engine to take 90% of the proof burden from the
>> programmer.
>> * The inference engine must not be too smart, otherwise the programmer
>> won't be able to interpret error messages.
>>
>> This covers type checking, resource constraints, and invariants. It
>> also gives domain-specific properties and invariants a place to
>> specify inside a library (e.g. Eiffel has a rather limited assertion
>> language, yet it was very helpful in codifying domain-specific
>> limitations).
>>
>> Combine syntactic simplicity as in Haskell, assertion semantics as in
>> Eiffel/Spark, a strict formal semantics as in Haskell/Spark, and
>> assertion validation, and the result should be able to serve as a
>> substrate for implementing most DSLs in the form of libraries.
>
> Sounds interesting. Maybe extending to linear logic or modal logic
> would be useful.
I think it would be better if the inferencer knew about multiple sets of
axioms and inference rules by way of libraries.
Different aspects of a program could then be formalized using the most
appropriate framework. I imagine things like the banker's method (it's a
kind of standard rules to compute bounds on amortized cost), codified as
a set of inference rules, and invoked by the programmer whenever he
needs it.
Linear and modal logic would then simply be yet another set of axioms
and inference rules :-)
(And the system might even know when to invoke these. E.g. in cases such
as the one covered in your financial-framework paper, the library
routines could explicitly use linear logic for their assertions, so the
inferencer would continue with that to construct any additional proofs.)
(The downside with that is that the inferencer won't be able to apply
much strategy. That's sort-of OK with me - the inferencer should be
relatively dumb anyway. It might be too dumb though... or it might need
strategy to get reasonable efficiency, and simply too slow to work on
arbitrary sets of inference rules. I'm not sure about the state of the
art in inferencing technology.)
Regards,
Jo
Henning Makholm wrote:
> Scripsit Mark.C...@Aetion.com (Mark T.B. Carroll)
>> tor...@app-3.diku.dk (Torben Ægidius Mogensen) writes:
>
>>> I tend to agree with you. TeX has a lot of warts and strange
>>> limitations, so I would really like to see a replacement designed by
>>> people who know programming language design, preferably declarative
>>> language design (I wouldn't want something looking like C++ or
>>> Java).
[...]
>
> An important problem in designing TeX Done Right<tm> is to keep the
> basic structure that the source file mostly is just a manuscript with
> markup added _and_ the ability to define new markup which trigger
> special processing, on the fly. The "Done Right" part entails that the
> language for special processing should be reasonably wart-free with
> sensible scoping and binding rules, and still allow defined markup to
> be viewed as something _injected_ into the manuscript structure.
[...]
> A design for TeX Done Right<tm> ought to be rooted in some
> considerations about how the "manuscript" and "programming" levels
> should interact in order to make all the things one resanably wants to
> do doable without sacrificing the sanity of the programming level.
In my opinion this can only be archived by having two separate
languages: a markup language, say TeX like, and a programming language
which is used to define the markup commands.
You might be interested in ant (ant.berlios.de) which implements this
idea.
Achim
--
________________________________________________________________________
| \_____/ |
Achim Blumensath \O/ \___/\ |
TU Darmstadt =o= \ /\ \|
www.mathematik.tu-darmstadt.de/~blumensath /"\ o----|
____________________________________________________________________\___|
> Well, the Changelog seems to have irritated me?!
>
> I looked into the documentation (from 2006) and found this:
>
> "Bigloo produces C files. C code uses the C stack, so some programs
> can't be properly tail recursive. Nevertheless all simple tail
> recursions are compiled without stack consumption."
>
>
> So... the tailrec-problem seems not to be solved?! :(
Bigloo has a lot to offer. There is a lot of fuss going on concerning
Bigloo. Mostly coming from the fact that Bigloo changes over time.
The first thing to consider: the Bigloo manual because it goes way
beyond any Scheme standard. People will miss out a lot if not studying
it well.
However, Bigloo is a very mature and especially stable compiler (used
it for my doctoral thesis in physics all the way and had to steer and
post/pre-processing external Fortran codes) but it is often not that
fast on some related problem.
That said: Bigloo is one of the most usable Scheme compilers for me on
Mac OSX and Unix.
Schneewittchen
>
> Which compiler could you recommend?
>
> Is there an overview doc somewhere?
Better ask in comp.lang.scheme. However, there are a lot of stable and
lively supported Scheme compilers out there: Chicken, Dr.Scheme,
Bigloo, etc.
I can only speak of Bigloo: very good C integration both way rounds,
pattern matching as you know it from functional languages, Java
back-end, some type monsters if you like, etc.
Drawback: Bigloo mostly shines on Unix like systems (Mac OSX, Linux,
etc.). However, there are some individuals who are using Bigloo on
Windows in a professional manner.
By all that one shouldn't forget: Bigloo is a compiler and it is not
adviceable to develop code at the command line where you will get
immediate feedback (e.g. DrScheme).
Schneewittchen
> On "Mandelbrot", MLton is 83 times faster, and on "n-body", it is 73
> times faster according to:
>
> http://shootout.alioth.debian.org/sandbox/benchmark.php?test=all&lang=bigloo&lang2=mlton
I will submit the Mandelbrot benchmark for Bigloo. It is within 2 times
the range of the posted C code. I have forgotten to submit it, however.
I wrote it last year.
Btw: I have posted it at that time on comp.lang.scheme and some
benchmark figures relating the C code vs. Bigloo.
Schneewittchen
>
> What in the bigloo-abstracts of the paper's page
> was mentioned was, that it does a whole-program optimization.
That might be true for Stalin.
As I wrote elsewhere: a good rule of thumb for Bigloo: if all the type
mechanics and floating point operators are used Bigloo is typically
within 2 times the range of the C code. Bigloo is not that good when
dealing with large arrays. I think there lies some potential for
further improvements.
Schneewittchen
> LISP/Scheme has somewhat weird syntax (made of parenthesis) and to
> understand it´s real power you´ll have to understand macros (however,
> Scheme is my personal language of choice).
I have to beg to differ a bit. It might be true that all the light will
shine if one understands macros. However, this doesn't mean that one
may not use Scheme or Lisp professionally without them.
You know: I am not aware of the potential inside my car I am still
happy driving it.
I am sometimes irritated by newbies who ask: may I use Scheme without
macros? I wonder where they do get the idea that one cannot write good
and stable beautiful code without macros. Yes it is possible.
I am the one who knows little about macros but using Bigloo on a daily
basis.
Schneewittchen