Jon Harrop wrote:
Wolfram Fenske wrote:
> Yeah, yeah, I was only using stuff I found in an OCaml tutorial.
> While we're at it, in Lisp I might have gotten away with simply using
> CONS cells and the built-in PUSH and POP macros. This might not be
> ideal for a production quality application but it might do for a
> prototype.In ML, you could get away with list literals and pattern matching:
let empty = and push h t = h::t and pop l = hd l, tl l
However, they are purely functional.
> On a similar note, I see a lot of Python code where
> dictionaries (Python-speak for hash tables) are used instead of
> classes (Python doesn't have structs so classes would be the only
> alternative). This is probably because Python's syntax for
> dictionaries is pretty concise and in a situation where all they want
> to do is pass around two or three values between a handfull of
> functions, people think the overhead of writing a class is just not
> worth it.Classes are generally the wrong tool for the job in OCaml.
>> The functor approach makes better use of static typing but a generic
>> print will not be as elegant in OCaml as it is in Lisp.
>
> This is my point. None of these is really "plug & play". They have
> other qualities, like higher efficiency and better support for static
> checks. But I don't value these as much as you do. IMO, programmer
> efficiency is more important a lot of the time. However, in your
> domain (your signature suggests it's scientific computing), things
> might be different. I imagine it involves a lot of number crunching,
> using complicated algorithms. Maybe I'd use OCaml instead of Lisp for
> this, too.From my point of view, having to write type-specific functions for a tiny
number of generic functions (e.g. print) is a small price to pay for
getting all of your programs checked by the compiler.>> Other MLs (e.g. F#) carry run-time type information and implement
>> print_any, which does what you want. However, they are as slow as
>> Lisp...
>
> Efficiency again. Yes, a statical type system makes building an
> optimizing compiler much easier. But this is the only real advantage
> I see, and it doesn't come for free.Absolutely, except I'd add "correctness" along with "performance".
> I'd like to see an optimizing Lisp compiler that uses type inference
> in the way OCaml does. I know that SBCL infers types where it can and
> uses this during optimization, but I don't know to what extent.Stalin does this for Scheme but it requires whole-program compilation and is
incredibly slow, e.g. 2,000x slower.> E. g., when OCaml compiles a function like Lisp.fold, I assume it
> duplicates it for each type signature the function is used on, like a
> C++ template. I wonder if any Lisp compilers do this.No, OCaml compiles to polymorphic assembler and does very little type
specialisation.>> to accept a value of this type (you can probably do more by
>> specifying the type of the function).
>
> I know, but why would I want write additional source code if I don't
> have to?You're going to write it in the docs. Why not have the docs checked against
the code by the machine?> I assume my programs would look like this:
>
> --8<---------------cut here---------------start------------->8---
> type variant =
> Str of string
> > Int of int
> ;;
>
> let printv arg =
> match arg with
> > Str s -> Printf.printf "%s\n" s
> > Int i -> Printf.printf "%d\n" i
> ;;
>
> let _ =
> printv (Str "foo");
> printv (Int 3)
> ;;--8<---------------cut here---------------end--------------->8---Absolutely not! You're implementing dynamic typing, which weakens the type
system to the point that you might as well be writing Lisp code. Write:print_string "foo";
print_int 3instead.
> The explicit type declaration isn't so bad, and a Lisp equivalent of
> printv would look very similar because it would also have to
> dispatch on the type of its input. But I imagine having to write (Str
> "foo") and (Int 3) all the time would get on my nerves.Yes. This is bad style in OCaml.
>> Then the type is explicit, so you don't need documentation that says
>> things like "Got that? Neither did I...", and your types will be
>> automatically and statically checked for you. Basically, you get
>> machine-verified documentation.
>
> Come on, putting OCaml type declarations into the *end user*
> documentation (because this is were the quotation came from) wouldn't
> really make things more understandable, would it.Absolutely. Almost all API documentation includes type information in
statically typed languages. In dynamically typed languages, it often
contains a waffly description of the allowed values in English that is
likely to be out of date.>> Lisp should do a lot better on tasks where performance is irrelevant
>> or not CPU-limited and where EVAL is useful. I don't believe
>> (decent) static typing is ever enough of a hindrance that it will
>> offset Lisp's missing features,
>
> Missing features? OK, it doesn't have pattern matching [1], but what
> else?Features related to pattern matching, like variant types. Features related
to static typing, like tuples vs arrays/lists. Features related to type
inference, like polymorphic variants and objects.>> so trying to find tasks well suited to dynamic typing is a red
>> herring (IMHO).
>
> The way I see it, using a statically typed language instead of a
> dynamically typed one has to be justified, not the other way around.
> IMO, a static type system is an additional cost most of the time, not
> a benefit. So I'd need a good reason to use a statically typed
> language, e. g. performance is critical or much better library
> support.Reliability is the main reason to use static typing, IMHO.
>> So if I wanted to make Lisp look relatively better then I'd try to write
>> an efficient interpreter. I'd like to see a Lisp equivalent of the
>> interpreter that I've put up here, for example:
>>
>> http://www.ffconsultancy.com/free/ocaml/interpreter.html
>
> Using OCaml's built-in lexer and parser support is cheating a bit,
> isn't it?I've used the built-in lexer generator that contains rules for ints and
floats but the parser is completely general. Using ocamllex to generate a
lexer that included rules for ints and floats explicitly would only add a
couple of LOC.> I could just use Common Lisp's READ (reads an s-expression
> form stdin) and EVAL and be about done.My interpreter contains a recursive descent parser for the grammar that I
chose. You can easily alter it to parse a different grammar (e.g. BASIC)
and it wouldn't require any extra code.> [1] I'm pretty sure pattern matching could be added using macros. In
> just under 50 lines I wrote a little macro that allowed me to
> define the good old flatten like this:
>
> (defun flatten (list)
> (match list
> (() ())
> (((x . y) . z) (append (flatten (cons x y)) (flatten z)))
> ((x . y) (cons x (flatten y)))))
>
> That was really fun!Absolutely. Even naive pattern matching is incredibly useful.
--
Dr Jon D Harrop, Flying Frog Consultancy
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists
I am More of a Ruby guy but i programed in CL and Scheme and SML.
dynamic typeing allows for less code and faaster develipment. static
typeings safty benifits are pointless becaus the # of bugs is
preporial to the lines_of_code. a line of code not needed is a correct
line of code!!!!! and how often do you get type errors