Reputation
4,067
Top tag
Next privilege 5,000 Rep.
Approve tag wiki edits
Badges
7 16
Newest
 Talkative
Impact
~300k people reached

  • 0 posts edited
  • 0 helpful flags
  • 173 votes cast
Aug
7
comment Storing the EOF (End of File) character in a char type
@delnan: The linked article isn't quite right about how Unix treats control-D. It doesn't close the input stream; it merely causes any fread() which is blocking on the console to return immediately with any as-yet-unread data. Many programs interpret a zero-byte return from fread() as indicating EOF, but the file will in fact remain open and able to supply more input.
Aug
7
comment What exactly makes the Haskell type system so revered (vs say, Java)?
@PaulDraper: BTW, I'd also include a protected "makeEquivalentTo(object target)` method whose base implementation would confirm that the target was of the exact same type as this, and which would instruct the GC that some or all of the references to one of the objects may be replaced with references to the other at any time the GC finds convenient, and such replacement would likely improve performance. If two separately-constructed thousand-character strings are compared once and found to be equal, it should be possible to recognize them as such forevermore without rescanning them.
Aug
7
comment What exactly makes the Haskell type system so revered (vs say, Java)?
@PaulDraper: If I were designing a language/framework, I would require that every item define a universal "equality" relation and a universal "equivalence" relation; objects must report themselves equivalent to themselves, but objects could also report themselves equivalent to other objects (every object would include a protected method to determine whether a given reference identified it, and the default equivalence relation would chain to that). Such semantics would maintain referential transparency but still allow self-referential object graphs to be analyzed in finite time.
Aug
7
comment What exactly makes the Haskell type system so revered (vs say, Java)?
@J.Abrahamson: If one had a CD-ROM where a nested directory /foo/bar contained hard-link /foo/bar/next mapped to /foo, such a structure would be equivalent to having a directory /foo/bar/next which contained everything /foo contained except with /foo/bar/next/bar/next containing a either a link to /foo, a link to /foo/bar/next, or else containing another directory which was recursively like /foo, but there would be no way to tell whether /foo and /foo/bar/next were deeply equivalent without being able to identify directories. Could Haskell create or handle something analogous?
Aug
7
comment What exactly makes the Haskell type system so revered (vs say, Java)?
@J.Abrahamson: IMHO, the concept of null is essential in cases where references identify things. I wouldn't such a concept would generally be necessary in a language where references can only encapsulate things, though I suppose such a thing might be required if it's possible to have objects hold mutual references. Out of curiosity, is that possible in Haskell [the ability to create such structures would not be inconsistent with referential transparency, though I'm not sure how one would determine that sub-structures were equivalent].
Aug
7
comment When did Undefined Behavior in C jump the causality barrier
@rwong: Another thing to consider is that if code needs to compute y > 31 ? 0 : x << y, and y values will always be within a range where a processor's shift-left instruction will yield that in an acceptable time frame [e.g. most ARM processors will do a single-cycle instruction to compute (y & 255) > 31 ? 0 : x << (y & 31)], the most useful thing the compiler can do is simply have x << y generate the shift instruction.
Aug
7
comment When did Undefined Behavior in C jump the causality barrier
@rwong: On the INMOS Transputer, computing x << -1 would stall the bus for 4294967296 cycles, and I doubt it was the first machine were that could happen. While it might have been possible for the Standard to say that compilers may arbitrarily mod-reduce the shift amount to any multiple of the word size and/or any power-of-two value larger than the word size, and say that values which are negative or excessively large may cause problems, such excessive detail wouldn't matter if not for an attitude compiler writers seem to have acquired around 2009.
Aug
7
comment What exactly makes the Haskell type system so revered (vs say, Java)?
@ChristianConkle: By the sound of it, Haskell favors the "encapsulation" semantic, as compared with the "identification" semantic favored by Java and .NET; does Haskell have a linguistic distinction between references that encapsulate versus identify things?
Aug
7
comment What exactly makes the Haskell type system so revered (vs say, Java)?
@ChristianConkle: I'm not familiar with Haskell, but I often find myself wishing that Java and .NET made a distinction between references that are used to encapsulate objects and those which identify them. References that encapsulate immutable objects should interpret null as a default object; those that encapsulate mutable objects should interpret null as a need to lazily-create an object. References that identify mutable objects should interpret null as not identifying any object; it's generally not necessary to identify immutable objects.
Aug
7
comment What exactly makes the Haskell type system so revered (vs say, Java)?
@PaulDraper: If a language has persistable pointers, there are going to exist times when a pointer exists but there is nothing useful it can identify. While one could design a language that would enforce the "Null Object Pattern" [create a useless dummy object and make what would be null pointers point to that instead] or auto-implement the lazy-creation pattern [implied by VB6 "Dim Foo as New Bar" syntax], both behaviors are prone to mask problems which would have been caught by a system that traps null dereferences.
Aug
7
comment Storing the EOF (End of File) character in a char type
...(unsigned char)y > 31 ? 0 : x << (unsigned char)y and doesn't care which, writing the expression the former way will make execution needlessly slow on ARM processors, and writing it the latter way will make it needlessly slow on x86 processors; if, as was historically the case on 99% of compilers, x << y meant "Generate whichever of the above expressions would be more convenient in any given case", that would allow compilers for both platforms to generate optimal code.)
Aug
7
comment Storing the EOF (End of File) character in a char type
...in cases where untrapped overflows would cause a program to produce incorrect results that might e.g. cause an engineer to erroneously believe a building would be strong enough to withstand its intended loads. Different programs have different requirements with regard to their handling of invalid inputs, and one of the reasons C could thrive was that different compilers could strike their own compromises between predictability and efficiency. Today, alas, the prevailing philosophy is that both should be thrown out the window (if code needs to compute either x << (y & 31) or...
Aug
7
comment Storing the EOF (End of File) character in a char type
...would consistently raise a signal in such cases. Since the Standard requires that implementations either yield a consistent mapping or consistently raise a signal, the only platforms where the Standard would leave room for something other than two's-complement reduction would be things like DSPs with saturating-arithmetic hardware. As for the historical basis for Undefined Behavior, I would say that the issue isn't just with hardware platforms. Even on a platform where overflow would behave in a very consistent fashion, it may be useful to have a compiler trap it...
Aug
7
comment Storing the EOF (End of File) character in a char type
Historically, the intention of the Standard was mostly as you describe, though the Standard describes some behaviors in sufficient detail as to require compilers for some common platforms to generate more code than would be required under a looser specification. The type coercion in int i=129; signed char c=i; is one such behavior. Relatively few processors have an instruction that would make c equal i when it's in the range -127 to +127 and would yield any consistent mapping of other values of i to values in the range -128 to +127 that differed from two's-complement reduction, or...
Aug
6
comment Has variable width types been replaced by fixed types in modern C?
Additionally, the Standard could also define types whose storage and aliasing were compatible with intN_t and uintN_t, and whose defined behaviors would be consistent with intN_t and uintN_t, but which would grant compilers some freedom in case code assigned values outside their range [allowing semantics similar to those that were perhaps intended for uint_least32_t, but without uncertainties like whether adding a uint_least16_t and an int32_t would yield a signed or usnigned result.
Aug
6
comment Has variable width types been replaced by fixed types in modern C?
A problem with types like uint_least32_t is that their interactions with other types are even more weakly specified than those of uint32_t. IMHO, the Standard should define types like uwrap32_t and unum32_t, with the semantics that any compiler which defines type uwrap32_t, must promote as an unsigned type in essentially the same cases as it would be promoted if int were 32 bits, and any compiler which defines type unum32_t must ensure that basic arithmetic promotions always convert it to a signed type capable of holding its value.
Aug
6
comment Storing the EOF (End of File) character in a char type
...I would regard such coercion as being reliable (not to say that code shouldn't document its intentions, but that (signed char)x is should be considered clearer and just as safe as ((unsigned char)x ^ CHAR_MAX+1))-(CHAR_MAX+1).) As it is, I don't see any likelihood of compilers implementing any other behavior complying with today's standard; the one danger would be that the Standard might be changed to break the behavior in the supposed interest of "optimization".
Aug
6
comment Storing the EOF (End of File) character in a char type
Coercing to type char values outside the range CHAR_MIN..CHAR_MAX will is required to either yield an Implementation-Defined value, yield a bit pattern which the implementation defines as a trap representation, or raise an implementation-defined signal. In most cases, implementations would have to go through a lot of extra work to do anything other than two's-complement reduction. If people on the Standards Committee subscribed to the idea that compilers should be encouraged to implement behaviors consistent with that of most other compilers in the absence of reasons to do otherwise...
Aug
6
comment Why C language is taught as the basis of Computer Programming Languages?
...(x<<y) | (x >> (32-y)), the days of C as a usable language will be numbered. If students are taught that there are different dialects of C, code using features common to 99% of dialects prior to 2009 can often yield better performance than not using such features, but that writing code in clunky and hard-to-read fashion will make it compatible with hyper-modern compilers that promise to make it faster but in some cases might not be able to achieve even 2009-level performance, then the language might be able to recover from such insanity.
Aug
6
comment Why C language is taught as the basis of Computer Programming Languages?
C is a family of dialects which feature different trade-offs between the cost of providing different features or guarantees and the value to programmers of those features or guarantees. The Standard specifies a rather anemic common core, but historically 99% of compilers have supported certain behavioral guarantees beyond those required by the Standard, and until 2009 I don't think there was any reason to believe that such guarantees would not continue to be treated as normative. If too many students are taught that respectable compilers require (x<<y) | (x >> (31-y) >> 1) rather than...