7 ms·
Exactly this. Pascal was a great language, and I wonder how much we've lost by having it go by the wayside. It was strongly-typed, easy to read, cross-platform
by ccleve 5y ago
Exactly this.
Pascal was a great language, and I wonder how much we've lost by having it go by the wayside. It was strongly-typed, easy to read, cross-platform, produced native executables, and was lightning fast to compile and execute.
I say "was" a great language because it isn't widely used today. I miss it.
- qalmakka 5y agoAlso it had sane strings. Strings with sizes, withouth the whole null-terminated madness of C which still haunts us nowadays.
- jstimpfle 5y ago"Sane" strings that may waste 4 bytes of length field for unnecessary count, or may have a 1 or 2 bytes length field that proves to be insufficient. Or "sane" strings that alloc and dealloc and refcount like mad, bringing the application to a stall. "Sane" strings that discourage the developer from just coming up with a simple memory management scheme that fits the situation at hand. "Sane" strings that lead to incredible bloat and incompatibility, because there is no one true "sane" string type, so every module that doesn't know better forces their own way onto the user.
- nwiswell 5y agoObviously C-style strings can still remain an option where they are needed, but in most cases using the 4 bytes for a length field is a sane default. How many buffer overflow attacks have been enabled by that four byte savings over the years? > "Sane" strings that discourage the developer from just coming up with a simple memory management scheme that fits the situation at hand. "Sane" compilers that discourage the developer from considering the machine level instructions. It's turtles all the way down. There's a reason that Python is so popular and it's not performance
- jstimpfle 5y agoThis is not Python so that's a strawman.
- nwiswell 5y agoBy that I meant that there is obviously value in abstracting away tasks and details that the programmer would otherwise need to manage. That is why compilers exist. The value-add for abstracting a string is certainly more than the cost of 4 bytes of memory in the typical case. Put another way: optimizing the management of strings in memory is almost never the best use of time to make progress toward an organization's objectives, and doubly so when that kind of micro-tuning can actually introduce security risks
- nerdponx 5y agoI hardly consider four bytes to track the length of a string "waste". I also don't really know why you assume that "sane" means "doesn't let you manage memory effectively". That said, how many applications really are bottlenecked by string processing in the first place? I don't care if processing Unicode graphemes is slow, as long as it's correct and doesn't mangle users' names.
- novok 5y agoHe is probably thinking about the context of the 1980s, when a large amount of 3 byte waste (the 1 byte null char is a form of 'waste' itself) might have been a problem back then.
- jstimpfle 5y agoPacked structs with char fields of 8 bytes or so are still common.
- jstimpfle 5y agoWell I for one optimized an authorization module of an enterprise application written in Delphi by getting rid of standard library strings. Speedups where 100x-1000x, accelerating application startup time from minutes to maybe 3 seconds.
- johnfn 5y agoThe thing is, not every developer wants to care about memory management. A lot of us just want to solve user problems, and we don’t mind too much if we spend a couple of extra bytes to do so.
- jstimpfle 5y agoIt's not primarily about the bytes. Heap allocating RAII style strings can absolutely kill performance. And they are baaaad for modularity. It's all in my OP, why do I even repeat?
- Jtsummers 5y agoIf the length field is 4 bytes then only 3 bytes are "wasted" compared to C with its null-terminated strings and 1-byte chars. The difference drops if you have wider character types. Not to mention the time saved not having to scan every string to determine its length. I always find it weird when people fret about bytes but not cycles, especially cycles that have to be spent waiting for memory reads.
- yongjik 5y agoYou are thinking as a developer in 2020s, not one in 1990s (or earlier). Memory was incredibly precious: 16-bit x86 had 64KB segments, so if your data didn't fit in, it would be a lot slower. People used nibbles (4 bits) because the extra instructions dealing with bit twiddling was worth the cost. Basically, no sane programmer in the 90s would be happy with a string type that wasted three bytes per object.
- Jtsummers 5y agoCPU cycles were also incredibly precious. It's a tradeoff. In the 80s and 90s you also had smaller caches so iterating over a string to determine its length was more expensive (more likely to hit RAM) than "just" reading its length parameter and carrying on with your life.
- yongjik 5y agoSure everything was more expensive, but not by the same factor. Main memory was smaller but also relatively faster compared to CPU. Search for "386 simm memory" and you'll see 60ns modules. Considering that 386 debuted with 12MHz clock, 60 ns is faster than one CPU clock cycle! In other words, "reading the whole string from memory" could be a performance problem, but a less serious problem for machines of those days, compared to using a few more bytes to store the length.
- pjmlp 5y agoYet JOVIAL, NEWP, PL/I, PL/S, PL.8 among other Algol dialects managed it.
- mdip 5y agoThis never, ever bit me in the Pascal days. I suspect this was primarily because the stack I was using was either "provided by the Borland Pascal standard library" pieces, or it was my own Pascal or assembler code. I had a limited number of calls into a library and a need to do a few things that escape me with regard to interacting with -- I think -- an 16550 UART[0] and its driver, but I don't recall them being particularly nasty to deal with. I mean, all things relative -- I was expecting these to be nasty to deal with because they often involved inline assembler, so the problem of "making it behave with the string" wasn't quite as pressing as "what the hell am I actually doing here?" :) [0] My huge project was a bulletin board system in the 90s.
- kaba0 5y agoHow is iterating over the string each time you want to do anything meaningful better? Also, there is a short string optimization, where you can store the string inside the pointer , eg. c++ does just that.
- jstimpfle 5y agoYou didn't read my comment right. My statement is there isn't one true string type. I didn't say you shouldn't use a length field. Zero terminated strings still make some sense of course - ease of reading when looking at byte level representation, and moderate cost savings in packed structs (4, 8, or 16 byte strings). The former is why I zero terminate by default where possible, even when using a separate length field stored somewhere else (almost always).
- adrianmsmith 5y agoI don't know the details but I doubt that 4 bytes would be used for a length of a string in the 90s. 2 bytes would lead to 64k characters which is surely more than you'd need for the average string. And surely if you malloc(..) a block of memory in C and store a string in it, the memory allocation system is going to store how large a block that is anyway (even if it isn't visible to either C or Pascal probably.) I know not all strings will be malloc'd but a lot will be. And we seemed to deal with this overhead fine in the 90s?
- jstimpfle 5y agoThat you have to weigh 2 vs. 4 byte lengths is exactly making my point. There is also a case for 1 byte lengths, and for string implementations other than length + pointer, like for example rope datastructure implementations. My point is that there is not one sensible string implementation, and acting like there was is in many situations trading short term convenience for long term pains in larger projects. > I know not all strings will be malloc'd but a lot will be. And we seemed to deal with this overhead fine in the 90s? It's a common but deeply flawed assumption that allocations and lifetimes are so random that every little object should be individually allocated and later deallocated with malloc()/free() or with another generic allocator. I don't use malloc() to allocate string buffers - except in rare situtations of laziness, knowing it will come back to bite me later. Not only performance concerns but also the practical impossibility of matching each malloc() with a free() forbids that. Systems like RAII come to help to solve the latter issue, but I prefer to take the difficulty of matching everything up as an indication that the general approach is too complicated. Instead I recommend to allocate strings using a fixed field (eg. char buf[16]) on a stack frame, or using a member in a struct, in order not to add any management overhead. Alternatively, for unbounded and dynamically sized strings, it's often a good idea to allocate them using linear allocators. For example, in a GUI renderer, it's a good idea to have a per-frame allocator that collects all allocations in a list of larger chunks, to minimize the allocation overhead to a few chunks (KBs to MBs) that were individually allocated from the system. With this, everything is freed using a single central function call after the frame was renderered and the data is now not needed any longer.
- pjmlp 5y agoLanguages 10 years older than C have proper strings, in a certain sense there are some design decisions common to Go and C, regarding adoption of common features.
- masklinn 5y ago> Also it had sane strings. Strings with sizes Except they were prefixes on the buffer which was bad and not sane, and greatly limited the size of the original pascal strings. And technically they were UCSD strings, not standard pascal, and other implementations used e.g. padded strings.
- teeray 5y ago> strongly-typed, easy to read, cross-platform, produced native executables, and was lightning fast to compile and execute. Sounds like Go
- doodpants 5y agoExcept that Go is for command line programs and backend code; its standard library doesn't include a cross-platform GUI API for desktop applications.
- zamadatix 5y agoWhat was the stdlib's cross platform GUI like in Pascal?
- codr7 5y agoProbably could have been awesome, the Windows flavor certainly was; but they dropped Kylix before it got a chance to go anywhere.
- Tozen 5y agoYou might want to look at Delphi's VLC and FireMonkey. With Free Pascal/Lazarus, they have the LCL (open source equivalent to VLC). Free Pascal/Lazarus has no problem with Linux or macOS. It was Delphi that stumbled around for some years about this, but presently can also be installed now on both. Of course, Delphi cost the big bucks.
- thriftwy 5y agoOn the other hand, it was verbose, and most of original Pascal ideas were unsound and replaced in Object Pascal with ones coming from C. "Break loop" being a function rather than keyword is serious PHP land. It had better OO than C++, though. I admit it, they managed to have a sane and compact statically checked compilable OO.
- Tozen 5y agoSeems like you are a bit mistaken, as Object Pascal borrowed very little from C, nor did it need to. Object Pascal is just an extension of Pascal. Objects and Classes are just another type, just like Records. The relationship between Pascal and Object Pascal is extremely close, far more than say between C and C++. Which is why many get confused, thinking there is such a similar gap. OO in Object Pascal is a lot more sane than in C++, because the concept of an Object was more aligned to the existing Record type. It would be something like taking C and empowering its structs with methods. There wasn't an attempt to make radical changes, but simply extend the language with OO. Where with C++, in comparison to C, much more fundamental changes were made that created more conflicts in how the languages are used.
- pjmlp 5y agoAt least in Germany it is still used enough to have a presence on some magazines, and there is an yearly conference.
- visarga 5y agoI used Pascal between 1992 and 2000, one thing I missed a lot was dynamic lists and dictionaries. It was so hard to develop everything with pointers and allocations, so fragile.