Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On Sat, Oct 14, 2017 at 10:16 PM, Ben Bacarissewrote: > "Peter J. Holzer" writes: >> Which probably boils down to the question: Why did providers offer PHP >> and not Python? One reason might be that at the time no suitable web >> framework for Python existed (Zope was released in 1999, and I remember >> it to be rather heavy-weight). One reason might be that providers didn't >> see PHP as a "real" programming language and therefore deemed it >> safer. > > That would be deeply ironic, given the security pain that it has turned > out to be! Yup. And not exactly surprising to any security expert. The history of computing - well, let's face it, the history of mankind - is littered with stories of "this is simple and easy, we don't need to secure it" turning into "this is actually a major problem". Sometimes we can retrofit enough protection onto the system without fundamentally breaking it (eg DNS, where a variety of forms of security have been added); other times, we learn a new best-prac and keep going (eg parameterized queries rather than risking SQL injection, which some people still haven't learned, but a lot have); and other times, we scrap the bad option and start a completely new way of doing things (bye bye Java applets, bye bye Flash, let's do everything with JS), which of course isn't necessarily perfect either, but is usually a big enough advantage to be worth it. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, Oct 14, 2017 at 10:12 PM, Steve D'Apranowrote: > But be reasonable, I had just asked almost exactly the same question not one > line earlier: > > "If it's read-only, how can the compiler write to it?" > > and (as far as I can see) *nobody* thought to actually answer my question > until perhaps a dozen posts later, when Chris more-or-less said: > > - the compiler doesn't, but the program loader does; > > - its not so much read-only memory as write-protected memory: > privileged code can still write to it. > > > (Have I got the details right? Or at least close enough?) Pretty close. There's a lot of levels of indirection involved. When a program asks to manipulate a piece of memory, it uses a segment selector and a memory location (offset); in most modern systems, a flat memory model is used, where all identical offsets mean the same piece of memory, so we tend to think of the offset as being the entire pointer. Those segment selectors refer to something in the segment table for *that process*. That means that location 0x12345678 in my process could be a completely different hunk of memory to location 0x12345678 in your process. (It's also possible that they're the same - loading shared modules (DLL/SO) often just means mapping an already-loaded block of memory into your process.) Your process is completely unaware of any memory that it doesn't have access to. It also has no way to violate the notion of "read-only", because that's a flag set on the memory pages in that process's page table. So when the program loader goes to work, it loads up a page of memory from the disk, then grants this process read-only access to it, by mapping that page into the process's memory space. The program loader, being part of the kernel, isn't just "privileged" in the sense of running as root/Administrator - it is the one that determines what "root" even means. If root is able to manipulate a process's page tables, it's only via kernel APIs. As such, the concept of "read-only" is actually hard-wired in the process's memory map. There's no way to violate that. (I may have some details wrong, as it's a long time since I've worked with any of this. Also, this is massively simplified. But I think it's about right.) > [...] >> Therefore I consider the phrasing "the >> compiler puts it into read-only memory", while certainly sloppy and not >> technically correct, perfectly comprehensible. > > And here we go again. Instead of holding the author responsible for the poor > phrasing, the reader is blamed for not somehow inferring the author's > intended meaning. > > "Somebody misunderstood Greg's sloppy and incorrect words to mean something > Greg didn't intend? And when given the opportunity to clarify, Greg failed to > do so and continued using the sloppy and incorrect phrasing? Oh, that's not > Greg's fault, it is the fault of the reader for not reading Greg's mind and > knowing what he really meant. I shall continue to defend the choice of words > which are LITERALLY WRONG rather than accept that somebody might have > legitimately misunderstood them." Saying that the compiler puts something into read-only memory is skipping a lot of steps in the procedure - notably, it's making a temporal jump right from compilation time to run time. Obviously the data is in some form of read/write storage in between (eg a hard drive), during which it can very well be mutated. So it's somewhat defensible to consider that the compiler sorta-kinda places things into the run-time process's memory (since the compiler (or the linker) is what instructs the program loader how to arrange the process memory tables), while still being reasonable to argue that, since the compiler is writing to it, it must be read/write (which it is - in the compiler's memory space). The distinction here is that there's been a change in POV; each time, we're talking from the POV of the current process, but that's a different process (compiler vs running program). >> And I can't find anything >> wrong with his revised phrasing "arrange for it to be in a location that >> is read-only at run time". That's exactly what the compiler does. > > Except *read-only* is a misleading and poor way to describe it and it too is > LITERALLY WRONG. The program loader can write to it, and does so every single > time a program is run. Why is it called read-only when it isn't read-only or > even Write Once Read Many? It *is* read-only, from the POV of the running process. Nothing (other than actual burned ROM) is truly read-only; possibly the flashable BIOS is read-only from the POV of a running system, but I'm not even sure of that. From the POV of the kernel, all RAM is read/write (I think; there might be some exceptions, but certainly everything we're looking at here is); from the POV of various processes, large slabs of memory are read-only. > I am sure that nobody, including Greg and yourself, would describe /root on a > standard
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
"Peter J. Holzer"writes: > On 2017-10-13 21:42, Ben Bacarisse wrote: >> That's one way to put it. Another is that to use Python I need to buy a >> new service that is already configured. > > That's exactly the same for PHP. You can't use that either unless > somebody configured to server to use it. I was not using "I" generically. *I* don't need to buy a service configured to use PHP because: > The difference is that lots of providers started configuring their > servers for use of PHP in the late 1990s, but didn't do that for Python. > >> If that's the way it's done, fine, but this sub-thread started with >> someone being surprised by the success of PHP. > > Which probably boils down to the question: Why did providers offer PHP > and not Python? One reason might be that at the time no suitable web > framework for Python existed (Zope was released in 1999, and I remember > it to be rather heavy-weight). One reason might be that providers didn't > see PHP as a "real" programming language and therefore deemed it > safer. That would be deeply ironic, given the security pain that it has turned out to be! -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, 14 Oct 2017 08:26 pm, Peter J. Holzer wrote: > On 2017-10-14 01:05, Steve D'Apranowrote: >> In context, we are talking about a computer program (the compiler) writing >> data to memory. > > No, I don't think so. You keep talking about that, even though Gregory > hasn't used those exact words and has since clarfified that he didn't > mean it that way. But without clarifying what he meant. I've had to piece that together from bits and pieces of random comments from other people. I still don't know exactly what Greg intended to say, only what I have inferred. Initially Greg said: "If the compiler can tell where p is initially pointing, it could put the pointer in read-only memory." and when I asked: "If it's read-only, how can the compiler write to it?" instead of clarifying what he meant, Greg defended his misleading choice of words with: "So, the factory is allowed to write to it. Possibly it's writing data that came from... a compiler?" So Greg himself has used the term "write" to describe the scenario he describes, it is not just me. It has taken, what, I guess something like a dozen or more back and forward posts before Chris happened to casually mention that the *program loader* (not compiler!) writes the data to *write-protected memory* (not ROM). If only people had said that in the first place, instead of reinforcing my misunderstanding by arguing whether or not the act of etching paths into a silicon chip at a factory counts as the compiler writing. We're all human and we all sometimes use sloppy phrasing. I know I do. But the least we can do is try to be more aware of when we're causing more confusion than insight, and instead of doubling down and defending the sloppy phrasing, try to explain what we mean. > Y'know, I'm all for writing as carefully und > unambiguously as possible and for discussing questionable wording > (especially in a large forum where many (including me) will have a > different native language), but we all are sloppy in our writing every > now and then and insisting that somebody must have meant X' because they > wrote X doesn't really help and gets boring pretty soon. The problem is not the initial miscommunication. The problem is the insistence on defending that miscommunication even in the face of confusion. Right from my first comment on this topic, I said: "I come from the days when ROM was actual ROM, burned in at the factory." because I already suspected that Greg was using "read-only" to mean something other than read-only, but what I did not know. Now maybe I could have been more explicit by asking "What the hell do you mean by read-only memory, if you're not talking about actual ROM?" and the fact that I didn't is *my* failure. (Mea culpa.) But be reasonable, I had just asked almost exactly the same question not one line earlier: "If it's read-only, how can the compiler write to it?" and (as far as I can see) *nobody* thought to actually answer my question until perhaps a dozen posts later, when Chris more-or-less said: - the compiler doesn't, but the program loader does; - its not so much read-only memory as write-protected memory: privileged code can still write to it. (Have I got the details right? Or at least close enough?) [...] > Therefore I consider the phrasing "the > compiler puts it into read-only memory", while certainly sloppy and not > technically correct, perfectly comprehensible. And here we go again. Instead of holding the author responsible for the poor phrasing, the reader is blamed for not somehow inferring the author's intended meaning. "Somebody misunderstood Greg's sloppy and incorrect words to mean something Greg didn't intend? And when given the opportunity to clarify, Greg failed to do so and continued using the sloppy and incorrect phrasing? Oh, that's not Greg's fault, it is the fault of the reader for not reading Greg's mind and knowing what he really meant. I shall continue to defend the choice of words which are LITERALLY WRONG rather than accept that somebody might have legitimately misunderstood them." > And I can't find anything > wrong with his revised phrasing "arrange for it to be in a location that > is read-only at run time". That's exactly what the compiler does. Except *read-only* is a misleading and poor way to describe it and it too is LITERALLY WRONG. The program loader can write to it, and does so every single time a program is run. Why is it called read-only when it isn't read-only or even Write Once Read Many? I am sure that nobody, including Greg and yourself, would describe /root on a standard Linux/Unix system as "a read only directory" just because non-root processes can't write to it. You'd probably describe it as write-protected, or similar terminology. And if somebody asked "How is it read-only, root can write to it?" I surely hope you wouldn't double-down and insist that, no, it really, truly is
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On Sat, 14 Oct 2017 11:41:08 +0200, Peter J. Holzer wrote: > On 2017-10-13 21:42, Ben Bacarissewrote: >> That's one way to put it. Another is that to use Python I need to buy >> a new service that is already configured. > > That's exactly the same for PHP. You can't use that either unless > somebody configured to server to use it. > > The difference is that lots of providers started configuring their > servers for use of PHP in the late 1990s, but didn't do that for Python. > >> If that's the way it's done, fine, but this sub-thread started with >> someone being surprised by the success of PHP. > > Which probably boils down to the question: Why did providers offer PHP > and not Python? One reason might be that at the time no suitable web > framework for Python existed (Zope was released in 1999, and I remember > it to be rather heavy-weight). One reason might be that providers didn't > see PHP as a "real" programming language and therefore deemed it safer. > > hp could it have been that it was simply a default Apache module installed by whatever version of Linux was being used by the host? -- PENGUINICITY!! -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On 2017-10-13 21:42, Ben Bacarissewrote: > That's one way to put it. Another is that to use Python I need to buy a > new service that is already configured. That's exactly the same for PHP. You can't use that either unless somebody configured to server to use it. The difference is that lots of providers started configuring their servers for use of PHP in the late 1990s, but didn't do that for Python. > If that's the way it's done, fine, but this sub-thread started with > someone being surprised by the success of PHP. Which probably boils down to the question: Why did providers offer PHP and not Python? One reason might be that at the time no suitable web framework for Python existed (Zope was released in 1999, and I remember it to be rather heavy-weight). One reason might be that providers didn't see PHP as a "real" programming language and therefore deemed it safer. hp -- _ | Peter J. Holzer| Fluch der elektronischen Textverarbeitung: |_|_) || Man feilt solange an seinen Text um, bis | | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr __/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-14 01:05, Steve D'Apranowrote: > On Sat, 14 Oct 2017 07:15 am, Peter J. Holzer wrote: >> On 2017-10-13 15:11, alister wrote: >>> On Sat, 14 Oct 2017 01:48:44 +1300, Gregory Ewing wrote: Steve D'Aprano wrote: > I wasn't questioning where the data came from, but how the compiler can > write to READ ONLY MEMORY which might not even be in the same continent > as the compiler that generated the code. I thought it would be fairly obvious that by "put it in read-only memory" I meant "arrange for it to be in a location that is read-only at run time". Obviously it can't be read-only at *compile* time, just as a physical ROM can't be read-only at manufacture time. >>> >>> oh yes it can >>> in the past for large quantitys the data in a ROM chip was part of the >>> chip etching mask (unless you consider a blank silicon wafer to be >>> "Programmable" by the etching process)rather than prom which used >>> programmable fuses or prom which could be erased by UV light (assuming >>> the chip was fitted with a window otherwise it was known as one time >>> programmable EPROM) >> >> He didn't say "programmable". He said that the is "not read-only". > > In context, we are talking about a computer program (the compiler) writing > data to memory. No, I don't think so. You keep talking about that, even though Gregory hasn't used those exact words and has since clarfified that he didn't mean it that way. Y'know, I'm all for writing as carefully und unambiguously as possible and for discussing questionable wording (especially in a large forum where many (including me) will have a different native language), but we all are sloppy in our writing every now and then and insisting that somebody must have meant X' because they wrote X doesn't really help and gets boring pretty soon. Right now I was replying to alister's claim that "yes [ROMs] can [be read-only at manufacture time]". That doesn't have anything with compilers. Where the information came from is irrelevant to the question whether ROMS are read-only during manufacture. Certainly they are not only read (I don't know if they are read at all, but I guess they are during quality control), but information is put onto them. I think that this process can be called "writing" (It's a lot closer to what has been called "writing" for the last few millenia than what happenes to a RAM chip during "writing"), but even that is a red herring as the word "write" wasn't actually used (only "read"). > Your example of writing on paper is a good one, but it argues *against* your > position, not for it. If you compile some code, then take a hex dump and > print it out: > > gcc program.c > xxd a.out | lp > > would you describe the process as "the compiler writes to the piece of paper"? No, but the printer does. And that means that the paper is not read-only. Which was the point of the exchange between Gregory and alister. The compiler isn't in the game any more. But there is a difference between printing the hex dump of the output of the compiler and loading it into memory to be executed. The latter is the intended purpose of the file. When a compile writes some data into the ".rodata" section of the file, the intention is that this data should be read-only at run-time. Therefore I consider the phrasing "the compiler puts it into read-only memory", while certainly sloppy and not technically correct, perfectly comprehensible. And I can't find anything wrong with his revised phrasing "arrange for it to be in a location that is read-only at run time". That's exactly what the compiler does. That the compiler doesn't actually have control over what happens to the file afterwards is immaterial. hp -- _ | Peter J. Holzer| Fluch der elektronischen Textverarbeitung: |_|_) || Man feilt solange an seinen Text um, bis | | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr __/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, Oct 14, 2017 at 2:46 PM, Steve D'Apranowrote: > On Fri, 13 Oct 2017 09:47 pm, Marko Rauhamaa wrote: > >> "Peter J. Holzer" : >> >>> On 2017-10-13 05:28, Gregory Ewing wrote: Not only does "byte" not always mean "8 bits", but "char" isn't always short for "character"... >>> >>> True. >> >> Well, it does, in my universe. That was cast in stone 10**-32 seconds >> after the Big Bang. > > You've never had char-grilled peppers? *wink* Yeah. They build character. *wink back* ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, 13 Oct 2017 09:47 pm, Marko Rauhamaa wrote: > "Peter J. Holzer": > >> On 2017-10-13 05:28, Gregory Ewing wrote: >>> Not only does "byte" not always mean "8 bits", but >>> "char" isn't always short for "character"... >> >> True. > > Well, it does, in my universe. That was cast in stone 10**-32 seconds > after the Big Bang. You've never had char-grilled peppers? *wink* -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-14, Gregory Ewingwrote: > >> I doubt that either process is in widespread usage any longer as >> most manufacturers no incorporate a way to update the firmware of a >> device > > Magnetic core technology died out long before that, due to > inability to build machines that simulated armies of ladies > with sewing needles! I interviewed at a company that was still making core memory in 1989. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, 14 Oct 2017 07:04 am, Peter J. Holzer wrote: > On 2017-10-13 15:28, Steve D'Apranowrote: >> On Sat, 14 Oct 2017 01:30 am, Chris Angelico wrote: It's just a technique, like greying out certain menu options - clicking them will do nothing, but you won't get an error message and you don't want to allow them anyway, risking more serious consequences. >>> >>> Even there, you often CAN get a report about the failure; clicking on >>> something that's disabled will cause a short beep, unless that's >>> disabled. Maybe you personally don't like that beep, and you'd rather >>> it be suppressed - but that's the end user's choice, NOT the >>> programmer's. "Errors should never pass silently, unless explicitly >>> silenced." >> >> Over 30 years since Apple first put out their user interface guidelines, >> and people still get the basics wrong. >> >> "Errors should never pass silently..." is excellent advise for programming, >> but not necessarily UIs. With a program, errors in the code represent bugs >> that should be fixed, and in principle we can remove the bugs one by one >> until there are none left, after which the program will be perfect. (Yeah, >> try not to laugh too much.) >> >> But in a UI, that will never be the case. Errors are not bugs, and can't be >> removed. > > It is also not a bug if - for example - a file cannot be opened, or is > malformed. But you have to tell the user what went wrong. Pretending > that all went well won't make the user happy (or at least that happyness > will be short-lived). I don't disagree with that -- I never said that ALL errors should pass silently. That would be silly. I said that UIs should be tolerant of *unimportant* errors. Being unable to open a file is clearly not unimportant. And besides, that's not really a UI error. Its either a programming error: say, the code tries to call open("filename", "t") or its an unavoidable environmental error (the file actually is corrupt, the disk is failing, the user doesn't have read permission for the file). Either case should be reported. >> All you can do is hope the user doesn't do it again, which they >> will. So UIs should follow a slightly different ideal: >> >> "Be tolerant of unimportant errors, and let them pass silently." > [...] >> Likewise, pressing the left arrow key when you are already at the start of >> the text should just silently remain at the start, not chastise the user. > [... other examples elided ...] >> But in fact, clicking a disabled button or menu item is not an error. > > If it is not an error, clearly the rule does not apply. Indeed. That was my position: since clicking a disable menu item is not an error, there's no need to treat it as an error. The action of disabling the menu item or the button is an explicit way of saying: temporary turn off the function of this item, and make clicking it harmless and once you have done so, there's no error condition to deal with because clicking it does nothing. > So it depends on > whether the action is an error or not (actually in the case of the > disabled button I would tend to think it is an error: I can't think of a > reason why anybody would intentionally click on a disabled button[1]). Why do they need a reason? Maybe they just like to click on things. Since clicking on disabled items is harmless, why elevate it to the state of an error? Maybe they're beginners to computers, and haven't yet learned the difference between active controls that respond when you click them, and inactive ones which do not respond. We all have to learn that, just as we learn which entities respond to voice control, and which do not: "Mummy, I'm thirsty, get me a glass of water please!" "Whiskers, I'm thirsty, get me a glass of water please!" The lack of response from the cat is enough to teach the user that asking your cat is not going to be effective, and the lack of any feedback from a disabled item likewise will quickly teach them that greyed out (disabled) items are inactive and don't respond to clicks. There's no need to treat it as an error and chastise the user, that just makes your program hostile and less usable. > Pressing the left arrow key when you are already at the start of the > line is good example. The user might expect the cursor to jump the end > of the previous line, I certainly do. But that's why I specified the beginning of the text, not the beginning of the line. There's no previous line to go back to. > so if your program doesn't do that you probably > should give some feedback. Or the user might just have pressed the key a > bit too long, then the cursor should just stop there ("vi has two modes: > One beeps a lot and the other doesn't"). Also known as "annoy the user" and "sensible" modes :-) -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. --
Re: Lies in education [was Re: The "loop and a half"]
On Sat, 14 Oct 2017 01:51 am, Chris Angelico wrote: > On Sat, Oct 14, 2017 at 1:32 AM, Steve D'Aprano >wrote: >> It seems to me that you're not talking about ROM at all, but ordinary RAM. >> Then what do you mean by "read only"? A block of memory with a flag that >> says "unprivileged processes are prohibited from writing here"? >> >> (That's also not a rhetorical question.) > > When I first learned about Protected Mode (as defined by the Intel > 80386 and used in OS/2), there was a real concept of read-only RAM. > The program loader would fetch up the executable file (data on the > disk) and construct its segments: code, data, and BSS/stack. The data, > BSS, and stack all end up as a single segment (data is what comes > straight off the disk, BSS is all zeroes initially, and stack is > uninitialized initially, but ultimately they're all read/write), and > code is in its own segment. When control is handed to the new process, > its segment table grants it read/write access to the data/stack > segment, but read-only access to its code segment. > Within that > process, the code really truly is read-only, unless some magic is > done. So... not actually read-only then? You have the program loader writing to it, repeatedly, every time you load a program. And even the unprivileged program itself can write to it, if it knows the correct incantation to use. So its more like Read/Write Memory, or as we normally call it, memory. You know, an awful lot of confusion could have been avoided if people had referred to write-protected memory as write-protected rather than read-only. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, 14 Oct 2017 07:15 am, Peter J. Holzer wrote: > On 2017-10-13 15:11, alisterwrote: >> On Sat, 14 Oct 2017 01:48:44 +1300, Gregory Ewing wrote: >>> Steve D'Aprano wrote: I wasn't questioning where the data came from, but how the compiler can write to READ ONLY MEMORY which might not even be in the same continent as the compiler that generated the code. >>> >>> I thought it would be fairly obvious that by "put it in read-only >>> memory" I meant "arrange for it to be in a location that is read-only at >>> run time". Obviously it can't be read-only at *compile* time, just as a >>> physical ROM can't be read-only at manufacture time. >> >> oh yes it can >> in the past for large quantitys the data in a ROM chip was part of the >> chip etching mask (unless you consider a blank silicon wafer to be >> "Programmable" by the etching process)rather than prom which used >> programmable fuses or prom which could be erased by UV light (assuming >> the chip was fitted with a window otherwise it was known as one time >> programmable EPROM) > > He didn't say "programmable". He said that the is "not read-only". In context, we are talking about a computer program (the compiler) writing data to memory. When we talk about programs writing data to memory, only certain types of actions are included, and a distant factory etching silicon chips is not usually one of them. The question is, does the process of manufacturing a silicon chip count as *writing*? I don't think so. Not every side-effect should be described as writing: if the compiler's output was fed into a robot that used it to assemble a car, I'm sure you would not want to say that the compiler wrote a car. That would be a misuse of language. I think the idea of writing a ROM chip is equally a misuse of language. Your example of writing on paper is a good one, but it argues *against* your position, not for it. If you compile some code, then take a hex dump and print it out: gcc program.c xxd a.out | lp would you describe the process as "the compiler writes to the piece of paper"? I don't think that is justified. The compiler isn't writing to the paper, the printer is printing to the paper. I would accept the description "lp writes to the printer", but that's as far as it goes. Instead of using a printer, perhaps you pipe the output to less and then spend the next hour laboriously hand-writing the hex dump out. (Perhaps you lost a bet, or you are playing a game of Truth Or Dare.) Do you still want to claim that the compiler did the writing? If you email the hex dump to a person on the other side of the world, who then post-processes the file in some unknown fashion, and passes the processed file to another machine, which uses that as input to an industrial process which etches wafers of silicon and manufacturers a ROM chip, do you still think it is reasonable to describe it as the *compiler* doing *writing*? I maintain the choice of words is wrong on both counts: the compiler is not the entity doing the work, and the work of manufacturing a ROM chip should not be described as writing. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
alister wrote: in the past for large quantitys the data in a ROM chip was part of the chip etching mask I know, I'm considering the masking process to be a kind of write operation. The Apollo lunar lander used a magnetic core store that was hard coded at the time it was "Woven" I doubt that either process is in widespread usage any longer as most manufacturers no incorporate a way to update the firmware of a device Magnetic core technology died out long before that, due to inability to build machines that simulated armies of ladies with sewing needles! -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Steve D'Aprano wrote: For example, pressing delete when there is no text to delete should just silently do nothing. That's really just a matter of deciding what should count as an error and what shouldn't. You've decided that "pressing Delete when there's nothing to delete does nothing" is a reasonable thing to include in the specifications of correct behaviour for the program. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
Chris Angelicowrites: > On Sat, Oct 14, 2017 at 8:42 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >> >>> On Fri, Oct 13, 2017 at 10:14 AM, Ben Bacarisse >>> wrote: Chris Angelico writes: > I abbreviated that down to nothing, but since you ask, here's a really > REALLY simple run-down of how to use Heroku: I think I see what you mean now. You meant no configuration is needed because you use (or buy?) a cloud service that's all set up for it already? >>> >>> Correct - because the setup needed is completely generic. >>> From this and other posts I think the position is that I do need to do some server configuration (and essentially install a proxy server) to run Python web applications on my typical Apache set-up. And I would then have to shop around for suitable hosting that is already set up for running them. Thanks. That's not quite what I was after but it's good to know how to do that should I want to that later. >>> >>> Yep, it's not too hard. >>> >>> And that's why it's cleaner to work with Python than PHP. To use >>> custom URL routing in PHP, you have to use custom server rules; to use >>> custom URL routing in Python, you use "@app.route(...)" lines inside >>> your app, and perfectly standard server rules. >> >> That's one way to put it. Another is that to use Python I need to buy a >> new service that is already configured. If that's the way it's done, >> fine, but this sub-thread started with someone being surprised by the >> success of PHP. > > Thing is, that's exactly the same for both languages these days. You > can get cheap (even zero-dollar) hosting that's preconfigured to be > able to support either. There USED to be a difference, and everyone's > acknowledged this - PHP built up some inertia - but there's now no > real reason for it other than "it's popular, therefore people use it". That's good to know, but of course the current success of PHP is based exactly on what used to be the case. It will take a while for the inherent inertia of people, skills, processes and so on to be overcome. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On Sat, Oct 14, 2017 at 9:02 AM, Grant Edwardswrote: > On 2017-10-13, Chris Angelico wrote: > > [regarding PHP vs Python capable web-hosting services] > >> Thing is, that's exactly the same for both languages these days. You >> can get cheap (even zero-dollar) hosting that's preconfigured to be >> able to support either. There USED to be a difference, and everyone's >> acknowledged this - PHP built up some inertia - but there's now no >> real reason for it other than "it's popular, therefore people use it". > > Well, it's said that suffering builds character... > > What they don't tell you is what sort of character. I think it mostly builds U+1F4A9. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On 2017-10-13, Chris Angelicowrote: [regarding PHP vs Python capable web-hosting services] > Thing is, that's exactly the same for both languages these days. You > can get cheap (even zero-dollar) hosting that's preconfigured to be > able to support either. There USED to be a difference, and everyone's > acknowledged this - PHP built up some inertia - but there's now no > real reason for it other than "it's popular, therefore people use it". Well, it's said that suffering builds character... What they don't tell you is what sort of character. -- Grant Edwards grant.b.edwardsYow! Am I SHOPLIFTING? at gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On Sat, Oct 14, 2017 at 8:42 AM, Ben Bacarissewrote: > Chris Angelico writes: > >> On Fri, Oct 13, 2017 at 10:14 AM, Ben Bacarisse wrote: >>> Chris Angelico writes: I abbreviated that down to nothing, but since you ask, here's a really REALLY simple run-down of how to use Heroku: >>> >>> I think I see what you mean now. You meant no configuration is needed >>> because you use (or buy?) a cloud service that's all set up for it >>> already? >> >> Correct - because the setup needed is completely generic. >> >>> From this and other posts I think the position is that I do need to do >>> some server configuration (and essentially install a proxy server) to >>> run Python web applications on my typical Apache set-up. And I would >>> then have to shop around for suitable hosting that is already set up for >>> running them. >>> >>> >>> >>> Thanks. That's not quite what I was after but it's good to know how to >>> do that should I want to that later. >> >> Yep, it's not too hard. >> >> And that's why it's cleaner to work with Python than PHP. To use >> custom URL routing in PHP, you have to use custom server rules; to use >> custom URL routing in Python, you use "@app.route(...)" lines inside >> your app, and perfectly standard server rules. > > That's one way to put it. Another is that to use Python I need to buy a > new service that is already configured. If that's the way it's done, > fine, but this sub-thread started with someone being surprised by the > success of PHP. Thing is, that's exactly the same for both languages these days. You can get cheap (even zero-dollar) hosting that's preconfigured to be able to support either. There USED to be a difference, and everyone's acknowledged this - PHP built up some inertia - but there's now no real reason for it other than "it's popular, therefore people use it". ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
Chris Angelicowrites: > On Fri, Oct 13, 2017 at 10:14 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >>> I abbreviated that down to nothing, but since you ask, here's a really >>> REALLY simple run-down of how to use Heroku: >> >> I think I see what you mean now. You meant no configuration is needed >> because you use (or buy?) a cloud service that's all set up for it >> already? > > Correct - because the setup needed is completely generic. > >> From this and other posts I think the position is that I do need to do >> some server configuration (and essentially install a proxy server) to >> run Python web applications on my typical Apache set-up. And I would >> then have to shop around for suitable hosting that is already set up for >> running them. >> >> >> >> Thanks. That's not quite what I was after but it's good to know how to >> do that should I want to that later. > > Yep, it's not too hard. > > And that's why it's cleaner to work with Python than PHP. To use > custom URL routing in PHP, you have to use custom server rules; to use > custom URL routing in Python, you use "@app.route(...)" lines inside > your app, and perfectly standard server rules. That's one way to put it. Another is that to use Python I need to buy a new service that is already configured. If that's the way it's done, fine, but this sub-thread started with someone being surprised by the success of PHP. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13/10/2017 15:39, Steve D'Aprano wrote: On Fri, 13 Oct 2017 11:54 pm, Gregory Ewing wrote: Neil Cerutti wrote: I can tell at a glance if a parameter is expected to be modifiable just by looking at the function signature. The question is why doesn't anyone feel the need to be able to do that for Python functions? Whether a function modifies things passed to it is just as important to know in Python as it is in C. Lots of people would like Python to have a "freeze" function that can make immutable objects, it is a moderately common feature request. Some people (myself included) would like a "const" declaration that gives us names that can only be bound to once: const spam = "NOBODY expects the Spanish Inquisition!!!" # Okay spam = "foo" # Error. Presumably also: const def f: const class c: const import i I don't mind if that is a runtime error, although a compile time error would be nicer. This would be of most use when the byte-code compiler (assuming there is one) knows about them. But many will be inside imported modules whose contents, AIUI, are not visible to the byte-code compiler. And then they would be accessed as: i.spam So this would be a const attribute. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-13 15:11, alisterwrote: > On Sat, 14 Oct 2017 01:48:44 +1300, Gregory Ewing wrote: >> Steve D'Aprano wrote: >>> I wasn't questioning where the data came from, but how the compiler can >>> write to READ ONLY MEMORY which might not even be in the same continent >>> as the compiler that generated the code. >> >> I thought it would be fairly obvious that by "put it in read-only >> memory" I meant "arrange for it to be in a location that is read-only at >> run time". Obviously it can't be read-only at *compile* time, just as a >> physical ROM can't be read-only at manufacture time. > > oh yes it can > in the past for large quantitys the data in a ROM chip was part of the > chip etching mask (unless you consider a blank silicon wafer to be > "Programmable" by the etching process)rather than prom which used > programmable fuses or prom which could be erased by UV light (assuming > the chip was fitted with a window otherwise it was known as one time > programmable EPROM) He didn't say "programmable". He said that the is "not read-only". Obviously the wafer is modified during the etching process and afterwards it contains information it didn't before. Would you say a piece of paper is "read-only" because you can't program it using address and data lines? I can write on it, I just need a different tool. hp -- _ | Peter J. Holzer| Fluch der elektronischen Textverarbeitung: |_|_) || Man feilt solange an seinen Text um, bis | | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr __/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, Oct 14, 2017 at 6:32 AM, Peter J. Holzerwrote: > On 2017-10-13 14:51, Chris Angelico wrote: >> On Sat, Oct 14, 2017 at 1:32 AM, Steve D'Aprano >> wrote: >>> It seems to me that you're not talking about ROM at all, but ordinary RAM. >>> Then what do you mean by "read only"? A block of memory with a flag that >>> says "unprivileged processes are prohibited from writing here"? >>> >>> (That's also not a rhetorical question.) >> >> When I first learned about Protected Mode (as defined by the Intel >> 80386 and used in OS/2), there was a real concept of read-only RAM. >> The program loader would fetch up the executable file (data on the >> disk) and construct its segments: code, data, and BSS/stack. > > This is still the case. The granularity is just finer now: Instead of > segments you use pages. (The 386 was the first x86 processor which > supported paging. OS/2 probably used segments because it was originally > designed for the 286.) ... either that, or I'm just misremembering, it being many MANY years since I did anything that low-level. Let's assume I was mistaken. :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-13 15:28, Steve D'Apranowrote: > On Sat, 14 Oct 2017 01:30 am, Chris Angelico wrote: >>> It's just a technique, like greying out certain menu options - clicking >>> them will do nothing, but you won't get an error message and you don't want >>> to allow them anyway, risking more serious consequences. >> >> Even there, you often CAN get a report about the failure; clicking on >> something that's disabled will cause a short beep, unless that's >> disabled. Maybe you personally don't like that beep, and you'd rather >> it be suppressed - but that's the end user's choice, NOT the >> programmer's. "Errors should never pass silently, unless explicitly >> silenced." > > Over 30 years since Apple first put out their user interface guidelines, and > people still get the basics wrong. > > "Errors should never pass silently..." is excellent advise for programming, > but not necessarily UIs. With a program, errors in the code represent bugs > that should be fixed, and in principle we can remove the bugs one by one > until there are none left, after which the program will be perfect. (Yeah, > try not to laugh too much.) > > But in a UI, that will never be the case. Errors are not bugs, and can't be > removed. It is also not a bug if - for example - a file cannot be opened, or is malformed. But you have to tell the user what went wrong. Pretending that all went well won't make the user happy (or at least that happyness will be short-lived). > All you can do is hope the user doesn't do it again, which they > will. So UIs should follow a slightly different ideal: > > "Be tolerant of unimportant errors, and let them pass silently." [...] > Likewise, pressing the left arrow key when you are already at the start of the > text should just silently remain at the start, not chastise the user. [... other examples elided ...] > But in fact, clicking a disabled button or menu item is not an error. If it is not an error, clearly the rule does not apply. So it depends on whether the action is an error or not (actually in the case of the disabled button I would tend to think it is an error: I can't think of a reason why anybody would intentionally click on a disabled button[1]). Pressing the left arrow key when you are already at the start of the line is good example. The user might expect the cursor to jump the end of the previous line, so if your program doesn't do that you probably should give some feedback. Or the user might just have pressed the key a bit too long, then the cursor should just stop there ("vi has two modes: One beeps a lot and the other doesn't"). So it depends on what the user expects. I think Chris a very good point here that this should be configurable unless your user base is very homogenous. hp [1] Except in a demo: "As you can see, this button is now disabled. Nothing happens when I click on it!" Everbody dives under the table just in time before the espresso machine in the corner explodes. -- _ | Peter J. Holzer| Fluch der elektronischen Textverarbeitung: |_|_) || Man feilt solange an seinen Text um, bis | | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr __/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-13 14:51, Chris Angelicowrote: > On Sat, Oct 14, 2017 at 1:32 AM, Steve D'Aprano > wrote: >> It seems to me that you're not talking about ROM at all, but ordinary RAM. >> Then what do you mean by "read only"? A block of memory with a flag that >> says "unprivileged processes are prohibited from writing here"? >> >> (That's also not a rhetorical question.) > > When I first learned about Protected Mode (as defined by the Intel > 80386 and used in OS/2), there was a real concept of read-only RAM. > The program loader would fetch up the executable file (data on the > disk) and construct its segments: code, data, and BSS/stack. This is still the case. The granularity is just finer now: Instead of segments you use pages. (The 386 was the first x86 processor which supported paging. OS/2 probably used segments because it was originally designed for the 286.) hp -- _ | Peter J. Holzer| Fluch der elektronischen Textverarbeitung: |_|_) || Man feilt solange an seinen Text um, bis | | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr __/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-13, Steve D'Apranowrote: > On Fri, 13 Oct 2017 11:54 pm, Gregory Ewing wrote: > >> Neil Cerutti wrote: >>> I can tell at a glance if a parameter is expected to be >>> modifiable just by looking at the function signature. >> >> The question is why doesn't anyone feel the need to be >> able to do that for Python functions? Whether a function >> modifies things passed to it is just as important to >> know in Python as it is in C. > > Lots of people would like Python to have a "freeze" function > that can make immutable objects, it is a moderately common > feature request. > > Some people (myself included) would like a "const" declaration > that gives us names that can only be bound to once: > > const spam = "NOBODY expects the Spanish Inquisition!!!" # > Okay spam = "foo" # Error. > > I don't mind if that is a runtime error, although a compile > time error would be nicer. When there are many constants I tend to create a class called Constant that either doesn't get instanced, or has only one instance (sometimes some of my constants need to be calculated once at runtime). > I don't know if either of these (actual immutable pure-Python > objects, and un-rebindable names) count as quite the same thing > you are asking Neil about. But I trust they're related. Looking at the Python functions I actually write today, I've evolved my style until I simply don't modify function arguments, so it matters not if parameters are declared const. But my oldest programs still in use are different. For example: records = defaultdict(Data) read_unmatched_records(records) And then later code continues screwing around with that dictionary and liberally using C-style constant names, e.g.: for fname in glob.glob(COUNSELING_ACK): process_counseling_acks(fname, records) for fname in glob.glob(PLUS_APP_ACK): process_plus_request(fname, records) Such code feels alien to me now. A small script for reading promissory note acknowledgements grew into a business-vital, 1,000 LOC octopus without my leave. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, Oct 14, 2017, Gregory Ewing wrote: > Message: 5 >Date: Sat, 14 Oct 2017 01:54:49 +1300 >From: Gregory Ewing>To: python-list@python.org >Subject: Re: Lies in education [was Re: The "loop and a half"] >Message-ID: >Content-Type: text/plain; charset=ISO-8859-1; format=flowed > >Neil Cerutti wrote: >> I can tell at a glance if a parameter is expected to be >> modifiable just by looking at the function signature. > >The question is why doesn't anyone feel the need to be >able to do that for Python functions? Whether a function >modifies things passed to it is just as important to >know in Python as it is in C. > I'm just trying to put myself in the position of the programmer who is in this position of identifying the modifiable parameters in the function signature. Where are you getting the function signature? Are you looking at the source code? Or from the help() that access the module? In both cases, the docstring is an easy solution. The documentation itself in certainly state whether it modifies any parameter. And it is directly visible along with the function signature either way. We don't need any annotations or attributes or whatnot if we have the perfectly normal function documentation. Or is that kind of habit no longer practiced in 'the real world'? Roger Christman Pennsylvania State University -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
alister: > On Sat, 14 Oct 2017 01:48:44 +1300, Gregory Ewing wrote: >> I thought it would be fairly obvious that by "put it in read-only >> memory" I meant "arrange for it to be in a location that is read-only >> at run time". Obviously it can't be read-only at *compile* time, just >> as a physical ROM can't be read-only at manufacture time. > > oh yes it can > [...] > > I doubt that either process is in widespread usage any longer as most > manufacturers no incorporate a way to update the firmware of a device > (usually with flash memory) Then there's the case of FPGA, which can expose parts of itself as memory, whether writable or read-only. You can reprogram its ROM (and other) parts, but not using the regular RAM write mechanisms. In general, memory-mapped I/O may be read-only to software. For example, you could read dip-switch settings or the error counts of a hard disk from "const volatile" memory areas. There, "const" means you can't write into it and "volatile" means it could change "by itself". Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13/10/2017 16:33, Steve D'Aprano wrote: On Sat, 14 Oct 2017 01:30 am, Chris Angelico wrote: For a novice, seeing 'Segmentation fault (core dumped)' is better? Better than silently doing nothing? YES. Absolutely it is. Chris, you forget that for Bart, his user-base is only himself. If he programs his home-made system to silently ignore writes to write-protected memory, that counts as the "...unless explicitly silenced" part of "Errors should never pass silently...". If that means his software is riddled with bugs, it will affect only himself, and no novices will be harmed. You're making light of a scheme that was extremely effective in a computer system with otherwise unprotected memory, that could write anywhere, including over all the code and over the OS. Without that write protection, what would have happened? Either it would go completely haywire, or hang, or could subtly change resident programs in dangerous ways. Or I could put that switch in then I could be CERTAIN that essential programs and data were untouched no matter what happened. So if it worked well then without needing to abort and report a message, why can't a scheme like that work now? BTW, when you're developing a new bit of hardware or software, and you're not part of team, then the user-base is normally just yourself. Nothing wrong with that, but you seem to like belittling people with such comments. What was the userbase when GvR started Python? -- Bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, 14 Oct 2017 01:30 am, Chris Angelico wrote: >> For a novice, seeing 'Segmentation fault (core dumped)' is better? > > Better than silently doing nothing? YES. Absolutely it is. Chris, you forget that for Bart, his user-base is only himself. If he programs his home-made system to silently ignore writes to write-protected memory, that counts as the "...unless explicitly silenced" part of "Errors should never pass silently...". If that means his software is riddled with bugs, it will affect only himself, and no novices will be harmed. But in any case, a seg fault is a pretty crude and dangerous way to report errors. It isn't so much an error report as the *consequences* of the error, a bit like your car engine seizing up because you forgot to put oil in it. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, 14 Oct 2017 01:30 am, Chris Angelico wrote: >> It's just a technique, like greying out certain menu options - clicking >> them will do nothing, but you won't get an error message and you don't want >> to allow them anyway, risking more serious consequences. > > Even there, you often CAN get a report about the failure; clicking on > something that's disabled will cause a short beep, unless that's > disabled. Maybe you personally don't like that beep, and you'd rather > it be suppressed - but that's the end user's choice, NOT the > programmer's. "Errors should never pass silently, unless explicitly > silenced." Over 30 years since Apple first put out their user interface guidelines, and people still get the basics wrong. "Errors should never pass silently..." is excellent advise for programming, but not necessarily UIs. With a program, errors in the code represent bugs that should be fixed, and in principle we can remove the bugs one by one until there are none left, after which the program will be perfect. (Yeah, try not to laugh too much.) But in a UI, that will never be the case. Errors are not bugs, and can't be removed. All you can do is hope the user doesn't do it again, which they will. So UIs should follow a slightly different ideal: "Be tolerant of unimportant errors, and let them pass silently." For example, pressing delete when there is no text to delete should just silently do nothing. Why annoy the user by beeping? They probably just held down the backspace key for a microsecond too long. Surely you wouldn't log the error: "delete pressed but no text to delete". Um, okay, what do you expect me to do about it? Likewise, pressing the left arrow key when you are already at the start of the text should just silently remain at the start, not chastise the user. Or clicking in the body of the window where there are no controls or text fields. (MYOB, I'm looking at you.) But in fact, clicking a disabled button or menu item is not an error. There's no need to chastise the user with a beep or by flashing the screen or logging the event ("warning: user clicked disabled menu"). The point of disabling the menu is to avoid errors by preventing the user from selecting a command that will fail. The reason the menu is disabled rather than hidden is to provide a consistent interface and immediate visual feedback to the user. Clicking a disabled item should simply do nothing at all. If, and *only* if, you cannot rely on visual feedback that the item is disabled (perhaps you're using a text-only interface with no way to visually distinguish items) then you should provide some other feedback, like a beep or flashing the screen, or better (since audible feedback is annoying) display an informational status message that doesn't require explicit acknowledgement from the user. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13/10/2017 15:59, Julien Salort wrote: Le 12/10/2017 à 17:57, bartc a écrit : With a const struct, you are stopped from directly modifying elements, but if an element is a pointer, nothing stops you writing to what the pointer points to, unless that has a const target too. And then you've going to have problems doing normal updates. This constness just insinuates itself everywhere. That is not very different from the mutable/immutable concept in Python, is it ? A tuple is immutable, but if it contains a mutable object, nothing prevents you from mutating it. Does it mean you think the mutable/immutable concept of Python is flawed? When you put it like that, then yes! But it depends on how you define the value of a tuple. If that is a recursive definition that includes all nested object levels, then it would be harder to keep the whole thing constant. If you look only one level deep, then it can be fully immutable (never mind that some elements could be functions that will give a different result each time they are evaluated). -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, 14 Oct 2017 01:48:44 +1300, Gregory Ewing wrote: > Steve D'Aprano wrote: >> I wasn't questioning where the data came from, but how the compiler can >> write to READ ONLY MEMORY which might not even be in the same continent >> as the compiler that generated the code. > > I thought it would be fairly obvious that by "put it in read-only > memory" I meant "arrange for it to be in a location that is read-only at > run time". Obviously it can't be read-only at *compile* time, just as a > physical ROM can't be read-only at manufacture time. oh yes it can in the past for large quantitys the data in a ROM chip was part of the chip etching mask (unless you consider a blank silicon wafer to be "Programmable" by the etching process)rather than prom which used programmable fuses or prom which could be erased by UV light (assuming the chip was fitted with a window otherwise it was known as one time programmable EPROM) The Apollo lunar lander used a magnetic core store that was hard coded at the time it was "Woven" I doubt that either process is in widespread usage any longer as most manufacturers no incorporate a way to update the firmware of a device (usually with flash memory) -- "I am not sure what this is, but an `F' would only dignify it." -- English Professor -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Le 12/10/2017 à 17:57, bartc a écrit : With a const struct, you are stopped from directly modifying elements, but if an element is a pointer, nothing stops you writing to what the pointer points to, unless that has a const target too. And then you've going to have problems doing normal updates. This constness just insinuates itself everywhere. That is not very different from the mutable/immutable concept in Python, is it ? A tuple is immutable, but if it contains a mutable object, nothing prevents you from mutating it. Does it mean you think the mutable/immutable concept of Python is flawed? Julien -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, Oct 14, 2017 at 1:32 AM, Steve D'Apranowrote: > It seems to me that you're not talking about ROM at all, but ordinary RAM. > Then what do you mean by "read only"? A block of memory with a flag that > says "unprivileged processes are prohibited from writing here"? > > (That's also not a rhetorical question.) When I first learned about Protected Mode (as defined by the Intel 80386 and used in OS/2), there was a real concept of read-only RAM. The program loader would fetch up the executable file (data on the disk) and construct its segments: code, data, and BSS/stack. The data, BSS, and stack all end up as a single segment (data is what comes straight off the disk, BSS is all zeroes initially, and stack is uninitialized initially, but ultimately they're all read/write), and code is in its own segment. When control is handed to the new process, its segment table grants it read/write access to the data/stack segment, but read-only access to its code segment. Within that process, the code really truly is read-only, unless some magic is done. And yes, since it is fully readable, constant data CAN be included alongside actual executable code, but it's never going to be mutable in any way. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, 13 Oct 2017 11:54 pm, Gregory Ewing wrote: > Neil Cerutti wrote: >> I can tell at a glance if a parameter is expected to be >> modifiable just by looking at the function signature. > > The question is why doesn't anyone feel the need to be > able to do that for Python functions? Whether a function > modifies things passed to it is just as important to > know in Python as it is in C. Lots of people would like Python to have a "freeze" function that can make immutable objects, it is a moderately common feature request. Some people (myself included) would like a "const" declaration that gives us names that can only be bound to once: const spam = "NOBODY expects the Spanish Inquisition!!!" # Okay spam = "foo" # Error. I don't mind if that is a runtime error, although a compile time error would be nicer. I don't know if either of these (actual immutable pure-Python objects, and un-rebindable names) count as quite the same thing you are asking Neil about. But I trust they're related. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, 13 Oct 2017 11:48 pm, Gregory Ewing wrote: > Steve D'Aprano wrote: >> I wasn't questioning where the data came from, but how the compiler can >> write to READ ONLY MEMORY which might not even be in the same continent as >> the compiler that generated the code. > > I thought it would be fairly obvious that by "put it in > read-only memory" I meant "arrange for it to be in a > location that is read-only at run time". Obviously it > can't be read-only at *compile* time, just as a > physical ROM can't be read-only at manufacture time. No, its not obvious. It is a lot less obvious than my reference to ROM being burnt into hardware at a factory, which you responded to with the irrelevant observation that the data originated from a compiler. Sure, some data in ROMs might come from a compiler -- and some of it might not. Suppose a ROM contains a list of the names of the computer's developers (as some Mac ROMs did). It would be an abuse of language to say "The text editor writes to the ROM" and it is equally an abuse to say that the compiler writes to ROM just because the data burned into the chip is some sort of compiled object code. As Peter Holzer points out, the compiler likely writes to an object file, not the ROM, and as I pointed out, the process manufacturing the ROM might not even be in the same continent as the compiler. So when you talk about Read Only Memory, you're apparently not actually talking about actual Read Only Memory (ROM). Something has to write this data to "read only memory", and it must be able to do it over and over and over again, each time the program runs. How is this *read only*? It's not even "Write Once, Read Many" (WORM). What sort of read only memory can be written to over and over again? (This is not a rhetorical question.) It seems to me that you're not talking about ROM at all, but ordinary RAM. Then what do you mean by "read only"? A block of memory with a flag that says "unprivileged processes are prohibited from writing here"? (That's also not a rhetorical question.) Since the compiler is an unprivileged process, how can it write to memory that unprivileged processes cannot write to? I'm guessing that it can't. Can it? If not, then its probably some privileged process (part of the OS?) which does the writing. Am I close? (Still not a rhetorical question.) Earlier you said: If the compiler can tell where p is initially pointing, it could put the pointer in read-only memory. i.e. that you believe it is the *compiler* doing the writing. If that's not actually what you meant, then what you meant is not sufficiently clear. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
bartc: > But what about the poor user reading the code? Or can that now only be > done with the aid or a browser that analyses 100,000 lines and applies > that same algorithm? > > We mustn't forget the person writing the code, who may have a certain > type in mind for X, but their (I nearly said 'his') analysis may not > match the compiler's. > > Annotations can be useful. The writer of the code is responsible for clear communication. However, I don't believe boilerplate is the answer, quite the contrary. Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, Oct 14, 2017 at 12:51 AM, bartcwrote: > On 13/10/2017 14:16, Chris Angelico wrote: >> >> On Sat, Oct 14, 2017 at 12:00 AM, bartc wrote: >>> >>> Even if data is actually in write-protected memory, attempts to write to >>> it >>> will cause a crash. On my home-made system, they just did nothing. Much >>> more >>> graceful. >> >> >> The novice thinks his job is to stop the program from crashing. The >> expert knows that a crash is actually far FAR better than silently >> doing nothing. > > > > For a novice, seeing 'Segmentation fault (core dumped)' is better? Better than silently doing nothing? YES. Absolutely it is. > There, a friendlier, more useful error message is called for ('writing into > read-only memory' is a good start). Minor distinction. Yes, it might be helpful to have different error messages for different errors, but it's a trade-off. > But the idea of having memory which is permanently or temporarily > write-protected is also useful: you can do what you like to it and it won't > change, and such an attempt wouldn't necessarily be an error. > > For example, you're drawing a series of points or connected lines into a > window to form a shape. But part of the shape is outside the window. So you > fix the logic and try again. You don't want it to crash if you gave it > coordinates (corresponding to memory beyond the window limits) outside the > boundaries. It's common to emulate an infinite drawable area and then optimizing it by displaying only the part that's outside the window. That's not the same thing as silently doing nothing if something goes wrong - for instance, ignoring one point in the shape, and drawing a shape with fewer points. That would, in my opinion, be utterly unacceptable. And yes, I've seen programs that do that - it's usually called a "glitch". > It's just a technique, like greying out certain menu options - clicking them > will do nothing, but you won't get an error message and you don't want to > allow them anyway, risking more serious consequences. Even there, you often CAN get a report about the failure; clicking on something that's disabled will cause a short beep, unless that's disabled. Maybe you personally don't like that beep, and you'd rather it be suppressed - but that's the end user's choice, NOT the programmer's. "Errors should never pass silently, unless explicitly silenced." ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13/10/2017 14:22, Marko Rauhamaa wrote: BTW, the original reason for C requiring declarations in the first place wasn't readability. Rather, it was to make compilation possible in the first place. It is interesting that C++ and Java have taken steps to remove such information where the compiler can know or guess it from the context. The compiler might be able to, after analysing 100,000 lines of prior code and applying complex algorithms. But what about the poor user reading the code? Or can that now only be done with the aid or a browser that analyses 100,000 lines and applies that same algorithm? We mustn't forget the person writing the code, who may have a certain type in mind for X, but their (I nearly said 'his') analysis may not match the compiler's. Annotations can be useful. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Paul Moore: > To put it another way, in C const is a property of the variable being > declared, not the value assigned to it. In Python, variables aren't > declared, and constness is an inherent property of the value (or its > type). One interesting question which this does raise is whether > there's a place for "const" in type annotations - I suspect not, > because it's either trivial (the type is immutable) or too hard to > define (you'd need to recursively know for all methods whether they > mutate the value). I don't think that's the core issue. User-defined classes (or, rather, objects) are often mutable. The question is who gets to modify them and what modifieds them (methods can have surprising side effects). "Const" would convey some of that information. However, why "const" out of the myriads of restrictions? The nice thing about Python is that I don't get to formally declare those things, and that makes my life easier. I don't have to worry about finding the right combination of these formal comments -- because I can't! Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13 October 2017 at 13:54, Gregory Ewingwrote: > Neil Cerutti wrote: >> >> I can tell at a glance if a parameter is expected to be >> modifiable just by looking at the function signature. > > > The question is why doesn't anyone feel the need to be > able to do that for Python functions? Whether a function > modifies things passed to it is just as important to > know in Python as it is in C. While I don't *really* know, my intuition is that const is important in C for guaranteeing that functions don't mess around with the innards of (conceptually) primitive types. Hence const char *, and const pointers/arrays. More complex types like collections - lists, trees, etc - can't be declared as "const". Well, they can, but typically that doesn't guarantee that the collection isn't changed, just that the pointer to it isn't. So in C, for all practical purposes const signifies that an argument is what in languages like C# would be called a value type - an immutable primitive value. In Python and other higher level languages, primitive types are immutable by default, or to put it another way, basic types are always value types, and constness is part of the definition of the *type* rather than of the name referring to it. So there's no need for an explicit "const" annotation. To put it another way, in C const is a property of the variable being declared, not the value assigned to it. In Python, variables aren't declared, and constness is an inherent property of the value (or its type). One interesting question which this does raise is whether there's a place for "const" in type annotations - I suspect not, because it's either trivial (the type is immutable) or too hard to define (you'd need to recursively know for all methods whether they mutate the value). Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13/10/2017 14:16, Chris Angelico wrote: On Sat, Oct 14, 2017 at 12:00 AM, bartcwrote: Even if data is actually in write-protected memory, attempts to write to it will cause a crash. On my home-made system, they just did nothing. Much more graceful. The novice thinks his job is to stop the program from crashing. The expert knows that a crash is actually far FAR better than silently doing nothing. For a novice, seeing 'Segmentation fault (core dumped)' is better? There, a friendlier, more useful error message is called for ('writing into read-only memory' is a good start). But the idea of having memory which is permanently or temporarily write-protected is also useful: you can do what you like to it and it won't change, and such an attempt wouldn't necessarily be an error. For example, you're drawing a series of points or connected lines into a window to form a shape. But part of the shape is outside the window. So you fix the logic and try again. You don't want it to crash if you gave it coordinates (corresponding to memory beyond the window limits) outside the boundaries. It's just a technique, like greying out certain menu options - clicking them will do nothing, but you won't get an error message and you don't want to allow them anyway, risking more serious consequences. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Gregory Ewing: > Neil Cerutti wrote: >> I can tell at a glance if a parameter is expected to be modifiable >> just by looking at the function signature. > > The question is why doesn't anyone feel the need to be able to do that > for Python functions? Whether a function modifies things passed to it > is just as important to know in Python as it is in C. I often ponder what information should be conveyed by the declaration. For example, some methods are called with lock taken while others not. Should that be indicated in the name of the function? Also ownership and other contractual matters. I occasionally fall into the temptation of coding such aspects in names, but equally often the attempt backfires. Most you get is silly syntactic clutter. Let's just say that the problem remains unsolved, maybe unsolvable, and any attempts at solving the problem seem to cause worse problems. BTW, the original reason for C requiring declarations in the first place wasn't readability. Rather, it was to make compilation possible in the first place. It is interesting that C++ and Java have taken steps to remove such information where the compiler can know or guess it from the context. Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Sat, Oct 14, 2017 at 12:00 AM, bartcwrote: > Even if data is actually in write-protected memory, attempts to write to it > will cause a crash. On my home-made system, they just did nothing. Much more > graceful. The novice thinks his job is to stop the program from crashing. The expert knows that a crash is actually far FAR better than silently doing nothing. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13/10/2017 12:49, Peter J. Holzer wrote: On 2017-10-13 10:37, Steve D'Apranowrote: or written by a dedicated hardware device: https://en.wikipedia.org/wiki/Programmable_read-only_memory And in this case there will be a tool which will read the object file and send the contents of the read-only sections to the device which writes the ((E)E)PROM. First time I did this was with a home-made programmer directly connected to a keyboard. I had to press the right key to generate the 7-bit pattern I wanted (I can't remember what I did about the 8th bit), burn it into the current location then step the address counter to the next. No mistakes were tolerated. It worked. And finally, the most frequent case: The OS will will read the executable into RAM, mark those pages from the read-only sections as read-only in the page table and start it. Or as I did it, on a home-made computer with two banks of 16KB RAM, one bank had the editor, compiler and source code, the other the generated code. Just before running it, I would flip a switch to write-protect the first bank in case something went wrong. (I didn't have floppies only slow, unreliable tape, so things had to be memory-resident as much as possible.) And, actually, even now machines don't have that much control: you create a large table of data at runtime, but it is still in writeable memory, and accidental or malicious code could write into it. No matter that the C source may have had a few consts sprinkled about. (It's bit like those incredibly annoying anti-piracy messages and videos you get on DVDS. No actual pirate would ever see them, only honest people who have no intention of copying!) Even if data is actually in write-protected memory, attempts to write to it will cause a crash. On my home-made system, they just did nothing. Much more graceful. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Neil Cerutti wrote: I can tell at a glance if a parameter is expected to be modifiable just by looking at the function signature. The question is why doesn't anyone feel the need to be able to do that for Python functions? Whether a function modifies things passed to it is just as important to know in Python as it is in C. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Steve D'Aprano wrote: I wasn't questioning where the data came from, but how the compiler can write to READ ONLY MEMORY which might not even be in the same continent as the compiler that generated the code. I thought it would be fairly obvious that by "put it in read-only memory" I meant "arrange for it to be in a location that is read-only at run time". Obviously it can't be read-only at *compile* time, just as a physical ROM can't be read-only at manufacture time. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-13 10:37, Steve D'Apranowrote: > On Fri, 13 Oct 2017 05:16 pm, Gregory Ewing wrote: >> Steve D'Aprano wrote: >>> On Fri, 13 Oct 2017 03:37 pm, Gregory Ewing wrote: >>> If the compiler can tell where p is initially pointing, it could put the pointer in read-only memory. >>> >>> If it's read-only, how can the compiler write to it? >>> >>> (I come from the days when ROM was actual ROM, burned in at the factory.) >> >> So, the factory is allowed to write to it. Possibly >> it's writing data that came from... a compiler? > > The data could come from anywhere, including a scanner: > > https://hackaday.com/2012/08/24/uncovering-easter-eggs-in-old-mac-roms/ > > I wasn't questioning where the data came from, but how the compiler can write > to READ ONLY MEMORY which might not even be in the same continent as the > compiler that generated the code. A compiler rarely writes into the final destination memory (JIT compilers are the exception). It writes into a file. This file often has sections like "code", "read-only data", etc. Another tool (maybe the OS, maybe an EPROM burner) will later read this file and take appropriate actions. "the compiler could put the pointer in read-only memory" is just shorthand for "the compile could put the pointer into one of the read-only sections of the object file". > Read-only memory (ROM) is typically burned into the silicon by the integrated > chip manufacturer at the factory: > > https://en.wikipedia.org/wiki/Mask_ROM In this case there will be tool (or more likely a whole tool-chain) which takes the read-only sections of the object file and converts them into a lithographic mask which will then be used to create chips. The pointer will end up as a bunch of transistors. > or written by a dedicated hardware device: > > https://en.wikipedia.org/wiki/Programmable_read-only_memory And in this case there will be a tool which will read the object file and send the contents of the read-only sections to the device which writes the ((E)E)PROM. And finally, the most frequent case: The OS will will read the executable into RAM, mark those pages from the read-only sections as read-only in the page table and start it. > Whether the data is burned into the silicon or electrically written by a > dedicated device, it isn't written by the compiler, and once written the data > is permanent. Did anyone claim that? >> A memory that couldn't be written to at all, ever, would be a bit >> useless! > > Macs used a ROM for at least a decade and probably more. The ROM contained > data such as mouse cursors, toolbox routines, icons, sounds, and a > bootloader. No Mac was capable of writing to their ROMs any more than they > could write to their mouse or a CD-ROM. Did anyone claim that? hp -- _ | Peter J. Holzer| Fluch der elektronischen Textverarbeitung: |_|_) || Man feilt solange an seinen Text um, bis | | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr __/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Marko Rauhamaa: > bartc : >> 'const' tries to do too many things, most of them poorly, although it >> does a very good job at adding clutter. > > +1 However, I do my best to honor "const" since it's there. I'm even more Catholic than the Pope and declare: int main(int argc, const char *const argv[]) I generally *don't* use "const" with opaque data types. Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
"Peter J. Holzer": > On 2017-10-13 05:28, Gregory Ewing wrote: >> Not only does "byte" not always mean "8 bits", but >> "char" isn't always short for "character"... > > True. Well, it does, in my universe. That was cast in stone 10**-32 seconds after the Big Bang. Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
bartc: > 'const' tries to do too many things, most of them poorly, although it > does a very good job at adding clutter. +1 Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, 13 Oct 2017 05:16 pm, Gregory Ewing wrote: > Steve D'Aprano wrote: >> On Fri, 13 Oct 2017 03:37 pm, Gregory Ewing wrote: >> >>>If the compiler can tell where p is initially pointing, it could >>>put the pointer in read-only memory. >> >> If it's read-only, how can the compiler write to it? >> >> (I come from the days when ROM was actual ROM, burned in at the factory.) > > So, the factory is allowed to write to it. Possibly > it's writing data that came from... a compiler? The data could come from anywhere, including a scanner: https://hackaday.com/2012/08/24/uncovering-easter-eggs-in-old-mac-roms/ I wasn't questioning where the data came from, but how the compiler can write to READ ONLY MEMORY which might not even be in the same continent as the compiler that generated the code. Read-only memory (ROM) is typically burned into the silicon by the integrated chip manufacturer at the factory: https://en.wikipedia.org/wiki/Mask_ROM or written by a dedicated hardware device: https://en.wikipedia.org/wiki/Programmable_read-only_memory Whether the data is burned into the silicon or electrically written by a dedicated device, it isn't written by the compiler, and once written the data is permanent. > A memory that couldn't be written to at all, ever, would > be a bit useless! Macs used a ROM for at least a decade and probably more. The ROM contained data such as mouse cursors, toolbox routines, icons, sounds, and a bootloader. No Mac was capable of writing to their ROMs any more than they could write to their mouse or a CD-ROM. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 13/10/2017 07:16, Gregory Ewing wrote: Steve D'Aprano wrote: On Fri, 13 Oct 2017 03:37 pm, Gregory Ewing wrote: If the compiler can tell where p is initially pointing, it could put the pointer in read-only memory. If it's read-only, how can the compiler write to it? (I come from the days when ROM was actual ROM, burned in at the factory.) So, the factory is allowed to write to it. Possibly it's writing data that came from... a compiler? A memory that couldn't be written to at all, ever, would be a bit useless! It's read-only in the same sense as a printed book; you can't change the marks already on the page. I've programmed EPROMS. Neither the C language nor the concept of 'const' attributes for data ever came into it. While executable code doesn't really need it. It is simply not a necessity. You just arranged for writeable portions of memory to be at different locations than that containing the code and fixed data. Sometimes it was only data. 'const' is anyway the wrong sort of attribute to use, as I've already explained. For example: const int A = rand(); // inside a function A is written to multiple times at runtime. It can't go into actual read-only memory like a ROM. And it might have trouble going into a memory page with read-only attributes. 'const' tries to do too many things, most of them poorly, although it does a very good job at adding clutter. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-13 05:28, Gregory Ewingwrote: > Grant Edwards wrote: >> On 2017-10-13, Stefan Ram wrote: >>> 1 byte >>> >>> addressable unit of data storage large enough to hold >>> any member of the basic character set of the execution >>> environment« >>> >>>ISO C standard > > Hmmm. So an architecture with memory addressed in octets > and Unicode as the basic character set would have a > char of 8 bits and a byte of 32 bits? No, because a char is also "large enough to store any member of the basic execution character set. (§6.2.5). A "byte" is just the amount of storage a "char" occupies: | The sizeof operator yields the size (in bytes) of its operand [...] | When applied to an operand that has type char, unsigned char, or signed | char, (or a qualified version thereof) the result is 1. (§6.5.3.4) So if a C implementation used Unicode as the base character set, a byte would have to be at least 21 bits, a char the same, and all other types would have to be multiples of that. For any modern architecture that would be rounded up to 32 bits. (I am quite certain that there was at least one computer with a 21 bit word size, but I can't find it: Lots of 18 bit and 24 bit machines, but nothing in between.) An implementation could also choose the BMP as the base character set and the rest of Unicode as the extended character set. That would result in a 16 bit byte and char (and most likely UTF-16 as the multibyte character representation). > Not only does "byte" not always mean "8 bits", but > "char" isn't always short for "character"... True. A character often occupies more space than a char, and you can store non-character data in a char. hp -- _ | Peter J. Holzer| Fluch der elektronischen Textverarbeitung: |_|_) || Man feilt solange an seinen Text um, bis | | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr __/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelico wrote: Certainly not. A byte would be 21 bits! Only if 21 bits were *also* an addressable unit of storage in addition to octets. That would be an interesting architecture indeed. If you really wanted that, it might be easier just to make the memory bit-addressable. In which case a char would be 1 bit! I believe Burroughs built a bit-addressable machine at one point. It was meant to be user-microprogrammable, so you designed an instruction set for what you wanted to do, and then programmed in that. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Steve D'Aprano wrote: On Fri, 13 Oct 2017 03:37 pm, Gregory Ewing wrote: If the compiler can tell where p is initially pointing, it could put the pointer in read-only memory. If it's read-only, how can the compiler write to it? (I come from the days when ROM was actual ROM, burned in at the factory.) So, the factory is allowed to write to it. Possibly it's writing data that came from... a compiler? A memory that couldn't be written to at all, ever, would be a bit useless! -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, Oct 13, 2017 at 4:28 PM, Gregory Ewingwrote: > Grant Edwards wrote: >> >> On 2017-10-13, Stefan Ram wrote: >> >>> 1 byte >>> >>> addressable unit of data storage large enough to hold >>> any member of the basic character set of the execution >>> environment« >>> >>>ISO C standard > > > Hmmm. So an architecture with memory addressed in octets > and Unicode as the basic character set would have a > char of 8 bits and a byte of 32 bits? > > Not only does "byte" not always mean "8 bits", but > "char" isn't always short for "character"... Certainly not. A byte would be 21 bits! Seriously though, I don't think anyone would design hardware like this. But I'd love to see what happens. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Grant Edwards wrote: On 2017-10-13, Stefan Ramwrote: 1 byte addressable unit of data storage large enough to hold any member of the basic character set of the execution environment« ISO C standard Hmmm. So an architecture with memory addressed in octets and Unicode as the basic character set would have a char of 8 bits and a byte of 32 bits? Not only does "byte" not always mean "8 bits", but "char" isn't always short for "character"... -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, Oct 13, 2017 at 4:16 PM, Steve D'Apranowrote: > On Fri, 13 Oct 2017 03:37 pm, Gregory Ewing wrote: > >> If the compiler can tell where p is initially pointing, it could >> put the pointer in read-only memory. > > If it's read-only, how can the compiler write to it? > > > (I come from the days when ROM was actual ROM, burned in at the factory.) Code pages (nothing to do with eight-bit character sets, I mean memory pages containing program code) are often - and should always be - read-only by default. The compiler can put constants into the code segment and reference them that way. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, 13 Oct 2017 03:37 pm, Gregory Ewing wrote: > If the compiler can tell where p is initially pointing, it could > put the pointer in read-only memory. If it's read-only, how can the compiler write to it? (I come from the days when ROM was actual ROM, burned in at the factory.) -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Grant Edwards wrote: It sure was an education the first I wrote C code for a machine where 1 == sizeof char == sizeof int == sizeof long == sizeof float == sizeof double All were 32 bits. Unicode-ready -- way ahead of its time! -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Stefan Ram wrote: void i_know_i_was_passed_a_pointer_to_an_array_and_how_many_elements_are_in_it ( char( *a )[ 4 ] ) { for( int i = 0; i < 4; ++i ) putchar( ( *a )[ i ]); } Only because you've statically made the array size part of the type. Your original example didn't do that; presumably it was intended to accept arrays of any size and cope with them dynamically. That's usually what you want, and the way you do that in C is to pass a pointer to the first element and convey the size separately. So the kind of declaration you used above is hardly ever seen in idiomatic C code. (I've *never* seen it done in real life.) -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
bartc wrote: (2) Declare data to be put into read-only memory as you say. That's fine with a 'const int * p', but what about a 'int * const p'? If the compiler can tell where p is initially pointing, it could put the pointer in read-only memory. Probably unlikely to happen in real code, though. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-13, Stefan Ramwrote: > Grant Edwards writes: There is no such >>thing as a "byte" in C. > > »3.6 > > 1 byte > > addressable unit of data storage large enough to hold > any member of the basic character set of the execution > environment« > > ISO C standard Ah, I had forgotten about that paragraph. Now that I see the phrase "large enough to hold any member of the basic character set of the execution environment", I'm pretty sure I knew that at some point in the past. That means that in the context of the ISO C standard, on that architecture, 1 byte is 32 bits. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Steve D'Apranowrote: > On Fri, 13 Oct 2017 02:06 am, Grant Edwards wrote: > >> It sure was an education the first I wrote C code for >> a machine where >> >> 1 == sizeof char == sizeof int == sizeof long == sizeof float == sizeof >> double >> >> All were 32 bits. > > > Does that imply that on that machine 1 byte = 32 bits? Maybe. That depends on what you mean by "byte". There is no such thing as a "byte" in C. The smallest addressable unit of memory in C is a "char". Nothing in C says that incrementing an address by 1 gets you to the next 8-bit chunk of memory. According to the "Byte" Wikipedia article: The size of the byte has historically been hardware dependent and no definitive standards existed that mandated the size -- byte-sizes from 1 to 48 bits are known to have been used in the past. The IEEE standards use the word "octet" to refer to a an 8-bit chunk of memory. When working with an architecture with a 32-bit char, you didn't use the word "byte" if you wanted to avoid confusion. > I don't suppose you remember the name of the machine do you? Texas Instruments TMS32C40. It's pretty common on DSPs to have only a single size for all datatypes. The 'C40 as pretty high-end -- it had floating point. Though I had to write routines to convert between IEE-754 and the native 32-bit format when I wanted to exchange floating point data with the outside world. :) -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On Fri, Oct 13, 2017 at 10:14 AM, Ben Bacarissewrote: > Chris Angelico writes: >> I abbreviated that down to nothing, but since you ask, here's a really >> REALLY simple run-down of how to use Heroku: > > I think I see what you mean now. You meant no configuration is needed > because you use (or buy?) a cloud service that's all set up for it > already? Correct - because the setup needed is completely generic. > From this and other posts I think the position is that I do need to do > some server configuration (and essentially install a proxy server) to > run Python web applications on my typical Apache set-up. And I would > then have to shop around for suitable hosting that is already set up for > running them. > > > > Thanks. That's not quite what I was after but it's good to know how to > do that should I want to that later. Yep, it's not too hard. And that's why it's cleaner to work with Python than PHP. To use custom URL routing in PHP, you have to use custom server rules; to use custom URL routing in Python, you use "@app.route(...)" lines inside your app, and perfectly standard server rules. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Fri, 13 Oct 2017 02:06 am, Grant Edwards wrote: > It sure was an education the first I wrote C code for > a machine where > > 1 == sizeof char == sizeof int == sizeof long == sizeof float == sizeof > double > > All were 32 bits. Does that imply that on that machine 1 byte = 32 bits? I don't suppose you remember the name of the machine do you? > Writing protocol code that dealt with the outside world via a serial > port was _painful_. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Heroku (was Re: Lies in education [was Re: The "loop and a half"])
Chris Angelicowrites: > On Fri, Oct 13, 2017 at 1:09 AM, Ben Bacarisse wrote: >> Chris Angelico writes: >> >>> On Thu, Oct 12, 2017 at 7:32 PM, Thomas Jollans wrote: On 2017-10-12 07:31, Chris Angelico wrote: > On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse > wrote: >> Provided some early part of the URL is handled by PHP, the rest of the >> URL path is provided to PHP in $_SERVER["PATH_INFO"]. > > Is it possible to do that without having ".php" visible in the path? Just like with Python-based frameworks, this requires a few lines of web server configuration. On Apache, you might use mod_wsgi to tell the server how to run the code in one case, and a combination of mod_php and mod_rewrite in the other. If you're using FastCGI with nginx or lighttpd, I believe the configuration would look pretty similar in both cases. Then again, I don't do much web programming any more and generally stay away from PHP, so I may be misremembering. >>> >>> Normally, with a Python-based framework, you don't need _any_ web >>> server configuration. You simply define your URL routing within the >>> Python code. The only thing the web server needs to know is where to >>> find the web app, and that's sufficiently standard that it can be done >>> off-the-shelf; for instance, you push your code to Heroku, and they >>> set everything up to pass requests to your app. Not possible with PHP, >>> since you need *custom* web server config to manage your rewrite >>> rules. >> >> That's at odds with what I've read online which admittedly may be all >> junk. I wanted to try Flask so I installed the Ubuntu packages but then >> got stuck on a huge document that suggested I needed to install things >> called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm >> sure the complex instructions I found are not really required -- it was >> probably just the usual "this is what I did so this is how it's done" >> document, but I'm having trouble finding the simpler way to do it. >> >> Since no web server configuration is needed (I have a working Apache >> installation that mirrors, as closely as possible, what my hosting >> provider uses) it should be relatively easy. Can you tell me, or can >> you point me to a resource that tells me, where to put the app? I don't >> yet know what "push your code to Heroku" means. > > I abbreviated that down to nothing, but since you ask, here's a really > REALLY simple run-down of how to use Heroku: I think I see what you mean now. You meant no configuration is needed because you use (or buy?) a cloud service that's all set up for it already? >From this and other posts I think the position is that I do need to do some server configuration (and essentially install a proxy server) to run Python web applications on my typical Apache set-up. And I would then have to shop around for suitable hosting that is already set up for running them. Thanks. That's not quite what I was after but it's good to know how to do that should I want to that later. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Jon Ribbenswrites: > On 2017-10-12, Ben Bacarisse wrote: >> I see. If I'm reading this right, the app requests are passed through >> to another server -- uWSGI. > > Yes. It doesn't have to be uWSGI; it could be gunicorn, or you could > probably use Apache's mod_fcgid. As a last resort you could use CGI, > which wouldn't involve any long-running processes, which has the > benefit of not requiring any special support from your host but the > disadvantage of most likely being very slow indeed. > >> How does this typically work on low-cost hosting? I may be able to set >> up the ProxyPass locally (i.e. in .htaccess) but I won't be able to >> write /etc/uwsgi/apps-available/appname.ini. Maybe there are a locally >> defined .ini files that uwsgi reads? > > You need to choose a host that supports one of the relevant systems > mentioned above. If you already have a host then it's possible they > already do, otherwise you may need to choose another. Ah, thanks. You've cleared up some of miasma of terms that seems to surround the various Python-for-the-web options. I'd like to try it, but not enough to switch hosting and, probably, spend more money. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12 03:47, ROGER GRAYDON CHRISTMAN wrote: Actually, FORTRAN and COBOL and Algol (for its control structures) Trying to support both of the first two was entertaining -- when you declared a variable, it wasn't enough to say it was an Integer: you had to also declare whether it was represented in Binary or Decimal, and also specify the desired precision. The IBM/360 architecture supported both binary and decimal integers, where the decimals were stored as BCD nybbles of arbitrary fixed length (as opposed to binary integers matching the machine word size) The world migrated away from PL/I back in those days because of the one-size fits none consequences of trying to do everything. So I always find myself looking askance when language designers try to repeat the exercise. You know, like designing a largely-interpreted object-oriented language with libraries supporting a functional programming style. I think I've seen a language like that somewhere around this forum. But I like it anyway I think the difference is that those other languages tried to be "complete" closed languages. Python, on the other hand, doesn't try to do everything itself, and it's open, so you can add functionality written in other languages and call external programs that already exist. [snip] -- https://mail.python.org/mailman/listinfo/python-list
Heroku (was Re: Lies in education [was Re: The "loop and a half"])
On Fri, Oct 13, 2017 at 1:09 AM, Ben Bacarissewrote: > Chris Angelico writes: > >> On Thu, Oct 12, 2017 at 7:32 PM, Thomas Jollans wrote: >>> On 2017-10-12 07:31, Chris Angelico wrote: On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse wrote: > Provided some early part of the URL is handled by PHP, the rest of the > URL path is provided to PHP in $_SERVER["PATH_INFO"]. Is it possible to do that without having ".php" visible in the path? >>> >>> Just like with Python-based frameworks, this requires a few lines of web >>> server configuration. >>> >>> On Apache, you might use mod_wsgi to tell the server how to run the code >>> in one case, and a combination of mod_php and mod_rewrite in the other. >>> If you're using FastCGI with nginx or lighttpd, I believe the >>> configuration would look pretty similar in both cases. >>> >>> Then again, I don't do much web programming any more and generally stay >>> away from PHP, so I may be misremembering. >> >> Normally, with a Python-based framework, you don't need _any_ web >> server configuration. You simply define your URL routing within the >> Python code. The only thing the web server needs to know is where to >> find the web app, and that's sufficiently standard that it can be done >> off-the-shelf; for instance, you push your code to Heroku, and they >> set everything up to pass requests to your app. Not possible with PHP, >> since you need *custom* web server config to manage your rewrite >> rules. > > That's at odds with what I've read online which admittedly may be all > junk. I wanted to try Flask so I installed the Ubuntu packages but then > got stuck on a huge document that suggested I needed to install things > called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm > sure the complex instructions I found are not really required -- it was > probably just the usual "this is what I did so this is how it's done" > document, but I'm having trouble finding the simpler way to do it. > > Since no web server configuration is needed (I have a working Apache > installation that mirrors, as closely as possible, what my hosting > provider uses) it should be relatively easy. Can you tell me, or can > you point me to a resource that tells me, where to put the app? I don't > yet know what "push your code to Heroku" means. I abbreviated that down to nothing, but since you ask, here's a really REALLY simple run-down of how to use Heroku: 1) Create a git repository to manage your code. (You should be doing this anyway.) 2) Install the Heroku CLI for your platform 3) Run "heroku login" and enter your credentials (once) 4) Run "heroku create" from your project repo to generate a URL to use for the project 5) Ensure that you list all your requirements in a file called "requirements.txt". Heroku uses this to (a) recognize that it's a Python project, and (b) install your dependencies, with "pip install -r requirements.txt". 6) Tell Heroku how to find your main file by making a file called "Procfile" 7) Run: "git push heroku master" There are other ways to do things (notably, Heroku will work with GitHub and Travis to do CI/CD just by pushing code to the master branch on GitHub - Travis will run your tests and then push to Heroku for you), but this is about the simplest it gets. Yes, there are a good few steps there, but most of them are simple one-offs, or are things you should do anyway. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Ben Bacarissewrote: > I see. If I'm reading this right, the app requests are passed through > to another server -- uWSGI. Yes. It doesn't have to be uWSGI; it could be gunicorn, or you could probably use Apache's mod_fcgid. As a last resort you could use CGI, which wouldn't involve any long-running processes, which has the benefit of not requiring any special support from your host but the disadvantage of most likely being very slow indeed. > How does this typically work on low-cost hosting? I may be able to set > up the ProxyPass locally (i.e. in .htaccess) but I won't be able to > write /etc/uwsgi/apps-available/appname.ini. Maybe there are a locally > defined .ini files that uwsgi reads? You need to choose a host that supports one of the relevant systems mentioned above. If you already have a host then it's possible they already do, otherwise you may need to choose another. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Thomas Jollanswrites: > On 2017-10-12 15:16, Ben Bacarisse wrote: >> Gregory Ewing writes: >> >>> Ben Bacarisse wrote: That's a different type. I think you mean that a human writing C (rather than bartc's code generator) would probably design the code to use tokenrec ** then I agree, but the latter is not just a different way to write the former. >>> >>> Yes, I was translating his English description of the type >>> into C, using C's meaning of the word "array". It seems that >>> arrays in the original language (Algol? One of Bart's >>> inventions?) are somewhat richer things. >> >> Probably, but you can have pointers to array types in C which is what >> the posted type used. Humans pass arrays in C by passing a pointer to >> the first element. Pointers to arrays therefore crop up when passing 2D >> (or higher) arrays, even when the code is hand written by a person. >> > > No, actually. Multi-dimensional arrays in C are not arrays of arrays. That's exactly what they are (in their simplest form). Other structures using pointers can be accessed in the same way so some people call those multi-dimensional arrays, but that can be a bit confusing. > They look very similar, but when the dimensions of the array are known > at compile time, arrays of any rank are a continuous region of memory > with the data, and a pointer to the start. > > Casting int[3][3] to int** will not do what you want it to do. Exactly. This is why I raised this as an example where you get a pointer to an array type. int ** is something else altogether. When you pass an int[3][3] to a function, it pops up in the function as an int (*)[3]. You can (due to another of C's odd rules) write the parameter as int a[][3], or int a[3][3], but the first array in the declarator is replaced by a pointer (and the size is ignored). > If, say, you have variables of the types: > > int a[M][N], **b; > > then a[i][j] is equivalent to *(a+(i*M)+j), No it isn't. That expression does not even have type int. In fact you will be surprised to learn that a[i][j] it is equivalent to *(*(a+i)+j). > while b[i][j] is equivalent to *(*(b+i)+j). That much is true. The fact that the genuine 2D array access (a[i][j]) is equivalent an expression of the same form as the pointer to pointer access (b[i][j]) looks odd because, as you know, they are doing different things. But they do different things because the types are different. > Observe: > short multi_array[3][3] = { > {1, 0, 0}, > {0, 1, 0}, > {0, 0, 1} > }; > short *array_array[3]; I would not have used that name. This is an array of pointers. > /* fill array_array elements of multi_array */ > for(i=0; i<3; ++i) { > array_array[i] = calloc(3, sizeof(short)); > /* This works because C arrays are row-major */ > memcpy(array_array[i], _array[i][0], 3*sizeof(short)); Some people would find array_array[i] = malloc(sizeof multi_array[i]); memcpy(array_array[i], multi_array[i], sizeof multi_array[i]); to be clearer and more maintainable. You don't repeat the element type and there's no need to reference the (possibly arbitrary) size 3. It makes it very clear that enough space is being allocated for what is being copied. > } > > /* print out the arrays */ > puts("multi_array:"); > for (i=0; i<3; ++i) { > for (j=0; j<3; ++j) { > printf("%d ", multi_array[i][j]); Try *(multi_array+(i*3)+j) here to see what happens (that's your re-write with 'a' and 'M' substituted). > } > puts(""); > } -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Rhodri Jameswrote: > On 12/10/17 16:06, Grant Edwards wrote: >> On 2017-10-12, Steve D'Aprano wrote: >>> On Thu, 12 Oct 2017 04:41 pm, Grant Edwards wrote: >>> > Even two different C compilers could return different values. Nope. If sizeof char is not 1, then it's not C. >>> >>> Today I Learned. >> >> It sure was an education the first I wrote C code for >> a machine where >> >> 1 == sizeof char == sizeof int == sizeof long == sizeof float == sizeof >> double >> >> All were 32 bits. > > Ah yes. In my case it was 16 bits, so sizeof long == 2 just for a > little variation. It does help when a char is an integral number of octets. Working with a machine where everything is 20 bits would be even worse. I wonder if anybody ever designed a CPU where the word size was odd? -- Grant Edwards grant.b.edwardsYow! How many retured at bricklayers from FLORIDA gmail.comare out purchasing PENCIL SHARPENERS right NOW?? -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Jon Ribbenswrites: > On 2017-10-12, Ben Bacarisse wrote: >> Chris Angelico writes: >>> Normally, with a Python-based framework, you don't need _any_ web >>> server configuration. You simply define your URL routing within the >>> Python code. The only thing the web server needs to know is where to >>> find the web app, and that's sufficiently standard that it can be done >>> off-the-shelf; for instance, you push your code to Heroku, and they >>> set everything up to pass requests to your app. Not possible with PHP, >>> since you need *custom* web server config to manage your rewrite >>> rules. >> >> That's at odds with what I've read online which admittedly may be all >> junk. I wanted to try Flask so I installed the Ubuntu packages but then >> got stuck on a huge document that suggested I needed to install things >> called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm >> sure the complex instructions I found are not really required -- it was >> probably just the usual "this is what I did so this is how it's done" >> document, but I'm having trouble finding the simpler way to do it. >> >> Since no web server configuration is needed (I have a working Apache >> installation that mirrors, as closely as possible, what my hosting >> provider uses) it should be relatively easy. Can you tell me, or can >> you point me to a resource that tells me, where to put the app? I don't >> yet know what "push your code to Heroku" means. > > "don't need _any_ web server configuration" is rather, er, optimistic. It did seem so. I could not imagine any way it would "just" work unless it was already set up to "just work". > For Apache you'd need the mod_proxy_uwsgi module installed, and the > config would be something like this: > > DocumentRoot /srv/www/appname/appname > > ProxyPass uwsgi://127.0.0.1:3031/ > > > ProxyPass ! > > > and you need an app container listening on the port defined above, > e.g. uwsgi with config like: > > /etc/uwsgi/apps-available/appname.ini: > > [uwsgi] > plugin = python3 > socket = 127.0.0.1:3031 > threads = 4 > master = 1 > chdir = /srv/www/appname > module = appname:app > # https://github.com/unbit/uwsgi/issues/1126 > wsgi-disable-file-wrapper = true > > and you'll need something to run uwsgi on system startup. I see. If I'm reading this right, the app requests are passed through to another server -- uWSGI. How does this typically work on low-cost hosting? I may be able to set up the ProxyPass locally (i.e. in .htaccess) but I won't be able to write /etc/uwsgi/apps-available/appname.ini. Maybe there are a locally defined .ini files that uwsgi reads? As for running something on startup... I suppose I can ask. Maybe it's usual to run it anyway. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 12/10/2017 16:18, Marko Rauhamaa wrote: Grant Edwards: Using const with strings in C with amateurish libraries is a headache because _some_people_ will write their declarations so as to require pointers to mutable strings even when they have no intention of mutating them. Those people should be hunted down and slapped with a herring until they understand the error of their ways. Hear, hear. The standard library is much better about that. You lost me there. Seriously, though. C strings are not the most problematic issue. How about other structures? What about: long ftell(FILE *stream); int fgetpos(FILE *stream, fpos_t *pos); Should that be "const FILE *stream"? In general, C record definitions (opaque structs) that represent encapsulated classes don't take a "const" in any context. They *could* but that isn't the tradition. For example, here's a random function from the Linux kernel: static bool tcp_fastopen_cookie_gen(struct request_sock *req, struct sk_buff *syn, struct tcp_fastopen_cookie *foc) { if (req->rsk_ops->family == AF_INET) { const struct iphdr *iph = ip_hdr(syn); __be32 path[4] = { iph->saddr, iph->daddr, 0, 0 }; return __tcp_fastopen_cookie_gen(path, foc); } #if IS_ENABLED(CONFIG_IPV6) if (req->rsk_ops->family == AF_INET6) { const struct ipv6hdr *ip6h = ipv6_hdr(syn); struct tcp_fastopen_cookie tmp; if (__tcp_fastopen_cookie_gen(>saddr, )) { struct in6_addr *buf = (struct in6_addr *) tmp.val; int i; for (i = 0; i < 4; i++) buf->s6_addr32[i] ^= ip6h->daddr.s6_addr32[i]; return __tcp_fastopen_cookie_gen(buf, foc); } } #endif return false; } If you took a working C program and removed all the consts, it would still work. I don't think the language would miss them if they were to disappear. It is anyway too crude a technique for the things people like to apply it to. > > Note how both "req" and "syn" could well be declared as "const" > pointers but are not. const pointer, or pointer to const struct? Or both? With a const struct, you are stopped from directly modifying elements, but if an element is a pointer, nothing stops you writing to what the pointer points to, unless that has a const target too. And then you've going to have problems doing normal updates. This constness just insinuates itself everywhere. -- bartc -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 12/10/17 16:06, Grant Edwards wrote: On 2017-10-12, Steve D'Apranowrote: On Thu, 12 Oct 2017 04:41 pm, Grant Edwards wrote: Even two different C compilers could return different values. Nope. If sizeof char is not 1, then it's not C. Today I Learned. It sure was an education the first I wrote C code for a machine where 1 == sizeof char == sizeof int == sizeof long == sizeof float == sizeof double All were 32 bits. Ah yes. In my case it was 16 bits, so sizeof long == 2 just for a little variation. Writing protocol code that dealt with the outside world via a serial port was _painful_. Amen, brother. -- Rhodri James *-* Kynesim Ltd -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Marko Rauhamaawrote: > Grant Edwards : > >> Using const with strings in C with amateurish libraries is a headache >> because _some_people_ will write their declarations so as to require >> pointers to mutable strings even when they have no intention of >> mutating them. Those people should be hunted down and slapped with a >> herring until they understand the error of their ways. > > Hear, hear. > >> The standard library is much better about that. > > You lost me there. I meant that in the include files for the C standard library, functions that aren't going to modify a string paramameter always declare the parameter as "const char *". > Seriously, though. C strings are not the most problematic issue. How > about other structures? What about: > >long ftell(FILE *stream); >int fgetpos(FILE *stream, fpos_t *pos); > > Should that be "const FILE *stream"? IMO, yes. > In general, C record definitions (opaque structs) that represent > encapsulated classes don't take a "const" in any context. They > *could* but that isn't the tradition. In my own code I do try to do that, but (as in the Linux kernel code you posted) you still run into problems using third-party libraries written by the, um, unenlightened. > For example, here's a random function from > the Linux kernel: > > > static bool tcp_fastopen_cookie_gen(struct request_sock *req, > struct sk_buff *syn, > struct tcp_fastopen_cookie *foc) > { [...] > Note how both "req" and "syn" could well be declared as "const" pointers > but are not. Yep. IMO, that's just sloppy programming. -- Grant Edwards grant.b.edwardsYow! Can you MAIL a BEAN at CAKE? gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Grant Edwards: > Using const with strings in C with amateurish libraries is a headache > because _some_people_ will write their declarations so as to require > pointers to mutable strings even when they have no intention of > mutating them. Those people should be hunted down and slapped with a > herring until they understand the error of their ways. Hear, hear. > The standard library is much better about that. You lost me there. Seriously, though. C strings are not the most problematic issue. How about other structures? What about: long ftell(FILE *stream); int fgetpos(FILE *stream, fpos_t *pos); Should that be "const FILE *stream"? In general, C record definitions (opaque structs) that represent encapsulated classes don't take a "const" in any context. They *could* but that isn't the tradition. For example, here's a random function from the Linux kernel: static bool tcp_fastopen_cookie_gen(struct request_sock *req, struct sk_buff *syn, struct tcp_fastopen_cookie *foc) { if (req->rsk_ops->family == AF_INET) { const struct iphdr *iph = ip_hdr(syn); __be32 path[4] = { iph->saddr, iph->daddr, 0, 0 }; return __tcp_fastopen_cookie_gen(path, foc); } #if IS_ENABLED(CONFIG_IPV6) if (req->rsk_ops->family == AF_INET6) { const struct ipv6hdr *ip6h = ipv6_hdr(syn); struct tcp_fastopen_cookie tmp; if (__tcp_fastopen_cookie_gen(>saddr, )) { struct in6_addr *buf = (struct in6_addr *) tmp.val; int i; for (i = 0; i < 4; i++) buf->s6_addr32[i] ^= ip6h->daddr.s6_addr32[i]; return __tcp_fastopen_cookie_gen(buf, foc); } } #endif return false; } Note how both "req" and "syn" could well be declared as "const" pointers but are not. Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12 15:16, Ben Bacarisse wrote: > Gregory Ewingwrites: > >> Ben Bacarisse wrote: >>> That's a different type. I think you mean that a human writing C >>> (rather than bartc's code generator) would probably design the code to >>> use tokenrec ** then I agree, but the latter is not just a different way >>> to write the former. >> >> Yes, I was translating his English description of the type >> into C, using C's meaning of the word "array". It seems that >> arrays in the original language (Algol? One of Bart's >> inventions?) are somewhat richer things. > > Probably, but you can have pointers to array types in C which is what > the posted type used. Humans pass arrays in C by passing a pointer to > the first element. Pointers to arrays therefore crop up when passing 2D > (or higher) arrays, even when the code is hand written by a person. > No, actually. Multi-dimensional arrays in C are not arrays of arrays. They look very similar, but when the dimensions of the array are known at compile time, arrays of any rank are a continuous region of memory with the data, and a pointer to the start. Casting int[3][3] to int** will not do what you want it to do. If, say, you have variables of the types: int a[M][N], **b; then a[i][j] is equivalent to *(a+(i*M)+j), while b[i][j] is equivalent to *(*(b+i)+j). Observe: --- #include #include #include int main (int argc, char **argv) { int i,j; /* multi-dimensional array: the compiler knows the dimensions! */ short multi_array[3][3] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }; short *array_array[3]; /* fill array_array elements of multi_array */ for(i=0; i<3; ++i) { array_array[i] = calloc(3, sizeof(short)); /* This works because C arrays are row-major */ memcpy(array_array[i], _array[i][0], 3*sizeof(short)); } /* print out the arrays */ puts("multi_array:"); for (i=0; i<3; ++i) { for (j=0; j<3; ++j) { printf("%d ", multi_array[i][j]); } puts(""); } puts("array_array:"); for (i=0; i<3; ++i) { for (j=0; j<3; ++j) { printf("%d ", array_array[i][j]); } puts(""); } printf("_array = 0x%llX\n", (long long)_array); printf("*multi_array = 0x%llX\n", (long long)(*(short**)multi_array)); printf("_array = 0x%llX\n", (long long)_array); printf("*array_array = 0x%llX\n", (long long)(*(short**)array_array)); /* clean up */ for (i=0; i<3; ++i) { free(array_array[i]); } return 0; } --- [OUTPUT] multi_array: 1 0 0 0 1 0 0 0 1 array_array: 1 0 0 0 1 0 0 0 1 _array = 0x7FFE0E736470 *multi_array = 0x1 _array = 0x7FFE0E736450 *array_array = 0x1A42010 -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Steve D'Apranowrote: > On Thu, 12 Oct 2017 04:41 pm, Grant Edwards wrote: > > >>> Even two >>> different C compilers could return different values. >> >> Nope. If sizeof char is not 1, then it's not C. > > Today I Learned. It sure was an education the first I wrote C code for a machine where 1 == sizeof char == sizeof int == sizeof long == sizeof float == sizeof double All were 32 bits. Writing protocol code that dealt with the outside world via a serial port was _painful_. -- Grant Edwards grant.b.edwardsYow! ... I want a COLOR at T.V. and a VIBRATING BED!!! gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Marko Rauhamaawrote: > Chris Angelico : > >> On Thu, Oct 12, 2017 at 6:22 PM, Marko Rauhamaa wrote: >>> Additionally, you can launder any constant string into a nonconstant >>> string with strstr(3): >>> >>> const char *cs = "hello"; >>> char *s = strstr(cs, ""); >>> s[0] = 'y'; >> >> Well hey, if you want that, you can just cast the pointer. > > Point is, there is no legitimate way to implement the strstr(3) > prototype. Somebody must be lying through their teeth. That's indeed a problem. Personally, I would just use two prototypes: char *strcstr(const char *s, char *s); const char *cstrstr(const char *s, const char *s); Whether you want to invoke some linker-script magic to make them refer to the same blob of code or not is optional. -- Grant Edwards grant.b.edwardsYow! I want my nose in at lights! gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Neil Ceruttiwrote: > On 2017-10-12, Marko Rauhamaa wrote: >> Bill : >> >>> Marko Rauhamaa wrote: One example is the surprising fact that string literals in C are "char *" and not "const char *". Yep, that's the basis for a lot of the problems with 'const' in C. Unfortunately for historical reasons, a lot of people expect string literals to be mutable. That should have been stamped out decades ago, but it's too late now. >>> If not, you couldn't pass a string literal to a function >>> having prototype void f(char *s); IMO, it should be illegal to pass a string literal to a function with prototype f(char *s). You shouldn't try to modify a string literal, and if f() isn't going to modify the string, it should have been declared f(const char *s). >> That *ought* to be prevented. That's the whole point. > > I'm far less experienced in C, but I threw up my hands and stopped > bothering with const qualifiers in C due to such headaches. When in > Rome, program without const qualifiers in C. Using const with strings in C with amateurish libraries is a headache because _some_people_ will write their declarations so as to require pointers to mutable strings even when they have no intention of mutating them. Those people should be hunted down and slapped with a herring until they understand the error of their ways. The standard library is much better about that. -- Grant Edwards grant.b.edwardsYow! Kids, don't gross me at off ... "Adventures with gmail.comMENTAL HYGIENE" can be carried too FAR! -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Ben Bacarissewrote: > Chris Angelico writes: >> Normally, with a Python-based framework, you don't need _any_ web >> server configuration. You simply define your URL routing within the >> Python code. The only thing the web server needs to know is where to >> find the web app, and that's sufficiently standard that it can be done >> off-the-shelf; for instance, you push your code to Heroku, and they >> set everything up to pass requests to your app. Not possible with PHP, >> since you need *custom* web server config to manage your rewrite >> rules. > > That's at odds with what I've read online which admittedly may be all > junk. I wanted to try Flask so I installed the Ubuntu packages but then > got stuck on a huge document that suggested I needed to install things > called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm > sure the complex instructions I found are not really required -- it was > probably just the usual "this is what I did so this is how it's done" > document, but I'm having trouble finding the simpler way to do it. > > Since no web server configuration is needed (I have a working Apache > installation that mirrors, as closely as possible, what my hosting > provider uses) it should be relatively easy. Can you tell me, or can > you point me to a resource that tells me, where to put the app? I don't > yet know what "push your code to Heroku" means. "don't need _any_ web server configuration" is rather, er, optimistic. For Apache you'd need the mod_proxy_uwsgi module installed, and the config would be something like this: DocumentRoot /srv/www/appname/appname ProxyPass uwsgi://127.0.0.1:3031/ ProxyPass ! and you need an app container listening on the port defined above, e.g. uwsgi with config like: /etc/uwsgi/apps-available/appname.ini: [uwsgi] plugin = python3 socket = 127.0.0.1:3031 threads = 4 master = 1 chdir = /srv/www/appname module = appname:app # https://github.com/unbit/uwsgi/issues/1126 wsgi-disable-file-wrapper = true and you'll need something to run uwsgi on system startup. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, 12 Oct 2017 11:01 pm, Stefan Ram quoted: > Basically I got sick of every single > aspect of C++ being designed around higher performance > instead of my productivity. Unlike C, where every single aspect of the language is designed around higher performance instead of the developer's productivity. > [...] If I had to write a > high performance application these days I would reach > for C. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelicowrites: > On Thu, Oct 12, 2017 at 7:32 PM, Thomas Jollans wrote: >> On 2017-10-12 07:31, Chris Angelico wrote: >>> On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse >>> wrote: Provided some early part of the URL is handled by PHP, the rest of the URL path is provided to PHP in $_SERVER["PATH_INFO"]. >>> >>> Is it possible to do that without having ".php" visible in the path? >> >> Just like with Python-based frameworks, this requires a few lines of web >> server configuration. >> >> On Apache, you might use mod_wsgi to tell the server how to run the code >> in one case, and a combination of mod_php and mod_rewrite in the other. >> If you're using FastCGI with nginx or lighttpd, I believe the >> configuration would look pretty similar in both cases. >> >> Then again, I don't do much web programming any more and generally stay >> away from PHP, so I may be misremembering. > > Normally, with a Python-based framework, you don't need _any_ web > server configuration. You simply define your URL routing within the > Python code. The only thing the web server needs to know is where to > find the web app, and that's sufficiently standard that it can be done > off-the-shelf; for instance, you push your code to Heroku, and they > set everything up to pass requests to your app. Not possible with PHP, > since you need *custom* web server config to manage your rewrite > rules. That's at odds with what I've read online which admittedly may be all junk. I wanted to try Flask so I installed the Ubuntu packages but then got stuck on a huge document that suggested I needed to install things called Nginx and Gunicorn. You've now mentioned another: Heroku. I'm sure the complex instructions I found are not really required -- it was probably just the usual "this is what I did so this is how it's done" document, but I'm having trouble finding the simpler way to do it. Since no web server configuration is needed (I have a working Apache installation that mirrors, as closely as possible, what my hosting provider uses) it should be relatively easy. Can you tell me, or can you point me to a resource that tells me, where to put the app? I don't yet know what "push your code to Heroku" means. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12 14:01, Stefan Ram wrote: > Many of the quotations are from the previous decade. Thanks Stefan, that was fun. > I must say that C++ has improved in this decade (the 2010s), > and there also is a rennaisance of C and C++ (compared to > "coffee languages") usage because single-thread processor > speeds do not grow anymore ("the free lunch is over") and so > in the 2010s C and C++ are more valued as efficiency > languages (also saving energy in the data centers). This is precisely the motivation of languages like Rust, Go and (in a way) Julia: "C++ is horrid, but C is a slog. Python is too slow for [insert specific use case]. There has to be a better way!" -- Thomas Jollans -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12, Marko Rauhamaawrote: > Bill : > >> Marko Rauhamaa wrote: >>> One example is the surprising fact that string literals in C >>> are "char *" and not "const char *". >> >> If not, you couldn't pass a string literal to a function >> having prototype void f(char *s); > > That *ought* to be prevented. That's the whole point. I'm far less experienced in C, but I threw up my hands and stopped bothering with const qualifiers in C due to such headaches. When in Rome, program without const qualifiers in C. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-11, Gregory Ewingwrote: > Neil Cerutti wrote: >> I dig const qualifiers, even though I'm comletely fine with >> their absence from Python. > > Out of curiosity, do you have any insights into why you like > them in C++, if you don't miss them in Python? I can tell at a glance if a parameter is expected to be modifiable just by looking at the function signature. Also using reference types feels more comfortable when it's easy to know it won't be changed. This isn't technical, but it feels somehow satifying the way const propogates seemlessly through a well-designed interface. When programming Python, the only constants I care about are magic numbers and lookup tables defined at the top of a program or outside the program. If there are enough of them I'll put them in a module or class/namespace. They don't exist in interfaces, so I don't think about them in that sense. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Gregory Ewingwrites: > Ben Bacarisse wrote: >> That's a different type. I think you mean that a human writing C >> (rather than bartc's code generator) would probably design the code to >> use tokenrec ** then I agree, but the latter is not just a different way >> to write the former. > > Yes, I was translating his English description of the type > into C, using C's meaning of the word "array". It seems that > arrays in the original language (Algol? One of Bart's > inventions?) are somewhat richer things. Probably, but you can have pointers to array types in C which is what the posted type used. Humans pass arrays in C by passing a pointer to the first element. Pointers to arrays therefore crop up when passing 2D (or higher) arrays, even when the code is hand written by a person. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelico: > On Thu, Oct 12, 2017 at 8:20 PM, Marko Rauhamaa wrote: >> BTW, C++ tries to be a bit stricter about "const". It declares two >> separate prototypes: >> >>const char *strstr(const char *, const char *); >>char *strstr(char *, const char *); >> >> http://www.cplusplus.com/reference/cstring/strstr/> >> >> Also, in C++, string literals are "const char *". > > So basically, C++ fixed some problems in C, in the same way that > Python 3 fixed some problems in Python 2. Yet for some reason Python 3 > is killing Python, but C++ isn't killing C. Not sure how that works. I have bitten the bullet and do my Python development in Python3. There's no going back. As far as C++ goes, though, it didn't succeed in becoming the "fulfillment" of C programming. In fact, it started a whole new religion. C and C++ share the same Old Testament but have completely different virtues and tenets. I'm not convinced by the tenets of C++. Marko -- https://mail.python.org/mailman/listinfo/python-list
Re: OT: MPC-HC project ending? [Re: Lies in education [was Re: The "loop and a half"]]
On Thursday, October 12, 2017 at 12:33:09 PM UTC+1, Chris Angelico wrote: > On Thu, Oct 12, 2017 at 8:12 PM, Thomas Jollans wrote: > > On 2017-10-12 02:51, Chris Angelico wrote: > >> If it wants new life, it's probably going to need a Linux version, > >> because that's where a lot of developers hang out. The reality is that > >> open source developers are much more likely to develop on Linux than > >> on Windows; you can maintain a Windows port of a Linux program with > >> fewer Windows experts than maintaining the entire program on Windows. > >> > >> The other option, though, would be for the useful parts to become > >> feature suggestions for VLC. > > > > > > It's the year of the Linux desktop! > > > > (No, actually, that was a few years ago, but nobody noticed at the time) > > I'm typing this up from my primary Linux system. Beside me, my laptop > also runs Linux. I use these computers for basically everything - > coding, testing, work, gaming, the lot. Just finished playing an > episode of The Walking Dead, streamed to Twitch.tv; yes, that game > wasn't released for Linux, but thanks to Wine, I can run the Windows > version, and it's flawless. > > It's the year of the Linux desktop alright. Has been for some time, > gonna still be for a while yet. > > ChrisA I have to agree as I've now moved to Linux, Ubuntu as it happens. I wish I'd done it years ago as it feels as if I've had a major hardware upgrade as it's so much more responsive. The most noticeable thing is that when watching videos from YouTube the sound and picture always stay in sync. Not a chance of that with Windows 10. -- Kindest regards. Mark Lawrence. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, 12 Oct 2017 04:41 pm, Grant Edwards wrote: >> Even two >> different C compilers could return different values. > > Nope. If sizeof char is not 1, then it's not C. Today I Learned. Thank you to everyone who corrected me, even the person who said I was not educated. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 12/10/2017 11:39, Stefan Ram wrote: bartcwrites: (1) Define named constants; except (in C) they can't be used like constant expressions, you can take their addresses, and accidentally or maliciously change their values. When I think of »const«, I do not think of ROM. »const« makes code more readable, because it conveys the intentions of the author and simplifies the mental variable model of the reader. »const« helps to find inadvertend modifications. void f( const int i ){ if( i = 4 )putchar( 'x' ); } That's two undesirable language features: (1) Having to use 'const' in front of every simple parameter, so that 'const' now dominates every program; (2) Mixing up '=' and '=='. You're saying it's OK to use both as they sort of cancel each other out! (Other languages solve the =/== problem by either not allowing assignment within an expression, or by using a symbol for it that isn't so easily mistaken for equality.) -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: OT: MPC-HC project ending? [Re: Lies in education [was Re: The "loop and a half"]]
On Thu, Oct 12, 2017 at 8:12 PM, Thomas Jollanswrote: > On 2017-10-12 02:51, Chris Angelico wrote: >> If it wants new life, it's probably going to need a Linux version, >> because that's where a lot of developers hang out. The reality is that >> open source developers are much more likely to develop on Linux than >> on Windows; you can maintain a Windows port of a Linux program with >> fewer Windows experts than maintaining the entire program on Windows. >> >> The other option, though, would be for the useful parts to become >> feature suggestions for VLC. > > > It's the year of the Linux desktop! > > (No, actually, that was a few years ago, but nobody noticed at the time) I'm typing this up from my primary Linux system. Beside me, my laptop also runs Linux. I use these computers for basically everything - coding, testing, work, gaming, the lot. Just finished playing an episode of The Walking Dead, streamed to Twitch.tv; yes, that game wasn't released for Linux, but thanks to Wine, I can run the Windows version, and it's flawless. It's the year of the Linux desktop alright. Has been for some time, gonna still be for a while yet. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, Oct 12, 2017 at 8:20 PM, Marko Rauhamaawrote: > Chris Angelico : > >> On Thu, Oct 12, 2017 at 6:22 PM, Marko Rauhamaa wrote: >>> Additionally, you can launder any constant string into a nonconstant >>> string with strstr(3): >>> >>> const char *cs = "hello"; >>> char *s = strstr(cs, ""); >>> s[0] = 'y'; >> >> Well hey, if you want that, you can just cast the pointer. > > Point is, there is no legitimate way to implement the strstr(3) > prototype. Somebody must be lying through their teeth. > > The idea of "const" (and other type declaration paraphernalia) is to > prevent accidental bugs at compile time. The noble idea of "const" has > been undermined by its sloppy use by the standard libraries and the > language itself. > > BTW, C++ tries to be a bit stricter about "const". It declares two > separate prototypes: > >const char *strstr(const char *, const char *); >char *strstr(char *, const char *); > > http://www.cplusplus.com/reference/cstring/strstr/> > > Also, in C++, string literals are "const char *". So basically, C++ fixed some problems in C, in the same way that Python 3 fixed some problems in Python 2. Yet for some reason Python 3 is killing Python, but C++ isn't killing C. Not sure how that works. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, Oct 12, 2017 at 7:32 PM, Thomas Jollanswrote: > On 2017-10-12 07:31, Chris Angelico wrote: >> On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse wrote: >>> Provided some early part of the URL is handled by PHP, the rest of the >>> URL path is provided to PHP in $_SERVER["PATH_INFO"]. >> >> Is it possible to do that without having ".php" visible in the path? > > Just like with Python-based frameworks, this requires a few lines of web > server configuration. > > On Apache, you might use mod_wsgi to tell the server how to run the code > in one case, and a combination of mod_php and mod_rewrite in the other. > If you're using FastCGI with nginx or lighttpd, I believe the > configuration would look pretty similar in both cases. > > Then again, I don't do much web programming any more and generally stay > away from PHP, so I may be misremembering. Normally, with a Python-based framework, you don't need _any_ web server configuration. You simply define your URL routing within the Python code. The only thing the web server needs to know is where to find the web app, and that's sufficiently standard that it can be done off-the-shelf; for instance, you push your code to Heroku, and they set everything up to pass requests to your app. Not possible with PHP, since you need *custom* web server config to manage your rewrite rules. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
Chris Angelicowrites: > On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarisse wrote: >> Chris Angelico writes: >> >>> On Thu, Oct 12, 2017 at 11:55 AM, Ben Bacarisse >>> wrote: Chris Angelico writes: > it binds your URLs to > the concrete file system. That may not seem like too much of a > problem, but it's a pretty big limitation; you can't have URLs like > "https://en.wikipedia.org/wiki/Foo; without some help from the web > server, eg Apache's mod_rewrite. I don't follow this. Your "can't" and "big limitation" suggests something inevitable, but I don't see it as an intrinsic problem with the language. I'm sure PHP is not as flexible as the frameworks you mention, but you are not tied to URLs mapping to files. Maybe you meant that this is what often happens, or what most people do, with PHP. >>> >>> How would you, with PHP itself, handle database-provided URLs? The >>> only way I've ever seen it done is at an external level - such as >>> mod_rewrite - which means that someone else, *not* the PHP script, is >>> managing your URLs. They're pushed to some external config file >>> somewhere. That's okay for just one URL pattern, but it doesn't scale >>> well, which is why (for example) Wikipedia's editing pages are >>> "/w/index.php?" instead of, say, "/wiki/Foo/edit" or >>> "/wiki/edit/Foo". >>> >>> Unless you know something I don't? >> >> Provided some early part of the URL is handled by PHP, the rest of the >> URL path is provided to PHP in $_SERVER["PATH_INFO"]. > > Is it possible to do that without having ".php" visible in the path? Yes, though because that will depend on how the server is configured I should perhaps say "usually yes"! -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 2017-10-12 07:31, Chris Angelico wrote: > On Thu, Oct 12, 2017 at 12:19 PM, Ben Bacarissewrote: >> Provided some early part of the URL is handled by PHP, the rest of the >> URL path is provided to PHP in $_SERVER["PATH_INFO"]. > > Is it possible to do that without having ".php" visible in the path? Just like with Python-based frameworks, this requires a few lines of web server configuration. On Apache, you might use mod_wsgi to tell the server how to run the code in one case, and a combination of mod_php and mod_rewrite in the other. If you're using FastCGI with nginx or lighttpd, I believe the configuration would look pretty similar in both cases. Then again, I don't do much web programming any more and generally stay away from PHP, so I may be misremembering. -- Thomas Jollans -- https://mail.python.org/mailman/listinfo/python-list