George Neuner <gneun...@comcast.net> wrote: +--------------- | r...@rpw3.org (Rob Warnock) wrote: | >Ahhh, how quickly they forget!!! BLISS <http://en.wikipedia.org/wiki/BLISS> | >predated C (at least publicly), and not only had pointers and an explicit | >dereference operator (the infamous "dot"!) | | You're right ... I did forget about BLISS. However, my comment was | about when the term entered popular usage - which I don't believe | BLISS accomplished. +---------------
Maybe not in the general public, though it certainly made it to a large subset of DEC users... and not always favorably! ;-} ;-}
+--------------- | >But even better, BLISS has "structures" which were actually little | >*user*-defined pieces of code for calculating a pointer, including | >subfields [the "P" (offset) & "S" (width) values above], so a more | >idiomatic way to write it [assuming "foo" had previously been "mapped" | >with an appropriate structure] would be: | > | > foo[13, my_nibble] = .foo[13, my_nibble] + 5; | | Interesting ... but does a pointer to a partial word have any utility | beyond device register control? +---------------
Sure, the same thing as bitfields in C -- any time you have compact data structures where you want to pack multiple values per machine word.
+--------------- | (Maybe what it was meant for?) +---------------
Not really. Actually, BLISS's pointers almost *exactly* mirror the hardware byte pointers in the DEC PDP-10 instruction set. The BLISS code:
foo[13]<12,4> = .foo[13]<12,4> + 5;
could be written in PDP-10 assembler like this:
movei t0, foo+15 / Note: Default base in MACRO-10 is octal. hrli t0, 140400 / Make a byte pointer from &foo[13]. ldb t1, t0 / Load byte using byte pointer in t0. addi t1, 5 dpb t1, t0 / Deposit byte.
If you need the subscript "13" to be computed dynamically, then you can use the built-in indexing in byte pointers, and construct one at compile time [assuming you can fix which register will be used for indexing -- here we assume that "t2" == register 7]:
myfield: xwd 140407,foo / Byte pointer to foo[t2]<12,4>
Then the code becomes:
move t2, ...[the index]... ldb t1, myfield / The contents of t2 get used by the hardware addi t1, 5 / in the calculation of the effective addr. dpb t1, myfield
The motivation for having such flexible byte pointers in hardware came in part from the fact that the PDP-10 was a 36-bit wide word-addressed machine that used 7-bit ASCII for normal text files [packed 5 to a word with one bit wasted] but also used *6*-bit subset ASCII for file names and extensions, as well as keywords in system calls. But the hardware actually supported *any* byte size from 1 to 36. [In fact, it even supported a byte size of 0, which gave a sometimes-useful no-op!]
I should also mention that there were also ILDB & IDPB instructions, which would first *increment* the referenced byte pointer [by decrementing the "position" field by the "size" field] and then perform the LDB or DPB function on the ultimate target location. If there weren't enough bits left in the byte pointer for the field to fit in the current word [the "position" field went negative], the ILDB/IDPB would increment the *word* address and reset the position field to 0, thus allowing the use of ILDB/IDPB to step sequentially through the bytes of a packed string.
-Rob
p.s. Yes, I used mixed-endian conventions in my sample code in the previous posting. The BLISS code there (and the PDP-10 assembler above) used big-endian byte descriptions, while the C code used little-endian. [I was trying to keep it simple.]
----- Rob Warnock <r...@rpw3.org> 627 26th Avenue <URL:http://rpw3.org/> San Mateo, CA 94403 (650)572-2607
On Mon, 18 Oct 2010 21:33:19 -0500, r...@rpw3.org (Rob Warnock) wrote: >George Neuner <gneun...@comcast.net> wrote: >+--------------- >| r...@rpw3.org (Rob Warnock) wrote: >| >Ahhh, how quickly they forget!!! BLISS <http://en.wikipedia.org/wiki/BLISS> >| >predated C (at least publicly), and not only had pointers and an explicit >| >dereference operator (the infamous "dot"!) >| >| You're right ... I did forget about BLISS. However, my comment was >| about when the term entered popular usage - which I don't believe >| BLISS accomplished. >+---------------
>Maybe not in the general public, though it certainly made it >to a large subset of DEC users... and not always favorably! ;-} ;-}
>+--------------- >| >But even better, BLISS has "structures" which were actually little >| >*user*-defined pieces of code for calculating a pointer, including >| >subfields [the "P" (offset) & "S" (width) values above], so a more >| >idiomatic way to write it [assuming "foo" had previously been "mapped" >| >with an appropriate structure] would be: >| > >| > foo[13, my_nibble] = .foo[13, my_nibble] + 5; >| >| Interesting ... but does a pointer to a partial word have any utility >| beyond device register control? >+---------------
>Sure, the same thing as bitfields in C -- any time you have compact >data structures where you want to pack multiple values per machine word.
>+--------------- >| (Maybe what it was meant for?) >+---------------
>Not really. Actually, BLISS's pointers almost *exactly* mirror the >hardware byte pointers in the DEC PDP-10 instruction set. The BLISS code:
> foo[13]<12,4> = .foo[13]<12,4> + 5;
>could be written in PDP-10 assembler like this:
> movei t0, foo+15 / Note: Default base in MACRO-10 is octal. > hrli t0, 140400 / Make a byte pointer from &foo[13]. > ldb t1, t0 / Load byte using byte pointer in t0. > addi t1, 5 > dpb t1, t0 / Deposit byte.
>If you need the subscript "13" to be computed dynamically, then you >can use the built-in indexing in byte pointers, and construct one >at compile time [assuming you can fix which register will be used >for indexing -- here we assume that "t2" == register 7]:
> myfield: xwd 140407,foo / Byte pointer to foo[t2]<12,4>
>Then the code becomes:
> move t2, ...[the index]... > ldb t1, myfield / The contents of t2 get used by the hardware > addi t1, 5 / in the calculation of the effective addr. > dpb t1, myfield
>The motivation for having such flexible byte pointers in hardware came >in part from the fact that the PDP-10 was a 36-bit wide word-addressed >machine that used 7-bit ASCII for normal text files [packed 5 to a word >with one bit wasted] but also used *6*-bit subset ASCII for file names >and extensions, as well as keywords in system calls. But the hardware >actually supported *any* byte size from 1 to 36. [In fact, it even >supported a byte size of 0, which gave a sometimes-useful no-op!]
>I should also mention that there were also ILDB & IDPB instructions, >which would first *increment* the referenced byte pointer [by decrementing >the "position" field by the "size" field] and then perform the LDB or DPB >function on the ultimate target location. If there weren't enough bits >left in the byte pointer for the field to fit in the current word [the >"position" field went negative], the ILDB/IDPB would increment the *word* >address and reset the position field to 0, thus allowing the use of >ILDB/IDPB to step sequentially through the bytes of a packed string.
>-Rob
>p.s. Yes, I used mixed-endian conventions in my sample code in the >previous posting. The BLISS code there (and the PDP-10 assembler above) >used big-endian byte descriptions, while the C code used little-endian. >[I was trying to keep it simple.]
Sorry I was a little dense - I never used a PDP, they were a little before my time :-) I'm more at home with VAX.
I forgot about the PDP's long words, packed strings, etc. In that context, having such a field pointer construct makes perfect sense. Thanks for taking the time to explain them.
On Mon, 18 Oct 2010 12:34:24 -0700 (PDT), Joshua Maurice
<joshuamaur...@gmail.com> wrote: >Stop me where you disagree:
>1- Java is a direct descendant of C++. It is not an extension of, nor >does it share the same design goals. However, Java is based largely >off the C family of languages, and specifically C++. Java was meant as >a better C++.
You can stop right here.
To my mind, a "better" version of a programming language should be at least equivalent in utility - the "better" can be in other dimensions such as safety and ease of use.
Gosling wrote that his motivation was to [clean up syntax, remove redundancy and make the language safer and easier to use] (I'm paraphrasing here, the actual quotes are long [1]).
But Gosling did not simply remove redundancy, he also removed critical language functionality without offering an equivalent. As compared to C++, Java is less expressive and provides less functionality.
How is that making it "better"?
YMMV, but I don't believe "dumbing down" a programming language can be considered an improvement. Programming languages are not door knobs, toasters or consumer MP3 players ... they are tools that need a sharp edge. You can put a guard over the edge or you can teach people to be careful, but removing the edge makes the tool useless.
Though still far from equivalent, C# nevertheless is closer than Java to being a functional replacement for C++.
>2- The C family of languages largely popularized the term "pointer". >The term "reference" was already well known, and its definition was >vague and meant many different related things in different contexts.
No, the definition of reference was not vague. As the C (and Pascal) families use them, the terms "reference", "reference variable" and "reference parameter" all were defined by Algol.
The languages of the C family, including Java, all use Algol's notions unchanged.
>3- Java's references have identical semantics to C pointers (minus >unsafe casting, pointer math, and null pointer checking), and they are >very different than C++ references. That is, there is a pre-existing >term widely known by all which excellently captured the semantics of >this construct of the new language Java, and that term was "pointer". >The identifying characteristic of "pointer" is not pointer math, nor >unsafe casting, nor null pointer checking or lack thereof, as >evidenced by the term pointer being used in other languages which also >lack those things. The term pointer references to an "object" or >"entity" which refers to another object. You can change the pointer to >point to a new object, and you can change the pointed-to object >without changing the pointer's state. They have distinct state.
Partly.
Modulo automatic dereferencing, C and C++ pointers, and Java's references all are semantically equivalent to Algol's reference variables. C++ references include the non-NIL, init-only attributes of Algol's reference parameters.
[Stroustrup's mistake, I think, was in making C++ references first class objects akin to pointers. Had references been simply name syntax, I don't think there would be as much (or even any) confusion about them.]
>4- The term which Java did pick, references, was vague in the >literature. It could refer to pointers, aliases, and any of kind of >thing which "references" another thing. Moreover, "references" had a >domain specific definition in C++, the language on which Java is >based.
The term was not vague in relevant literature. Rather I think people superimpose the everyday meaning of the term upon their (often shallow) understanding of the semantics as defined by the programming language ... and then are surprised when the real semantics don't conform to their bogus understanding.
>5- By choosing the vague term "reference" which was already overloaded >in its predecessor language which denoted a thing very related but >distinct from pointer, the Java creators introduced confusion into the >programming world. Yes, this confusion is quite minor, perhaps not >even enough to write home about. I merely noted it as a pet peeve.
C++ does not "overload" the term reference. Algol did, to some extent, with dual notions of reference both as a syntactic identifier and as a first-class, address container object.
C++ does not have Algol's notion of reference as "syntax" ... it has only the notion of "container object". So despite whatever misconceptions people may have, there is no overloaded meaning.
Similarly, Java has only the notion of "container object".
Moreover, all the notions of "pointers" and "references", regardless of language, include notions of object identity and aliasing, so those too are not overloaded meanings.
George [1] James Gosling, Henry McGilton, "The Java language Environment: A white paper", Sun Microsystems, 1996
> But Gosling did not simply remove redundancy, he also removed critical > language functionality without offering an equivalent. As compared > to C++, Java is less expressive and provides less functionality.
> How is that making it "better"?
If, in removing some functionality, you can cut the number of bugs by eye-popping amounts, I would consider it better.
I presume you're referring to manual memory management and pointer arithmetic as the tools that Java lacks to make it "less functional".
> YMMV, but I don't believe "dumbing down" a programming language can be > considered an improvement. Programming languages are not door knobs, > toasters or consumer MP3 players ... they are tools that need a sharp > edge. You can put a guard over the edge or you can teach people to be > careful, but removing the edge makes the tool useless.
Not necessarily. I may not easily be able to express exactly how long I want this Java object to last, but it's not a feature I use very often when I have that capability.
The world doesn't need a One True Programming Language which solves any problem under the sun--what you get when you try that is an unholy kludge of a language which has surprisingly little compiler interoperability, is truly understood by almost nobody, and which requires style guidelines to limit you to a strict subset of the language to be usable in production code.
Instead, it is better to have multiple languages which work very well for their design goals and are reasonably interoperable between each other. For example, you can call C code from pretty much any language, and some dynamic languages even have modules to allow you to dynamically call C code ("ctypes").
-- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald E. Knuth
In article <i9l0lc$el...@news-int.gatech.edu>, Pidgeo...@verizon.invalid says...
> On 10/19/2010 04:04 PM, George Neuner wrote: > > But Gosling did not simply remove redundancy, he also removed critical > > language functionality without offering an equivalent. As compared > > to C++, Java is less expressive and provides less functionality.
> > How is that making it "better"?
> If, in removing some functionality, you can cut the number of bugs by > eye-popping amounts, I would consider it better.
> I presume you're referring to manual memory management and pointer > arithmetic as the tools that Java lacks to make it "less functional".
Not having to deal with memory management and pointer arithmetic is, by far, the biggest reason I prefer Java over C++.
-- Steve Sobol, Apple Valley, California, USA sjso...@JustThe.net
No offense to Stefan intended, but I intend great offense towards the source of that quote. I don't even know what to say to it. It's so stupid. Scheme is a functional programming language, a Lisp dialect, whereas Java and C++ are very much based on ALGOL and imperative programming (though they both offer limited support for functional programming styles). The semantics of Java and the semantics of Lisp and Scheme are worlds apart.
On Tue, 19 Oct 2010 14:40:21 -0700, Steve Sobol wrote: > In article <i9l0lc$el...@news-int.gatech.edu>, Pidgeo...@verizon.invalid > says...
>> On 10/19/2010 04:04 PM, George Neuner wrote: >> > But Gosling did not simply remove redundancy, he also removed >> > critical language functionality without offering an equivalent. As >> > compared to C++, Java is less expressive and provides less >> > functionality.
>> > How is that making it "better"?
>> If, in removing some functionality, you can cut the number of bugs by >> eye-popping amounts, I would consider it better.
>> I presume you're referring to manual memory management and pointer >> arithmetic as the tools that Java lacks to make it "less functional".
> Not having to deal with memory management and pointer arithmetic is, by > far, the biggest reason I prefer Java over C++.
+1
Pointer arithmetic probably has no place in a high-level language. And, no, much as I like it, I don't consider C to be a HLL - more a structured assembler.
-- martin@ | Martin Gregorie gregorie. | Essex, UK org |
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Joshua Maurice <joshuamaur...@gmail.com> writes: >>The semantics of Java and the semantics of Lisp >>and Scheme are worlds apart.
> LISP was the first language with a garbage collector, now > Java also has a GC, while C++ does not have a GC. But this > is only one aspect.
One could try to use BoehmGC.
Unfortunately, I'm not sure at 100% that it would be safe, given how hard C++ libraries and preconized C++ usage tries to make it hard for a GC to work well with C++ code...
Nonetheless, some success have been reported, eg. with using Qt with BoehmGC.
> However, in Java, one can partially > emulate the LISP style, where functions (like CONS) return > complex entities (dotted pairs) allocated at runtime which > might be linked and passed around in complex ways. In C++, > this is much more difficult, because there is no garbage > collector.
Indeed. There's still Lpp (but you'd need an old gcc).
> From: Joshua Maurice <joshuamaur...@gmail.com> > Related: Java only has pass by value - its functions pass its pointers > (which it calls references) by value.
I assume you're talking about C++ jargon, where you somehow pass the *place* (Lisp jargon, means a mutable cell in the caller's space, or even a higher-up caller's space if the "reference" is passed through multiple levels of function calling) where a value can be updated directly by the called function.
But in ordinary language, a reference is: - A citation of prior art, listing title of book or journal and enough additional information to find the article or book in a library. (Used in a new article/book that cites information from the prior art.) - A letter attesting to a claim that somebody is of good quality, such as does good work and/or is of good moral character. (Used when applying for a job or a security clearance or housing etc.)
So instead of arguing whether C++ or Java uses the word "correctly", when in fact *neither* does, best to avoid the word entirely.
For what C++ passes, what the Lisp Machine called locatives, we should use the Common Lisp jargon "place". Tell the function the *place* where it is allowed to make references despite the fact that *place* is in a higher-up space hence normally is forbidden for access by the called function. Place = mutable cell. Locative = mechanism by which a place is passed to a function. All the application programmer cares about is that the function knows the place; the application programmer needn't know the mechanism; hence my preference for "place" instead of "locative" in API documentation.
For what Java passes, we could call it a "handle", because it's more than just a pointer (machine address), it's a tagged pointer, something that identifies both the machine address and the type of data to be found there, by a tag accompanying the machine address and/or by inspection of what is seen in the target. Likewise Lisp pointers should also be called "handles" rather than "pointers".
For what C passes, that's just a machine address, with no type info at runtime, so it's a "pointer". (And with casting to/from void*, even the compiletime typing isn't really enforced.) int x = 5; int* px = &x; void* pv = px; double* pf = pv; double y = sqrt(*pf); Untested. Did I get all that correct? I'm not really expert at C.
BTW many years ago, before Common Lisp, I made a try at designing a new kind of Lisp where all parameters were places/locatives, even when a computed value was being passed (the place within the stack where that temporary value appears would be passed). It would be the responsibility of the called function to fetch the old value from that place if it was needed, and/or store the updated value there before returning. It would be the responsibility of the application programmer not to waste CPU cycles by passing a temporary value to a function that was going to change it (and then after return the caller has no way to make any use of that updated value). In this way, SETF macros would never be needed. Instead of: (setf (car x) 5) ==macroExpand=> (let ((val 5)) (rplaca x val) val) with my system we could just write (setq (car x) 5) and it would work as-is, compiling code to use the locative to the CAR of whatever x was at the time. But I was busy with other stuff and never developed the idea much, and then discovered Common Lisp with SETF macros and got lazy and just adapted to SETF.
Now I realize that one of the principles of OO, namely that places can be hidden from the outside, requiring a method call to view and/or set them, is often a good safety precaution, to protect against disrupting data structures to be invalid (with respect to the usual algorithms for them), thus to prevent the occurrance of really hard-to-diagnose bugs. So now each ADT has a formal API which is the *only* way any foreign code is allowed to examine/modify the structures per the ADT, and the idea of passing a locative (to a place within your data structure) to somebody who may then modify that place any time it wants, thereby potentially invalidating your data structure, so that *your* code breaks because of what the other code did to your data, seems way too dangerous.
> No offense to Stefan intended, but I intend great offense towards the > source of that quote. I don't even know what to say to it. It's so > stupid. Scheme is a functional programming language, a Lisp dialect, > whereas Java and C++ are very much based on ALGOL and imperative > programming (though they both offer limited support for functional > programming styles). The semantics of Java and the semantics of Lisp > and Scheme are worlds apart.
totally agree here. To say that java's semantic is mostly based or connected to scheme lisp in would be the most egregious sophistry.
one might as well say any 2 langs is based on any other.
On Tue, 19 Oct 2010 16:56:12 -0400, Joshua Cranmer
<Pidgeo...@verizon.invalid> wrote: >On 10/19/2010 04:04 PM, George Neuner wrote: >> But Gosling did not simply remove redundancy, he also removed critical >> language functionality without offering an equivalent. As compared >> to C++, Java is less expressive and provides less functionality.
>> How is that making it "better"?
>If, in removing some functionality, you can cut the number of bugs by >eye-popping amounts, I would consider it better.
>I presume you're referring to manual memory management and pointer >arithmetic as the tools that Java lacks to make it "less functional".
No.
It's amazing to me that Java enthusiasts/apologists have so much contempt for things they can't seem to master. Moreover, those same things are the first thoughts that pop into their heads whenever someone mentions C or C++.
What Java lacks that limits its utility with respect to C or C++ is the ability to overlay a logical view of structured data at an arbitrary memory location. This ability is the single feature of C and C++ which makes them strictly more powerful than Java.
[C and C++ union types are not types in their own right but merely convenience syntax for overlaying views of multiple data structures at the same location.]
Java doesn't have any equivalent. The often recommended nio.Buffer, ByteBuffer, MappedByteBuffer, etc. are severely limited and offer only some of the functionality of a union type.
First, there is no way *reliably* to obtain an arbitrary location mapping on memory. Not all systems will support such mappings and even if a particular platform does support it (e.g., Linux's /dev/mem, /proc/<ID>/mem, etc.) there may be in place security protocols in the JVM and/or host system which will prevent it.
Second, Java provides no way to determine the offset of a particular data field within an object. The physical layout of an object in memory is implementation dependent ... only the JVM knows how to find an object's data fields. So even if you could get a reliable location mapping, you still could not overlay ByteBuffer views of different objects on it. Working within Java, you can achieve unions of only the primitive types. [Of course, you can achieve a union using JNI, but then you're cheating by going outside the language ... not to mention that you'll end up coding in the very language that Java was supposed to have improved upon.]
In contrast, both C and C++ do guarantee the order of data fields in a struct. Field alignment padding is implementation dependent, but virtually all compilers allow unaligned/unpadded structs if desired. Both C and C++ provide the standard macro offsetof() for determining the offset of a data field from the beginning of the structure. Thus you could directly access a byte buffer containing an instance of a struct without overlaying a view of the struct on the buffer.
Moreover, C#, which lots of people accuse of being a clone of Java, also has the ability to overlay data structures on memory.
>> YMMV, but I don't believe "dumbing down" a programming language can be >> considered an improvement. Programming languages are not door knobs, >> toasters or consumer MP3 players ... they are tools that need a sharp >> edge. You can put a guard over the edge or you can teach people to be >> careful, but removing the edge makes the tool useless.
>Not necessarily. I may not easily be able to express exactly how long I >want this Java object to last, but it's not a feature I use very often >when I have that capability.
So what? C++ has this feature called a "library" that, among other things, allows you to use functions that you didn't write.
Among the many "libraries" that are available for C++ there are ... OMG! Garbage Collectors ?!? Not refcounting hacks ... real collectors from names you might actually recognize - that is if you know anything at all about GC.
Guess what? C and C++ programmers don't have to manually manage memory unless they want to. True, GC is not a *standard* library ... yet ... but, you see, there is this thing called the World Wide Web and it has a thing called "Google" that finds non-standard libraries for you.
Searching Google with "C++ garbage collector" you will immediately locate the best known and very well respected Boehm-Demers-Weiser collector. http://www.hpl.hp.com/personal/Hans_Boehm/gc/
Searching Google with "C memory management library" you will find others, some of which are just as good as BDW.
>The world doesn't need a One True Programming Language™ which solves any >problem under the sun -- what you get when you try that is an unholy >kludge of a language which has surprisingly little compiler >interoperability, is truly understood by almost nobody, and which >requires style guidelines to limit you to a strict subset of the >language to be usable in production code.
This is bullshit.
There are languages that offer power fully equivalent to C++ but which are cleaner, safer and easier to use. Some of them are OO, some are functional. Almost all have built-in GC.
Java is not among them.
>Instead, it is better to have multiple languages which work very well >for their design goals and are reasonably interoperable between each >other.
Finally a reasonable statement that I can agree with.
>For example, you can call C code from pretty much any language, >and some dynamic languages even have modules to allow you to dynamically >call C code ("ctypes").
Haven't you been arguing all along that nobody should be using C?
FWIW: I don't give a rat what language anybody chooses to use. What I do care about is that comparisons made between languages be fair and include ALL the relevant information so that people unfamiliar with them are not drawing erroneous conclusions from unsupported claims.
> What Java lacks that limits its utility with respect to C or C++ is > the ability to overlay a logical view of structured data at an > arbitrary memory location. This ability is the single feature of C > and C++ which makes them strictly more powerful than Java.
This doesn't work as well in C/C++ as you think. Specifically, in:
union { int a; double b;
} x;
x.a = 5;
The value of double is undefined. And let's not get into type punning.
I have occasionally desired union types in Java, but never really union types.
> First, there is no way *reliably* to obtain an arbitrary location > mapping on memory. Not all systems will support such mappings and > even if a particular platform does support it (e.g., Linux's /dev/mem, > /proc/<ID>/mem, etc.) there may be in place security protocols in the > JVM and/or host system which will prevent it.
How can Java be more powerful than what its host system provides? You could probably do nio on /dev/mem, e.g., for Linux, though.
In any case, I have found little reason to do this, even in C or C++. About the closest I can think of is mmap'ing binary files for performance--nio can do that--or perhaps easier binary I/O, in which case Java's Object{Input,Output}Stream is sufficient for my serialization needs.
> In contrast, both C and C++ do guarantee the order of data fields in a > struct. Field alignment padding is implementation dependent, but > virtually all compilers allow unaligned/unpadded structs if desired. > Both C and C++ provide the standard macro offsetof() for determining > the offset of a data field from the beginning of the structure. Thus > you could directly access a byte buffer containing an instance of a > struct without overlaying a view of the struct on the buffer.
offsetof has limitations. Specifically, offsetof does not work on non-POD classes. Which was the first and only time to date I have needed it [1].
You also forgot about the implementation-dependent issue of endianness.
> So what? C++ has this feature called a "library" that, among other > things, allows you to use functions that you didn't write.
So does Java.
> Among the many "libraries" that are available for C++ there are ... > OMG! Garbage Collectors ?!? Not refcounting hacks ... real > collectors from names you might actually recognize - that is if you > know anything at all about GC.
Garbage collection is not built in, and I do recall there being some issues with garbage collection in C++, especially when you do large, multithreaded programs. One program I worked on attempted to convert from refcounting to garbage collection and failed.
> There are languages that offer power fully equivalent to C++ but which > are cleaner, safer and easier to use. Some of them are OO, some are > functional. Almost all have built-in GC.
> Java is not among them.
All I am trying to say is that a language doesn't need to do everything. Also, if such languages exist, why does almost no one use them?
[1] Specifically, I was trying to write a C++ bridge library for dynamic interlanguage trampolining, and needed offsets to the fields of a class, so my use case totally involves non-POD classes.
-- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald E. Knuth
On 2010-10-21 13:11:39 +0100, Joshua Cranmer said:
> In any case, I have found little reason to do this, even in C or C++. > About the closest I can think of is mmap'ing binary files for > performance--nio can do that--or perhaps easier binary I/O, in which > case Java's Object{Input,Output}Stream is sufficient for my > serialization needs.
I think you really do need this kind of get-at-an-arbitrary-location-in-memory to do a lot of low-level things like device drivers &c. Neither Java nor Common Lisp support that sort of thing without non-standard extensions as far as I know (well, I know CL does not, and I think I know Java does not).
On Oct 21, 2:51 pm, Tim Bradshaw <t...@tfeb.org> wrote:
> On 2010-10-21 13:11:39 +0100, Joshua Cranmer said:
> > In any case, I have found little reason to do this, even in C or C++. > > About the closest I can think of is mmap'ing binary files for > > performance--nio can do that--or perhaps easier binary I/O, in which > > case Java's Object{Input,Output}Stream is sufficient for my > > serialization needs.
> I think you really do need this kind of > get-at-an-arbitrary-location-in-memory to do a lot of low-level things > like device drivers &c. Neither Java nor Common Lisp support that sort > of thing without non-standard extensions as far as I know (well, I know > CL does not, and I think I know Java does not).
I fail to see why device drivers & co. are considered by C++ folks as a common and fundamental enough problem to have the language heavily adapt to it, while, e.g., multithreading is not. If I need to program a device driver, I'd expect to use a specialized language for writing device drivers. C might still be considered as one, but C++ is "sold" as a general-purpose OO language... So for the sake of "efficiency" C++ is an extremely static language, everything is decided in advance, and the result of compilation is a solid block of stone. GC is theoretically possible, but the language does not require it, and code is rarely written with a GC in mind. The result is complexity beyond any other language known to man, because you have to carefully explain to the compiler *everything* that's required to know statically in order to translate all those "high- level" concepts to a solid block of stone. That's the cause for the utter madness that are templates, the severely leaky abstractions in the OO system, the absurdly long compilation times and incomprehensible error messages, among other things. Oh, and C++0x is going to add *more* complexity.
Java is syntactically in the C/C++ family, but it follows a pretty different philosophy. While certainly limiting expressiveness in some situations, and requiring definitely too much verbosity in others, it is far more dynamic than most people think. It has GC, some form of runtime typing, dynamic code loading, poor man's closures, reflection... In that regard, Gosling's sentence about Java bringing C+ + programmers halfway to Lisp is not far off.
Joshua Cranmer <Pidgeo...@verizon.invalid> writes: > How can Java be more powerful than what its host system provides? You > could probably do nio on /dev/mem, e.g., for Linux, though.
Define 'powerful'!
My answer is: - emergent properties, - turing equivalence, - virtual machine.
That is, mostly: do not care what occurs on the host. You can write any power inside the VM.
Of course, if your definition of power is to use the raw hardware, then you should go to assembly, or C.
But if you accept to abstract things away a little, then any Turing Equivalent VM can be more powerful, in the sense that it will let you write more efficiently programs that are more expressive and more able than anything you could do on bare hardware or with crude tools such as C or C++.
>> Among the many "libraries" that are available for C++ there are ... >> OMG! Garbage Collectors ?!? Not refcounting hacks ... real >> collectors from names you might actually recognize - that is if you >> know anything at all about GC.
> Garbage collection is not built in, and I do recall there being some > issues with garbage collection in C++, especially when you do large, > multithreaded programs. One program I worked on attempted to convert > from refcounting to garbage collection and failed.
One of the most problematic aspects of C++, is that since it's an unfinished programming language, each project defines its own programming "conventions", in effect, defines its own programming language, and thus may produce libraries that are in practice incompatible with others.
In the specific case of memory management, it may be very difficult or even impossible to mix and match objects obtained from different libraries.
Tim Bradshaw <t...@tfeb.org> writes: > On 2010-10-21 13:11:39 +0100, Joshua Cranmer said:
>> In any case, I have found little reason to do this, even in C or >> C++. About the closest I can think of is mmap'ing binary files for >> performance--nio can do that--or perhaps easier binary I/O, in which >> case Java's Object{Input,Output}Stream is sufficient for my >> serialization needs.
> I think you really do need this kind of > get-at-an-arbitrary-location-in-memory to do a lot of low-level things > like device drivers &c. Neither Java nor Common Lisp support that > sort of thing without non-standard extensions as far as I know (well, > I know CL does not, and I think I know Java does not).
But neither do C or C++ either. Since you have to add implementation specific extensions anyways, you can as well add them to a Common Lisp implementation!
On 2010-10-21 14:50:53 +0100, Pascal J. Bourguignon said:
> But neither do C or C++ either. Since you have to add implementation > specific extensions anyways, you can as well add them to a Common Lisp > implementation!
I'm pretty sure that in C you can write code which is "essentially legal" which on a known platform will let you get at specific memory locations. ("essentially legal" because I bet there are restrictions on dereferencing pointers to memory you did not allocate and so on, but in practice compilers can't spot this and don't complain). Obviously that code is not portable, but it doesn't need to be.
However, I definitely was not trying to argue that this is a good reason for using C rather than CL or Java in almost all cases!
Alessio Stalla <alessiosta...@gmail.com> writes: > reflection... In that regard, Gosling's sentence about Java bringing C+ > + programmers halfway to Lisp is not far off.
> Not implying I am a great result of my education, but in my case it was > more: > - Theory of abstract classes and polymorphism, pseudo-language and > trivial design patterns. > - UML > - C++ > - And /then/, Java.
On 21 out, 15:48, Petter Gustad <newsmailco...@gustad.com> wrote:
> Alessio Stalla <alessiosta...@gmail.com> writes: > > reflection... In that regard, Gosling's sentence about Java bringing C+ > > + programmers halfway to Lisp is not far off.
> > Not implying I am a great result of my education, but in my case it was > > more: > > - Theory of abstract classes and polymorphism, pseudo-language and > > trivial design patterns. > > - UML > > - C++ > > - And /then/, Java.
On Thu, 21 Oct 2010 08:11:39 -0400, Joshua Cranmer wrote: > On 10/21/2010 02:58 AM, George Neuner wrote: >> What Java lacks that limits its utility with respect to C or C++ is the >> ability to overlay a logical view of structured data at an arbitrary >> memory location. This ability is the single feature of C and C++ which >> makes them strictly more powerful than Java.
> This doesn't work as well in C/C++ as you think. Specifically, in:
> union { > int a; > double b; > } x;
> x.a = 5;
> The value of double is undefined. And let's not get into type punning.
Spot on. If you're using unions to remap an area then you're misusing them.
The intention, as I understand it, of the union was a sort of polymorphism that would allow an array or list of structs to be built with one or more common fields in the struct together with a union of other structs and/or data types. One of the common fields says what member of the union is being used in this instance of the container struct.
The only HLL where memory remapping works as you would expect is COBOL, and even there its only really useful if the REDEFINES all map onto a character string and all the definitions have the same length. If you try to do anything else you get tripped up by the alignment requirements of COMPUTATIONAL data items and end up confusing the hell out of any poor sod who has to maintain the mess.
-- martin@ | Martin Gregorie gregorie. | Essex, UK org |
On 21 Ott, 21:05, namekuseijin <namekusei...@gmail.com> wrote:
> On 21 out, 15:48, Petter Gustad <newsmailco...@gustad.com> wrote:
> > Alessio Stalla <alessiosta...@gmail.com> writes: > > > reflection... In that regard, Gosling's sentence about Java bringing C+ > > > + programmers halfway to Lisp is not far off.
> > Wasn't that Steele?
> yes, about Gosling's Mocklisp... ;)
Ok, sorry, I misquoted. But the meaning of the sentence remains true.