I'm a CS student and I often need to write number-crunching code dealing
with combinatorial optimization problems.
What I do usually is implementing ad-hoc algorithms and testing their
performance against other previously-known solutions, including general
solvers.
In the past I used C, but now I have decided to change language.
I'm looking for a "better" one.
Here follow the features it should have, ranked approximately by relevance:
0) open-source support and an alive community
1) directly compiled to efficient code
2) statically typed and object-oriented, better if multi-paradigm
3) general-purpose libraries (possibly standardized, either by standard
or de facto), including containers and some math abstractions.
4) garbage collected. As an alternative, provide memory management
policies via libraries (e.g. memory pools and such)
5) optional run-time checks and some kind of control over compilation
and low-level issues
6) "relatively simple and consistent"
So I have considered these alternatives: FreePascal, Eiffel, Ada and
Modula-3.
I have taken a look at all of them and I'm still undecided. Below are
the impressions I got for each language.
Can you help me? Feel free to recommend other languages as well.
TIA
--> Impressions I got for each language
- FreePascal is a safe and modular alternative to C and C++, but
it is also close to the latter in terms of expressiveness. Moreover it
doesn't seem to have the libraries I need.
==>Qualifies for 0,1,2,5. Not sure about 3 and 4
- Eiffel is geared toward application programming in
medium/large-sized teams relying heavily on OO modelling. It is designed
for (re)usability, correctness and efficiency in this order.
My needs are somewhat different though.
The main gripe I have with Eiffel is the lack of a well-documented
standard gpl'ed library.
GOBO and EiffelBase seem to have incomplete or non-free documentation
and I couldn't find tutorials; as such, I couldn't get a clear picture
about them.
==> Qualifies for 0,1,2,4,5 and 6. Not sure about 3.
- Ada is best suited for large teams and/or critical software, thus
it may be overkill for my work, OTH it could have anything I might
happen to need.
What holds me from jumping onto Ada is the potential complexity
It would be interesting to hear the experience of other people learning
Ada from the C/Java background.
As for memory management (requirement 4), I heard there are different
takes on the matter:
(a) Ada uses dynamic stack allocation a lot, and in a transparent way,
reducing the need of manual management (MM)
(b) Ada libraries adopt idioms that further simplifies MM issues
(c) Conservative garbage collectors such as Bohem's can be used with
Ada, and they are supposed to work "better" with Ada than with unsafe
languages such as C and C++
So can MM be said to be easier in Ada than in C? I hope Ada-ers will
mercifully shed some light on the issue.
There seems to be a lot of Ada95 free documentation on the net, I guess
it's suitable for Ada05 as well.
==> Qualifies for 0,1,2,3,5 and, partially, 4
- Modula-3 is simpler/smaller than Ada and has been successfully
used for system/application programming.
It seems to be the most consistent, simple and easy to grok, but I
couldn't find any container/math library ready to use.
==> Qualifies for 0,1,2,4,5,6.
You might also consider modern fortran.
Richard Harter, c...@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
If I do not see as far as others, it is because
I stand in the footprints of giants.
You said you are a student. So probably your goal is to get a job after your
studies. If this is the case, you forgot the most important thing regarding
language selection: The possibility to get a job !
In that context, I wouldn't use any of the language you mentionned ! Ok,
maybe FreePascal which would be replaced by Delphi or Delphi Prism once you
are in a company for a real work. If it is not Delphi, then use C# or Java.
It is likely that Delphi would be the fastest regarding number crunching.
Delphi has a large and alive community. You can find a lot of opensource and
freeware for Delphi.
--
francoi...@overbyte.be
The author of the freeware multi-tier middleware MidWare
The author of the freeware Internet Component Suite (ICS)
http://www.overbyte.be
> Hi folks!
>
> I'm a CS student and I often need to write number-crunching code
> dealing with combinatorial optimization problems.
> What I do usually is implementing ad-hoc algorithms and testing their
> performance against other previously-known solutions, including
> general solvers.
>
> In the past I used C, but now I have decided to change language.
> I'm looking for a "better" one.
>
> Here follow the features it should have, ranked approximately by relevance:
>
> 0) open-source support and an alive community
> 1) directly compiled to efficient code
> 2) statically typed and object-oriented, better if multi-paradigm
> 3) general-purpose libraries (possibly standardized, either by
> standard or de facto), including containers and some math
> abstractions.
> 4) garbage collected. As an alternative, provide memory management
> policies via libraries (e.g. memory pools and such)
> 5) optional run-time checks and some kind of control over compilation
> and low-level issues
> 6) "relatively simple and consistent"
Have a look at Haskell.
> So I have considered these alternatives: FreePascal, Eiffel, Ada and
> Modula-3.
Of those, I'd use Modula-3.
(you may also consider: Objective Modula-2)
--
__Pascal Bourguignon__
The OP already knows C, so he will not have any problem finding a job.
Choosing a language based on perceived demand is a bad idea. A CS
student is supposed to learn as many languages as possible so as to be
able to compare them later, and not become captive of any one
language. Even more importantly, you need to learn paradigms; this
makes it easy to pick up any language that a job requires later on.
Conversely, hiring people based on the languages they know is an
equally bad idea. If you think knowledge of a particular language is
a must for an engineering position, you are wrong. Better criteria
include (but are not limited to) knowledge of sofware design (not just
"design patterns"; the real thing), algorithms, version control
systems, ability to work in teams, understanding of software
maintenance and general attitude towards software quality.
I think the OP understands all this very well; that's why he did not
mention job opportunities or market demand in his criteria for
language selection.
Banks and insurance companies also understand this; they train their
new hires in COBOL or Ada and don't care what languages they knew
previously.
(PS. comp.lang.pascal trimmed because it's archived now).
--
Ludovic Brenta.
I don't think it is overkill; Ada is not only an engineer's dream but
also an engineering student's dream because of its clear separation of
concerns (e.g. between inheritance (derived types) and encapsulation
(packages).
> What holds me from jumping onto Ada is the potential complexity
You don't have to learn all of the language all at once; you can start
with Ada as a "Pascal done right" (i.e. with separate compilation
built in and the "dangling else" problem fixed). You can learn the OO
and generic features later, as you need them.
> It would be interesting to hear the experience of other people learning
> Ada from the C/Java background.
> As for memory management (requirement 4), I heard there are different
> takes on the matter:
> (a) Ada uses dynamic stack allocation a lot, and in a transparent way,
> reducing the need of manual management (MM)
> (b) Ada libraries adopt idioms that further simplifies MM issues
> (c) Conservative garbage collectors such as Bohem's can be used with
> Ada, and they are supposed to work "better" with Ada than with unsafe
> languages such as C and C++
I have to add:
(d) controlled types allow you to control allocation and
deallocation without a garbage collector.
> So can MM be said to be easier in Ada than in C? I hope Ada-ers will
> mercifully shed some light on the issue.
Yes, MM is definitely easier in Ada than in C; my experience with
Java's garbage collector is that (a) you never learn to manage memory,
and (b) is is very easy to run out of memory and get the infamous
OutOfMemoryError. That has never happened to me in Ada, simply
because Ada forces me to think about this problem.
Another reason why Ada is easier than C is because you use pointers
only for what they were designed: dynamic allocation and
deallocation. As a consequence, each time you introduce a pointer you
naturally think about memory management. Contrast this to C where
simple parameter passing often requires pointers, and with Eiffel or
Java where everything is a pointer whether you like it or not.
> There seems to be a lot of Ada95 free documentation on the net, I guess
> it's suitable for Ada05 as well.
Yes indeed, thanks to backward compatibility. Also there are now
several textbooks on Ada 2005, inclusing the free Wikibook "Ada
programming".
Finally, since strong static typing is one of your criteria, Ada has
the strongest and most powerful typing system I've ever seen in any
language, and it also has "escape hatches" to allow you to circumvent
it in extreme situations like interfacing directly to hardware. This
typing system comes complete with compile-time and run-time checks
which you can selectively disable at the few places where performance
is critical.
I would perhaps add another criterion to your list: ease of
installation of the compiler and associated tools on your preferred
platform. In one extreme, you have to bootstrap the compiler yourself
and then build all libraries from source; at the other end of the
spectrum, there are complete binary distributions ready to use.
--
Ludovic Brenta.
("better" is debatable... some define it in terms of more subjective
aspects, and others are more pragmatic about the matter...).
> Here follow the features it should have, ranked approximately by
> relevance:
>
> 0) open-source support and an alive community
> 1) directly compiled to efficient code
> 2) statically typed and object-oriented, better if multi-paradigm
> 3) general-purpose libraries (possibly standardized, either by standard or
> de facto), including containers and some math abstractions.
> 4) garbage collected. As an alternative, provide memory management
> policies via libraries (e.g. memory pools and such)
> 5) optional run-time checks and some kind of control over compilation and
> low-level issues
> 6) "relatively simple and consistent"
>
> So I have considered these alternatives: FreePascal, Eiffel, Ada and
> Modula-3.
> I have taken a look at all of them and I'm still undecided. Below are the
> impressions I got for each language.
> Can you help me? Feel free to recommend other languages as well.
>
although I don't personally use it (for varried and numerous reasons), have
you considered Java?...
afaik, modern Java involves a fair amount of JIT-time optimization, and so
for carefully written code can be performance-competative with C and C++...
it is a similar situation with C#.
(the big cost in my case, however, is not performance, but that they depend
on these particular VMs...).
for my uses though, I typically use C and C++ (and ASM...). these languages
are just best suited for what I do with them.
of those listed, FreePascal and Ada seem like ok bets.
the main cost is that they have far smaller development communities than C
and Java and like, and like I have seen with many smaller languages, the
developer communities often tend to have a kind of fanatical zeal... (in
place of a more pragmatic outlook...).
Delphi may be worth looking into, given it is similar to FreePascal, and has
(AFAIK) a larger developer base.
conservative GC typically works plenty well in C, at least as long as people
refrain from esoteric trickery ("oh I can't xor pointers or store them in a
file, thus GC is useless", ...).
granted, conservative GC does work better in single-threaded C and C++ than
in multithreaded code...
There is not such a thing as pointers in Eiffel, there is only
references. A reference may be implemented as a pointer, but must not
be supposed so. An object in Eiffel, may be instanciated on the local
machine, or in a remote mahine over a network, or anything else one
may imagine. This is a abstract reference.
I was to reply to the original poster as well, but will come back
later for that.
Other people have been adding to your list but Objective Caml is still
missing. It ticks all you boxes.
--
Ben.
Ludovic Brenta wrote:
> I think the OP understands all this very well; that's why he did not
> mention job opportunities or market demand in his criteria for
> language selection.
>
Let me expand on this: I don't care for the language to get a job.
I've studied less widespread languages and that's been a rewarding
experience so far. I learnt a lot and my skills at coding and problem-
solving improved considerably. Moreover, some job interviewers were
pleasantly surprised by the that I "knew" "unpopular" languages.
Apart from this, I'll be writing scientific algorithms for at least
the next two years and the only thing I care about is avoiding the
unnecessary headaches that I can get for using unsafe languages.
Just for this the most suited languages are probably Ada and Eiffel.
Modula3 is probably also a good candidate, but I do not know the current
status (Open Source compiler? libraries? user community?) of this language.
Ada has the advantage of a standard and built-in concurrency.
--
--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.net - http://v2p.fr.eu.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver keys.gnupg.net --recv-key F949BD3B
bad wording, should be:
and the /most important/ thing I care about...
> Contrast [Ada parameter passing] to C where
> simple parameter passing often requires pointers, and with Eiffel or
> Java where everything is a pointer whether you like it or not.
Neither is true: Eiffel has expanded objects and expanded
classes (if they work in an implementations). A name of a
variable will NOT be attached to some object (a reference)
but denotes exactly one object. Also, expanded objects
Eiffel prevent the aliasing that is possible with pointers
of references.
Java has had basic types that have no references forever.
Wrappers were added later. However, in this case neither
seems a good compensation for the other.
I do not mean these remarks to be a statement favoring
these or others languages.
*
Is number crunching going to be done in parallel? Eiffel's
separate classes (whose objects execute on a conceptual
"processor") is not fully available yet. I'd think that control
of fundamentals of concurrent execution is, however, readily
available with Ada's concurrent types.
Ada's base type system---like Modula's it features name
equivalence---should help abstracting your numeric types
most efficiently, and precisely, as you decide yourself
about bits, ranges, and optionally representation.
--
Georg Bauhaus
Y A Time Drain http://www.9toX.de
You should be able to check out the ELKS core library, that's what
everyone uses these days. http://sourceforge.net/projects/freeelks/
This is open sourced under a permissive license, not necessarily a
copy-left like the GPL.
Some other resources for you:
http://forums.eiffel.com
http://www.eiffelroom.com
> So I have considered these alternatives: FreePascal, Eiffel, Ada and
> Modula-3.
> I have taken a look at all of them and I'm still undecided. Below are
> the impressions I got for each language. Can you help me? Feel free to
> recommend other languages as well.
These are all fine choices of languages, but I wonder how much benefit
you will be getting for yourself, as a sole-coder programming to produce
results, rather than code?
I think that you should consider stretching yourself a bit further:
others have suggested Ocaml and Hascall. I'd add that modern Common Lisp
(eg SBCL) ticks all of your boxes too. You might be surprised that there
are some scheme implementations that will fit, too, and both of those are
perhaps more "multi-paradigm" than the languages that you've got on your
short list.
In the end, though, you really need to check your decision criteria:
1: how fast is fast enough? Will you be waiting weeks for a run to
complete, or will you be coding for weeks and then running for ten
minutes? If the latter, something more expressive but perhaps a little
further from "speed of light" ASM might be more helpful. Also, if your
code will be spending most of its time in optimized library matrix
algebra code (eg atlas) then it doesn't matter much how the language
itself fares. (eg Matlab is slow but expressive unless you use it as a
wrapper around BLAS/LAPAC, in which case it's hard to get close to.)
2: How much do you really need object orientation? Inheritance isn't
necessarily particularly useful for a lot of numerical code, and there
are lighter-weight strategies that support modular and safe coding.
3: Libraries are good to have. You'll find that C and Fortran still have
the lions share of the numerical ones, though.
4: Garbage collection is really nice to have, as a programmer. Leave
this one in, but recognize that (a) you can do it in C if you want to and
(b) doing without involves more pain but can be made to work. See (1).
5: C and Fortran don't give you much of this out of the box, it's true,
but C has assert(), and used wisely and extensively in your own code will
give you some of the same "catch mistakes early" benefit of language-
supported checks, and you can turn it off with -DNDEBUG. The lisps and
schemes typically have a very wide range of "knobs" to control the amount
of run-time checking that they do.
6: C is simple and consistent.
When I had my own "C ennui" experience a couple of years ago, I picked
scheme, on the understanding that sometimes I would probably have to
still write some C and assembler to support C-using colleagues and for
ultimate performance. (And I wanted to learn something really different
from C.) I've been happy with the outcome, so far.
Cheers,
--
Andrew
Just my 2c...
If you need to do heavy number-crunching, I would suggest Matlab or
its open-source brother Octave (http://www.gnu.org/software/octave/).
My main professional interests are in DSP and the three languages that
I use most are Matlab (for number-crunching problems) and Ruby (for
F&D scripts and/or text processing) and Ada (for everything else).
Since Matlab is not compiled, you do not reach the full theoretical
computational speed that you could achieve with your computer, but if
you write your code with a little care (that is, avoiding loops and
trying to write your problem as "vectorized" as possible) you can
achieve very good performances (your mileage can vary depend on your
specific problem, though). The advantage of Matlab/Octave is that
you have a very large library of numerical algorithm and development
can be quite fast. On the cons side, since it is easy to write "fast
and dirty" matlab scripts, matlab code can turn out more difficult to
mantain (this depends on your "style" too).
Hope this helps.
On 19 Lug, 03:04, Andrew Reilly <andrew-newsp...@areilly.bpc-
users.org> wrote:
> I think that you should consider stretching yourself a bit further:
> others have suggested Ocaml and Hascall. I'd add that modern Common Lisp
> (eg SBCL) ticks all of your boxes too. You might be surprised that there
> are some scheme implementations that will fit, too, and both of those are
> perhaps more "multi-paradigm" than the languages that you've got on your
> short list.
I'm still learning CL and that's been enlightening so far.
I implemented Prim's MSTP algorithm with that, getting pretty
satisfying performance for large instances (thansk to
declare&friends).
However CL is dynamically typed, and my algorithms will hardly need
(its) dynamic typing. Out of curiosity, I've already planned to
reimplement an algorithm of mine, a branch-and-bound one, in CL to
see, among other things, how it compares in terms of effciency. In
future I'd like to write a neural-network toolbox similar to Mathlabs'
for CL as well. Note that these are *plans*, something I think of and
that I'll be sitting on for a long time ;^)
I looked at O'CaML a few times, and I've heard different opinions on
the usenet. I can't remember exactly, but it felt like having some
annoying idiosyncrasies both at language and implementation level.
I ruled it out because differs a lot from other languages (i.e.
algol's heirs) and I wanted a more familiar language, one I can
currently trust given my cultural preparation.
Finally Haskell. It requires a significant mental shift, something I
can't afford now. And I fear that lazy evaluation may cause a
disastrous performance loss with my algorithms when used improperly.
Too risky for now.
On 19 Lug, 03:04, Andrew Reilly <andrew-newsp...@areilly.bpc-
users.org> wrote:
> These are all fine choices of languages, but I wonder how much benefit
> you will be getting for yourself, as a sole-coder programming to produce
> results, rather than code?
>
For various reasons, that's not a problem. There are projects for
which I'll be alone anyway.
> 1: how fast is fast enough?
It may be "just enough" or "as much as possible". For most of the
heuristic approaches the former, for exact ones the latter.
> 2: How much do you really need object orientation?
None of the languages I listed prevents me from using modularity in
place of OO.
> 3: Libraries are good to have. You'll find that C and Fortran still have
> the lions share of the numerical ones, though.
I can interface to both with any of the languages above IIRC.
> 4: Garbage collection is really nice to have, as a programmer. Leave
> this one in, but recognize that (a) you can do it in C if you want to and
> (b) doing without involves more pain but can be made to work. See (1).
>
Still, as I learnt with CL and C, the problem always reduces to these
recommendations:
- if you need dynamic memory, don't use it
- Manage memory as rarely as possible
- standard allocators suck
> 5: C and Fortran don't give you much of this out of the box,
I don't know Fortran, unfortunately
As for C, been there, done that. I never used assert because I strived
to organize the code in a more structured way, and that, together with
bug-fixing and writing comments to explain the code, took most of the
time.
In other terms, I recognized I was reimplementing what Ada, M3,
Eiffel.... give and optimize for free.
Now I want to check if what they offer is true. Eventually, less may
still be more, or not, who knows?
Andrea
Andrea
Check the Modula-3 FAQ.
Like all the other 'rare' programming language, you don't necessarily
have big and redundant libraries of variable quality (of which you may
spend time to choose wisely the one of best quality of course), but if
you're autonomous, you usually can find what you need, or develop it
more easily (remember, these unpopular programming languages are
unpopular also in part because it's easier to develop with them, so
the absence of a "library" is not usually a problem when you have a
concrete program to write). And finally, while it's not a tasty
solution (because you lose in part the advantages of your advanced but
rare programming language), there's always the possibility of FFI
(Foreign Function Interface), letting you call functions in libraries
written in C or any other programming language following the C ABI.
--
__Pascal Bourguignon__
Given that you have notions of CL, then you could postpone your choice
of programming language.
You're interested in algorithms, so just write your algorithms in
s-exp forms.
I understand that it might be fun to let the computer execute the
algorithms to see how they work out (I assume you prove your
algorithms independantly of any execution, which I'll remind you can
only prove that you have errors, not that your algorithm is correct).
So you could write in Common Lisp the DSL (Domain Specific Language)
able to interpret or translate your algorithms into CL, for animation
purposes.
Later, when you have a collection of proven algorithms, you may write
(still in Common Lisp, why reject a winning team?), a translator to
convert your algorithmic s-exps into the target language of your
choice, be it Ada, Pascal, C, Eiffel, Fortran, Haskell, Modula-2 or
Modula-3, whatever you need. It's almost trivial to generate such
code from a DSL expressed in s-exps.
C/USER1[602]> (algorithm gcd
(parameters (input a integer)
(input b integer))
(result integer)
(cases
when (= a b) then (return a)
when (< a b) then (return (gcd (- b a) a))
when (> a b) then (return (gcd (- a b) b))))
GCD
C/USER1[603]> (gcd 42 12)
6
C/USER1[686]> (translate-to-c '(algorithm gcd
(parameters (input a integer)
(input b integer))
(result integer)
(cases
when (= a b) then (return a)
when (< a b) then (return (gcd (- b a) a))
when (> a b) then (return (gcd (- a b) b)))))
int gcd(int a,int b)
{
if((a)==(b)){
return(a);
}
else if((a)<(b)){
return(gcd((b)-(a),a));
}
else if((a)>(b)){
return(gcd((a)-(b),b));
}
}
--
__Pascal Bourguignon__
Sorroy for beeing late to reply, here is my little contribution.
I would like to say that if you are mainly to deal with algorithmics,
you may also add Lisp to your list (not joking, althought these words
together are a bit funny I know).
Here is an article I deeply agree with, except in some aspects :
http://www.paulgraham.com/icad.html
Well, the limitation is that if you need to be aware of some real-
world aspects, like the fact that no machine has an infinite register
width, then Lisp may not be the best solution (the author seems to
forget sometime about real-life).
But it your main scope is complexe structures and “ intelligent ” and
plastic-malleable algorithms, then Lisp may be a good idea, while it
would not be if data typing and real life range-limitations is one of
your concern (as an exemple).
Note: if I'm not wrong, there is a plan to add some lambda-expressions
like stuff in the next Ada revision (at least something which made me
think it was a bit looking like).
> Later, when you have a collection of proven algorithms, you may write
> (still in Common Lisp, why reject a winning team?), a translator to
> convert your algorithmic s-exps into the target language of your
> choice, be it Ada, Pascal, C, Eiffel, Fortran, Haskell, Modula-2 or
> Modula-3, whatever you need. It's almost trivial to generate such
> code from a DSL expressed in s-exps.
How can a translation can be trivial unless it is but a
mere syntactic rewrite? This way one dismisses both an
essential constraint and an opportunity: the programmed
algorithm, the computation, is performed in steps, by a
human, by a Lisp machine, by a von Neumann PU, or by
some innovative parallel computer, each having known
formal properties. Is it possible to let these influence
the s-expressions (the algorithm, that is) such that
the "target language"'s features will be effective?
Of course, it depends on your algorithmic language (DSL), and on the
target languages.
But mostly, it will be trivial, because the target languages are
themselves "algorithmic" languages. Nominally, apart from Haskell,
all the language mentionned above are mere procedural languages in
which imperative algorithms will be trivial to transcribe, yes,
basically just a syntactic operation.
If we targetted Haskell, Lisp or Prolog, indeed it would be more
complex, since procedural algorithms don't translate well there (well
for Common Lisp, it would still translate well since Common Lisp is
really multi-paradigm a language which includes imperative procedural
code (it even has GOTO!), even if an experienced lisp programmer would
normally rewrite the imperative algorithms in more idiomatic (higher
level) lisp).
Moreover, notice how Pr. Knuth use a rather low level language to
describe his algorithms (a virtual machine language actually). He
doesn't expect anything fancy semantically from his algorithmic
language. http://www-cs-faculty.stanford.edu/~knuth/taocp.html
Therefore I stand on my affirmation, such a transformation is trivial.
--
__Pascal Bourguignon__
> Moreover, notice how Pr. Knuth use a rather low level language to
> describe his algorithms (a virtual machine language actually). He
> doesn't expect anything fancy semantically from his algorithmic
> language. http://www-cs-faculty.stanford.edu/~knuth/taocp.html
Actually, a paradigmatic counter-example of Knuths' is, I think,
Algorithm T (Topological sort in �2.2.3), which is I guess not
targeted at number crunching, but serves as an example of
ingenious use of hardware properties. While the description,
"taking away nodes from a graph", is in a sense high level,
the data structures used, and the runnable program are just
about as far away from high level Lisp as can be, I'd think ;-)
So how could this be achieved in a general fashion, using
syntax transformation?
So a translation that yields this proven un-functional
data layout doesn't look so trivial to me; wouldn't
you end up writing algorithm-specific optimizer macros
or some such if you wanted the same efficiency to be gained
from a Lisp DSL?
Did you take a look at Seed7?
Greetings Thomas Mertes
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
1) More than complex, Ada is feature-rich, with some properties that do
not exist in most other languages (user defined elementary types,
discriminants, stack-allocated dynamic structures ...). Of course,
you'll have to learn about these features - if you want to use them.
2) Ada is extremely consistent. You'll have to learn the basic
principles, but once you've got them, you'll discover that all the
features follow the same logic. Therefore, the first step might be
higher than for other languages, but then everything appears logical and
easy to grasp.
3) Ada is simple to use, because difficulty of implementation has never
been an excuse for forbidding something that the user would expect to
work. However, that makes the language complex to compile, and part of
the alledged complexity of Ada refers to complexity of implementation,
not complexity of use. Of course, as a user, you don't care about this,
since you have compilers, even free ones, that implement the language
correctly, and this is checked by passing the validation suite (AKA ACATS).
--
---------------------------------------------------------
J-P. Rosen (ro...@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr
|-----------------------------------------------------------------------------|
|"[..] |
| |
|Of those, I'd use Modula-3. |
|(you may also consider: Objective Modula-2)" |
|-----------------------------------------------------------------------------|
This is the first I have heard of Objective Modula-2. Thank you.
Unfortunately, Wirthian languages tend to use structural equivalence
of types instead of occurrence equivalence, such as Modula-3 according
to
HTTP://web.archive.org/web/20051001044031/http://archive.dstc.edu.au/AU/staff/crawley/ada/m3-vs-ada.html#section4.1
and many interpretations of an early Pascal definition, so I suspect
that Modula-2 also had this weakness. The following excerpt from
HTTP://Objective.Modula2.net/
- "[..]
The base language is Modula-2 as defined by Niklaus Wirth in the
fourth edition of Programming in Modula-2 with the following omissions
and restrictions:
Omissions
[..]
* No subrange types
[..]" -
seems to indicate that it is even worse.
Ada allows you to choose for some types to be treated with occurrence
equivalence (called types in Ada:
WWW.AdaIC.org/standards/05rm/html/RM-3-2-1.html
) and for other types to be treated as
structurally equivalent (called subtypes in Ada:
WWW.AdaIC.org/standards/05rm/html/RM-3-2-2.html
) as you deem to be appropriate. Unlike for example Eiffel's Design by
Contract, this is not something which is activated or deactivated by a
compiler switch: a single Ada function can exploit both approaches at
the same time without being recompiled.
Regards,
Nicholas Paul Collin Gloucester
It is not necessary to circumvent the type system when interfacing to
hardware. An Ada fixed type (which unlike a FORTRAN fixed type does
not necessarily need to be an integer) can be used with a
representation clause for strongly typed memory-mapped I/O.
With kind regards,
Nicholas Paul Collin Gloucester
|-----------------------------------------------------------------------------|
|-----------------------------------------------------------------------------|
Why Objective Caml instead of JoCaml; G'Caml; Chamau; BIGLOO; HimML;
CeML; or Gaml?
Ciao!
I agree that static typing is important, but Modula-3; Eiffel; and
many versions of Pascal perhaps including FreePascal are restricted to
structural equivalence of types only. This is not sufficient strong
typing.
I give an example showing that Ada is better than Eiffel (and Modula-3
and many versions of Pascal) in this regard, based on an example by
Bertrand Meyer in the second edition of the book "Object-oriented
software construction". In that book, Dr. Meyer claimed that Ada's
overloading is inferior to Eiffel's overloading. He called Ada's
overloading syntactic overloading. He called Eiffel's overloading
semantic overloading. I believe that he was being sincere, but he was
definitely mistaken. He claimed that it would not be possible to
sensibly discriminate between overloaded subprograms for a point if
the real-number parameters could be in any of Cartesian notation and
polar notation.
This is refuted by the following Ada code...
procedure Syntactic_Overloading_Example_Based_On_An_Example_By_Bertrand_Meyer is
type Horizontal_Coordinate is new Float;
type Vertical_Coordinate is new Float;
procedure Point(X : Horizontal_Coordinate; Y : Vertical_Coordinate) is
begin
null; --Whatever.
end;
type Magnitude is new Float;
type Radians is new Float range -3.14*2.0 .. 3.14*2.0;
procedure Point(R : Magnitude; Theta : Radians) is
begin
null; --Whatever.
end;
X : Horizontal_Coordinate;
Y : Vertical_Coordinate;
R : Magnitude;
Theta : Radians;
begin
X := 1.1;
Y := 2.2;
R := 3.3;
Theta := 0.5;
Point(X, Y);
Point(R, Theta);
--The above is all legal Ada. However, the following mistakes would
--be legal in Eiffel but would be rejected by an Ada compiler...
R := X;
--An example compiler complaint...
--"Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:29:09: expected type "Magnitude" defined at line 9
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:29:09: found type "Horizontal_Coordinate" defined at line 2
--gnatmake: "Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb" compilation error".
Point(X, Theta);
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:35:04: no candidate interpretations match the actuals:
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:35:10: expected type "Magnitude" defined at line 9
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:35:10: found type "Horizontal_Coordinate" defined at line 2
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:35:10: ==> in call to "Point" at line 11
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:35:13: expected type "Vertical_Coordinate" defined at line 3
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:35:13: found type "Radians" defined at line 10
--Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb:35:13: ==> in call to "Point" at line 4
--gnatmake: "Syntactic_overloading_example_based_on_an_example_by_Bertrand_Meyer.adb" compilation error
end;
> I agree that static typing is important, but Modula-3; Eiffel; and
> many versions of Pascal perhaps including FreePascal are restricted to
> structural equivalence of types only. This is not sufficient strong
> typing.
Modula-3's BRANDED keyword overrides the structural equivalence.
[ followups trimmed ]
Mark
|------------------------------------------------------------------------|
|------------------------------------------------------------------------|
Thank you for the response.
The author of
HTTP://web.archive.org/web/20051001044031/http://archive.dstc.edu.au/AU/staff/crawley/ada/m3-vs-ada.html#section4.1
warned that he did not know Modula-3 well, so was his claim
"Branding only applies to reference types"
untrue?
Could you show us a Modula-3 version of the code in
news:h41n4c$pm0$1...@news.eternal-september.org
which is better than Eiffel and at least as good as Ada?
Thanks again,
N. P. C.
> On 2009-07-20, Mark T.B. Carroll <Mark.C...@Aetion.com> wrote:
>
> |------------------------------------------------------------------------|
> |"Nicholas Paul Collin Gloucester <Colin_Pau...@ACM.org> writes: |
> | |
> |> I agree that static typing is important, but Modula-3; Eiffel; and |
> |> many versions of Pascal perhaps including FreePascal are restricted to|
> |> structural equivalence of types only. This is not sufficient strong |
> |> typing. |
> | |
> |Modula-3's BRANDED keyword overrides the structural equivalence." |
> |------------------------------------------------------------------------|
>
> Thank you for the response.
>
> The author of
> HTTP://web.archive.org/web/20051001044031/http://archive.dstc.edu.au/AU/staff/crawley/ada/m3-vs-ada.html#section4.1
> warned that he did not know Modula-3 well, so was his claim
> "Branding only applies to reference types"
> untrue?
I think that's true. However, that is not equivalent to Modula-3 being
"restricted to structural equivalence of types only", which is why I
corrected you. (Note that you can have reference types of even integers
or whatever, it's not just objects.)
> Could you show us a Modula-3 version of the code in
> news:h41n4c$pm0$1...@news.eternal-september.org
> which is better than Eiffel and at least as good as Ada?
I don't know Eiffel at all and barely remember Ada, so probably not I'm
afraid.
Mark
That is exactly the area where Ada left the path of Pascal. Pascal
was designed to be easy to implement. Nicklaus Wirth had good
reasons to keep the implementation simple. He once said (IIRC):
What can be parsed easily by a compiler can also be
parsed easily by a human and this can be an asset.
He probably did not use exactly this words, but they hopefully
describe his intentions.
Many languages try to make the job of writing a program easier
and at the same time make the job of reading programs is
harder. All this wonderful "do what I mean" concepts used by
many languages fail in some cases.
IMHO complex compilation processes are an indication
of hard-to-understand concepts or hard-to-read constructs.
As such a complex compilation process only seemingly
(and not really) makes programming easier.
|---------------------------------------------------------------------------------------------------------------------|
|"Nicholas Paul Collin Gloucester <Colin_Pau...@ACM.org> writes: |
| |
|> On 2009-07-20, Mark T.B. Carroll <Mark.C...@Aetion.com> wrote: |
|> |
|> |------------------------------------------------------------------------| |
|> |"Nicholas Paul Collin Gloucester <Colin_Pau...@ACM.org> writes: | |
|> | | |
|> |> I agree that static typing is important, but Modula-3; Eiffel; and | |
|> |> many versions of Pascal perhaps including FreePascal are restricted to| |
|> |> structural equivalence of types only. This is not sufficient strong | |
|> |> typing. | |
|> | | |
|> |Modula-3's BRANDED keyword overrides the structural equivalence." | |
|> |------------------------------------------------------------------------| |
|> |
|> Thank you for the response. |
|> |
|> The author of |
|> HTTP://web.archive.org/web/20051001044031/http://archive.dstc.edu.au/AU/staff/crawley/ada/m3-vs-ada.html#section4.1|
|> warned that he did not know Modula-3 well, so was his claim |
|> "Branding only applies to reference types" |
|> untrue? |
| |
|I think that's true. However, that is not equivalent to Modula-3 being |
|"restricted to structural equivalence of types only", which is why I |
|corrected you. (Note that you can have reference types of even integers |
|or whatever, it's not just objects.) |
| |
|[..]" |
|---------------------------------------------------------------------------------------------------------------------|
Touch�.
> That is exactly the area where Ada left the path of Pascal. Pascal
> was designed to be easy to implement. Nicklaus Wirth had good
> reasons to keep the implementation simple. He once said (IIRC):
>
> What can be parsed easily by a compiler can also be
> parsed easily by a human and this can be an asset.
>
> He probably did not use exactly this words, but they hopefully
> describe his intentions.
A human who has parsed some part of a program is far away from having
understood the part of the program: Many concepts expressed "easily"
in "simple" languages hide the fact that a complex combination
of simple things needs to be studied (and made "conventional"
or idiomatic) in order to arrive at an understanding of what
is really going on, and what is intended, due to the combination.
Sometimes these lengthy combinations of "simply" expressed things
are equivalent to a simple builtin of less "simple" languages.
> Many languages try to make the job of writing a program easier
> and at the same time make the job of reading programs is
> harder. All this wonderful "do what I mean" concepts used by
> many languages fail in some cases.
True, but this does not apply to Ada. Ada was designed with requirements
that explicitely required ease of reading over ease of writing.
> IMHO complex compilation processes are an indication
> of hard-to-understand concepts or hard-to-read constructs.
> As such a complex compilation process only seemingly
> (and not really) makes programming easier.
>
Not at all. Let me take an example to show you what I meant. If you have
a record (in Pascal) or struct (in C), you are not allowed to compare
them directly. Why? because records may contain gaps that shouldn't be
compared, and skipping the gaps was deemed too much work for the
compiler. In Ada, there is no problem writing:
if Rec1 = Rec2 then ....
would you argue that it is /less/readable than writing:
if Rec1.F1 = Rec2.F1 and Rec1.F2 = Rec2.F2 and Rec1.F2 = Rec2.F3...
No reason at all if these all meet the OP's needs. I don't know them
so I could not reasonably suggest them. OCaml is the only ML-like
language I know that is object oriented as asked for. A quick look at
some of your list suggests that not all of them are.
--
Ben.
>
> I give an example showing that Ada is better than Eiffel (and Modula-3
> and many versions of Pascal) in this regard, based on an example by
> Bertrand Meyer in the second edition of the book "Object-oriented
> software construction". In that book, Dr. Meyer claimed that Ada's
> overloading is inferior to Eiffel's overloading. He called Ada's
> overloading syntactic overloading. He called Eiffel's overloading
> semantic overloading. I believe that he was being sincere, but he was
> definitely mistaken. He claimed that it would not be possible to
> sensibly discriminate between overloaded subprograms for a point if
> the real-number parameters could be in any of Cartesian notation and
> polar notation.
>
> This is refuted by the following Ada code...
>
Not it's not, your code only changed the problem appearance but not
substance:
> procedure Syntactic_Overloading_Example_Based_On_An_Example_By_Bertrand_Meyer is
> type Horizontal_Coordinate is new Float;
> type Vertical_Coordinate is new Float;
> procedure Point(X : Horizontal_Coordinate; Y : Vertical_Coordinate) is
> begin
> null; --Whatever.
> end;
Here you create two "subtypes" which are only nicknames for Float in
order to help the Ada compiler to discriminate the signature. BTW, why
the need of two subtypes for coordinates?
>
> type Magnitude is new Float;
> type Radians is new Float range -3.14*2.0 .. 3.14*2.0;
> procedure Point(R : Magnitude; Theta : Radians) is
Ditto with two more "subtypes", and for no reason creating a new mess as
you made a design decision that Radians can only go from -6.28 to +6.28,
so you leave to the poor programmers that shall use this code the task
of normalizing the angles before creating points else runtime exceptions?
> begin
> null; --Whatever.
> end;
>
> X : Horizontal_Coordinate;
> Y : Vertical_Coordinate;
> R : Magnitude;
> Theta : Radians;
> begin
> X := 1.1;
> Y := 2.2;
> R := 3.3;
> Theta := 0.5;
> Point(X, Y);
> Point(R, Theta);
>
> --The above is all legal Ada. However, the following mistakes would
> --be legal in Eiffel but would be rejected by an Ada compiler...
>
> R := X;
Careful reading of this line of code shows the 'protection' against
mistakes occurs only after the 'subtype' has been initialized, but this:
X := 3.3; -- for the sake of argument programmer
Y := 0.5; -- wrote the GUI code backwards
R := 1.1;
Theta := 2.2;
Point(X, Y);
Point(R, Theta);
Happy compiler and code runs, albeit with unexpected results...
--
Cesar Rabak
PS.: for some reason could not set the Followup-To so I trimmed to the
pertaining language NGs.
A type does not only designate a range of allowed values, it also
designate a source, which in turn, associate design property to it
(this can be asserted relying on type matching rules).
If you want to be sure what a function recieve only come from a
defined set of functions, then you define a type, some functions
returning value of this types, or procedure modifying this type. Two
types may seem similar at a quick sight, but types are not only used
to define ranges.
Types allow to define the valid flow of some objects or values, it
allows to make assertions about where it come from and where it can go
(thus, what was done with on/with it). This as to deal with the
overall design, the whole usage of a library, and not only with the
set of value allowed for a given type.
This is not a kind of nickname, this is a difference written in the
stone
>> procedure
>> Syntactic_Overloading_Example_Based_On_An_Example_By_Bertrand_Meyer is
>> type Horizontal_Coordinate is new Float;
>> type Vertical_Coordinate is new Float;
>> procedure Point(X : Horizontal_Coordinate; Y : Vertical_Coordinate) is
>> begin
>> null; --Whatever.
>> end;
>
> Here you create two "subtypes" which are only nicknames for Float in
> order to help the Ada compiler to discriminate the signature. BTW, why
> the need of two subtypes for coordinates?
Horizontal_Coordinate and Vertical_Coordinate are specifically
*not* nicknames, not even informally.
Two new types derived from the same ancestor are definitely
*not* only nicknames for Float. I see you are trying to
come up with an argument about the same literals providing
values for objects of entirely different types, and that's
certainly formally true and a nice try. But if you defer to
the programmers, I will, too, and suggest
X := Vertical_Coordinate'(1.1);
so as to say what they mean. Et voila,
21. X := Vertical_Coordinate'(1.1);
|
>>> expected type "Horizontal_Coordinate" defined at line 2
>>> found type "Vertical_Coordinate" defined at line 3
I'm sure Gloucester will speak for himself, but it's tempting
to step in.
(Nitpick: he is introducing two new distinct types,
not subtypes as an Ada subtype is a type with a constraint
as in subset of values that are in the type).
Every one of the tricks you play below in your example
assigns values of literals of anonymous predefined type
'universal_real' to objects of distinct types. There
is certainly an issue with literals not being silver
bullets. Yes, some programmers do not define typed
constants of important values. Yes, they are not even
using C's untyped #define, they just sprinkle literals.
> Careful reading of this line of code shows the 'protection' against
> mistakes occurs only after the 'subtype' has been initialized, but this:
>
> X := 3.3; -- for the sake of argument programmer
> Y := 0.5; -- wrote the GUI code backwards
> R := 1.1;
> Theta := 2.2;
> Point(X, Y);
> Point(R, Theta);
>
> Happy compiler and code runs, albeit with unexpected results...
Well, there is no way to write full application programs in
type systems(*). But what's your point? If we add rigor to your
argument then we might just as well have but one type and make
the compilers even happier with that universal type...
(*) except Qi's, I should think.
--
Georg Bauhaus
They are *considered* different in Ada technology, I respect that, but
from a OO point of view, they are not: a new type would define a new set
of operations on it.
>
> A type does not only designate a range of allowed values, it also
> designate a source, which in turn, associate design property to it
> (this can be asserted relying on type matching rules).
In Ada language, defined as such.
>
> If you want to be sure what a function recieve only come from a
> defined set of functions, then you define a type, some functions
> returning value of this types, or procedure modifying this type. Two
> types may seem similar at a quick sight, but types are not only used
> to define ranges.
Which is syntatic sugar for allowing signatures and allowing for
internal consistency in the program *after* the variables have been
initialized from a primitive type.
>
> Types allow to define the valid flow of some objects or values, it
> allows to make assertions about where it come from and where it can go
> (thus, what was done with on/with it). This as to deal with the
> overall design, the whole usage of a library, and not only with the
> set of value allowed for a given type.
After have been initialized by primitive types (as your own example shows).
>
> This is not a kind of nickname, this is a difference written in the
> stone
From a practical matter it is only a nickname, see my example you snipped.
|----------------------------------------------------------------------------------|
|----------------------------------------------------------------------------------|
As an Ada compiler would detect the difference and Bertrand Meyer was
unable to realize that the difference can be detected like this and
used that as his justification for his version of overloading, I
believe I have disproved the rationale of Dr. Meyer's.
|----------------------------------------------------------------------------------|
|" BTW, why |
|the need of two subtypes for coordinates?" |
|----------------------------------------------------------------------------------|
They might not be necessary, but they do no harm.
|----------------------------------------------------------------------------------|
|"> |
|> type Magnitude is new Float; |
|> type Radians is new Float range -3.14*2.0 .. 3.14*2.0; |
|> procedure Point(R : Magnitude; Theta : Radians) is |
| |
|Ditto with two more "subtypes", and for no reason" |
|----------------------------------------------------------------------------------|
In this case there is a reason for having more types. An angle and a
length are simply not interchangable, so they should not be
represented both by Float. The amount of money equal to U.S.$1.00 is
not equal to the amount of money equal to 1.00 Canadian dollar, but
they are both written with the number 1.00.
|----------------------------------------------------------------------------------|
|"creating a new mess as |
|you made a design decision that Radians can only go from -6.28 to +6.28, |
|so you leave to the poor programmers that shall use this code the task |
|of normalizing the angles before creating points else runtime exceptions?" |
|----------------------------------------------------------------------------------|
If you really want to be able to write values such as 390 degrees; 750
degrees; 1470 degrees; 1830 degrees; and 2190 degrees as was done in
Section 3.2 Case Study 3: Errors in the Direct Evaluation of the Sine
Series of the book William S. Dorn and Daniel D. McCracken, "Numerical
Methods with Fortran IV Case Studies", then you can do so without
normalization. Of course, to do so I would suggest a Degree type, and
yes, I would probably had written
type Degree is new Float range 0.0 .. 360.0;
or
type Degree is new Float range -180.0 .. 180.0;
instead of
type Degree is new Float;
as I would not had realized that this would distract you from the
emphasis that the Magnitude and angular types are very different, even
though they are both based on floating point types.
Even if we wanted to allow radians outside of the range I prescribed,
the restriction -6.28 to +6.28 might still be used internally with
normalization performed in a wrapper. Do you realize that when you
write a number with ASCII numerals, it is probably going to be
represented with something other than ASCII numerals before long?
With the type Radians as I had typed it,
Theta := 7.0;
would not result in a runtime exception. It would be rejected by a
compiler.
|----------------------------------------------------------------------------------|
|"> begin |
|> null; --Whatever. |
|> end; |
|> |
|> X : Horizontal_Coordinate; |
|> Y : Vertical_Coordinate; |
|> R : Magnitude; |
|> Theta : Radians; |
|> begin |
|> X := 1.1; |
|> Y := 2.2; |
|> R := 3.3; |
|> Theta := 0.5; |
|> Point(X, Y); |
|> Point(R, Theta); |
|> |
|> --The above is all legal Ada. However, the following mistakes would |
|> --be legal in Eiffel but would be rejected by an Ada compiler... |
|> |
|> R := X; |
| |
|Careful reading of this line of code shows the 'protection' against |
|mistakes occurs only after the 'subtype' has been initialized," |
|----------------------------------------------------------------------------------|
What?
|----------------------------------------------------------------------------------|
|" but this: |
| |
|X := 3.3; -- for the sake of argument programmer |
|Y := 0.5; -- wrote the GUI code backwards |
|R := 1.1; |
|Theta := 2.2; |
|Point(X, Y); |
|Point(R, Theta); |
| |
|Happy compiler and code runs, albeit with unexpected results..." |
|----------------------------------------------------------------------------------|
Nothing is foolproof, but I did prevent some accidents.
The converse, however, is not necessarily true: that which cannot be
parsed easily by a compiler sometimes still can be parsed easily by a human.
This will remain so until strong AI is developed.
Yes, formally it is my gripe. Remember this is not a thread is running
in Ada NG only, so recursing to Ada _terminology_ does not add to
discourse here.
> But if you defer to
> the programmers, I will, too, and suggest
>
> X := Vertical_Coordinate'(1.1);
>
> so as to say what they mean. Et voila,
>
> 21. X := Vertical_Coordinate'(1.1);
> |
> >>> expected type "Horizontal_Coordinate" defined at line 2
> >>> found type "Vertical_Coordinate" defined at line 3
Still, a pretense feeling of safety as the programmer had to work very
hard to allow the compiler find the 'error'.
>
>
> I'm sure Gloucester will speak for himself, but it's tempting
> to step in.
>
> (Nitpick: he is introducing two new distinct types,
> not subtypes as an Ada subtype is a type with a constraint
> as in subset of values that are in the type).
I comment this on other post.
>
> Every one of the tricks you play below in your example
> assigns values of literals of anonymous predefined type
> 'universal_real' to objects of distinct types. There
> is certainly an issue with literals not being silver
> bullets. Yes, some programmers do not define typed
> constants of important values. Yes, they are not even
> using C's untyped #define, they just sprinkle literals.
I'm not playing tricks, just showing something may appear unnoticed if
not debated. Although the example has been on literals, I've noticed
the bulk of problems happen when data is read from the outside of the
program (file reading, GUI fields, etc.).
>
>
>> Careful reading of this line of code shows the 'protection' against
>> mistakes occurs only after the 'subtype' has been initialized, but this:
>>
>> X := 3.3; -- for the sake of argument programmer
>> Y := 0.5; -- wrote the GUI code backwards
>> R := 1.1;
>> Theta := 2.2;
>> Point(X, Y);
>> Point(R, Theta);
>>
>> Happy compiler and code runs, albeit with unexpected results...
>
> Well, there is no way to write full application programs in
> type systems(*). But what's your point? If we add rigor to your
> argument then we might just as well have but one type and make
> the compilers even happier with that universal type...
>
>
> (*) except Qi's, I should think.
I avoided mentioning because this would open even more the discussion,
but the OP could do its own research.
Yes your assertion goes in the Lisp direction, which for numerics could
even be more interesting as numbers are stored in a more accurate way
(if you avoid 'premature optimization' syndrome ;-)
I disagree strongly: an angle in radians is a real number as any other
there is not any intrinsic difference in its *type* on ordinary
Mathematics. Dimensionally they are 'pure numbers' with no unit
atached, your example on monetary units being fallacious, so non sequitur.
> |----------------------------------------------------------------------------------|
> |"creating a new mess as |
> |you made a design decision that Radians can only go from -6.28 to +6.28, |
> |so you leave to the poor programmers that shall use this code the task |
> |of normalizing the angles before creating points else runtime exceptions?" |
> |----------------------------------------------------------------------------------|
>
> If you really want to be able to write values such as 390 degrees; 750
> degrees; 1470 degrees; 1830 degrees; and 2190 degrees as was done in
> Section 3.2 Case Study 3: Errors in the Direct Evaluation of the Sine
> Series of the book William S. Dorn and Daniel D. McCracken, "Numerical
> Methods with Fortran IV Case Studies", then you can do so without
> normalization.
I was not thinking on this, only on the 'ergonomy' of the solution,
which I maintain happens due the desire to create 'type' (in Ada
parlance [but in fact a nickname for Float]) so to allow the compiler to
make critics in values *after have been initialized* with a primitive type.
My thinking was why one should restrict prematurely a range while it
still make sense mathematically (1000 radians is a number that can come
from some rotational routine or from an external data set, for example).
> Of course, to do so I would suggest a Degree type, and
> yes, I would probably had written
> type Degree is new Float range 0.0 .. 360.0;
> or
> type Degree is new Float range -180.0 .. 180.0;
> instead of
> type Degree is new Float;
> as I would not had realized that this would distract you from the
> emphasis that the Magnitude and angular types are very different, even
> though they are both based on floating point types.
They are not different at all both are real numbers, just that. Their
*interpretation* in the program after they have been used in the Point
object is different.
>
> Even if we wanted to allow radians outside of the range I prescribed,
> the restriction -6.28 to +6.28 might still be used internally with
> normalization performed in a wrapper. Do you realize that when you
> write a number with ASCII numerals, it is probably going to be
> represented with something other than ASCII numerals before long?
Yes for your question, and of course I understand we are not discussing
the design of the whole class/object, as we'd need to agree if magnitude
can or not be negative, etc.
As for normalization, IMNHO it has to be done in the constructor of the
class/object, and not as an (external) wrapper.
>
> With the type Radians as I had typed it,
> Theta := 7.0;
> would not result in a runtime exception. It would be rejected by a
> compiler.
Because we are dealing with examples with literals, let the value come
from an input...
Yes, I agree on that and Ada has been a step forward on this direction,
but as has been written elsewhere in this thread, Ada types do not form
a 'type system' so it brings moderate safety against errors.
Could, I'd say. A derived type could (1) define a new set of
operations, or it could (2) just create a different kind of
fruit exhibiting the same behavior (operation-wise),
or (2a) override an operation,
or it could (3) defer (Eiffel) or abstract (Ada) some operations.
Except, perhaps, that Eiffel's elementary types are frozen,
that is, cannot be subclassed at all (last time I checked).
If Ada had an explicit unit system in addition to it's
type properties (the 'First and so on), then I could imagine
a case for requiring (2) to become (2a). Define a new (an own)
floting point type derived from some other floating point
type and make explicit where you expect them to be different,
for example in their units.
Ada is not a language for mathematicians (mathematicians would rather
use e.g. Octave), it is a language for engineers. In engineering,
there are very few pure numbers and quite a lot of dimensioned
numbers. As an engineer, I certainly view angles, frequencies and
dimensionless constants (e.g. correction factors) as all having
different dimensions.
I would have declared the types for angles thus:
type Radians is new Float; -- no range restriction
You focused too much, IMHO, on the range restriction which is not the
important part. The important part is that, in Ada, this declares a
new *type* (not a "subtype" or "nickname for Float"), which is
*incompatible* with Float or any other type. This incompatibility has
two benefits: early detection of some errors (except, of course, those
involving literals of type universal_real) and documentation, to the
human reader, of what objects of the type represent in the real world.
[...]
> > Nothing is foolproof, but I did prevent some accidents.
>
> Yes, I agree on that and Ada has been a step forward on this direction,
> but as has been written elsewhere in this thread, Ada types do not form
> a 'type system' so it brings moderate safety against errors.
In Ada, floating-point literals (which were the crux of your argument)
belong to the type universal_real which allows implicit conversion to
any floating-point type. If I understand your argument correctly, you
are suggesting that universal_real (and universal_integer) should
disappear and that the language should force the programmer to qualify
every literal, i.e.:
X : Radians := Radians'(3.0);
?
--
Ludovic Brenta.
Nice you bring this, Ludovic! However, remember the OP question:
<quote>
I'm a CS student and I often need to write number-crunching code dealing
with combinatorial optimization problems.
What I do usually is implementing ad-hoc algorithms and testing their
performance against other previously-known solutions, including general
solvers.
</quote>
So your suggestion is to steer from Ada?
> I would have declared the types for angles thus:
> type Radians is new Float; -- no range restriction
>
> You focused too much, IMHO, on the range restriction which is not the
> important part. The important part is that, in Ada, this declares a
> new *type* (not a "subtype" or "nickname for Float"), which is
> *incompatible* with Float or any other type.
More or less. It has all the operations of the derived type, uses the
same representation on the machine. The incompatibility is syntactic no
in its essence.
For example: which type is the operation X^2 + Y^2, or Magnitude *
cos(Theta)?
Does the subtyping in Ada complain if one makes an operation on two
variables of type Length (here defined as 'type Length is new Float;')
that there is not a compatible Length squared defined?
> This incompatibility has
> two benefits: early detection of some errors (except, of course, those
> involving literals of type universal_real) and documentation, to the
> human reader, of what objects of the type represent in the real world.
I agree this allows for some error protection, but as I showed already
this only happens *after* the variable has been initialized with a value
which for non trivial programs have to come from outside world.
>
> [...]
>>> Nothing is foolproof, but I did prevent some accidents.
>> Yes, I agree on that and Ada has been a step forward on this direction,
>> but as has been written elsewhere in this thread, Ada types do not form
>> a 'type system' so it brings moderate safety against errors.
>
> In Ada, floating-point literals (which were the crux of your argument)
> belong to the type universal_real which allows implicit conversion to
> any floating-point type. If I understand your argument correctly, you
> are suggesting that universal_real (and universal_integer) should
> disappear and that the language should force the programmer to qualify
> every literal, i.e.:
>
> X : Radians := Radians'(3.0);
>
Why? Doesn't it make sense for you?
How would Ada gurus suggest the interfaces for reading data from outside
the program (GUI, command line parameters, fields in files, etc.) be
coded (in order to make full use of Ada features)?
> Hibou57 (Yannick Duchêne) escreveu:
>> On 20 juil, 20:33, Cesar Rabak <csra...@yahoo.com.br> wrote:
>>> Here you create two "subtypes" which are only nicknames for Float in
>>> order to help the Ada compiler to discriminate the signature. BTW, why
>>> the need of two subtypes for coordinates?
>> Not “ subtype ” but “ type ”, which is not the same. Ada has both, and
>> both are differents.
>
> They are *considered* different in Ada technology, I respect that, but
> from a OO point of view, they are not: a new type would define a new set
> of operations on it.
It defines a new set of values, which automatically makes the operations
different even if they are numerically equivalent or their low-level
implementations are shared.
You know, two bottles of beer are numerically equivalent to two worn socks.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
No, I would personally use Ada and make the number-crunching code into
generic units. The user would then provide their application-defined
floating-point type as a generic parameter to instantiate the code.
> > I would have declared the types for angles thus:
> > type Radians is new Float; -- no range restriction
>
> > You focused too much, IMHO, on the range restriction which is not the
> > important part. The important part is that, in Ada, this declares a
> > new *type* (not a "subtype" or "nickname for Float"), which is
> > *incompatible* with Float or any other type.
>
> More or less. It has all the operations of the derived type, uses the
> same representation on the machine. The incompatibility is syntactic no
> in its essence.
>
> For example: which type is the operation X^2 + Y^2, or Magnitude *
> cos(Theta)?
Simple. In Ada, these expressions are illegal. The user must
explicitly convert some of the values to a compatible type before
being allowed to mix objects of different types, e.g.
X : Horizontal_Coordinate := ...;
Y : Vertical_Coordinate := ...
R : Magnitude := Magnitude (X)**2 + Magnitude (Y)**2;
X := Horizontal_Coordinate (R) * Magnitude (cos (Theta));
You may say is it not "ergonomic" but, as an engineer, I see this as
"saying what you mean". The best approach, of course, is to make the
above operations into application-specific operators, e.g.
function Magnitude_Of (X : Horizontal_Coordinate; Y :
Vertical_Coordinate)
return Magnitude;
> Does the subtyping in Ada complain if one makes an operation on two
> variables of type Length (here defined as 'type Length is new Float;')
> that there is not a compatible Length squared defined?
No, unfortunately. In Ada, Length squared is a Length. There are
however libraries like [1] that allow full dimensioned computations.
They use compile-time checks where possible and run-time checks where
necessary.
[1] http://www.dmitry-kazakov.de/ada/units.htm
> > This incompatibility has
> > two benefits: early detection of some errors (except, of course, those
> > involving literals of type universal_real) and documentation, to the
> > human reader, of what objects of the type represent in the real world.
>
> I agree this allows for some error protection, but as I showed already
> this only happens *after* the variable has been initialized with a value
> which for non trivial programs have to come from outside world.
No. The incompatibility between types is checked at compile time and
does not depend on values. Indeed, it still works if all types are
declared as "new Float" with no range restriction.
> > [...]
> >>> Nothing is foolproof, but I did prevent some accidents.
> >> Yes, I agree on that and Ada has been a step forward on this direction,
> >> but as has been written elsewhere in this thread, Ada types do not form
> >> a 'type system' so it brings moderate safety against errors.
>
> > In Ada, floating-point literals (which were the crux of your argument)
> > belong to the type universal_real which allows implicit conversion to
> > any floating-point type. If I understand your argument correctly, you
> > are suggesting that universal_real (and universal_integer) should
> > disappear and that the language should force the programmer to qualify
> > every literal, i.e.:
>
> > X : Radians := Radians'(3.0);
>
> Why? Doesn't it make sense for you?
>
> How would Ada gurus suggest the interfaces for reading data from outside
> the program (GUI, command line parameters, fields in files, etc.) be
> coded (in order to make full use of Ada features)?
The interfaces for reading from the outside already exist and they all
use typed input-output routines which check for range constraints (if
applicable) at run time. This makes is simply impossible to create
untyped values, or values of type universal_real, from outside the
program source. One example with streams:
type Radians is new Float;
F : Ada.Streams.Stream_IO.File_Type;
begin
Ada.Streams.Stream_IO.Open (File => F,
Mode => Ada.Streams.Stream_IO.In_File,
Name => "foo.dat");
declare
S : constant Ada.Streams.Stream_IO.Stream_Access :=
Ada.Streams.Stream_IO.Stream (F);
R : Radians;
begin
Radians'Read (Stream => S, Item => R);
end;
end;
(note : I wrote the above in an extra-verbose style to make context
unnecessary).
--
Ludovic Brenta.
I don't think that Ludovic's example with dimensioned values was a good
argument. In fact there is no language with a good support of units. Ada is
not an exception here.
As for mathematics, Ada's type system is exactly right thing because it
supports ADTs. Mathematician would never talk about floats, but reals,
fields, rings etc. These mathematical structures are ADTs. An individual
number without specifying the structure where it belongs to is meaningless
in mathematics. The property of 1 of real and 1 of integer are different.
This is what the notion of type is about.
For number crunching it is even more important, because numerical methods
deal with different models of numbers. Even if the domain set is say real
(R), you might wish to consider to use something different than Long_Float,
because Long_Float is just a model of R, which might turn unsuitable for
your needs. Ada allows you to use various models, develop models of your
own, and design algorithms in terms of a specific model, as well as generic
ones in terms of some set of models.
Another important aspect is strong typing, which allows you to concentrate
on the problem rather than on debugging. Sometimes it is very difficult to
debug scientific applications like number crunching, because in many cases
you cannot tell whether the result is right. After all, the task of the
application is to give a result. If you knew it, you would not need to
crunch anything...
It might be worth mentioning that derived elementary types
neet *not* have the same representation. Gems #27 and #28
talk about opportunities and dangers of using two different
representations for the "same" derived type (as I am certain
you know):
http://www.adacore.com/category/developers-center/gems/
For example, the multiplications in a silly dummy below
use operands of different sizes, as expected. So they are
really different, even at the machine level.
procedure Rep is
package P is
type T0 is range 0 .. 1_000;
for T0'Size use 16;
function From_String(Input: String) return T0;
type T1 is new T0;
for T1'Size use 64;
end P;
package body P is separate;
use P;
X0: T0;
X1: T1;
Y: T0;
begin
X0 := P.From_String("3");
X1 := P.From_String("5");
X0 := X0 * X0;
X1 := X1 * X1;
Y := X0 + T0(X1);
pragma Inspection_Point(Y); -- stop ambitious optimizers
end Rep;
--
Georg Bauhaus
He said performance was important.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
None of them have alive communities except Bigloo which is a Scheme
implementation and, therefore, is not statically typed.
In contrast, OCaml has a substantial community, lots of libraries and offers
superb performance with one of the most expressive static type systems in
existence. OCaml's proprietary cousin at Microsoft, F#, is also a superb
high-performance language.
I am very surprised at the list of languages you arrived at! FreePascal,
Eiffel and Modula-3 are all essentially dead. Ada is alive but sacrificed
many hugely-productive forms of abstraction (e.g. first-class functions) in
order to be optimally suitable for embedded programming. Unless you're
planning on number crunching on a PIC, which I seriously doubt, Ada would
be a step in the wrong direction.
I specialize in scientific computing and I've never heard of anyone using
any of those languages for it. I doubt any even have efficient
implementations by modern standards.
My vote would certainly go to OCaml. If you allow proprietary then also
OCaml's cousin F# from Microsoft because it offers even better parallelism.
Both of these languages are used extensively for scientific computing.
I would also strongly recommend avoiding conservative garbage collectors
because they leak uncontrollably:
http://flyingfrogblog.blogspot.com/2009/01/mono-22-still-leaks-memory.html
You take the 'embedded' tag given to Ada too stongly - it's a general
language with very good support for embedded domains (but also
others).
Runtime performance wise, you can usually get something akin to 'C'-
like speed. Switching off all runtime checks and the difference is
(obviously) even smaller.
> I specialize in scientific computing and I've never heard of anyone using
> any of those languages for it. I doubt any even have efficient
> implementations by modern standards.
That's will come as a huge shock to the guys over at NARVAL [http://
www.cs.kuleuven.be/~dirk/ada-belgium/events/09/090207-fosdem/05-narval.pdf]!!!
:-)
In their own words:
"It is a distributed data acquisition software system
that collects and processes data from nuclear and
particles physics detectors. NARVAL replaces an older
system based on C, Fortran and proprietary technologies
with Ada and Debian GNU/Linux and is itself Free
Software."
Sounds pretty scientific to me...and there are plenty others, e.g.
some Astrophysics work [http://homepage.univie.ac.at/martin.stift/].
AdaCore have 150+ universities signed up for the Academic package
offering tools and support for free (beer & speech) [http://
www.adacore.com/home/academia/] - I doubt very many of them are using
PICs!! ;-)
Cheers
-- Martin
|----------------------------------------------------------------------|
|"[..] |
| |
|[..] In fact there is no language with a good support of units. Ada is|
|not an exception here. |
| |
|[..]" |
|----------------------------------------------------------------------|
Though Dmitry A. Kazakov and I both like Ada, we do not necessarily
agree as to what constitutes good support of units. Ada provides the
mapping
Type * Type -> Type
and ML provides the mapping
Type x Type -> (Type x Type)
and both of these can be worthy without being universally
desirable. It might be nice to have a language which supports both of
these kinds of mappings.
|-------------------------------------------------------------------------------|
|"[..] |
|Nicholas Paul Collin Gloucester escreveu: |
|> On 2009-07-20, Cesar Rabak <csr...@yahoo.com.br> wrote: |
|[..] |
|> In this case there is a reason for having more types. An angle and a |
|> length are simply not interchangable, so they should not be |
|> represented both by Float. The amount of money equal to U.S.$1.00 is |
|> not equal to the amount of money equal to 1.00 Canadian dollar, but |
|> they are both written with the number 1.00. |
|> |
| |
|I disagree strongly: an angle in radians is a real number as any other there is|
|not any intrinsic difference in its *type* on ordinary Mathematics. |
|Dimensionally they are 'pure numbers' with no unit atached, your example on |
|monetary units being fallacious, so non sequitur." |
|-------------------------------------------------------------------------------|
I doubt that you or I shall convince me or you but... if you want to
complain that I misuse the word "type", then fine. If you want to
claim that an angle in radians is the same thing as a length, then you
are mistaken. You can measure an angle with a protractor. You can not
measure a length with a protractor. You can measure a length with a
ruler. You can not measure an angle with a ruler (without some
additional hassle). A rotation is not a translation, despite both
being transformations.
If you believe that a real number of an angle in radians is the same
as a length, then do you believe that a real number of an angle
gradients is the same as a real number of an angle in degrees? 200.0
(a measurement in gradients of an angle) is not equal to pi (a
measurement in radians of the same angle) which is not equal to 180.0
(a measurement in degrees of the same angle). The angle is the same
and the numbers are not so casually interchangable.
A NASA probe was lost when all units were treated as equivalent
numbers.
|-------------------------------------------------------------------------------|
|"[..] |
| |
|As for normalization, IMNHO it has to be done in the constructor of the |
|class/object, and not as an (external) wrapper." |
|-------------------------------------------------------------------------------|
I did not necessarily prohibit that. The wrapper could be called by
the constructor. The wrapper is external to the floating point Ada
type Radians or Magnitude or X_Coordinate or Y_Coordinate, which
itself could be restricted to the internals of a client's class, much
as a C++ std::string might use a char* internally.
If normalization is required, it might not be ideal to keep it in the
constructor because a variable could be constructed whose value is
changed later, for example
--Call a constructor for Radius but do not give it a value yet.
[..]
for some_iterations loop
Radius := Get_Current_Radius;
--Do stuff.
end loop;
|-------------------------------------------------------------------------------|
|"> With the type Radians as I had typed it, |
|> Theta := 7.0; |
|> would not result in a runtime exception. It would be rejected by a |
|> compiler. |
| |
|Because we are dealing with examples with literals, let the value come from an |
|input... |
| |
|[..]" |
|-------------------------------------------------------------------------------|
Literals are not restricted to input, but yes, a runtime exception
would occur with input if some other precaution is not taken.
(If you consider static algebraic operations on types, then Ada supports
Cartesian product of types as well: that is standard record types.)
The problem with "good" units support is that you need both statically and
dynamically constrained (by the dimension) types, which are not only
numeric, but also containers. Ada (and any other language I know) lack
means to express the way dimension constraints propagate through (annotate)
type algebraic operations (like "A is array of T") rendering the operations
of the resulting types as unit-aware. Further these operations are normally
cross-typed (matrix of velocities multiplied by a vector of durations).
Ada's type system does not capture relations between types other than
inheritance. Maybe the algebra of dimensioned types can be expressed by
inheritance, maybe not. But Ada's inheritance is too weak for this.
And this is just a beginning, not even an end of the beginning. Consider
the thing other languages just ignore, I mean accuracy of the numeric
operation. In Ada we carefully specify the precision of the types we
declare. Now imagine these types annotated by dimensions. What happens with
the accuracy of computations of the data in inches performed in meters?
I do not doubt that. My concern about Ada is primarily that it prohibits
many conventional and hugely-productive mainstream abstractions like
first-class lexical closures. Those are particularly beneficial in the
context of scientific computing.
>> I specialize in scientific computing and I've never heard of anyone using
>> any of those languages for it. I doubt any even have efficient
>> implementations by modern standards.
>
> That's will come as a huge shock to the guys over at NARVAL [http://
>
www.cs.kuleuven.be/~dirk/ada-belgium/events/09/090207-fosdem/05-narval.pdf]!!!
> :-)
>
> In their own words:
>
> "It is a distributed data acquisition software system
> that collects and processes data from nuclear and
> particles physics detectors. NARVAL replaces an older
> system based on C, Fortran and proprietary technologies
> with Ada and Debian GNU/Linux and is itself Free
> Software."
In their own words, they are trying to replace a system that is running on
embedded 68k CPUs.
> Sounds pretty scientific to me...and there are plenty others, e.g.
> some Astrophysics work [http://homepage.univie.ac.at/martin.stift/].
Might be interesting to translate some of the examples in those lecture
notes from Ada to a more modern language.
> AdaCore have 150+ universities signed up for the Academic package
> offering tools and support for free (beer & speech) [http://
> www.adacore.com/home/academia/] - I doubt very many of them are using
> PICs!! ;-)
That link says that Ada is:
"the right choice for courses in elementary programming"
it is very new but it seems like a promising multi-paradigm
programming language.
Cheers,
Parnell
> Pascal J. Bourguignon wrote:
>> Have a look at Haskell.
>
> He said performance was important.
And it's achievable in Haskell, especially with a bunch of the work
that's been done in GHC 6.6, 6.8, 6.10, and especially if you have
multiple cores. (I'm not just talking about things like short cut
fusion, but a bunch of library improvements like in ByteStrings.)
The caveat - and you may consider it a showstopper, but I don't - is
that it's easy for a newbie to write grossly inefficient Haskell. It
takes some understanding of what GHC's up to and what fancy stuff is
available, and some use of the profiler, to really be able to eke good
performance out of the system, and you may not think it acceptable that
(a) it's not easy for new users to figure out how to get good
performance from it and (b) if a part of the code has to be much changed
to make it fast, that part often ends up looking rather ugly. (I'd be
interested to see if Haskell fans can rebut me on those points, but
I bet some of the language shootout code still looks horrifying.)
Admittedly, the last I looked, it may be that Data.HashTable is still
slower than I'd have thought reasonable. But if I figure that if I
use it anyway then someone'll fix it and I'll notice the improvement
when I upgrade GHC. (-:
[ followups trimmed ]
Mark
|----------------------------------------------------------------------|
|"Nicholas Paul Collin Gloucester wrote: |
|> Why Objective Caml instead of JoCaml; G'Caml; Chamau; BIGLOO; HimML;|
|> CeML; or Gaml? |
| |
|[..] Bigloo which is a Scheme |
|implementation and, therefore, is not statically typed. |
| |
|[..]" |
|----------------------------------------------------------------------|
I am sorry for making that mistake.
But I'm afraid it does...20 years ago it didn't.
[snip]
> In their own words, they are trying to replace a system that is running on
> embedded 68k CPUs.
Yes, that's right...and they are replacing them with GNU/Linux
bozes...you didn't read far enough.
> > Sounds pretty scientific to me...and there are plenty others, e.g.
> > some Astrophysics work [http://homepage.univie.ac.at/martin.stift/].
>
> Might be interesting to translate some of the examples in those lecture
> notes from Ada to a more modern language.
There's plenty that's modern about Ada - it did multi-core natively
and portably long before the current flavour-of-the-month boys came to
the party.
The one thing that is missing is lambda support but that doesn't
bother me to much given the sort of domains I work in. I think I heard
it was being considered for the next language revision.
> > AdaCore have 150+ universities signed up for the Academic package
> > offering tools and support for free (beer & speech) [http://
> >www.adacore.com/home/academia/] - I doubt very many of them are using
> > PICs!! ;-)
>
> That link says that Ada is:
>
> "the right choice for courses in elementary programming"
Nothing wrong with that - it's also very well suited to intermediate
and advanced programming.
I've nothing against functional languages (my thesis used SML/
NJ)...but I'm afraid your making assertions about Ada that just aren't
true...
Cheers
-- Martin
I'll also add to the list of 'modern' features...full OO-support for
tasks (i.e. lightweight threads) - I don't know of any other language
that can say that.
Cheers
-- Martin
> I've nothing against functional languages (my thesis used SML/
> NJ)...but I'm afraid your making assertions about Ada that just aren't
> true...
Huh, there is nothing wrong in criticizing functional abstractions like
first-class functions etc, or at least in questioning whether a primitive
operation should be considered an object and in which sense exactly. I have
my reservations about functionality of functional abstractions. (:-))
Yes it will, providing you've design things to go this way (compilers
are still automata, not form or artificial with capabilities to read
in your minde).
For your example, you may first define a private type, so that the
user of the type (except package implementation and child package)
cannot rely on its representation (a black box). You may define
initializers, which would be required, as the user would not be able
to initialize any value otherise. Ex. “ function To_Length (Value :
Natural) return Length_Type ” or “ procedure Set (Length : in out
Length_Type; Value : Natural); ”. You may also have a “ type
Length_Squared_Type is private; ”, private as well and a function “
function Length_Squared (Left, Right : Length_Type) return
Length_Squared_Type; ”. As you see, you can have a fully secured set
of specifications : the user can do only what is defined, and nothing
else. So it is easy to enforce Length_Type * Length_Type to be of type
Length_Squared_Type. Beceause the user cannot do a direct Length_Type
* Length_Type and must use the function you provide in this purpose.
Note : as Length_Type and Length_Squared_Type would probably be
defined in the same package specification, then Length_Squared_Type
could not derived from Length_Type (language rules), and and if you
want to use the same representation for both they could just both
derives from a base representation type which could not exist in the
public speficiation of the package, and then a little convertion will
be needed in the implementation. However, it would probably be nice to
have a wider type for Length_Squared_Type and to not have the same
representation (unless the Length_Type is designed so that there is
never an overflow when computing a Length_Squared_Type).
I apologize for details, as I'm not sure you know Ada well (it seems
this thread is broadcasted in multiple comp.lang.* at the same time).
But even with your Eiffel skills, I think it is possible to understand
the most important aspects.
I don't think so. FP seems to have a pretty alive community, GOBO
libraries seem to be actively updated. I can't confirm for M3, but its
supporters seem to be "alive and kicking".
Anyway, you're hitting me where it hurts.
Perhaps I'm just clueless, or childish, but I just can't stand this
situation. The more I learn, the more I feel that something went wrong
in the "language war" in the '80, and this leaves a bad tastes in my
mouth. It may be ridiculous since I was a child when that "war" took
place.
Nevertheless, I can't do anything but note that the languages above
got something right that modern mainstream languages haven't yet.
> I would also strongly recommend avoiding conservative garbage collectors
> because they leak uncontrollably:
Thanks for the tip.
It defines a syntactic difference and as shown until now all the
operations remain equal, even when the OO technique would suggest not:
for example the new 'type' proposed for the angle measurement could make
the wrapping automatically when operations made the results greater than
2*pi.
>
> You know, two bottles of beer are numerically equivalent to two worn socks.
>
This is cardinality not equivalence, non sequitur for this discussion.
If sometimes peoples feel one of these is not alive anymore, this is I
think beceause each of its users are leaving on there own island and
most of time do not know about what is going on, on other islands.
All of these, with also by the way, Ada, Prolog and derivatives, Lisp
and derivatises, and two or three others (I forgot their names), are
stil living. Most of them beceause they rely on a good theory (except
FreePascal perhaps) and will continue to live for long.
I agree.
> As for mathematics, Ada's type system is exactly right thing because it
> supports ADTs. Mathematician would never talk about floats, but reals,
> fields, rings etc. These mathematical structures are ADTs. An individual
> number without specifying the structure where it belongs to is meaningless
> in mathematics.
The support for ADTs in Ada is appropriate for its primary use but for
mathematics it is not enough, except if you don't care of coding a lot
of boilerplate code to have all the consistency you'll need (see
Ludovic's reply to my observation about I/O for example).
> The property of 1 of real and 1 of integer are different.
> This is what the notion of type is about.
You did choose a very peculiar example :-) anyway for an [infinity] of
values your assertion is reasonable true.
>
> For number crunching it is even more important, because numerical methods
> deal with different models of numbers. Even if the domain set is say real
> (R), you might wish to consider to use something different than Long_Float,
> because Long_Float is just a model of R, which might turn unsuitable for
> your needs. Ada allows you to use various models, develop models of your
> own, and design algorithms in terms of a specific model, as well as generic
> ones in terms of some set of models.
Ada here is not as suitable as other languages, which Lisp is a better
example because Floats ultimately map to the underlying HW (a case of
premature optimization), whereas it could store the number as rationals
increasing accuracy and avoiding numerical instability.
However, I agree if the OP is willing to develop the number crunching
algorithms for similar languages (someone wrote in this thread 'Pascal
like') them Ada is OK.
>
> Another important aspect is strong typing, which allows you to concentrate
> on the problem rather than on debugging. Sometimes it is very difficult to
> debug scientific applications like number crunching, because in many cases
> you cannot tell whether the result is right. After all, the task of the
> application is to give a result. If you knew it, you would not need to
> crunch anything...
>
After years working with both strong (and static) typed and more
'dynamic' ones, I disagree on this. Strong static typing plus the need
of the signatures as we're discussing here brings a lot of artifacts
that do not anything to do with the problem to be solved.
For doing experimental work (here as opposed to, say, writing a library
for publishing) I suggest all be done in a dynamic language.
--
Cesar Rabak
PS.: this post scriptum to circumvent the pesky news server that decided
to censor the number of 'quoted lines' in message, but apparently makes
it in a dumb way (perhaps computing some form of porcentage?).
Not according to John Barnes' "Rationale for Ada 2005":
http://www.adaic.org/standards/05rat/html/Rat-3-4.html
> [snip]
>> In their own words, they are trying to replace a system that is running
>> on embedded 68k CPUs.
>
> Yes, that's right...and they are replacing them with GNU/Linux
> bozes...you didn't read far enough.
If they are still running on embedded 68k CPUs then it cannot be very
computationally intensive work by today's standards. They seem to be just
gathering a not-huge amount of data which is neither interesting nor
relevant in this context.
>> > Sounds pretty scientific to me...and there are plenty others, e.g.
>> > some Astrophysics work [http://homepage.univie.ac.at/martin.stift/].
>>
>> Might be interesting to translate some of the examples in those lecture
>> notes from Ada to a more modern language.
>
> There's plenty that's modern about Ada - it did multi-core natively
> and portably long before the current flavour-of-the-month boys came to
> the party.
Fortran did parallelism before Ada and the current "flavour-of-the-month
boys" like Cilk and .NET 4 provide modern solutions for parallelism built
upon wait-free work-stealing concurrent deques that Ada not only does not
have but cannot even express.
> The one thing that is missing is lambda support but that doesn't
> bother me to much given the sort of domains I work in. I think I heard
> it was being considered for the next language revision.
What do you mean by "lambda support" if not first-class lexical closures?
>> > AdaCore have 150+ universities signed up for the Academic package
>> > offering tools and support for free (beer & speech) [http://
>> >www.adacore.com/home/academia/] - I doubt very many of them are using
>> > PICs!! ;-)
>>
>> That link says that Ada is:
>>
>> "the right choice for courses in elementary programming"
>
> Nothing wrong with that - it's also very well suited to intermediate
> and advanced programming.
In the embedded space, perhaps.
> I've nothing against functional languages (my thesis used SML/
> NJ)...but I'm afraid your making assertions about Ada that just aren't
> true...
Not according to the latest Ada specification, AFAICT.
F# is still pretty obscure so look at this trend of FreePascal vs F# by
Google searches:
http://www.google.com/trends?q=freepascal%2Cf%23
> FP seems to have a pretty alive community, GOBO
> libraries seem to be actively updated. I can't confirm for M3, but its
> supporters seem to be "alive and kicking".
I was taught Modula-3 as an undergrad 13 years ago and have not seen it
since.
> Anyway, you're hitting me where it hurts.
> Perhaps I'm just clueless, or childish, but I just can't stand this
> situation. The more I learn, the more I feel that something went wrong
> in the "language war" in the '80, and this leaves a bad tastes in my
> mouth. It may be ridiculous since I was a child when that "war" took
> place.
Well, you do seem to be picking all of the languages that lost the war. ;-)
> Nevertheless, I can't do anything but note that the languages above
> got something right that modern mainstream languages haven't yet.
Mainstream languages are for business apps and web programming so they do
not have the qualities that you are looking for.
Yes but the crux is another: the four 'new types' suggested for solution
to a problem shown by B. Meyers in Ada language for the need of
different function signatures *do not* reflect the problem domain: for
the later all the numbers are just this _numbers�_. The Ada
implementation in order to be able to have two different 'constructors'
for the new type Point (this indeed a *new* type) created through its
mechanisms subtypes, which only send the trash over the wall. All this
discussion about avoiding programmer errors can be attained instead of
creating four nicknames for Float to allow:
procedure makePointXY(X : Float; Y : Float) is
begin
null; --Whatever.
end;
procedure makePoint_R_Theta(R : Float; Theta : Float) is
begin
null; --Whatever.
end;
Do you agree the programmer will find the mistake easily as well?
--
Cesar Rabak
[1] Specializations of the concept for say a screen where coordinates
are integers and limited to screeen area, for example are not being
discussed here, as are not the kernel of Meyer's critique.
The user is free to define (override) the arithmetic operations to do
that.
As can happen with brief code snippets, one can erroneously infer that
language 'X' can not do something because a very small example does
not show that it can do it!
Cheers
-- Martin
>
> I doubt that you or I shall convince me or you but... if you want to
> complain that I misuse the word "type", then fine.
I don't think you do on purpose, it is the nature of the crosspost to
have certain concepts blurred by the naming conventions of each technology.
> If you want to
> claim that an angle in radians is the same thing as a length, then you
> are mistaken.
I did not say that, and your example also is not an implementation of that.
> You can measure an angle with a protractor. You can not
> measure a length with a protractor. You can measure a length with a
> ruler. You can not measure an angle with a ruler (without some
> additional hassle). A rotation is not a translation, despite both
> being transformations.
>
> If you believe that a real number of an angle in radians is the same
> as a length, then do you believe that a real number of an angle
> gradients is the same as a real number of an angle in degrees? 200.0
> (a measurement in gradients of an angle) is not equal to pi (a
> measurement in radians of the same angle) which is not equal to 180.0
> (a measurement in degrees of the same angle). The angle is the same
> and the numbers are not so casually interchangable.
>
Worse than that: radians are always pure numbers because the way they
are defined they are relations between two lengths (which for correct
results have to be in the same unit ;-).
If you want to discuss about new types around above arguments, you'll
agree that a new type Length would need to accept several _units_ of
measurement and keep an internal representation which is opaque for
this, but able to respond to requests of its 'size' in whichever units
the system have been devised to support. Also some operations would
create no units at all (division would give pure numbers [except if both
operands explicitly require different units, to allow unit conversions],
multiplication would give Area, etc.).
> A NASA probe was lost when all units were treated as equivalent
> numbers.
Yes and no line of Ada code could save the poor engineers that made that
mistake (I bet B. Meyer would say Eiffel would :-)
>
> |-------------------------------------------------------------------------------|
> |"[..] |
> | |
> |As for normalization, IMNHO it has to be done in the constructor of the |
> |class/object, and not as an (external) wrapper." |
> |-------------------------------------------------------------------------------|
>
> I did not necessarily prohibit that. The wrapper could be called by
> the constructor. The wrapper is external to the floating point Ada
> type Radians or Magnitude or X_Coordinate or Y_Coordinate, which
> itself could be restricted to the internals of a client's class, much
> as a C++ std::string might use a char* internally.
Notice that all this would be unnecessary if the language's needs did
not entered into the problem: once an internal representation for the
type Point had been chosen, the constructors would accept the values and
do the conversion, which in case of the <rho, theta> representation
would be done as part of the constructor job.
>
> If normalization is required, it might not be ideal to keep it in the
> constructor because a variable could be constructed whose value is
> changed later, for example
> --Call a constructor for Radius but do not give it a value yet.
> [..]
> for some_iterations loop
> Radius := Get_Current_Radius;
> --Do stuff.
> end loop;
The example must be too contrived and I have not code Ada for years to
understand it, but again it seems to be more an Ada technology related
issue than a fundamental aspect.
>
> |-------------------------------------------------------------------------------|
> |"> With the type Radians as I had typed it, |
> |> Theta := 7.0; |
> |> would not result in a runtime exception. It would be rejected by a |
> |> compiler. |
> | |
> |Because we are dealing with examples with literals, let the value come from an |
> |input... |
> | |
> |[..]" |
> |-------------------------------------------------------------------------------|
>
> Literals are not restricted to input, but yes, a runtime exception
> would occur with input if some other precaution is not taken.
Ludovic has shown all else would be required to attain a safer
implementation. As soon one starts to code for real the number of lines
of code grow exponentially ;-)
Regards,
--
Cesar Rabak
Wow, that's amazing. I stopped using Modula-3 in the late 90's when it
seemed to be dying under me; finally moving over to Java (probably in
2000) was something of a disappointment that I posted complaints about
at the time (where's GENERIC? where's TYPECASE? etc., etc.). I'd still
sometimes be using it now if I really ever saw much life in, say,
comp.lang.modula3 where this thread is going. Debian hasn't even carried
pm3 for years. It must be quite a remote little island: are they
positively trying to avoid being a victim of success or something? I
pray that you're correct - I actually kept my Modula-3 books (have /any/
been in print for years?) and would be using it sometimes now if I
thought there were more than a handful of others doing likewise.
[ followups trimmed ]
Mark
> Dmitry A. Kazakov escreveu:
>> On Mon, 20 Jul 2009 22:33:59 -0300, Cesar Rabak wrote:
>> For number crunching it is even more important, because numerical methods
>> deal with different models of numbers. Even if the domain set is say real
>> (R), you might wish to consider to use something different than Long_Float,
>> because Long_Float is just a model of R, which might turn unsuitable for
>> your needs. Ada allows you to use various models, develop models of your
>> own, and design algorithms in terms of a specific model, as well as generic
>> ones in terms of some set of models.
>
> Ada here is not as suitable as other languages, which Lisp is a better
> example because Floats ultimately map to the underlying HW (a case of
> premature optimization), whereas it could store the number as rationals
> increasing accuracy and avoiding numerical instability.
Huh, numerical instability is a property of an algorithm. It is not one of
rounding errors.
There is nothing in Ada which should prevent use of rational arithmetic, if
that might be useful. Especially because one type of rational arithmetic is
built in the language (see fixed point numbers).
>> Another important aspect is strong typing, which allows you to concentrate
>> on the problem rather than on debugging. Sometimes it is very difficult to
>> debug scientific applications like number crunching, because in many cases
>> you cannot tell whether the result is right. After all, the task of the
>> application is to give a result. If you knew it, you would not need to
>> crunch anything...
>>
> After years working with both strong (and static) typed and more
> 'dynamic' ones, I disagree on this. Strong static typing plus the need
> of the signatures as we're discussing here brings a lot of artifacts
> that do not anything to do with the problem to be solved.
>
> For doing experimental work (here as opposed to, say, writing a library
> for publishing) I suggest all be done in a dynamic language.
I am doing both scientific (fuzzy machine learning) and engineering
(automation, SCADA) work in Ada. I never felt any need in making it more
dynamic. In fact, I'd like to see much more static features in Ada, than it
presently has. In my list are:
1. Contracted exceptions
2. Static pure functions
3. Compile time type constraints
4. Static pre-/postconditions and invariants
I don't buy Ada's current trend towards anonymous types, run-time checks,
run-time pre-/post conditions, "functional style" of limited types
initialization.
Chris Okasaki has an entertaining assessment of functional
programming in Ada 2005:
http://okasaki.blogspot.com/2008/07/functional-programming-inada.html
(What one can't do (really) is pass an environment up the call
chain...)
But why not show or point to some striking example of what
is possible to achieve, result-wise, in number-crunching or
scientific computing with full "closures" that is demonstrably
difficult or cumbersome to do using generics, downward "closures"
and objects only.
|------------------------------------------------------------------------------|
|"[..] |
| |
|[..] In fact, I'd like to see much more static features in Ada, than it |
|presently has. [..]" |
|------------------------------------------------------------------------------|
I also.
|------------------------------------------------------------------------------|
|"2. Static pure functions |
|[..] |
| |
|[..]" |
|------------------------------------------------------------------------------|
The latest version of VHDL has these.
|-------------------------------------------------------------------------------|
|"[..] |
| |
|[..] All this discussion about avoiding programmer errors can be attained |
|instead of creating four nicknames for Float to allow: |
| |
|procedure makePointXY(X : Float; Y : Float) is |
| begin |
| null; --Whatever. |
| end; |
| |
|procedure makePoint_R_Theta(R : Float; Theta : Float) is |
| begin |
| null; --Whatever. |
| end; |
| |
|Do you agree the programmer will find the mistake easily as well? |
| |
|[..]" |
|-------------------------------------------------------------------------------|
Yes.
How is the example you have given different from
procedure informalHint_H001(A : ANY; B : ANY) is
begin
null;
end;
procedure informalHint_H002(A : ANY; B : ANY) is
begin
null;
end;
with the procedure names replaced to match some
formal terms from the problem domain, but the types
left as is?
And what should we conclude then?
We need a solid general case here, I think, to get this
argument away from things that are accidental. What's the
power of a type when it comes to program construction?
Floats are an issue here. Let my insignificant finger
point at a strange mental, but measurable, line that language
makers and programmers alike draw
- between types reflecting elementary school experience,
- and types that they themselves defin, carefully[*].
Int, float, and char are taken to be meaningful rocksolid
concepts!
To the effect that every other week you see a CERT
advisory putting our noses into a dangerous mud of int
overflows (and buffer overflows), risking entire systems'
operation.
Isn't this a <emphasis void="crescendo">hint</emphasis>
that *not* bothering with elementary types is an
EMBARRASING_MISTAKE of programming men and women!?
Well, at least if programming errors of this careless
kind do not contribute to our staying in business.
[*] Dabbling in basics of mathematics, I noticed that the
more prominent an author is or was, the higher his awareness
of the fact that we *don't* know what numbers are,
or how we manipulate them (Landau, Halmos, Weyl,
Dirichlet/Dedekind---I just looked at some intriguing
material, not the entire stuff).
|-----------------------------------------------------------------------------------|
|"[..] |
|[..]" |
|-----------------------------------------------------------------------------------|
No, it is not contrived. Unlike a functional language in which every
so-called variable is actually constant, Ada is an imperative language
in which it is common to assign a different value to a variable after
it has already been assigned an earlier value.
In this example, a variable was declared and it was assigned many
values in a loop (perhaps from a GUI). Unless you meant something else
by constructor, checking for errors should not be performed just in
the constructor when the variable begins to exist.
Regards,
Colin Paul Gloster
I conclude that the intent to prove B. Meyer was wrong in his OOSC
example about the issue of procedure signatures for overloading (which
happened to be in Ada and Colin bit the bullet) did not arrive at its
intent.
> We need a solid general case here, I think, to get this
> argument away from things that are accidental. What's the
> power of a type when it comes to program construction?
The new types were introduced as means to circumvent Meyer's objection,
and in this case we arrive at the conclusion that they quickly become
artificial artifacts and worsen the 'ergonomics' of the programming.
>
>
> Floats are an issue here. Let my insignificant finger
> point at a strange mental, but measurable, line that language
> makers and programmers alike draw
> - between types reflecting elementary school experience,
> - and types that they themselves defin, carefully[*].
>
Sorry if it seems so. The issue I was trying to rise is that subtyping
(in this case Float) did not solve, instead make it worse, the problem
that B. Meyer rises.
That can happen with other types as well.
> Int, float, and char are taken to be meaningful rocksolid
> concepts!
> To the effect that every other week you see a CERT
> advisory putting our noses into a dangerous mud of int
> overflows (and buffer overflows), risking entire systems'
> operation.
Yes, but this is subject to another thread. But before you get too much
hope, remember an int overflow did blow an Arianne rocket...
> Isn't this a <emphasis void="crescendo">hint</emphasis>
> that *not* bothering with elementary types is an
> EMBARRASING_MISTAKE of programming men and women!?
Buffer overflows are not an 'elementary types' problem, it is another
kind of problem.
> Well, at least if programming errors of this careless
> kind do not contribute to our staying in business.
As I mentioned in this thread, the error about measurement systems that
costed NASA a Mars mission was coded in type safe system's language,
wasn't it?
>
>
> [*] Dabbling in basics of mathematics, I noticed that the
> more prominent an author is or was, the higher his awareness
> of the fact that we *don't* know what numbers are,
> or how we manipulate them (Landau, Halmos, Weyl,
> Dirichlet/Dedekind---I just looked at some intriguing
> material, not the entire stuff).
[**] Yup! But then we slip to very philosophical discussion ;-)
> On Jul 21, 3:09�pm, Jon Harrop <j...@ffconsultancy.com> wrote:
>> I do not doubt that. My concern about Ada is primarily that it prohibits
>> many conventional and hugely-productive mainstream abstractions like
>> first-class lexical closures. Those are particularly beneficial in the
>> context of scientific computing.
>
> But I'm afraid it does...20 years ago it didn't.
No, that's not quite right. Ada 2005 does not have "first-class lexical
closures", as Jon said. Ada has "downward closures" (sometimes called
"inward closures"). In Ada, you can pass a nested function to a
non-nested function. You cannot return a nested function from the
function containing it. Both are required, to make them "first class"
(or "full closures"), as in OCaml, Lisp, Haskell, etc.
I'd say downward closures give you at least 80% of what one might want
from closures.
Unfortunately, the syntax for downward closures is pretty awful
in Ada, compared to (e.g.) OCaml. There are proposals to make
it better in the next version of Ada. It is unlikely that the
next version of Ada will have full closures. (Of course, you can
always simulate full closures in Ada, using tagged and class-wide
types, but it can get pretty ugly.)
I'd still choose Ada over OCaml for what the OP wants to do.
E.g. Ada's ability to have multiple user-defined integer
types seems like a trivial thing, but in practice it is
hugely beneficial.
For example, suppose I have an array containing indices into another
array. Using a different index type for the two arrays makes the code
clear -- when I see an integer variable, I can immediately tell from
its type which array it is intended to index.
Both OCaml and Ada are pretty good language designs -- far better than
some of the more popular languages. Both have advantages and
disadvantages.
I would not choose any version/dialect of Pascal or Modula for anything,
these days. Ada is strictly better.
Eiffel is a nice language design, but suffers from some other problems.
By the way, some of the "design by contract" stuff from Eiffel has
already been implemented in GNAT (the free-software Ada compiler),
and even more is being considered for the next version of Ada.
>> > Sounds pretty scientific to me...and there are plenty others, e.g.
>> > some Astrophysics work [http://homepage.univie.ac.at/martin.stift/].
>>
>> Might be interesting to translate some of the examples in those lecture
>> notes from Ada to a more modern language.
Jon, why do you use "modern" to mean "good"? They are not synonymous!
For example, closures are good, but they were invented a long
time ago -- they're certainly not "modern".
If you said, "Might be interesting to translate some of the examples in
those lecture notes from Ada to a language with full closures", then
I'd agree -- it would be interesting indeed.
- Bob
P.S. You should know my potential biases: I was heavily involved in the
design of Ada 95, and somewhat involved in the design of Ada 2005,
and continue to be somewhat involved in the ongoing design of the
next version. And I currently work for AdaCore.
It's not that much of a mistake, I believe. My understanding was that
Manuel Serrano started bigloo with the intention of making a compilation
back-end that had both ML and scheme front-ends. Only the scheme front-
end survives, and bigloo-scheme is fairly unique in how thoroughly it
allows and encourages type annotations (which it uses for optimization
purposes, I believe.) It also has a JVM-bytecode back-end, fwiw, but the
native (via C) back-end is said to produce better/faster code. [Bigloo
also does classes and objects, so it could tick all of the OP's boxes,
except for the Wirthian syntax one...]
Cheers,
--
Andrew
The first part of this shows how they weren't...read on and it shows
that have been added (anonymous access types) to provide downward
closures (what I took from "first-class lexical closures").
> > Yes, that's right...and they are replacing them with GNU/Linux
> > bozes...you didn't read far enough.
>
> If they are still running on embedded 68k CPUs then it cannot be very
> computationally intensive work by today's standards. They seem to be just
> gathering a not-huge amount of data which is neither interesting nor
> relevant in this context.
No - they are Intel/Linux boxes (GNAT GPL 2007 is Intel only), not PPC
and they gather _and_ process the data (the FORTRAN bit they are
replacing).
I didn't realise there was a size threshold before something became
"interesting" :-)
I have no idea how much data they are collecting / processing but it's
certainly relevant - your claim was you had "never heard of anyone
using any of those languages for it" ('it' being scientific computing)
and I've provided an example, so now you have.
> > There's plenty that's modern about Ada - it did multi-core natively
> > and portably long before the current flavour-of-the-month boys came to
> > the party.
>
> Fortran did parallelism before Ada and the current "flavour-of-the-month
> boys" like Cilk and .NET 4 provide modern solutions for parallelism built
> upon wait-free work-stealing concurrent deques that Ada not only does not
> have but cannot even express.
Yes, their were other pre-Ada concurrent languages - just shows how
modern Ada is! ;-)
I don't use .NET but there's certainly Ada support for it (A# as it
was called, now available from https://libre.adacore.com/libre/). If
it's built into .NET then I don't see any reason why support couldn't
be added. Does .NET offer different task scheduling policies? Or do
you just 'get what's implemented'? There are 4 tasking policies
already defined in Ada and implementations are free to add others:
pragma Tasking_Dispatch_Policy
(Wait_Free_Work_Stealing_Concurrent_Deques);
...doesn't exactly trip off the tongue but that's it expressed...
Or if you're refering to the work by Chase & Lev @ Sun, then they
implemented it in C++. As far as I know there is nothing you can
implement in C++ that you can't in Ada (or many other languages) and
visa-versa, so it could be added as an external library (akin to
replacing the built in language 'task' keyword with library calls as
you do when using an ARINC-653 supporting OS).
> > The one thing that is missing is lambda support but that doesn't
> > bother me to much given the sort of domains I work in. I think I heard
> > it was being considered for the next language revision.
>
> What do you mean by "lambda support" if not first-class lexical closures?
Ada only supports downward closures not full blown lambda expressions
or functions - that really is the domain of the functional languages
(or TMP).
I can't write unnamed functions, e.g. classic C++ Boost example:
for_each(a.begin(), a.end(), std::cout << _1 << ' ');
^^^^^^^^^^^^^^^^^^^^^^
unnamed function
I'd have to wrap that in a function in Ada to a pass that (named)
function. I can't return an unnamed function in Ada either. It's just
downwards. But that's a whole lot more that the original Ada83 spec,
which expected you to use generic (template) functions instead. Do-
able but a lot more effort.
I believe there is work on adding some sort of unnamed function
support to a future language revision.
> >> "the right choice for courses in elementary programming"
>
> > Nothing wrong with that - it's also very well suited to intermediate
> > and advanced programming.
>
> In the embedded space, perhaps.
Not just embedded - it's a general purpose language but it certainly
isn't functional. Most of my Ada work isn't embedded at all these
days...usually console apps.
Cheers
-- Martin
No, it explicitly states that Ada still has only downward closures and not
first-class lexical closures.
My assertion about Ada was exactly correct: they sacrificed
hugely-productive features for embedded apps.
>> > Yes, that's right...and they are replacing them with GNU/Linux
>> > bozes...you didn't read far enough.
>>
>> If they are still running on embedded 68k CPUs then it cannot be very
>> computationally intensive work by today's standards. They seem to be just
>> gathering a not-huge amount of data which is neither interesting nor
>> relevant in this context.
>
> I didn't realise there was a size threshold before something became
> "interesting" :-)
If the context is high-performance computing then work being done on 68k
CPUs today is irrelevant.
>> > There's plenty that's modern about Ada - it did multi-core natively
>> > and portably long before the current flavour-of-the-month boys came to
>> > the party.
>>
>> Fortran did parallelism before Ada and the current "flavour-of-the-month
>> boys" like Cilk and .NET 4 provide modern solutions for parallelism built
>> upon wait-free work-stealing concurrent deques that Ada not only does not
>> have but cannot even express.
>
> Yes, their were other pre-Ada concurrent languages - just shows how
> modern Ada is! ;-)
>
> I don't use .NET but there's certainly Ada support for it (A# as it
> was called, now available from https://libre.adacore.com/libre/). If
> it's built into .NET then I don't see any reason why support couldn't
> be added. Does .NET offer different task scheduling policies? Or do
> you just 'get what's implemented'? There are 4 tasking policies
> already defined in Ada and implementations are free to add others:
>
> pragma Tasking_Dispatch_Policy
> (Wait_Free_Work_Stealing_Concurrent_Deques);
>
> ...doesn't exactly trip off the tongue but that's it expressed...
>
> Or if you're refering to the work by Chase & Lev @ Sun, then they
> implemented it in C++. As far as I know there is nothing you can
> implement in C++ that you can't in Ada (or many other languages) and
> visa-versa, so it could be added as an external library (akin to
> replacing the built in language 'task' keyword with library calls as
> you do when using an ARINC-653 supporting OS).
Atomic intrinsics are an obvious counter example.
>> > The one thing that is missing is lambda support but that doesn't
>> > bother me to much given the sort of domains I work in. I think I heard
>> > it was being considered for the next language revision.
>>
>> What do you mean by "lambda support" if not first-class lexical closures?
>
> Ada only supports downward closures not full blown lambda expressions
> or functions - that really is the domain of the functional languages
> (or TMP).
>
> I can't write unnamed functions, e.g. classic C++ Boost example:
>
> for_each(a.begin(), a.end(), std::cout << _1 << ' ');
> ^^^^^^^^^^^^^^^^^^^^^^
> unnamed function
>
> I'd have to wrap that in a function in Ada to a pass that (named)
> function. I can't return an unnamed function in Ada either. It's just
> downwards. But that's a whole lot more that the original Ada83 spec,
> which expected you to use generic (template) functions instead. Do-
> able but a lot more effort.
>
> I believe there is work on adding some sort of unnamed function
> support to a future language revision.
So Ada not only lacks first-class lexical closures but it doesn't even have
anonymous functions. Even C# has both of those features now.
>> >> "the right choice for courses in elementary programming"
>>
>> > Nothing wrong with that - it's also very well suited to intermediate
>> > and advanced programming.
>>
>> In the embedded space, perhaps.
>
> Not just embedded - it's a general purpose language but it certainly
> isn't functional.
Right.
Unfortunately that picks up a lot of swear-word replacements, as in
"what the f#@$!" and for some reason a heck of a lot of asian
financial pages!!!
Same goes for a straight Google search...
Cheers
-- Martin
Right. I had read that before...
> But why not show or point to some striking example of what
> is possible to achieve, result-wise, in number-crunching or
> scientific computing with full "closures" that is demonstrably
> difficult or cumbersome to do using generics, downward "closures"
> and objects only.
Currying and, therefore, partial application are the most obvious examples.
I recently wrote an F# implementation of QR decomposition that is up to 3x
faster than the Intel MKL (!). I first wrote it with explicit copies. Then
I rephrased it to index everything via functions (making heavy use of
partial application) rather than explicit data structures (creating "views"
of the matrix without copying it). Then I rearranged those to make them
more cache coherent and finally introduced parallelism.
There is a brief description here:
http://flyingfrogblog.blogspot.com/2009/07/ocaml-vs-f-qr-decomposition.html
Moreover, my implementation is parameterized over its element type and
operations so it can be applied to single or double precision or even
symbolic matrices.
> I recently wrote an F# implementation of QR decomposition that is up to 3x
> faster than the Intel MKL (!). I first wrote it with explicit copies. Then
> I rephrased it to index everything via functions (making heavy use of
> partial application) rather than explicit data structures (creating "views"
> of the matrix without copying it). Then I rearranged those to make them
> more cache coherent and finally introduced parallelism.
>
> There is a brief description here:
>
> http://flyingfrogblog.blogspot.com/2009/07/ocaml-vs-f-qr-decomposition.html
>
> Moreover, my implementation is parameterized over its element type and
> operations so it can be applied to single or double precision or even
> symbolic matrices.
Interesting example, thank you.
BTW, readers interested in "state of the art" concurrent
and parallel algorithms in ISO-languages or other languages
might want to be made aware of the patent situation of
some of the technology required,
http://www.patents.com/Dynamic-circular-work-stealing-deque/US7346753/en-US/
http://www.freepatentsonline.com/7346753.html
http://www.wikipatents.com/7346753.html
etc.
--
--
Georg Bauhaus
Y A Time Drain http://www.9toX.de
|------------------------------------------------------------------------------|
|"[..] |
| |
|Yes, but this is subject to another thread. But before you get too much hope, |
|remember an int overflow did blow an Arianne rocket..." |
|------------------------------------------------------------------------------|
An Ariane 5 rocket which was running flawless software for an Ariane 4
rocket which was misapplied to the Ariane 5 by a manager despite
objections from the software developers. Furthermore, Ada could have
had an exception handler there, but it has not yet proven to be
necessary for an Ariane 4.
|------------------------------------------------------------------------------|
|"[..] |
| |
|As I mentioned in this thread, the error about measurement systems that costed|
|NASA a Mars mission was coded in type safe system's language, wasn't it? |
| |
|[..]" |
|------------------------------------------------------------------------------|
I do not know. Some hints...
FORTRAN influence:
Robert B. Love
Subject: Re: Loss of Mars Climate Orbiter due to units of measurment conflicts
Date: 1999/10/02
Message-ID: <6C26F727ACB69543.66B23092...@lp.airnews.net>#1/1
comp.lang.ada
(and Ada advocacy: Michel DELARCHE
Subject: Re: Loss of Mars Climate Orbiter due to units of measurment conflicts
Date: 1999/10/02
Message-ID: <37F64C20...@cybercable.fr>#1/1
)
and
Lockheed Martin did not adhere to contracted units:
Michel DELARCHE
Subject: Re: Loss of Mars Climate Orbiter due to units of measurment conflicts
Date: 1999/10/02
Message-ID: <37F648AE...@cybercable.fr>#1/1
Yes, however the exception on Ariane 5 happened and it blew (or had to
be blown): no technology saves us from mismanagement, but a wrong feel
of safety helps managers to make bad calls...
>
> |------------------------------------------------------------------------------|
> |"[..] |
> | |
> |As I mentioned in this thread, the error about measurement systems that costed|
> |NASA a Mars mission was coded in type safe system's language, wasn't it? |
> | |
> |[..]" |
> |------------------------------------------------------------------------------|
>
> I do not know. Some hints...
Nor I either, and probably if we dig in the issue, some account similar
to the Arianne will surface where managers would be behind the root cause.
It has to be that way, right!? They're better paid, can afford to make
more expensive mistakes :-D
Before 2004, Google Trends registered nothing for F#. If you look at the
trend, it correlates very strongly with F# releases and major
announcements. It is an accurate measure of people searching for the F#
programming language.