From: Rahul Jain on
"Henry Bigelow" <hrbigelow(a)gmail.com> writes:

> does the standard require that "lisp can be written in itself" as paul
> graham says (whatever that means)?

It doesn't explicitly require that, but it defines a turing-complete
language, so yeah... you can write a lisp compiler and interpreter in
lisp, as you can in C or Perl. The difference, I think, that PG is
getting at is that the most basic lisp data is code itself. Thinking
about code in an abstract manner is just second nature when you're
programming in lisp.

> and, is that why
>
> somehow has a drawback that aggressive type inference can't be done,
> with any compiler of lisp.

I don't see how those two statements could possibly correlate, and later
I demonstrate more aggressive type inference being done than any other
language I've heard of.

>> Lisp has a much richer type system than any of the MLs. CMUCL, for
>> example, can do type inference to determine whether the arcsin of a
>> value rounded off to the nearest integer will fit in a machine word or
>> whether it might need to have a bignum (MLs don't have bignums as part
>> of the language).
>
> yes, but it's been mentioned several times that, in order to get lisp
> code to run fast, you have to "litter it with type declarations". so,
> it seems, there isn't much type inference going on.

No, you "litter" it where needed. It depends from compiler to compiler.
C and Java code is so littered with type declarations, the highway
police would arrest the programmer if he hadn't already run into a
lamppost because his code crashed.

> also, i got that idea from this wikipedia page:
>
> http://en.wikipedia.org/wiki/Type_system
>
> about halfway down it mentions this:
>
> Static typing usually results in compiled code that executes more
> quickly. When the compiler knows the exact data types that are in use,
> it can produce machine code that just does the right thing. Further,
> compilers in statically typed languages can find shortcuts more easily.
> Some dynamically-typed languages such as Common Lisp allow optional
> type declarations for optimization for this very reason. Static typing
> makes this pervasive. See optimization.

Haha! I just modified that paragraph last month to fix the way it
described "Lisp". But yes, Common Lisp can be as static or dynamic as
you want it to be.

> i see. that's pretty cool. so, what is your programming style? do
> you first prototype something without any type declarations, and then
> add in a few in the compute-intensive code?

That's the third rule of optimization applied to type declarations. So
yes. :)

Remember not to conflate type declarations with type checks. (Although
code declared to be safe will always check types when it calls standard
lisp functions.)

--
Rahul Jain
rjain(a)nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Rahul Jain on
Jon Harrop <jon(a)ffconsultancy.com> writes:

> Rahul Jain wrote:
>> Lisp has a much richer type system than any of the MLs.
>
> I'm not sure what you mean by that. ML does lots of things that Lisp does
> not and vice-versa.

Hmm. I'm not sure about that. All I can think of is inference of
parametrized array types (non-upgraded) across functions. Lisp just
doesn't _require_ those things to be done. If someone cared, they could
augment a compiler to do it.

What I'm talking about, to clarify, is for an array declared to have an
element type of (integer 1 100), a function that returns an element of
it should have an inferred return type of (integer 1 100).

For:
(defun test (x)
(declare (type (array (integer 1 100) (*)) x))
(aref x 1))
CMUCL inferrs a return type of:
Its result type is:
(UNSIGNED-BYTE 8)

So it has upgraded the element type to what it's actually going to store
in memory. Dunno why it doesn't just propagate the element type
defintion directly.

>> CMUCL, for
>> example, can do type inference to determine whether the arcsin of a
>> value rounded off to the nearest integer will fit in a machine word or
>> whether it might need to have a bignum
>
> ML doesn't have a numeric tower. You have to explicitly state that you want
> an int, float, bignum and so on.
>
>> (MLs don't have bignums as part of the language).
>
> OCaml, SML and F# all have bignums as part of the language.

Interesting. Some self-proclaimed ocaml genius claimed that it didn't
have bignums. Maybe he meant that you need to explicitly... um...
declare (?!?) a number to be a bignum? That would fit in with the lack
of a numeric tower.

>> This topic is VERY, VERY important to optimizing Lisp numeric code, so
>> be SURE to study it carefully.
>
> In contrast, succinct ML is typically fast ML.

Yeah, but you don't know if it's going to be correct unless you manually
perform the kind of type inference that CMUCL does. :)

On a more serious note, you still end up with the problem that your code
is either slow but tolerant of different architectures or it's fast on
some architectures and incorrect on others. Sure, you could maintain two
parallel versions of the codebase, but don't programmers like
abstraction? (yeah, I know, the mainstream abhors abstraction. They'd be
happy writing machine code if they could still get paid enough for their
time.)

--
Rahul Jain
rjain(a)nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Javier on

Rahul Jain ha escrito:

> Hmm. I'm not sure about that. All I can think of is inference of
> parametrized array types (non-upgraded) across functions. Lisp just
> doesn't _require_ those things to be done. If someone cared, they could
> augment a compiler to do it.
> What I'm talking about, to clarify, is for an array declared to have an
> element type of (integer 1 100), a function that returns an element of
> it should have an inferred return type of (integer 1 100).
>
> For:
> (defun test (x)
> (declare (type (array (integer 1 100) (*)) x))
> (aref x 1))
> CMUCL inferrs a return type of:
> Its result type is:
> (UNSIGNED-BYTE 8)
>
> So it has upgraded the element type to what it's actually going to store
> in memory. Dunno why it doesn't just propagate the element type
> defintion directly.

One important thing I miss from Lisp compared to ML, is for example the
ability to test at compile time about the type of something. For
example you can define a list type in the style of Lisp:

type 'a lisp_list = Nil | List of 'a list

so now every variable using this type can be either Nil or a list
itself. Or even binary trees:

type 'a btree = Empty | Node of 'a * 'a btree * 'a btree

I found this feature very usefull.

> Interesting. Some self-proclaimed ocaml genius claimed that it didn't
> have bignums.

It does:

http://caml.inria.fr/pub/docs/manual-ocaml/libref/Big_int.html

If you don't like those function names, you can rename the operators:

let ( +$ ) = add_big_int


> Maybe he meant that you need to explicitly... um...
> declare (?!?) a number to be a bignum? That would fit in with the lack
> of a numeric tower.

I don't understand what you're talking about, but you can always
convert any int or string to big_int and viceversa.

> >> This topic is VERY, VERY important to optimizing Lisp numeric code, so
> >> be SURE to study it carefully.
> >
> > In contrast, succinct ML is typically fast ML.
>
> Yeah, but you don't know if it's going to be correct unless you manually
> perform the kind of type inference that CMUCL does. :)

I think that if you are a good programmer, you must know the type of
anything you are writing, even if it is writen in Lisp. And ML does
allow you to use "generic" or arbitray types when you need. Just take
the example of the binary tree above.

> On a more serious note, you still end up with the problem that your code
> is either slow but tolerant of different architectures or it's fast on
> some architectures and incorrect on others.
> Sure, you could maintain two
> parallel versions of the codebase, but don't programmers like
> abstraction? (yeah, I know, the mainstream abhors abstraction. They'd be
> happy writing machine code if they could still get paid enough for their
> time.)

Static inference always produce faster code compared with dynamic
inference, for an equivalent code base. But you usually need to declare
things on dynamic languages to help the inferer, while in statically
infered ones you don't, so you save a lot of time on both writing and
profiling.
You don't need to maintain parallel versions of the codebase, or if you
do, you would also do in Lisp (this is not language specific, but the
kind of algorithm/implementation you choose).

From: Jon Harrop on
Rahul Jain wrote:
> Jon Harrop <jon(a)ffconsultancy.com> writes:
>> Rahul Jain wrote:
>>> Lisp has a much richer type system than any of the MLs.
>>
>> I'm not sure what you mean by that. ML does lots of things that Lisp does
>> not and vice-versa.
>
> Hmm. I'm not sure about that. All I can think of is inference of
> parametrized array types (non-upgraded) across functions. Lisp just
> doesn't _require_ those things to be done. If someone cared, they could
> augment a compiler to do it.

Sure, you can augment a compiler to do anything.

>> OCaml, SML and F# all have bignums as part of the language.
>
> Interesting. Some self-proclaimed ocaml genius claimed that it didn't
> have bignums. Maybe he meant that you need to explicitly... um...
> declare (?!?) a number to be a bignum? That would fit in with the lack
> of a numeric tower.

Yes. More than just declare though, you have to annotate every literal and
use different operators.

>> In contrast, succinct ML is typically fast ML.
>
> Yeah, but you don't know if it's going to be correct unless you manually
> perform the kind of type inference that CMUCL does. :)
>
> On a more serious note, you still end up with the problem that your code
> is either slow but tolerant of different architectures or it's fast on
> some architectures and incorrect on others. Sure, you could maintain two
> parallel versions of the codebase, but don't programmers like
> abstraction? (yeah, I know, the mainstream abhors abstraction. They'd be
> happy writing machine code if they could still get paid enough for their
> time.)

In practice, I have never had a problem caused by fixed-precision integers.
However, I have lots of problems caused by floating point precision. Does
CMUCL's type inference do anything to help with that?

--
Dr Jon D Harrop, Flying Frog Consultancy
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists
From: Joe Marshall on

Javier wrote:
>
> Static inference always produce faster code compared with dynamic
> inference, for an equivalent code base.

http://www.hpl.hp.com/techreports/1999/HPL-1999-77.pdf

``Contrary to intuition, we demonstrate that it is possible to
use a piece of software to improve the performance of a
native, statically optimized program binary, while it is
executing. Dynamo not only speeds up real application
programs, its performance improvement is often quite
significant. For example, the performance of many +O2
optimized SPECint95 binaries running under Dynamo is
comparable to the performance of their +O4 optimized
version running without Dynamo.''

First  |  Prev  |  Next  |  Last
Pages: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Prev: Pocket Lisp Machine
Next: Next Generation of Language