Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > What is Expressiveness in a Computer Language

Reply
Thread Tools

What is Expressiveness in a Computer Language

 
 
Pascal Costanza
Guest
Posts: n/a
 
      06-16-2006
Torben ∆gidius Mogensen wrote:
> Pascal Costanza <(E-Mail Removed)> writes:
>
>> Torben ∆gidius Mogensen wrote:

>
>>> So while it may take longer to get a program that gets
>>> past the compiler, it takes less time to get a program that works.

>> That's incorrect. See http://haskell.org/papers/NSWC/jfp.ps -
>> especially Figure 3.

>
> There are many other differences between these languages than static
> vs. dynamic types, and some of these differences are likely to be more
> significant. What you need to test is langauges with similar features
> and syntax, except one is statically typed and the other dynamically
> typed.
>
> And since these languages would be quite similar, you can use the same
> test persons: First let one half solve a problem in the statically
> typed language and the other half the same problem in the dynamically
> typed language, then swap for the next problem. If you let a dozen
> persons each solve half a dozen problems, half in the statically typed
> language and half in the dynamically typed language (using different
> splits for each problem), you might get a useful figure.


....and until then claims about the influence of static type systems on
the speed with which you can implement working programs are purely
guesswork. That's the only point I need to make to show that your
original unqualified statement, namely that it takes less time to get a
program that works, is incorrect.


Pascal

--
3rd European Lisp Workshop
July 3 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
 
Reply With Quote
 
 
 
 
genea
Guest
Posts: n/a
 
      06-16-2006

Torben ∆gidius Mogensen wrote:

> There are several aspects relevant to this issue, some of which are:
> - Compactness: How much do I have to type to do what I want?

......
> - Naturality: How much effort does it take to convert the concepts of
> my problem into the concepts of the language?
> - Feedback: Will the language provide sensible feedback when I write
> nonsensical things?
> - Reuse: How much effort does it take to reuse/change code to solve a
> similar problem?

......

I am fairly new to Haskell, but the compactness of the language and the
way you can express a lot in a very small amount of real estate is very
important.. I used to program back in the 80's in forth a lot.... okay
I'm a dinosaur!, but "good" definitions were usually very short, and
sweet. Unicon/Icon that I used {still do!} in the imperative world,
very compact. I will give an example that covers compact, reusable,
and because of static typing when will give back mis-type info when you
load a new "a or xs" into it to form a new function.
-- what is happening below is a is being replaced with the curried
lambda: ((++) 3) and
-- xs a list: [1..6], so when that definition of f is used it is type
checked to see if the
-- elements in xs match the type of a, so if this were going to be
compiled, it would
-- checked and guaranteed to work.

Prelude> :t f
f :: forall a b. (Show b) => (a -> b) -> [a] -> IO ()
Prelude> let f a xs = putStr $ foldr (++) "\n" $ map (((++) "\n").
show . a ) xs
Prelude> f ((*) 3) [1..6]
3
6
9
12
15
18
Prelude>

another substitution of parameters.. using the same definition of f
allowed by the the
polymorphic parameters allowed in Haskell add to the versatility and
reusability angle:

Prelude> f sqrt [0.5,1.0..4]
0.7071067811865476
1.0
1.224744871391589
1.4142135623730951
1.5811388300841898
1.7320508075688772
1.8708286933869707
2.0

Same function 'f" now used with a different type..
[0.5,1.0..4] :: forall a. (Fractional a, Enum a) => [a]

I don't know, but this just makes programming fun, for me anyway, and
if it is fun, it is expressive.. I've heard this statement made about
Ruby and Unicon, to name a few... some would say Python.. but it really
applies to the functional languages too, with all their strict typing,
with the type inference mechanisms, it isn't usually that big a deal..
If you just get into it, and can learn to take some constructive
criticism from your compiler, well hey, it is a really patient
teacher... you might get frustrated at times.. but the compiler will
happily remind you of the same type mis-matches, until you get a handle
on some concept and never once complain...
Happy Programming to all!
-- gene

 
Reply With Quote
 
 
 
 
Raffael Cavallaro
Guest
Posts: n/a
 
      06-16-2006
On 2006-06-16 05:22:08 -0400, Joachim Durchholz <(E-Mail Removed)> said:

> And this is a typical dynamic type advocate's response when told that
> static typing has different needs:
>
> "*I* don't see the usefulness of static typing so *you* shouldn't want
> it, either."


But I haven't made this sort of argument. I never said you shouldn't
use static typing if you want to. There are indeed types of software
where one wants the guarantees provided by static type checks. For
example, software that controls irreplaceable or very expensive
equipment such as space craft, or software that can kill people if it
fails such as software for aircraft or medical devices. The problem for
static typing advocates is that most software is not of this type.

There is a very large class of software where user inputs are
unpredictable and/or where input data comes from an untrusted source.
In these cases run-time checks are going to be needed anyway so the
advantages of static type checking are greatly reduced - you end up
doing run-time checks anyway, precisely the thing you were trying to
avoid by doing static analysis. In software like this it isn't worth
satisfying a static type checker because you don't get much of the
benefit anyway\0 and it means forgoing such advantages of dynamic typing
as being able to run and test portions of a program before other parts
are written (forward references to as yet nonexistent functions).

Ideally one wants a language with switchable typing - static where
possible and necessary, dynamic elsewhere. To a certain extent this is
what common lisp does but it requires programmer declarations. Some
implementations try to move beyond this by doing type inference and
alerting the programmer to potential static guarantees that the
programmer could make that would allow the compiler to do a better job.

In effect the argument comes down to which kind of typing one thinks
should be the default. Dynamic typing advocates think that static
typing is the wrong default. The notion that static typing can prove
program correctness is flawed - it can only prove that type constraints
are not violated but not necessarily that program logic is correct. It
seems to me that if we set aside that class of software where safety is
paramount - mostly embedded software such as aircraft and medical
devices - we are left mostly with efficiency concerns. The 80-20 rule
suggests that most code doesn't really need the efficiency provided by
static guarantees. So static typing should be invoked for that small
portion of a program where efficiency is really needed and that dynamic
typing should be the default elswhere. This is how common lisp works -
dynamic typing by default with static guarantees available where one
needs them.

 
Reply With Quote
 
Raffael Cavallaro
Guest
Posts: n/a
 
      06-16-2006
On 2006-06-16 11:29:12 -0400, Raffael Cavallaro
<raffaelcavallaro@pas-d'espam-s'il-vous-plait-mac.com> said:

> In software like this it isn't worth satisfying a static type checker
> because you don't get much of the benefit
> anyway\0\0text\0\0\0\0*Dx§\0\0\0description\0£\0\0\0text\0\0\0\0*DxĘ\0\0\0fromname
> as being able to run and test portions of a program before other parts
> are written (forward references to as yet nonexistent functions).


I don't what bizarre key combination I accidentally hit here, but the
original read:

In software like this it isn't worth satisfying a static type checker
because you don't get much of the benefit anyway and it means forgoing
such advantages of dynamic typing as being able to run and test
portions of a program before other parts are written (forward
references to as yet nonexistent functions).

 
Reply With Quote
 
Raffael Cavallaro
Guest
Posts: n/a
 
      06-16-2006
On 2006-06-16 05:22:08 -0400, Joachim Durchholz <(E-Mail Removed)> said:

> And this is a typical dynamic type advocate's response when told that
> static typing has different needs:
>
> "*I* don't see the usefulness of static typing so *you* shouldn't want
> it, either."


But I haven't made this sort of argument. I never said you shouldn't
use static typing if you want to. There are indeed types of software
where one wants the guarantees provided by static type checks. For
example, software that controls irreplaceable or very expensive
equipment such as space craft, or software that can kill people if it
fails such as software for aircraft or medical devices. The problem for
static typing advocates is that most software is not of this type.

There is a very large class of software where user inputs are
unpredictable and/or where input data comes from an untrusted source.
In these cases run-time checks are going to be needed anyway so the
advantages of static type checking are greatly reduced - you end up
doing run-time checks anyway, precisely the thing you were trying to
avoid by doing static analysis. In software like this it isn't worth
satisfying a static type checker because you don't get much of the
benefit anyway and it means forgoing such advantages of dynamic typing
as being able to run and test portions of a program before other parts
are written (forward references to as yet nonexistent functions).

Ideally one wants a language with switchable typing - static where
possible and necessary, dynamic elsewhere. To a certain extent this is
what common lisp does but it requires programmer declarations. Some
implementations try to move beyond this by doing type inference and
alerting the programmer to potential static guarantees that the
programmer could make that would allow the compiler to do a better job.

In effect the argument comes down to which kind of typing one thinks
should be the default. Dynamic typing advocates think that static
typing is the wrong default. The notion that static typing can prove
program correctness is flawed - it can only prove that type constraints
are not violated but not necessarily that program logic is correct. It
seems to me that if we set aside that class of software where safety is
paramount - mostly embedded software such as aircraft and medical
devices - we are left mostly with efficiency concerns. The 80-20 rule
suggests that most code doesn't really need the efficiency provided by
static guarantees. So static typing should be invoked for that small
portion of a program where efficiency is really needed and that dynamic
typing should be the default elswhere. This is how common lisp works -
dynamic typing by default with static guarantees available where one
needs them.

 
Reply With Quote
 
Raffael Cavallaro
Guest
Posts: n/a
 
      06-16-2006
On 2006-06-16 05:22:08 -0400, Joachim Durchholz <(E-Mail Removed)> said:

> And this is a typical dynamic type advocate's response when told that

static typing has different needs:
> "*I* don't see the usefulness of static typing so *you* shouldn't

want it, either."

But I haven't made this sort of argument. I never said you shouldn't
use static typing if you want to. There are indeed types of software
where one wants the guarantees provided by static type checks. For
example, software that controls irreplaceable or very expensive
equipment such as space craft, or software that can kill people if it
fails such as software for aircraft or medical devices. The problem for
static typing advocates is that most software is not of this type.

There is a very large class of software where user inputs are
unpredictable and/or where input data comes from an untrusted source.
In these cases run-time checks are going to be needed anyway so the
advantages of static type checking are greatly reduced - you end up
doing run-time checks anyway, precisely the thing you were trying to
avoid by doing static analysis. In software like this it isn't worth
satisfying a static type checker because you don't get much of the
benefit anyway and it means forgoing such advantages of dynamic typing
as being able to run and test portions of a program before other parts
are written (forward references to as yet nonexistent functions).

Ideally one wants a language with switchable typing - static where
possible and necessary, dynamic elsewhere. To a certain extent this is
what common lisp does but it requires programmer declarations. Some
implementations try to move beyond this by doing type inference and
alerting the programmer to potential static guarantees that the
programmer could make that would allow the compiler to do a better job.

In effect the argument comes down to which kind of typing one thinks
should be the default. Dynamic typing advocates think that static
typing is the wrong default. The notion that static typing can prove
program correctness is flawed - it can only prove that type constraints
are not violated but not necessarily that program logic is correct. It
seems to me that if we set aside that class of software where safety is
paramount - mostly embedded software such as aircraft and medical
devices - we are left mostly with efficiency concerns. The 80-20 rule
suggests that most code doesn't really need the efficiency provided by
static guarantees. So static typing should be invoked for that small
portion of a program where efficiency is really needed and that dynamic
typing should be the default elswhere. This is how common lisp works -
dynamic typing by default with static guarantees available where one
needs them.


 
Reply With Quote
 
Matthias Blume
Guest
Posts: n/a
 
      06-16-2006
Darren New <(E-Mail Removed)> writes:

> Joachim Durchholz wrote:
>> Give a heterogenous list that would to too awkward to live in a
>> statically-typed language.

>
> Printf()?


Very good statically typed versions of printf exist. See, e.g.,
Danvy's unparsing combinators.
 
Reply With Quote
 
Matthias Blume
Guest
Posts: n/a
 
      06-16-2006
Darren New <(E-Mail Removed)> writes:

> Matthias Blume wrote:
>> Very good statically typed versions of printf exist. See, e.g.,
>> Danvy's unparsing combinators.

>
> That seems to ignore the fact that the pattern is a string, which
> means that printf's first argument in Danvy's mechanism has to be a
> literal.


In Danvy's solution, the format argument is not a string.

> You can't read the printf format from a configuration file
> (for example) to support separate languages.


You don't need to do that if you want to support separate languages.
Moreover, reading the format string from external input is a good way
of opening your program to security attacks, since ill-formed data on
external media are then able to crash you program.

> It doesn't look like the
> version of printf that can print its arguments in an order different
> from the order provided in the argument list is supported either;
> something like "%3$d" or some such.


I am not familiar with the version of printf you are refering to, but
I am sure one could adapt Danvy's solution to support such a thing.

> Second, what's the type of the argument that printf, sprintf, fprintf,
> kprintf, etc all pass to the subroutine that actually does the
> formatting? (Called vprintf, I think?)


Obviously, a Danvy-style solution (see, e.g., the one in SML/NJ's
library) is not necessarily structured that way. I don't see the
problem with typing, though.

Matthias
 
Reply With Quote
 
Joachim Durchholz
Guest
Posts: n/a
 
      06-16-2006
Sacha schrieb:
>
> Many lists are heterogenous, even in statically typed languages.
> For instance lisp code are lists, with several kinds of atoms and
> sub-lists..


Lisp isn't exactly a statically-typed language

> A car dealer will sell cars, trucks and equipment..
> In a statically typed language you would need to type the list on a common
> ancestor...


Where's the problem with that?

BTW the OO way isn't the only way to set up a list from heterogenous data.
In statically-typed FPL land, lists require homogenous data types all
right, but the list elements aren't restricted to data - they can be
functions as well.
Now the other specialty of FPLs is that you can construct functions at
run-time - you take a function, fill some of its parameters and leave
others open - the result is another function. And since you'll iterate
over the list and will do homogenous processing over it, you construct
the function so that it will do all the processing that you'll later need.

The advantage of the FPL way over the OO way is that you can use ad-hoc
functions. You don't need precognition to know which kinds of data
should be lumped under a common supertype - you simply write and/or
construct functions of a common type that will go into the list.

> What would then be the point of statical typing , as you stilll need to type
> check each element in order to process that list ?


Both OO and FPL construction allow static type checks.

> Sure you can do this in a
> statically-typed
> language, you just need to make sure some relevant ancestor exists. In my
> experience
> you'll end up with the base object-class more often than not, and that's
> what i call dynamic typing.


Not quite - the common supertype is more often than not actually useful.

However, getting the type hierarchy right requires a *lot* of
experimentation and fine-tuning. You can easily spend a year or more
(sometimes *much* more) with that (been there, done that). Even worse,
once the better hierarchy is available, you typically have to adapt all
the client code that uses it (been there, done that, too).

That's the problems in OO land. FPL land doesn't have these problems -
if the list type is just a function mapping two integers to another
integer, reworking the data types that went into the functions of the
list don't require those global changes.

>> Give a case of calling nonexistent functions that's useful.

>
> I might want to test some other parts of my program before writing this
> function.


That's unrelated to dynamic typing. All that's needed is an environment
that throws an exception once such an undefined function is called,
instead of aborting the compilation.

I'll readily admit that very few static languages offer such an
environment. (Though, actually, C interpreters do exist.)

> Or maybe will my program compile that function depending on user input.


Hmm... do I really want this kind of power at the user's hand in the age
of malware?

> As long as i get a warning for calling a non-existing function, everything
> is fine.


That depends.
For software that's written to run once (or very few times), and where
somebody who's able to correct problems is always nearby, that's a
perfectly viable strategy.
For safety-critical software where problems must be handled within
seconds (or an even shorter period of time), you want to statically
ensure as many properties as you can. You'll take not just static
typing, you also want to ascertain value ranges and dozens of other
properties. (In Spark, an Ada subset, this is indeed done.)

Between those extremes, there's a broad spectrum.
 
Reply With Quote
 
Joachim Durchholz
Guest
Posts: n/a
 
      06-16-2006
Raffael Cavallaro schrieb:
> There is a very large class of software where user inputs are
> unpredictable and/or where input data comes from an untrusted source. In
> these cases run-time checks are going to be needed anyway so the
> advantages of static type checking are greatly reduced - you end up
> doing run-time checks anyway, precisely the thing you were trying to
> avoid by doing static analysis.


There's still a large class of errors that *can* be excluded via type
checking.

> Ideally one wants a language with switchable typing - static where
> possible and necessary, dynamic elsewhere.


That has been my position for a long time now.

> To a certain extent this is
> what common lisp does but it requires programmer declarations. Some
> implementations try to move beyond this by doing type inference and
> alerting the programmer to potential static guarantees that the
> programmer could make that would allow the compiler to do a better job.


I think it's easier to start with a good (!) statically-typed language
and relax the checking, than to start with a dynamically-typed one and
add static checks.
With the right restrictions, a language can make all kinds of strong
guarantees, and it can make it easy to construct software where static
guarantees abound. If the mechanisms are cleverly chosen, they interfere
just minimally with the programming process. (A classical example it
Hindley-Milner type inference systems. Typical reports from languages
with HM systems say that you can have it verify thousand-line programs
without a single type annotation in the code. That's actually far better
than you'd need - you'd *want* to document the types at least on the
major internal interfaces after all *grin*.)
With a dynamically-typed language, programming style tends to evolve in
directions that make it harder to give static guarantees.

> It seems to
> me that if we set aside that class of software where safety is paramount
> - mostly embedded software such as aircraft and medical devices - we are
> left mostly with efficiency concerns.


Nope. Efficiency has taken a back seat. Software is getting slower
(barely offset by increasing machine speed), and newer languages even
don't statically typecheck everything (C++, Java). (Note that the
impossibility to statically typecheck everything in OO languages doesn't
mean that it's impossible to do rigorous static checking in general.
FPLs have been quite rigorous about static checks; the only cases when
an FPL needs to dynamically typecheck its data structures is after
unmarshalling one from an untyped data source such as a network stream,
a file, or an IPC interface.)

The prime factor nowadays seems to be maintainability.

And the difference here is this:
With dynamic typing, I have to rely on the discipline of the programmers
to document interfaces.
With static typing, the compiler will infer (and possibly document) at
least part of their semantics (namely the types).

> So static typing should be invoked for that small portion of a program
> where efficiency is really needed and that dynamic typing should be the
> default elswhere. This is how common lisp works - dynamic typing by
> default with static guarantees available where one needs them.


Actually static typing seems to become more powerful at finding errors
as the program size increases.
(Yes, that's a maintainability argument. Efficiency isn't *that*
important; since maintenance is usually the most important single
factor, squelching bugs even before testing is definitely helpful.)

Regards,
Jo
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is Expressiveness in a Computer Language Xah Lee Java 640 07-22-2006 03:50 PM
What is Expressiveness in a Computer Language Xah Lee Python 671 07-22-2006 03:50 PM
A language-agnostic language Ed Java 24 03-27-2006 08:19 PM
[perl-python] text pattern matching, and expressiveness Xah Lee Python 4 02-11-2005 09:11 PM
[perl-python] text pattern matching, and expressiveness Xah Lee Perl Misc 1 02-07-2005 08:18 PM



Advertisments