Continued from ValueExistenceProofTwo:
{It's self-evident that constructs like "if (p) {} else {}" and "while (p) {}" have the same semantics in all popular imperative programming languages. That is sufficient to demonstrate commonality.}
I'm sorry, it's not obvious to me. Perhaps CommonSenseIsAnIllusion is applicable. Every head is different. I might use the same thought processes between similar languages, but that is not a necessity, nor do other humans necessarily use the same thought processes that I do. What keeps somebody from using Head Model A for say End-X style block (VB-like) languages and Head Model B for curly-brace-style languages? (PHP) Granted, such may be poor reuse of mental models, but that's a "design quality" issue, not an absolute requirement.
{If it's not obvious that constructs like "if (p) {} else {}" and "while (p) {}" have the same semantics in all popular imperative programming languages, then there should be an example of a popular imperative programming language where "if (p) {} else {}" or "while (p) {}" differs semantically from other popular imperative programming languages. What is that language, and how do "if (p) {} else {}" or "while (p) {}" differ semantically in that language?}
But it may be tradition (historical patterns) that say the End-X block style is interpreted similarly (processed similarly) or matches the curly-brace style. In other words, it is "ingrained" that language patterns such as "while...end while" can be interpreted as (mentally replaced by) "while {...}" There are different mental techniques to arrive at similar answers and thus different mental techniques to apply these cross-substitutions in the mind when needed. For example, person A may think in End-X style and person B think in curly-brace style. When person A sees curly braces, in their mind they will translate to End-X style; and vise versa for person B. To me they are using different semantics in their head, but can cross-translate as needed. Person C may use a mental Tinker-Toy model to "run code" in their head, and translate both End-X and curly-brace style into their tinker-toy model. Person C is not using the same semantics as person A and B, but can translate the syntax to his/her preferred semantic model. I'm not sure there is an objective or clear commonality between all 3 people's head models. X being able to be translated into Y does not necessarily mean X and Y have "common semantics".
{What does this have to do with "head models"? "Different semantics in their head" is irrelevant, and treating "End-X block style" as different from "the curly-brace style" is about syntax, not semantics. Programming language semantics are about how language statements are computed, not what sequences of characters (or whatever) are used to specify them. I know of no language where "if (p) {} else {}" or "IF p THEN ... ELSE ... END IF" does anything but evaluate boolean expression 'p' to determine which of two code blocks is executed. I know of no language where "while (p) {}" or "WHILE p BEGIN ... END WHILE" does anything but repeatedly execute the code block as long as the boolean expression 'p' evaluates to 'true'. You can choose whatever words or formalisms you like to express it or describe it, but what happens in terms of the language on the machine -- i.e., the semantics -- are the same.}
We don't know if it's about semantics or syntax or both without x-ray-ing heads. Heads may be able to gleam a lot of info from JUST syntax patterns; enough to convert it into a personal arbitrary pet "semantic" model. A programmer may think in BrainFsck, and develop mental techniques to internally parse Php into BrainFsck in their head, and then "run" it as BrainFuck in their head. If their head is running BrainFsck, they are NOT processing Algol-style languages.
1. A BrainFsck interpreter does not "have" ("apply"?) Algol-style semantics, correct?
2. And we can write a translator that translates Php into BrainFsck via syntax rules, correct? (I'm assuming here syntax-based translation is not application of "semantics", but since "semantics" is vague, am not fully committing to it.)
3. And then we can run that translated version of code on a BrainFsck interpreter, correct?
4. But the BrainFsck interpreter is STILL NOT processing "Algol-style semantics", correct?
5. Thus, we don't need Algol-style semantics to run/emulate Algol-style code (such as Php), correct?
(Please reply below the list, using the numbers to reference statements.)
{We don't have to "xray heads" to distinguish syntax from semantics. In programming languages, syntax consists of rules -- typically expressed via a grammar -- that define what characters may appear where in order to form valid statements. Semantics describes what the language parts are, how they interact, and what they do at a language level. Semantics are what define that a statement like "a = foo() + b;" means -- and by "means", I mean (hah!) how language statements describe or use variables, assignment, functions, function invocation, addition, values, and so on. All of these things have to be defined, mapped to syntax, and rules created that specify how they interact. That's semantics. When we say, "the keyword 'while' is followed by a left parenthesis, an expression (itself a series of rules for assembling characters), a right parenthesis, a left curly brace, an arbitrary block of code (another set of character sequence rules), and finally a right curly brace", that's syntax. When we say that the syntax describes "a 'while' loop that executes the code block as long as the boolean expression is true", that's semantics.}
- Again, that doesn't communicate to me anything specific or concrete about "semantics". "Meaning" is in human heads and probably subjective; varying per head. Interpreters don't "think" and don't have "ideas". Nor do they translate code to English, and different people will give different English translations/versions of "meaning" of a given code snippet. Semantics may exist in their head, but nothing above proves a measurable commonality between each English writer's "semantics". A rough common generality in such English versions would probably be physical analogies such as moving or copying "stuff" from one "thing" or "object" to another "thing" or "object', not unlike marked bricks from buckets to buckets. But the labels, classification, and/or packaging (grouping) of these things and parts varies.
- {No, variables, assignment, functions, function invocation, addition, values and so on are all very real components of the language, regardless what we call them. We may interpret them different ways, but they execute one way. A loop is still a loop, and a variable is still a variable, whether you recognise it or not.}
- Most of those listed have an objective syntax representation per grammar/parse rules of the language. I don't dispute that. We've been over that already.
- {Sure, in many languages it's possible to unambiguously map syntax to semantics (and in some it's not, or it's very limited) so grammar specifications frequently refer to semantic elements in order to make them easy to read. However, all that syntax really specifies are things like "<sequence of characters> := <sequence of characters> ( <symbol> <sequence of characters> )*". Associating "variable reference" or "expression" with a given <sequence of characters> is semantics.}
- The last sentence is not clear to me. Who or what is doing this associating, and why does association alone make it "semantics" exactly?
- {A language designer defines the association, and a compiler/interpreter writer implements it in code. It's "semantics" because that's what ComputerScience and SoftwareEngineering call it.}
- But it's not formally defined any more than "idea" or "meaning" is formally defined. Just because an (alleged) scientist uses "idea" to describe something does NOT by itself make the term a rigorous concept. Ideas influence language design and algorithms, but that's not the same as "being in" them.
- {What does "formally defined" or "rigorous" have to do with it? Semantics aren't an "idea", they're simply the mapping between language statements and language interpretation. Without such mapping, you have a syntax recogniser and nothing else. With such mapping, you can build an interpreter that implements what the language designer intended.}
- That's an algorithm, not "semantics". Yes, semantics influence algorithms, but that's not the same as "containing" semantics.
- {A variable isn't an algorithm, but what a variable is, in a programming language, is defined by semantics.}
- As we've been around before, "is" is vague. (Bill Clinton was right.) It implies equivalency or classification, which generally is relative to need or context, which is generally notions or ideas in human heads, not machines.
- {Despite "is" apparently being vague, it shows up frequently in English and communication successfully carries on in spite of it. Language consists of two components, syntax and semantics. Every programming language construct -- variables, for example -- will be defined in terms of zero or more syntactic aspects, and zero or more semantic aspects. Note my use of "zero or more": some syntax has no semantic role -- commas in lists, for example -- whilst some semantic elements have no syntactic aspect, such as return values returned by functions.}
- People bicker over categories and classifications all the time in colloquial conversation, such as whether ObamaCare? is socialism. Colloquial English is hardly a model of rigor. (Commas in a list have no "meaning"? That's a curious claim.) A variable "can be viewed as" a StateMachine, but that does not necessarily mean it "is" a StateMachine. "Is" is too strong a statement. Generally one has to select a fairly rigorous model of some concept or idea in order to be able to do rigorous analysis and comparisons on the concept. But participants have to agree on the validity of the model, and they may not necessarily be obligated to do so. TheMapIsNotTheTerritory. I do not accept your version of "value" as a necessary sub-model or "part" of programming language models, even though I accept it as a valid alternative. It's inclusion or exclusion has various trade-offs associated with it, and we disagree over the weighting of these tradeoffs, which I won't get into here.
- {If you're unhappy with the rigour of English, we can switch to using purely mathematical notation. That will make our discussions unambiguous and rigorous, but I suspect they'll be a tad hard to read. People do indeed bicker over categories and classifications, but they don't usually bicker over "is".}
- {The commas in a list have no semantics -- they only syntactically delimit the items. Should "Dave" "Bob" "Richard" mean something different from "Dave", "Bob", "Richard" in a list of names? There's nothing that says we can't associate meaning with commas in a programming language -- say, with commas it's a linked list but without commas it's an array -- but we don't, at least not in any popular imperative programming language that I'm aware of. Commas in a list are there only to simplify the parser and/or improve human readability.}
- [You should check out the comma operator in C or C++.]
- {Ah, of course. They are semantically significant in many languages. I was thinking purely of its use as a separator in, e.g., "int a=1, b=2, c=3, i=0;" I'd forgotten its use as an operator in, say, "i = (a += 3, b + 2)";}
- As far as the list and commas, they do have meaning to me. They tell me adjacent items are not part of the same "cell". I'd likely interpret the list different without commas, or be confused by it. If I saw "Dave" "Bob" "Richard", I wouldn't know what the hell it is (unless some prior convention is established).
- {You are again conflating human interpretation with programming language semantics. The presence or absence of commas in a list of names has no effect on the list of names. Unless we deliberately defined the language so that commas have semantics, the same list would result in the computer's memory (assuming the syntax supports it) whether the commas are there or not.}
- And "is" does create contention fairly often, per my "socialism" example above. And switching to a purely mathematical notation will not necessarily resolve conflicts. Your "math" model would probably define values similar to your existing writeup, and I'd disagree with it, and the same fights would break out. To satisfy your claim that your version of "value" is necessary, you'd have to demonstrate that all possible "correct" models must clearly use your version of "value". This is what I informally refer to as the "uniqueness requirement". (By "correct", I mean "I/O profile" matches as previously defined.) Thus, the existence of a math model by itself won't necessarily resolve conflicts over WetWare issues, which I believe is what this conflict is about, not some universal objective truth. We have multiple models that work correctly. The dispute is whether they reflect "common semantics". Actually, I'm not clear on the scope of your claim. Do you claim that all correct models MUST have your version of "values", or that most developers mentally use your version of it?
- {My claim is that all popular imperative programming languages have "my version" of "values".}
- In ValueExistenceProofTwo I've asked for objective evidence of that, and have not seen a satisfactory answer. But this topic is probably not the place to continue that debate. We also have issues with how "have" is determined/measured for our target purpose.
- {Can you provide evidence of a language that does not have "my version" of values?}
- No, similar to how I cannot verify there are no ghosts on planet Earth. I know of no objective tests of their existence or absence in terms of a language's I/O profile. One approach we've tried is to see whether all possible (or "known" as a sampling proxy) models that match a language's I/O profile require their existence, and that answer clearly is "no" to me. But you claim I'm not recognizing something undefined (to me).
- {What you're not recognising is illustrated by the answer to these simple questions about programming language semantics: What does a variable store? What does a function return? What does an expression evaluate to? These all have the same answer, and it's the same answer in all popular imperative programming languages. It doesn't matter what you call it. What matters is that the answer to these questions possesses the same semantics in every popular imperative programming language, modulo those differences described at the top of TypeSystemCategoriesInImperativeLanguages. You may quibble about minutiae all you like, but the fundamental truth of that is indubitable and borne out by both program behaviour and language references.}
- Re: "These all have the same answer" -- you haven't clearly demonstrated that. Your appear to inject your pet interpretation into them (without realizing it), and mistaking those interpretations for equivalency. What I'd like to see as a starting point is clear steps that resemble the following:
Language A --> semanticsExtractor --> "blazz gim zerf"
Language B --> semanticsExtractor --> "moof plet blanch"
Language C --> semanticsExtractor --> "uugnot zerf pleemp"
write(isSemanticsEquiv("blazz gim zerf","moof plet blanch")); // result: "True" (A==B)
write(isSemanticsEquiv("moof plet blanch","uugnot zerf pleemp")); // result: "True" (B==C)
write(isSemanticsEquiv("blazz gim zerf", "uugnot zerf pleemp")); // result: "True" (A==C)
.
- {What is a "semanticsExtractor"? I can provide evidence that they do have the same answer. Here's some Javascript: "v=3; function foo() {return 3}; alert((v == foo()) == (v == 2 + 1) == (foo() == 2 + 1));" Now, provide evidence that they do not have the same answer.}
- "semanticsExtractor" is some operation that returns some kind of textual representation/notation of semantics. I'll let you decides what that is (although I'll ask a lot of questions about it later). And your example is comparing output, NOT semantics. If you wish to use the stated "I/O profile" criteria to measure "semantic equivalency", or something like it, be my guest. Just be clear that's what you are doing.
- {DenotationalSemantics provides a textual representation/notation of semantics. Is that what you mean? My example isn't comparing output at all. It's comparing the result of a function invocation with what's stored in a variable with the result of evaluating an expression -- where a literal 3 is stored in the variable, a literal 3 is used to denote the function's return value, and the expression should evaluate to 3 -- then outputting 'true' if they are all equal and 'false' otherwise. The only output is "true" or "false". Not surprisingly, it outputs "true". So, what does a variable store? What does a function return? What does an expression evaluate to? If they're equal, they must be the same.}
- Sorry, you lost me. They are the "same" in what way? You mean the result of both expressions are equivalent (as defined by the language)? That's not necessarily a measurement of semantic equivalence. If you claim it's a legitimate way to measure semantic equivalence, then you need to establish that first. Otherwise, it appears you are making up semantic equivalence tests out of the blue. And I'm not convinced that DenotationalSemantics is actually encoding pure "semantics". That paper just claimed it was, as a given. It's a legitimate question to ask how one knows if a given notation system is actually encoding semantics and not partly or in whole something else (such as algorithms or mere "logic observations" about the code).
- {The results of all three expressions are more than just equivalent, they're equal. The language demonstrates this. Unless we have reason to believe the language uses its equality operator ('=') to lie, it demonstrates that the result of expression evaluation, function evaluation, and variable dereferencing are the same by showing that they are equal. This demonstration -- with mere syntactic tweaks and changing to whatever each language uses in place of 'alert' -- works in every popular imperative programming language. We can create further demonstrations to show that the result of expression evaluation, function evaluation, and variable dereferencing can be used interchangeably everywhere an expression may appear, thus confirming their equivalence. What is notable, however, is that whilst we can assign to a variable -- e.g., "v=3" -- we cannot assign to an expression and we cannot assign to a function invocation. It seems "foo() = 3;" doesn't work, nor does "2 + 1 = 3;" Thus, in popular imperative programming languages, there is a clear distinction between variables and the result of function invocation or the result of expression evaluation. Whatever the result of result of function invocation or the result of expression evaluation might be, it isn't the same as a variable.}
- Re: "works in every popular imperative programming language" -- Okay, but what does this objectively say about semantics? Such languages share similar conventions, I don't dispute that. If 3 companies steal a typewriter design from company X and clone it with minor variations, then all 3 typewriter brands will work similarly and have similar conventions. That's a no-brainer. Everybody copied a popular tool.
- {This objectively says they have common semantics in common. The "similar conventions" are syntactic, and certainly semantic, because if we're not talking about language syntax, we're talking about language semantics. There isn't anything else except language design philosophy, language history, etc., that aren't relevant here.}
- I don't see how it's objective. Please elaborate. And the last 2 sentences don't make sense to me. "Talking about" for what? You seem to be doing some kind of subtraction. Two other things that can be looked at is output and algorithms. We may be able to say that similar syntax results in similar I/O profiles, but I'm not sure semantics are defined by I/O profiles. I'm not sure what semantics are because they are ideas/concepts/notions in peoples heads and are not any more dissect-able than "love" is.
- {It's certainly not subjective, is it? A programming language is syntax and semantics. There isn't anything else.}
- I/O profile.
- {There's no such thing. What language reference manual describes its "I/O profile"? What good would it be to a programmer if it did? Language reference manuals describe syntax -- how to form valid statements -- and semantics, what the statements mean to us and what they do in the machine. If syntax and semantics are described completely, then the language is completely described.}
- Just because it's not in your favorite books means it doesn't exist? ArgumentFromAuthority galore. Perhaps I'm using the wrong terminology. What does application testing software call it?
- {Application testing software calls I/O "I/O". An "I/O profile" is terminology I've seen used to describe performance of DBMSs, but never the way you use it. You appear to use it to indistinctly conflate language syntax, language semantics, and application I/O.}
- Well, I don't know what it's called, but I described what it is and use it to test interpreters or interpreter-like models for equivalency. If you know of a better tool to test equivalency, please present it. Not every tool is going to be in your damned books.
- {I don't see how your approach can test for equivalency, as even a trivial change to (say) a variable name will result in non-equivalent results despite equivalent semantics.}
- I didn't say it was a measure of semantics.
- {So it's a measure of syntax? If source code is part of your input, you have to either be measuring syntax or semantics, because you don't appear to be doing text analysis, i.e., measuring the number of characters in total, or the number of characters in the longest line, etc.}
- The comparing technique was discussed near Example loopy-72 in ValueExistenceProofTwo. I don't know if it falls under a larger classification or label. It is what it is.
- {I can't find any "loopy-72". As for what it is, it appears that you may be comparing a mix of semantics and syntax, but it's not clear.}
- Try again. Somebody removed or overwrote it; I put it back.
- {The criticisms of that approach are discussed beneath it. It seems to confirm that you're including a conflated mix of syntax and semantics in your comparison, and all it appears to confirm is that two interpreters or compilers successfully implement the same language. It looks like it's going to fail every time two otherwise-identical and working examples of source code differ only by the name of an identifier. I don't see its purpose.}
- Perhaps the definition of "syntax" comes into play. Anyhow, I don't know what changing identifiers shows us. Please clarify. That different "Algol-style" languages have similarities does not necessarily mean they have the same "semantics". They have similar "behavior", but is that similar "semantics"? In your view, what is the relationship between behavior and semantics? Two things having similar behavior means that given the same or similar environment, the two things will react similarly. This is close to the "I/O profile" metric I refer to. An animal example would be "predator". Mammal predators will display similar behavior in a similar environment and we can identify these patterns, such as observing and stalking prey, selecting the younger or lame animals from a group, lunging, surrounding the prey (if hunting in a group), etc. In colloquial-land, it would be a stretch to call such similarities "similar semantics" or even "similar meaning" (since "semantics" may be reserved for languages and not animal behavior). It's not "meaning", it's just their behavior.
- {That different "Algol-style" languages "have similarities" is simply a way of saying they share common syntax and semantics. Indeed, by in large, they mainly differ in syntax, and differ in semantics as described at the top of TypeSystemCategoriesInImperativeLanguages. Semantics define language behaviour. In short, semantics describe what happens when a program runs. For example, if the semantics state that, for example, "a = 3 + 4;" means "the value resulting from evaluating the expression '3 + 4' is assigned to a", we can verify the behaviour defined by the semantics by writing, say (in Javascript), "var a; alert(a == 3 + 4); a = 3 + 4; alert(a == 3 + 4);" We'd expect it to pop up "false", then "true".}
- We've been over this already. Your English snippet is (from) YOUR head model, not a necessarily a universal form of "meaning". And your "verifying behavior" is checking the I/O profile, not processing your English snippet.
- {I didn't make up my "head model" all by myself. It's based on reading programming language reference manuals and related documentation, including numerous "learn to program" and "learn to program in language <x>" texts, and having an understanding of computer architecture. I don't know what an "I/O profile" is, but my simple verification program is not using I/O for verification; it's merely using I/O to announce the results of using '==' for verification.}
- I've agreed that a certain writing style(s) has generally been copied, and that (current) implementation terminology may have leaked into various documentation. But a lot of the language is not rigorous, at least as used by regular programmers. Like I've pointed out before, "value" and "literal" and "field" are quite often used interchangeably, for example.
- {The language used -- or mis-used -- is irrelevant. The fact that a given algorithm can be copied from one popular imperative programming language to another, with only minor syntactic changes, is ample proof that all popular imperative programming languages share the same semantics and similar syntax.}
- Even if true, I don't see how it relates to prior statements.
- {This threadlet started with discussion about languages having common semantics in common, with which you appeared to have disagreed.}
- Common behavior is not necessary common semantics.
- {Actually, it is.}
- It is what? Equivalent?
- {Common behaviour is necessarily common semantics. I'm assuming, of course, that the "common behaviour" you're referring to is that of programming language statements, not that of a whole program written using those statements.}
- If they are equivalent, then please use "behavior" INSTEAD OF "semantics". Semantics generally implies human ideas in human heads. It's not a good word outside of the field of psychology if clarity matters. And "behavior" is actions (output) based on the environment (input). How an interpreter responds to source code (whichi s part of its environment) is its pattern of behavior.
- {Equivalence is not quite accurate. Semantics specifies behaviour. Behaviour is what we observe of language execution, but of course there can be undesired behaviour. A compiled program could crash due to a compiler bug or running out of memory. That behaviour would not have been specified by the language semantics. Behaviour is not just I/O. A while loop produces no output, but demonstrates significant behaviour.}
- We can only observe the affects of a While loop via I/O. True, sometimes there are a chain of affects because of other statements in the app source, but its behavior pattern can be teased out and modeled via careful experiments, which observe the I/O profile. Science.
- {Output can't tell us whether it's a while loop that's produced it, or merely a linear collection of 'writeln' statements. Behaviour of individual statements can be observed using a debugger. As for "science", you appear to be unnecessarily applying natural science techniques to a mathematical discipline.}
- [I seriously doubt what he's using are natural science techniques. Usually those experiments involve controls, limiting the effects of confounding variables, predictions of the results, etc. He doesn't appear to be doing any of that.]
- {Here, I'm inclined to give Top the benefit of the doubt and presume he understands the ScientificMethod, solely for the sake of not broadening the scope of the debate any more than is necessary.}
- TypeTagDifferenceDiscussion shows examples of examining one or few factors at a time. And "prediction of the results" is what the tag model does. The rest appears irrelevant.
- {If TypeTagDifferenceDiscussion is confined to individual language statements, then it may have value -- though it's also redundant; language documentation and canonical semantics describe the behaviour of individual language statements, and TypeTagDifferenceDiscussion merely complicates the matter by conflating behaviour with I/O.}
- You should be able to predict my response to mention of "documentation" by now. Perhaps "behavior" is another messy English word. I am using the I/O profile to determine if a model is "correct" (in relation to a reference implementation) and will not delve further into the term "behavior".
- "I/O profile" is more than just "output". I suggest you review it. And I don't consider debuggers part of "I/O profile" for reasons already heavily debated. In short, two different vendors are not required to match debugging I/O to be considered producing the "same language" by most accounts.
- PageAnchor Debugger638
- {If your "I/O profile" includes source code, then it must actually be about syntax and semantics. A debugger is an excellent tool for observing language behaviour; your reasons for rejecting it have never been clear. I don't know what "two different vendors are not required to match debugging I/O to be considered producing the 'same language' by most accounts" means.}
- Sigh. If IBM created a C# compiler, but its debugger looked and worked a lot different than Microsoft's, most would not use that as a reason to say IBM's C# is "not the same language" as Microsoft's C#. In most heads, computer languages are not defined by what the debugger shows. We don't use the I/O of the debugger as a definition of a given language. In fact, IBM wouldn't even have to include a debugger. Debuggers are just "courtesy views" into the back room, which may be implementation-specific. Further, I've used a debugger that broke expressions down into "internal variables" similar to what's seen in TopsTagModelTwo. It's where I got the idea. (I don't remember the language; that was roughly 30 years ago.) Granted, it may have done "bloaty" stuff when debugging was switched on versus when it was off, but that just shows there are different ways to implement the guts, kicking the canonical cat in the cocoanuts.
- {Of course debuggers don't define languages. However, they are very helpful for understanding language behaviour by allowing the user to "walk through" programs step-by-step, and observe as loops cause blocks of code to be repeatedly executed, 'if' statements cause code to be executed or skipped, variable assignment causes the value in a variable to change, and so on. Some debuggers do permit nuanced views of the underlying machine, but that's not the usual use of a debugger, which is to execute programming language code in slow motion and observe what it does.}
- Yes, but debuggers just allow us to see the guts of a particular implementation. It does not make the implementation canonical. For example, a debugger may let one "see" the expression evaluation stack, but your side already agreed that stacks are an implementation detail and don't represent a canonical "semantics" (for lack of a better term). Seeing an expression stack in a debugger can be quite useful, but it's merely a courtesy view to a UsefulLie. In fact, a powerful debugger would let us change the "values" in such stacks. Mutable! -t
- {I can't recall the last time I used a debugger to go to the machine language level and "see the guts of a particular implementation". I don't even know how to get into that mode on the debuggers I frequently use, assuming it's supported. Change the values in the run-time stacks? Maybe that can be done, but I can't imagine why. (And the values themselves are immutable; the stack is, necessarily, mutable.) Normally, a debugger is used to single-step through the source code, executing it statement-by-statement so that you can examine the effect of each statement. For a given language, that will do exactly the same thing in every implementation.}
- I didn't mention "machine language" in the prior paragraph. And you seem to be limiting "debugger" to a fairly narrow definition here. I have seen expression de-construction debuggers as described (although the details are foggy). Statement-sized is sometimes too large a granularity of debugging when working with expressions with lots of parts. Expression-stack X-raying would be another approach to examining sub-expressions. Further, as I pointed out elsewhere, "smart" interpreters/compilers can potentially perform certain sets of statements in parallel, even thorough a debugger may show it only sequentially. That's to fit human notions or perhaps to keep the debugger simpler, not to represent all possible execution/emulation techniques.
- {If you can "see" the "expression evaluation stack", it typically implies at least some level lower than the language whose source code you're stepping through. For a typical compiler, that's machine language. Regardless what debugger machinery you use to step through language statements, the semantics of those statements will be observable. Optimisations -- such as parallelisation -- are irrelevant unless they affect the semantics.}
- The stack shown in the debugger does not have to be machine language. It can be a "cleaned up" view of the stack, somewhat like the function call stack, which is usually viewable with function names instead of say RAM addresses. My point is clear: debuggers can and do show specific implementation perspectives that are not necessarily required features of a language. You lost that sub-debate, give it up. Re: "Semantics are observable": I cannot confirm nor deny that without clear ways to measure "semantics".
- {Whether machine language or not, it's certainly lower level than the programming language being single-stepped. Again, regardless what debugger machinery you use to step through language statements, the semantics of those statements will be observable whether you choose recognise the definition of "semantics" or not. I don't know what "sub-debate" you're referring to; I didn't realise there was a sub-debate -- I thought I was clarifying your misunderstandings about debuggers.}
- There's no misunderstanding of debuggers. I didn't say anything wrong about them. And yes, they DO show lower abstractions, that's largely what makes them useful: they help find the devil in the detail. Okay, there are ghost semantics that only you and your special friends and that pink rabbit in your bathroom can see. I applaud your special ability to see and measure things the rest of us can't. You can take your ghost ruler and do ghost measurements and ghost science and publish ghost papers in Ghost Science Weekly and win the Ghoulbell prize.
- {Not only can debuggers show lower levels of language implementations, they directly show the computational effects of language statements at run-time. These are defined by the language semantics, which are precisely what language design documents and reference manuals describe, when they're not talking specifically about syntax or (say) language history and design philosophy. Nothing ghost-like there; the majority of language documentation is describing language semantics.}
- I disagree with your characterization of debuggers, but typical debuggers don't contradict my model either way.
- {What part do you disagree with?}
- If my model doesn't contradict typical debuggers, why get into a vocab quibble over "debugger"?
- {Could you answer my question, please?}
- Your suggestion that a debugger must not show implementation-specific features. See expression stack issue below.
- {I've never suggested that "a debugger must not show implementation-specific features". Where did I appear to suggest that?}
- You have implied it, but let's drop it for now. My main point is that a debugger is not guaranteed to keep implementation specifics out of its interface. Whether current ones do or not, who knows. Nobody's done a thorough survey, only anecdotes. I don't recognize debuggers as reliable comparison tools, other than suggesting further exploration.
- {I've never seen a debugger that, in a single-step mode, did anything but unambiguously show the expected visible language elements like variables and source code. If anything else was visible -- like the underlying machine code being executed, or live stack traces -- it was clearly distinguished. I would certainly expect a debugger to be a far less ambiguous or confusing view of semantics in action than relying on I/O, because relying on I/O conflates the statements being examined with the statements that implement I/O.}
- Search for "magazine" for a section below that looks at "absolute" debuggers versus existing debuggers. And yes, I/O statements can affect our view of things, but we don't have a better choice, because debuggers may leak implementation specifics or have arbitrary features. For example, they may format numbers with commas to make them "nice", but another vendor's debugger for the same language may not include commas. If we compare on debugger I/O, then both languages are not equivalent because one shows commas and the other not, which goes against the common notion of what defines languages. Languages are NOT defined by their debuggers. They don't even have to include a debugger. It's merely a bonus or a peak view.
- I don't know why you keep talking about these "reverse assignments". It's an odd obsession of yours. My model doesn't accept that (despite your repeated false insistence that it does). And for the sake of argument, even if one wanted to make a language that accepted that, nobody has shown a use for it. It doesn't do useful work, or hasn't been defined in a way that both does useful work and is simpler than existing conventions. Nobody's going to deviate from the Algol convention like that unless it adds utility (such as less code than the existing alternatives). Even if I "broke" my model to allow such syntax, it doesn't affect the results because the "temp" variable would either never be used by later steps or be overwritten by the next step (unless you break yet more things inside). It would be as good as a no-op and wouldn't affect the output. I could jury-rig your model in a similar way to create an orphan value that nothing uses. -t
- {I talk about "reverse assignments" because your model appears to accept them. If values and variables are the same -- call them valvarueiables -- and we can assign to valvarueiables, then we can assign to valvarueiables. What part of your model decides that you can assign to a valvarueiable in once place and not another? Your model doesn't appear to deal with language syntax (nor would I expect it to), so there can't be a syntactic restriction.}
- Then you don't understand the model. There can be any syntactical restriction needed to model the target language. Most won't bother to add such because they came to work on type-related issues, not syntax issues. But if you don't bother to put the filter on your fish tank as a short-cut, then don't complain if junk accidentally gets through. It's only a model, so no real fish or puppies die anyhow. One can remove/skip the safety equipment to get a better look at the device's guts, but that also means you have no safety equipment: tradeoffs tradeoffs.
- {I think I do understand the model, and it permits semantically meaningless operations. You are forcing reasonable semantic restrictions to be implemented in syntax, that need not be forced into syntax.}
- See above, I spruced up the safety analogy. I'm not sure what you mean by the second half. As I've mentioned elsewhere, I've seen vendors change at what stage errors were caught in subsequent versions, and few would consider the revision a "different language" (in a practical sense). I'm not sure what "harm" you are trying to prevent. "Forced"? Odd choice of words. I'm not even sure the user should have to care about "stages" of code processing. If something is wrong in the code, it's wrong. Error messages tend to leak info about the implementation guts when they don't have to. Statement processing and syntax checking could in theory be more heavily intertwined than it typically is, but interpreter makers don't do it that way, perhaps because it makes it harder use and find "generic" components because the specifics of processing would then be dictated by syntax issues.
- {You require that syntax be restricted in order to prevent a semantic problem -- assigning to valvarueiables when it is inappropriate to allow assignment. That is overly complex and unnecessary. A clear distinction between values and variables would eliminate that problem. Yes, it would involve "nesting", but every programmer is already familiar with the idea that a variable "nests", i.e., stores, a value.}
- How are you measuring "overly complex"? That's a rather general statement. You are exaggerating the weight of this "problem", if it's even a problem to being with. Like I keep saying over and over again, the variable thingy is the most frequently-used structure in the model. Sure, users can "get used to" reading through the extra verbosity of nested-ness just like one can get used to COBOL's verbosity, but given a choice I'd rather have the most common structure be as simple as possible EVEN if it complicates rarely used parts as a TRADEOFF, and I believe most regular programmers would agree with such a decision. (And no, I cannot "prove" they would. It's an estimate, just like your counter claim will be.)
- {I'm measuring "overly complex", in this case, by the appearance of StampCoupling in the operations that use your valvarueiables. I'm not convinced "frequently-used structure" is meaningful, given that you can turn any system into something that has a single structure to represent everything, with as many attributes as needed to record every instance of its use. It would certainly be frequently-used, but is it reasonable to create a GodClass just because it would (inevitably!) be used frequently?}
- The StampCoupling claim is addressed in ValueExistenceProof. It's not stamp coupling because there are not two different things in my model and all 3 slots are almost always used. Further, stamp coupling is not about "complexity", but about side-effects. I find the model conceptually simpler with the "flat" structure and I believe most regular developers would agree. It's an AnecdoteImpasse over WetWare; LetTheReaderDecide which structure they prefer. Stop arguing about that already.
- Re: "Execute one way" - I call that their "I/O profile" (IOP, and source code is part of "I"), but matching IOP hasn't been proven to also mean semantics match. And the labeling of source code parts can be defined and mentally identified via syntax patterns alone. Even source code patterns (multiple statements) can be done via syntax pattern recognition alone, using a large-enough training set. No higher-level cognition is necessary; it can be done with plane-jane pattern training using off-the-shelf AI algorithms. Such a setup could probably say, "X has a double loop" without ever "knowing" what a double loop "is" (in the human sense).
- {The only thing that ever needs to "know" what a "double loop" is, is the language interpreter. And by "know", I mean only that the interpreter can mechanically turn source code into the machine execution that the language designer intended. Are you sure "off-the-shelf AI algorithms" (?) will work to unambiguously model an "I/O profile"? Based purely on syntax, you can successfully identify language parts in most languages simply by writing a parser based on the language's documented grammar. No "higher-level cognition" is needed for that, either. However, there are elements crucial to implementing (and modelling) languages that syntax alone does not express. Sometimes there are grammar ambiguities that only semantics can resolve; operator precedence, for example, is specified in the semantics rather than the syntax. Of course, some parser-generator tools will let you specify operator precedence in the grammar. I'm not aware of any, however, that allows you to specify, say, short-circuit evaluation. I.e., you have to recognise whether or not bar() will be executed in a statement like "if (foo() || bar()) {}", if foo() returns true. In many languages, if foo() is true bar() will not be executed; it will only execute if foo() is false, which may have significant effects on how the program subsequently runs if bar() has side-effects. So, if source code is part of a language's "I/O profile", then you're probably going to have to take (at least) operator precedence and short-circuit evaluation into account, and that means dealing with semantics.}
- Operator precedence is defined by algorithms, and these algorithms usually follow the precedence rules we largely learned in school (multiplication before addition unless parenthesis, etc.). Interprets have their particular version/implementation of such algorithms and each human head also has it's own. That's "algorithm", not semantics.
- Algorithms implement language semantics. Operator precedence is implemented by algorithms, but its definition is semantics.
- Re: "Are you sure "off-the-shelf AI algorithms" (?) will work to unambiguously..." -- No, but humans don't either.
{How programmers interpret syntax, or semantics, is irrelevant. Semantics define what code is meant to do. How we understand a program to run has no effect on how it runs.}
{You can certainly translate a language 'a' having semantics 'x' into language 'b' having semantics 'y'.}
So you agree that at least in theory an interpreter can "run" language X withOUT using language X's "semantics"? (Via cross-translation.)
{You've misunderstood me. If you translate language X to language Y and execute language Y, you're not running language X. If you implement language X in language Y, then the semantics are language X, because language Y is not visible (it has its own semantics) to language X.}
Re: "If you translate language X to language Y and execute language Y, you're not running language X" -- Do you mean an interpreter for X or source code apps in X?
{I mean source code apps. Translating C# apps to Haskell will result in Haskell semantics.}
So is it safe to say that "semantics are being translated"?
{The semantics of the application may be changed. The semantics of the language(s) is(are) constant.}
I agree that an algorithm can be influenced by "semantics" (ideas, notions, concepts), but that is not the same as an algorithm "having" semantics "in" it. How do we objectively verify an algorithm "has" semantics "in" it, and how do we compare to know if algorithm A has equivalent semantics to algorithm B? -t
Algorithms don't have semantics, so your question is ill-formed. However, this quite clearly comes from the claim that semantics are implemented with algorithms. You can tell if implementations have the same semantics by comparing the effects of running them. (Note: the effects in question are limited to the ones the language in question specifies at the abstraction level specified by the language in question. Generally, we don't care if a particular bit is set or cleared. We just care whether or not the variable (however that got implemented) contains the value 5 of type integer (however that got implemented). BTW, I don't agree that algorithms are can be influenced by semantics.
How do we know exactly that "algorithms don't have semantics"? You say its "in" languages but not "in" algorithms. How does one check this in-ness?
One looks at the definitions. Semantics are the mapping of language structures to meanings. Algorithms aren't language structures. QED.
Sorry, I'm not following. This "mapping" happens in human heads, not in interpreters.
In humans, it happens in heads. In computers, it happens in interpreters and compilers. Programming languages map language structures to meanings in human heads, interpreters and compilers, because programming languages are understood by both humans and computers.
I still reject the idea that interpreters "see" or "contain" meaning directly. Meaning influenced their design, but influence is not equivalence.
Perhaps interpreters don't "see" or "contain" meaning the same way humans do -- we don't know how humans see or contain meaning, so we can't tell -- but we certainly know how interpreters "see" or "contain" meaning. Given human understanding of language semantics -- for example, how variables are meant to work, based on a language design specification or language reference manual -- we associate language structures with parts of the interpreter or compiler implementation. In a typical interpreter or compiler, this requires (in part) explicitly associating elements of the language grammar with actions that are to be performed by the interpreter or compiler when those elements are encountered whilst parsing the source code. That's how the meaning of a language is "seen" or "contained" by an interpreter or compiler.
Yes, that's "influenced by".
Yes, that's "influenced by", but it's also "implements". Both humans and computers "understand" the meaning of programming languages; perhaps in different ways, but sufficiently for all practical purposes.
I disagree that interpreters "understand" meanings. They process algorithms blindly. If there are "semantics" inside, it so far is not an objectively observable trait.
For all we know, human brains process algorithms blindly. "Understand" may be (and in the case of programming language interpreters and compilers, is) entirely mechanical. There's nothing that says "semantics", or meaning, requires human-style self-aware cognition.
We don't know what it requires because it's so ill-defined.
No, it's well-defined but abstract. We don't know what it requires in human brains because the human brain is not well-understood. We know exactly what it requires in interpreters and compilers because interpreter and compiler construction is well-understood. We know exactly how to turn the semantics of a programming language into specific actions to be performed by the interpreter or compiler when it interprets or compiles source-code. So, we say the interpreter or compiler implements the semantics of the language, or, in other (deliberately anthropomorphic) words, it "understands" the language.
But there are multiple ways to implement interpreters. Most are shaped by common conventions modeled after time-tested and road-tested ideas and tuned for machine efficiency on existing hardware. Future hardware or new interpreter ideas may change all that some day, or there may be interpreters built merely to predict and highlight certain concepts/features without concern for efficiency (sound familiar?). What you describe as "understand" above appears to be one of many possible paths to "understanding". Measuring understanding by current or popular implementation techniques does not produce the "canonical semantics" you claim/suggest exists. The "uniqueness problem" still persists. And who's to say that human programmers all run the same "ideas" in their head to predict code results? There's probably multiple "meaning" paths in human heads also. I already gave examples of different "school paper" techniques one can use to process expressions on paper. -t
There are multiple ways to implement interpreters, and there are perhaps multiple ways for us to understand the semantics of languages. However, independent of individual human (mis)interpretation, the semantics of all popular imperative programming languages -- based on language behaviour and various sources of language documentation -- are consistent to the point of being canonical. These are documented at the top of TypeSystemCategoriesInImperativeLanguages.
I'm skeptical it's "canonical". And if it were canonical, I'm skeptical TypeSystemCategoriesInImperativeLanguages is THE canon (except maybe among interpreter/compiler writers, per tradition or machine-centric tuning). I'd like better evidence. English rephrasing doesn't cut it, in part because such descriptions are not unique per target code snippet, and because much of English is vague or ambiguous. I agree there could be a "historical habit" of ways of thinking about or describing the processing of code, but it's hard to extract such information from developers beyond anecdotes. Further, the historical habit doesn't have to be universal. It may be shaped by machine efficiency concerns and/or just plain historical habit ("we always did it that way"). Please make clear what stance you are taking or talking about with regard to actual-as-is/historical canonization versus universal canonization (independent of human/Earth history/habits/hardware). I tend to partly agree with the WikiZen complaining about bias of the "Von Neumann habit" (CanProgrammingBeLiberatedFromTheVonNeumannStyle). Our thought processes may be shaped by it, and that's not necessarily a bad thing (our common reference "engines" may necessarily be some arbitrary common UsefulLie to aide in communication), but it may be possible that the real universal "canonical" semantics may look very different from the usual descriptions we give it (such as "move the results of expression evaluation on the right to the slot on the left"). Humans talk in terms of moving and copying parts or objects to and from slots or buckets (arguing over the names of these parts and buckets). But these are metaphors borrowed from our physical human world. Perhaps there's a quantum or many-worlds metaphor/semantics that is equally or more valid, for example. -t
You should be able to justify your scepticism by demonstrating at least one popular imperative programming language that deviates from others in terms of the semantics -- and, hence, the language behaviour -- of variable assignment, and/or function definition and invocation, and/or 'if' statements or 'while' loops. Furthermore, you should be able to demonstrate at least one popular imperative programming language that deviates from the explanations in TypeSystemCategoriesInImperativeLanguages.
- You are assuming your characterization of the semantics is the default truth. It's not. I know of no objective way to measure semantics to "prove" much about it, period. It has not been scientifically isolated. Your statement is like asking me to disprove that unicorns are blue by finding a non-blue one. If I cannot find a non-blue one, that is not proof that unicorns are blue. And TypeSystemCategoriesInImperativeLanguages is too poorly written to use as proof of anything. At best it's one model of multiple possible and has not been proven to be canonical.
- I know of no popular imperative programming language reference manual that TypeSystemCategoriesInImperativeLanguages contradicts, or that contradicts it. That is sufficient to be considered canonical. Your failure to understand it is precisely equivalent to your inability to read, say, French or Korean. The fact that you can't read French or Korean does not mean French or Korean are unreadable. The fact that you can't understand French or Korean -- or can't understand TypeSystemCategoriesInImperativeLanguages, or recognise programming language semantics -- means absolutely nothing.
- What do you mean by "contradict"? Note that using overloaded terms allows a fair amount of wiggle room in manuals such that it's harder to be technically wrong (or non-matching) with such words. The existence of overloading allows writing to be ambiguous without being wrong. As an implementation model, I don't claim your model is "wrong" (at least for the most common dynamic languages). I'm only claiming it has not been proven "canonical" (outside of interpreter writers). You are confusing mere implementation accuracy with universality.
- By "contradict", I mean there is nothing in TypeSystemCategoriesInImperativeLanguages that differs from popular imperative programming languages. There is nothing there to which an expert in programming languages would say, "That's wrong, language <x> doesn't do <y>".
- I'm not measuring what "experts" think. Modelling how experts think (if possible) is a fairly minor goal for stated project. I/O profile accuracy and grokkability to average programmers are the primary goals for the project.
- How anyone thinks is immaterial. I only reference "experts" as a body that would trivially note that TypeSystemCategoriesInImperativeLanguages accurately reflects the semantics of popular imperative programming languages.
- PageAnchor: Hardware-Bias-71
- So you claim. Expert implementers are not necessarily expert philosophers. Masters of machines are often not masters of the human mind or philosophy. Machine-side efficiency is a key driver of design for most experts of language (interpreter) implementation. They can be socially or philosophically inept, but masters at squeezing out the last drops of space and speed from digital hardware. I believe current descriptions and documentation are heavily tainted by hardware-centric concerns, and any commonality may reflect that hardware-centric viewpoint. (There is also a body a "free" interpreter-building tools and parts that may taint viewpoints of implementors even though they may not be the most efficient. If you wish to establish a standard or convention, handing out stuff free is a good way to start, even if the free stuff is not optimal for some purposes.)
- Outside of philosophy itself, I know of absolutely nothing that a philosopher -- expert or otherwise -- is good for in ComputerScience and SoftwareEngineering. There is as much reason to interject philosophy here as there is to include astrology and astronomy.
- For one, it may help them write better type-related documentation.
- Why? Do philosophers tend to write better type-related documentation than anyone else? Types in programming languages have as much to do with philosophy as mechanical engineering has to do with religion.
- They couldn't do much worse than the first batch. At least they might ask some tough questions that would rattle the stubborn traditionalists. Type documentation is an embarrassment to the field.
- Again, I can't imagine what "tough questions that would rattle the stubborn traditionalists" that philosophers might ask. Equivalently, I suppose astrologers might ask astronomers some "tough questions", which the astronomers would (rightfully) ignore or mock. If you don't understand "type documentation", perhaps you need to make a greater effort to understand it rather than demonstrating that you've made little effort to understand it.
- They may help them realize that their favorite head models or traditions are not universal canons, but rather one of many possible paths to produce desired results.
- Be that as it may, in terms of language semantics we're not interested in "favorite head models or traditions". They simply don't apply.
- "Semantics" inside languages doesn't seem to apply to anything. It's not scientifically measurable as currently (poorly) defined in terms of languages themselves.
- Inside languages, semantics defines what the parts of the language are and what they do. Without it, a language is just strings of characters that obey rules for constructing strings of characters.
- Humans define, not "semantics". You are anthropomorphizing again.
- Semantics define the parts of the language and what they do in the same sense that a blueprint defines a building.
- No, blueprints are relatively clear. I can print them out and most experienced constructors would build similar buildings based on them. Most rely on code examples and experience from similar languages to learn language behavior because the writing is so poor, especially when it comes to dynamic type-related info.
- Some language documentation is poor. Not all language documentation is poor. See Sun/Oracle's Java language documentation for examples of how to do it well.
- Why can't you find a good example of dynamic language type-related documentation? Static or strong typing is relatively low-hanging-fruit documentation-wise.
As for a "quantum or many-world metaphor/semantics that is equally or more valid", I'd like to see it. Until then, I'll have to regard the chances that there are valid "quantum or many-world metaphor/semantics" as being roughly on par with "New Age" crystals being valid explanations for scientific phenomena. I.e., none at all. Of course, even if there are such semantics, that wouldn't mean the conventional semantics are suddenly invalid or no longer conventional.
Fine, use the Babbage-style scenario instead of a mechanical expression evaluator. A Babbage-like technician's "semantics" may be purely mechanical. The technician may "think mechanically" to describe or think about expression evaluation. You may decide to call a certain gear movement "assigning", but that's just an arbitrary label slapped on it. There's no current proof that it has/uses some some canonical "semantics" it shares with some other interpreter or reference semantics.
How some "Babbage-like technician" may misinterpret language semantics is irrelevant. The misunderstandings of individuals are no basis for anything. In my youth, a young friend of mine told me he believed, as a child, that trained ants ran up and down inside our limbs and pulled our skin and bones from the inside when we wanted to move. Obviously, no reasonable medical science would ever be based on some "ant theory" of musculature! Similarly, no consideration need be given to some odd "Babbage-like" gear-movement-assignment theory of programming language semantics.
I base my determination that there are common language semantics on (at least) two things: 1. Programming language reference manuals, which document language syntax and semantics; and 2. the run-time behaviour of programming languages. I note that any straightforward algorithm employing variables, variable assignment, expressions, functions and loops can be ported from one popular imperative programming language to another with only negligible tweaks to syntax. That, in itself, is a sound demonstration that there are canonical semantics common to all popular imperative programming languages.
Furthermore, any mediocre programmer can read a straightforward algorithm employing variables, variable assignment, expressions, functions and loops in any popular imperative programming language, with -- at most -- a quick primer on syntax differences. That is further demonstration that there are canonical semantics common to all popular imperative programming languages.
No no no, I didn't say the mechanical version is "wrong". It can properly model/predict typical math expressions (I/O profile-wise). It is not objectively "wrong".
It doesn't matter whether it's right or wrong. I know of no "mechanical version" in the literature. I know of no language reference -- and certainly not for any popular imperative programming language -- that describes a "mechanical version" of semantics.
- Could you at least consider such as a hypothetical? Or perhaps replace "mechanical" with BrainFsck.
- What for? It's as much value as considering "angry gods on the moon" in a theory of cosmology.
- Huh? Actually, an interesting theory is that religion is a UsefulLie to help deal with unseen phenomenon such as germs or poisons. If one "learns" that plants A, B, and C are "possessed by the Coughing Demon", then stay away from such plants. Germs and poisons may not be known or understood by early man, but they can relate to beast or human-like forms that can "hide" inside of plants. Plus, there may be no unique/canonical "right" way to think about code evaluation: software is virtual. Interpreter users don't care how they "work", as long as they produce the expected results (excluding machine performance for now). If the internal or "study" model uses demons and dragons, so be it.
- As interesting as that theory may be, it's irrelevant here. It's true that there may be no unique/canonical "right" way to think about code, but that doesn't matter. How we think about code is irrelevant. Semantics aren't about how individuals (mis)interpret ComputerScience and language documentation and language behaviour, but about what ComputerScience and the language documentation says the semantics and language behaviour should be.
- The documentation is poor and vague, and ComputerScience is not fucking science. It's a bunch of stodgy traditionalists defending their turf.
- That's a rant, not evidence, which is a clear demonstration that you realise you are losing the debate.
- Sometimes frustration means the other guy is an asshat. The fact that you claim it's a "clear" demonstration provides further evidence that you not only project your personal head models into machines, but also into people. You are NOT a mind reader, dude. You've been caught red minded!
- Again with the insults? I don't know why you keep mentioning "personal head models"; they are irrelevant here.
- PageAnchor projection-problem
- It illustrates a probable flaw in your reasoning technique by showing a pattern of the flaw occurring both in your analysis of machines (software) and of human beings. Something about someone's motivation is "clear" to you because you inject your internal interpretation or estimate of what's going on into your external description of that other person, place, or thing. There's no clear, unique logic path that can be externally presented that proves that insults are a sure sign the other person is "losing the debate". There can by myriad reasons a person insults another (including frustration). But you discard those and go with your personal "gut" feeling, mistaking it for "clear" (your words). I believe at this point it should be obvious to the reader that you have a projection problem with BOTH humans and machines, and that's why discussions with you are difficult and anti-science. Until you correct your mind of this flaw, we won't get anywhere new. -t
- Motivation is irrelevant. What is clear is that insults are a substitute for a lack of an evidence-based argument, because otherwise it would be unreasonable and pointless to use an insult when you could have presented an evidence-based argument.
- Flawed logic. I can identify AT LEAST 3 reasons why somebody may insult: 1) Losing argument (your claim), 2) Random behavior (humans do that), 3) Personal catharsis due to frustration. Unless you can show that #1 is the most likely in terms of roughly 95% probability, "clear" should not even be considered a decent rational conclusion. So, where does your 95% come from?
- Why would anyone waste the effort of typing text for the sake of personal catharsis? I can understand a cathartic outburst in speech, leading to (say) an explosive emission of expletives, but there's no need for such a thing in text. If you're feeling angry, get off the keyboard and go do something else. Or stay on the keyboard and play a videogame. As for random behaviour -- if you can't control what you write, you've got some personal development to work on.
- Your complaint is noted.
And what you describe may be common
syntactical elements/patterns, not necessarily "common semantics". One can see such syntax patterns, and translate such to their personal favorite head model, even a mechanical Babbage-like one, and produce the "right" answer.
Syntax only describes orderings and arrangements of symbols. The fact that similar syntax behaves identically when a program is executed is evidence of common semantics. What a programmer can see, what his or her "favorite head model" might be, is irrelevant.
- That's a description of "behavior", not necessarily "meaning". "Similar behavior" generally means same output (external behavior) for the same input (environment).
- Semantics describes meaning, including expected behaviour. For example, semantics describes what a variable is (e.g., a time-varying named container of a value) and its capability (e.g., store a value in a variable given its name, and retrieve a value given a variable name) and what behaviour we expect at run-time, e.g., if 'a' is a variable and p is an expression, then we should expect that the assignment "a = p;" always results in "a == p" being true.
- That's can merely be an observational pattern of syntax occurrence, not necessarily "meaning".
- What is an "an observational pattern of syntax occurrence"?
- When pattern X appears, pattern Y (output) tends to follow.
- There's a lot more to almost every program than output. Indeed, "a = foo() + b;" has no output at all, yet any programmer can both recognise it and explain what it does in every popular imperative programming language.
- Because it has no output, it's equivalent (as a tool) to all other programs that have no output, including "x=0;". "Explaining" such is just going through the motions that would be done for an output-capable program, but discarding or ignoring the internal processing "stuff" when finished.
- If "a = foo() + b;" is "equivalent (as a tool)" with "x=0;", imagine a working program where "a = foo() + b;" is an existing statement. How well do you think that program would work if we removed "a = foo() + b;" and replaced it with "x=0;"?
- You are changing your example now. Obviously a statement about one example may not apply to another.
- I'm simply responding to your example, and demonstrating its flawed reasoning.
- It's not flawed reasoning, at least for the original example. If it produces no output, then its output behavior is equivalent to any other program that produces no output (speed aside).
- If the only thing a program does is produce no output, then all programs that produce no output are equivalent -- assuming there are no other side effects, which could be as rudimentary as producing heat from the CPU. That does not apply to individual language statements, which may produce no output but do have an effect on the program execution by changing program state or flow of execution.
- The "flow change" affects output. Like any science endeavor, the more variables/phenomena that are mixed together, the more difficult science and model testing/verification is. The various factors are still impacting the observations (output); it's just harder to know what is affecting what. If we want to explore JUST While loops, for example, then we write snippets devoid of or minimizing of other structures and test their results (output) separately.
- The "flow change" may eventually affect output, by printing 'true' instead of 'false' after executing 10,000,000,000,000 lines of output-free code. You appear to be conflating natural science with mathematical discipline. We don't have to rely on observations of output to examine program behaviour any more than we have to rely on the output of a pocket calculator to understand an algebraic formula. In a program, all the parts are visible; we need only know what they do. Having said that, I certainly encourage programmers to create experiments to test the effect of language statements, especially if the language documentation is unclear, but that is not the only way to understand programming languages.
- I'm not grokking your 10,000,000,000,000 example. To simplify things, I'm excluding speed issues for now.
- Speed is irrelevant. My "10,000,000,000,000 lines of output-free code" could be any complex algorithm -- or even a simple one, such as to compute the result of an Ackermann function -- in which a lot of I/O-free execution must take place in order to determine a simple result consisting of minimal I/O.
- The intermediate calculations affect the output in some way, no?
- Eventually, but a program that emits (say) only "true" or "false" provides no insight into its operation without examining what it does. If we're examining what it does, then most of the statements we're going to consider will neither be producing output nor consuming input.
- This is consistent with science: some phenomena are difficult to analyze. Evidence for the Higgs boson was hard to come by based on limited clues, but with enough experiments, the models can be reasonably evaluated. With imperative languages we use the UsefulLie of sequential execution and independent statements and break expressions or programs down into smaller programs so we can analyze the "parts" in a more isolated setting to avoid the flood of too many factors fogging the results. In practice, an optimizer may re-org the execution order etc. to make more efficient use of existing hardware. For example, an optimizer can execute some loops or statements in parallel rather than sequential if it detects certain patterns (of non-time-dependance). Thus, Sequence is merely a UsefulLie to better tie it to human experience. One's mental model or machine model (optimizer) does not have to live with such UsefulLies. There are multiple valid paths to match the working definition of "I/O profile". None are "canonical", other than perhaps via popularity vote (which is a sticky issue and may be shaped by "hardware habits", as much of our terminology and idioms come from past physical design, such as "dialing" a phone number).
- Could you explain that without analogies and discursion? Whatever point you're trying to make is lost, and I can't find anything in it that counters, or even makes reference to, the point I made. Are you agreeing with me and adding commentary? I can't tell.
- I guess I'm not understanding your point then. I thought I answered it as I interpreted it. "Does" is a messy word, as we've been over already. I interpret "does" in terms of I/O profile since the alternative definitions/applications of the word are very difficult to objectively measure. Could you try re-stating it without using "does"?
- For "what it does", substitute "the computations it performs at run-time".
- I think you are thinking I'm claiming one can "learn about" the program and/or language in a thorough way by studying the output in this particular example. That's NOT my claim. The test only validates the model formed by other tests, mostly based on simpler app programs. This is typical of science: we run controlled experiments on small or isolated parts, and then use that insight to form models, and then check those models against observations in more realistic conditions ("the field"). One tends not to gain the details from the field, but merely confirm the models gained from more controlled experiments.
- Why would you use an observation-based "model"? Programming languages don't evolve naturally, and they aren't dug up out of the ground or seen through telescopes. The actual semantics of programming languages can be understood merely by studying computer science, and this understanding can be supplemented by reading language documentation and running debuggers to observe run-time behaviour. I certainly don't deprecate writing test programs to verify semantics -- that's a good idea, in fact -- but to rely solely on it, and ignore what we know from computer science and software engineering and language documentation and single-stepping using a debugger, seems peculiar.
- They did evolve. People settled on a style because they liked it after trying Fortran, COBOL, Lisp, Assembler, and others. They didn't settle on them because some equation or OfficialCertifiedDoubleBlindPeerReviewedPublishedStudy said THIS IS THE RIGHT WAY TO DESIGN A LANGUAGE. Further, they are heavily influenced by math notation, which was invented before machines could process math. Math was designed to communicate with humans, not machines. And like I've said many times, existing documentation on dynamic type-related issues sucks. As far as debuggers, that's discussed above. In short, it's not accepted that languages are defined by their debuggers, and they can "leak" implementation issues.
- Certainly languages evolve, but they don't evolve by themselves. They evolve via human agency, so there is no mystery to how language behaviour comes about. If language documentation sucks, then language documentation should be fixed. We don't need to create an Institute of Language Investigation to divine the ancient mysteries of language behaviour. As for debuggers, of course languages aren't defined by their debuggers, but debuggers reveal language run-time behaviour. Run-time behaviour is defined by semantics, so debuggers can help us understand semantics. I don't know what you mean by "debuggers ... 'leak' implementation issues".
- I don't know what you mean by "human agency" and why the reference to "Institute of Language Investigation".
- Programming languages don't evolve by themselves. They're designed and written by people. Your writing appears to imply that you assume programming languages have evolved naturally, and thus contain mysteries that require natural science in order to understand them. My "Institute of Language Investigation" is a tongue-in-cheek reference to the apparent need for natural science in order to understand language semantics.
- In a way, it kind of does match natural sciences. We only have indirect clues based on history and various writings and job ads etc. Why do some IT ideas "stick" and some not? It's not much different than "Why do Zebra tend to prefer watering hole B over hole A?". We can make observations about the environment and position of each hole and form hypotheses, and then test these hypotheses by examining more extreme examples of specific factors (such as finding watering holes with significantly more prey around them) and/or put fake props out.
- Natural science approaches, or history approaches, may be entirely appropriate for investigating the sociological, psychological and historical aspects of computing. None of them apply to language semantics, unless you're studying (say) why humans have made various decisions about the semantics they've included in their language designs.
- They do apply to human CHOICE of which semantic/syntax systems/techniques to use and which to ignore.
- How is that relevant here?
- Your "none of them apply..." is wrong. Semantics is about WetWare.
- Programming language semantics are not "about WetWare", they're about what language statements do when they're executed on a computational machine. As such, natural science and history approaches are inapplicable.
- The problem is that we each define/measure "do" differently. I use the stated "I/O profile", and you use something convoluted, obtuse, and round-about such as to be non-approachable and non-verifiable by typical developers. My approach is relatively easy to understand and empirically test, and does not dictate implementation. Your approach is incomprehensible and appears to dictate implementation (such as certain kind of "values"). Thus, it sucks.
- Since "I/O profile" doesn't appear to address the execution of language statements that do not involve I/O -- such as assignment, expression evaluation, function invocation, or flow control -- it appears to be somewhat limited.
- I'm not sure what you mean. You've yet to demonstrate a practical problem with similar complaints.
- The problem is that your "I/O profile" doesn't tell us anything about the actual behaviour of language statements, and in some cases it's counter-informative: From an "I/O profile" point of view, a program that generates prime numbers by calculating them is the same as a program that lists a set of prime numbers that have been embedded in the source code. From an "I/O profile" point of view, a program that prints a random number is a different program every time it runs because its output is different every time it runs. In short, "I/O profile" is meaningless, except perhaps when applied to individual language statements. When it's applied to individual language statements, it becomes merely an awkward way of describing the semantics of language statements, and then it requires a conflation of I/O statements and language statements in order to be meaningful. This inevitably calls into question whether the observed I/O is a product of the language statement in question, or a product of the I/O statements used to illustrate it.
- I already told you why your "list of primes" would fail a "full" I/O profile test. You keep falling back into the habit of only testing one case. And TRUE random numbers would require outside INPUT. I know of no language that has a built in true random number generator. You are scraping for obscure excuses via obscure features. It appears to be desperation. And I already addressed your complaint about I/O statements. I'm not going to repeat it. Further, you haven't presented a clear alternative to determine if two interpreters/models "run" the same language.
- If even one case fails, then the "I/O profile test" fails as a methodology, especially as a "full" I/O profile test would be infinite -- it would require testing every possible input, including every possible program. As for random numbers, they're merely one example, and whether the generated sequence is pseudo-random or not is irrelevant. Since most modern pseudo-random number generators are seeded by some source of entropy, they're sufficiently random for the purpose of demonstrating that your "I/O profile test" trivially fails. Another example is a program that simply prints the current time; using your "I/O profile test" it's a different program when the time changes. As for proving whether or not two interpreters/modules "run" the same language, you can't. At best, you can only rely on the statement of their author(s) that an attempt has been made to faithfully implement the same semantics in both.
- The prime list does not fail anything. I don't know what failure you are referring to. And I consider the system time (clock) to be "input". And in a practical sense, it does NOT depend on testing every possibility. No scientific theory can be 100% tested for 100% cases. Sampling is common and normal in science and the metric is as accurate as you want, per resource devotion (economics). We've been over these already. Every language I know either uses the system clock and/or a seed value to manage random number generation, generally because lack of repeatability makes testing applications a PITA (and science too). And your "alternative" appears to be either "nothing" or "trust the author". Clearly, my approach is better than "nothing" or "just trust me" even IF your nitpicky edge cases and fake flaw claims were real problems (which they are not). I'm racing ghosts, it seems.
- The "prime list" example fails to distinguish a static list of prime numbers from a prime number generator, other than to note that they are "different", only because their source code is different. As for the current time or random seed being "input", all that does is make your "I/O profile" approach more awkward, and less feasible to apply in practice. Your notion of applying natural science to programming language design is both peculiar and pointless. ComputerScience is a mathematical science, which no more benefits from observation in terms of understanding programming language semantics than elementary arithmetic "benefits" from repeated trials to verify that 2 + 2 always equals 4. Semantics are defined, not observed. To understand them, it is sufficient -- if there is any ambiguity in documented writing -- to query the definer. Observation is inherently and inevitably weaker.
- Your prime-list statement if flat wrong. I'll let you ponder it for a few days before (re) explaining. As far as "awkward", I'd like to compare it to the alternatives first because awkward is relative, but there is no alternative yet, at least not an objective one. (Using time (as input) complicates ANY empirical testing of code, both apps and interpreters. Regular IT people know this and expect it. Further, our "type" issues are not related to clocks, so it's only an academic issue here. You are inventing problems.) And what exactly is "mathematical science"? And semantics are NOT defined (in any clear, objective way). Thus, if you depend on that fact, you are screwed royally. Re: "Query the definer" -- What were you just saying about "less feasible to apply in practice"? I smell another double standard. It's usually far easier to empirically test to answer a question, unless you really like hours of IBM's and MS's elevator music. -t
- Mathematical sciences are those based on logic -- such as algebra, SetTheory and ComputerScience -- for which empirical observation only serves to confirm logical inference, unlike the natural sciences in which logical inference only occasionally confirms empirical observation. In popular imperative programming languages, the semantics are so simple that formal notations are unnecessary -- and I have no idea what these have to do with "'type' issues" or things "related to clocks" -- so whilst empirical testing may be helpful for achieving a beginner's understanding of unfamiliar statements, I know of no popular imperative programming language in which an already experienced programmer in at least one popular imperative programming language can't become an expert in another, purely by reading the standard documentation and writing code based on it, in a matter of hours. (This doesn't include becoming expert in the associated libraries, but of course they're not part of the language.)
- I'm not sure I'd call that "science", but won't get into that definition bath today. As far as "expert in another", search for "sucks dirty smelly ass on a good day".
- Then call it "mathematics". Regardless what it's called, it's inherently more rigorous than natural science, and applying natural science approaches to ComputerScience where they're not warranted -- such as understanding programming language semantics -- is unnecessary.
- Higher math is often difficult for most people and programmers. Using an imperative algorithm may make a more palatable model. Your mistake is to assume the math-centric models are the One True Model, which is utter bullshit. Further, higher math cannot practically be used to prove compilers/interpreters are 100% accurate. At least some empiricism (spot testing) is necessary.
- My working definition of "language behavior" is the described I/O profile. And yes, I agree language documentation should be fixed, but nobody agrees on how to fix it. I have not seen dynamic types documented well and I myself DON'T KNOW HOW to do it well using primarily English. That's precisely why I formed the tag model because I can show instead of tell using communication techniques most programmers must know to get a job: empirical code and XML. It's not perfect, but it's either better than the crap out there, or provides an alternative way to explain dynamic types (in terms of observable behavior) to supplement or replace other techniques a programmer may struggle with. And I reject your claim of a canonical model of internal "values".
- How could an "I/O profile" (it's still not clear what that is) describe language behaviour? Assume input is received in the first of ten statements, and output is produced in the last of ten statements. How does the "I/O profile" explain what happens when the eight statements with neither input nor output are executed?
- Didn't you already ask a question like that? You seem to be assuming that one develops a model based on a SINGLE I/O instance, which is rarely the case. "Profile" is a "wide" profile. Remember the double-loop? And I/O profile cannot build models itself, it only validates them. And, usually smaller simpler snippets would be used to analyze I/O profile to help form initial models. One wouldn't typically start with a complex example of the kind you describe. Such a thing would be used to test the model, not form it.
- Even if you develop a "'wide' profile", with the majority of programs the I/O portions will be a small percentage of the overall processing, such that the majority of the run-time behaviour will only be indirectly related to I/O. If, on the other hand, you're simply using I/O to validate individual statements and operators, then you're not creating an "I/O profile", you're simply using I/O to explore and verify language semantics. I/O, in that case, is just a tool roughly equivalent to using a debugger, though probably not as good because it conflates I/O with the statement or operator you're examining.
- I'm not sure what you are getting at still. "Individual statement" outside of syntax is merely a UsefulLie (for humans). They don't have to exist to qualify the interpreter. The interpreter does not have to process stuff sequentially, like one would typically do on paper, for example. (Debuggers may have to turn off certain efficiency features to act like we normally expect.)
- If non-sequential processing has an impact on semantics, the single-step mode of the debugger will show non-sequential processing. Otherwise, if non-sequential processing has no impact on the semantics, than showing statements as if they execute sequentially will be indistinguishable from showing statements that execute non-sequentially.
- Re: "indistinguishable from": That's because there is NO ONE RIGHT semantics. QED. -t
- You've misunderstood. They are indistinguishable because the single-step mode of the debugger will show the semantics of the language and nothing but the semantics of the language. If the implementation employs parallelism or other internal optimisations such as memoisation or expression re-writing, these have no effect on the semantics and so will not be shown by the debugger in single-step mode. There may be mechanisms in the debugger that will allow viewing these optimisations, or viewing other machinery like what machine-level instructions are being executed, but these are always distinct from single-step mode.
- We traditionally view/present them sequentially, but this is not the only or "proper" way to "think of" processing. True, it may be the majority preference, but then you are employing ArgumentFromPopularity (in humans). You can argue a "most popular semantics", but so far that has been difficult to measure given existing materials, at least for certain aspects of "computation".
- Whether or not processing can be "thought of" as parallel is irrelevant, unless there is some identifiable difference between executing statements in parallel vs executing them sequentially. Of course, in most imperative programming languages, parallel execution can create very different results from sequential execution -- whether intended or not -- such that parallelisation does affect semantics. For that reason, most imperative programming language compilers employ parallelisation in very strict and controlled contexts. In such contexts, parallel execution is indistinguishable -- from a user's point of view -- from sequential execution, so the semantics are invariably (for simplicity's sake) described in sequential terms.
- I never claimed that it was entirely parallel-izable. But in the last part you appear to admit a non-sequential (or partially non-sequential) semantics is at least possible. Is this correct?
- Certainly, non-sequential semantics are possible. See, for example, http://daniel-zinn.de/KahnProcessNetworks.pdf However, some argue that where possible, programming language semantics should be serial even if the underlying processing is parallel. See http://software.intel.com/en-us/articles/four-reasons-why-parallel-programs-should-have-serial-semantics
- "Should be"? Why are we talking about should-be's here? The key issue is that there is no one single semantic. It's the same with human heads: there are multiple semantic models that produce the right answer.
- Human heads are irrelevant. There are programming languages with explicit parallelisation semantics. There are programming languages with serial semantics, which internally (and therefore invisibly) implement parallelisation. The former is more complex than the latter, so some recommend the latter.
- I don't see the relevance of this. There are multiple semantics for a given language; you already admitted it. Saying one semantic is simpler than the other is irrelevant to the point because simplicity is not the topic of this sub-argument.
- There can be conceivably be multiple semantics for a given language, but these are irrelevant. There can be multiple interpretations of a given definition of language semantics, but these are irrelevant. All that matters are the semantics defined by the language designer -- or that exist canonically for a given language family -- and that are documented in a definitive language manual or implemented in a reference implementation.
- This doesn't say anything new or useful for our needs to objectively compare semantics. You know my take on written manuals already. And using a reference implementation(s) is the basis for I/O Profile.
- Why do we now have "needs to objectively compare semantics"? How is a reference implementation "the basis for 'I/O Profile'"? It's not clear what an "I/O Profile" is, let alone how a reference implementation has anything to do with it.
- If you say X and Y have "common semantics", wouldn't it be helpful to have an objective way to confirm such rather than just take one's word for it? What specific question to have about I/O Profile?
- Given the trivial simplicity of popular imperative programming languages, I doubt anything would be simpler than reading the manual. That's certainly far simpler than anything suggested for an "I/O Profile", which as described seems unlikely to demonstrate common anything, let alone semantics, at least not within any finite time period.
- It's always good to have rigor behind claims or opinions. And you already know my opinion about existing manuals. You even agreed that Php's online manual is poorly done for certain aspects. The existing writing on dynamic types, in particular, for dynamic languages sucks dirty smelly ass on a good day. Nobody knows how to write about them in a clear and approachable way. With a few tricks, one can generally cajole such languages to get what they want without a having clear model, but having a clear model is still a nice thing. An imperative model may be as good as anything out there being that the bar is so low. And your "finite time period" is not a significant complaint, per IoProfile. It sucks less than the alternatives.
- Rigour is good where rigour is possible. Much like a high resolution image cannot be made from a low resolution image, high rigour cannot be created from low rigour. If PHP's online manual is the best description we have of PHP semantics, you'll not make them more rigorous by rephrasing them, unless you extrapolate rigour from somewhere else -- such as general understanding of dynamically-typed imperative programming languages. Regarding the "finite time period" required by your "I/O Profile", I mentioned it because as you've described your "I/O Profile", it is not possible to derive an "I/O Profile" in a finite period of time. That makes it useless, as described. However, if we read between the lines, it seems your "I/O Profile" is nothing more than a collection of examples of source code and the run-time behaviour of the resulting programs. That's fine, and a helpful way of confirming or understanding language semantics. It does not, however, add any more rigour than any other example programs.
- I don't know how to use English to describe dynamic types well, and have not found anybody who has. Thus, I created an imperative model instead because most programmers know imperative programming. We've been over this many times already repeatedly redundantly. As far as IoProfile, it's a fallacy to say that something is useless because it's imperfect. By the same reasoning, science would also be "useless" because we cannot practically observe every particle at every instance everywhere. Science accepts "spot testing" as a practical alternative to idealism (a God-wide view of all). You are being obstinate for obstinate's sake. Shape up! And your "collection of programs" claim is wrong.
- Again, you appear to be treating programming language semantics as something to be inferred. They are not. Programming language semantics are designed and specified. How they are inferred or (mis)interpreted by humans is irrelevant, as long as the interpreter or compiler correctly implements the semantics that the language designer intended.
- Your claims about what semantics are or are not are moot without some tangible and clear way to measure semantics.
- Semantics are tangible and clear when stated tangibly and clearly by their authors -- even using English, as is traditionally done with language reference manuals and ANSI or ISO standards documents. What you appear to want is an automated way to measure semantics. The best automated way to measure semantics -- at least, informally -- is with a reference implementation of the programming language that the semantics describe. Whilst it is infeasible to test every possible program against the reference implementation and the implementation under test, many languages have test suites that are used to achieve a reasonable degree of validation. See, for example, http://www.plumhall.com/ZVS031_mp.pdf
- English sucks for certain aspects of tech docs, and you appeared to agree at one point (unless one used an uncommon and unnatural writing style). I'm not going to re-re-re-re-argue that point here yet again. And I don't necessarily want an automated way to compare semantics, but automation forces authors/claimers to clarify themselves. It's a good way to RaceTheDamnedCar. English was designed for the physical and social world of humans, not cyberspace, as LayneThomas also generally observed. And your testing approach heavily resembles the I/O Profile standard.
- So you don't want an automated way to compare semantics? What, then, is it that you want? Furthermore, what is an "I/O Profile" and how does it relate to "my" testing approach?
- I'll be happy with anything that's clear and objective. An imperative algorithm is a great, time-tested way to provide such, and is recognizable and grokkable by many programmers and IT folk, but is not the only way. See IoProfile for more on I/O Profiles.
- ''As noted on IoProfile, an "I/O Profile" nothing more than a collection of sample programs. They're certainly handy, but not so notable that it's worth giving them the special name "I/O Profile".
- That's blatantly wrong, but I'll address it at IoProfile.
- An example of the "leak" issue is that it would be acceptable for a debugger to display an expression stack as expressions are being evaluated (such as stepping thru expressions). However, expression stacks are not typically part of the language documentation (nor a common head model among typical programmers) and are often considered an implementation detail. Thus, debuggers are NOT required to match "language semantics as documented". My model does not contradict typical debuggers anyhow.
- The so-called "leak" is a non-issue; just don't go into the "stack view". Debuggers consistently provide a means to single-step through source code. I know of no debugger whose single-step mode contradicts the language semantics. If it did, it would be immediately obvious as a bug.
- Huh? A debugger that lets one see the expression evaluation stack is/has a "bug"? You seem to be making up arbitrary rules again.
- No, where did I say that a debugger feature is a bug? I simply suggested not using the implementation-dependent "expression stack" feature if you're concerned about avoiding implementation dependence. What I wrote was that I know of no debugger where the single-step mode -- where you can execute source code statements in slow motion so you can examine their run-time behaviour -- contradicts language semantics. If a single-step mode contradicted language semantics -- for example, it showed that executing "a = 3;" put -3 in variable 'a', but the rest of the program demonstrated that 'a' contains (as we would expect) 3 -- that would be a bug.
- If you don't allow expression stack analysis to be part of a debugger, then you are cherry picking what you consider a "debugger". I'm not considering what "most do now", but rather what is considered a "debugger". As a general statement, debuggers may show implementation specifics, such as expression stacks, and still be considered to be a "debuggers" by regular folks. Definition-wise, one cannot rule out implementation specifics being shown in a debugger. I'm not reviewing debugger products for a magazine. (I don't see anything wrong with such a feature anyhow, utility-wise.)
- But, if you are merely saying that an interpreter can be rigged or coincidentally aligned to work for only one specific test case, you are right. Sneaky or surprise stuff can happen. Maybe the laws of the universe are such that the Higgs boson only appears in loop-shaped cyclotrons of a certain size and nowhere else such that general extrapolation of their existence is a mistake. Ideally, we have many more test cases, which is what "I/O profile" expects (in ideal circumstances).
- Higgs boson??? A rigged interpreter??? Huh? What does this have to do with what I wrote?
- Seems a communications breakdown. See above.
Suppose a new programmer learns to program in
JavaScript (JS) and gets a few years under their belt. Then they are asked to program in VB-Script (VBS). At first the different syntax throws them for a loop (no pun intended), but after a short while they mentally learn to translate VBS into JS back and forth in the mind (and learn rules of thumb to handle the differences in capabilities). They are
not reading meaning directly from VBS, but translating it into JS in their mind. It's essentially "dumb" syntactical translation.
We can extrapolate this scenario into the mechanical view. Syntactical patterns could probably be mentally mapped to mechanical constructs (which are capable of producing the correct output). In fact "stack" comes from a mechanical idiom.
The fact that our hypothetical programmer can translate syntax, without having to translate semantics, is evidence of common semantics in the languages. It doesn't matter what's in the programmer's head.
Without a clear-cut way to measure and verify your description of "semantics", I cannot confirm nor deny your claim. And my colloquial interpretation of "semantics" is that it's something that only happens in human heads (and maybe AI machines). Your "in the machine" statement contradicts this. And as a reminder, semantics (ideas) may influence implementations, but that's not the same as "being in".
You can trivially verify my claim. Write the same simple program -- say, to find the first ten prime numbers -- in five different popular imperative programming languages. Make sure the implementations work. Show them to your colleagues and ask them to read the programs and tell you whether or not they think the programs do the same thing.
What does this prove exactly, and how? I only see it proving predictive capability of the human readers.
This proves that the same syntax has the same meaning in popular imperative programming languages.
- No, it only means people found a way to map inputs to expected outputs (using various mental techniques). It does NOT prove a canonical "meaning". You are reading more into it than is observationally "there". If you want to define "semantics" as being about behavior (I/O profile), be my guest, but be clear about it.
- Again, how people "map inputs to expected outputs (using various mental techniques)" is irrelevant. The fact that the same syntax has the same meaning in popular imperative programming languages -- based solely on language documentation and common language implementation behaviour -- is sufficient evidence to prove the assertion that the same syntax has the same meaning in popular imperative programming languages.
- You are mixing up heads and documentation and output in a big confusing soup here. You are confusing the cannibals. The steps to get to your alleged conclusions are not clear to me. You used that word "has" again.
- Let's look at it a different way: Take a program written in C to generate the first hundred prime numbers. By changing the syntax slightly -- but making no other changes -- it will generate the first hundred prime numbers in Java, Objective-C, C++, C#, PHP, Visual Basic, Python and Javascript. That is proof that these nine popular (based on the TiobeIndex) imperative programming languages share the same semantics.
- By what specific "logic rule" of semantics? That's proof of "similar behavior" between such languages. Semantics is a hazy supernatural force as best I can tell from your writing.
- There is no "logic rule" of semantics. Semantics define behaviour, and a language is defined in terms of syntax and semantics, so it must be that "similar behaviour" -- though I'd call it the same behaviour, in this case -- is a result of equivalent syntax and the same semantics.
- Re: "There is no "logic rule" of semantics." -- There you have it folks; that sums things up perfectly. Re: "Semantics define behaviour" -- How so? Can you illustrate it clearly doing some "defining"?
- There's no "logical rule" of calculus, or linear algebra either. I don't know what '"logical rule" of semantics' means. Anyway, "semantics define behaviour" example: If the semantics for a variable assignment states that "a = e;" means "the value resulting from evaluating expression 'e' is assigned to variable 'a'", and therefore an example like "a = 3 + 4;" means "the value resulting from evaluating the expression '3 + 4' is assigned to variable 'a'", we can verify the behaviour defined by the semantics by writing, say (in Javascript), "var a; alert(a == 3 + 4); a = 3 + 4; alert(a == 3 + 4);" We'd expect it to pop up "false", then "true".
- You mean semantics is comparable to calculus? That's an odd claim. As far as "x means English y" type of patterns, you need to provide better evidence of such. Repetition of claim does not improve evidence.
- I mean only that semantics is analogous to calculus in that there is no "logical rule" for either (I presume; though I still don't know what it means) but both are valid and have pragmatic uses. Any language reference manual is full of "x means English y" examples. I suggest looking at the Java language reference for well-written examples. E.g.: http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html
- Explicit typing is generally much easier to document because the types are, well, explicit.
- That sounds like a supposition rather than an observation. By "explicit typing", do you mean manifest static typing? Whether typing is manifest and static, or inferred and dynamic, or something else, good documentation can be written to describe it. The TypeSystem of a language has no effect whatsoever on a technical author's (in)ability to write clearly.
- Whatever the cause, existing writing on dynamic typing is quite crappy. I don't notice comparable problems in the "type heavy compilish" languages.
- It's true that writing on popular dynamically-typed programming languages tends to be weak. Whilst not popular, Smalltalk is dynamically-typed and its documentation is quite good. See http://www-01.ibm.com/support/docview.wss?uid=swg27000344&aid=1 The Objective-C documentation isn't as good, but it is a popular language and it supports dynamic typing. See https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/FoundationTypesandCollections?/FoundationTypesandCollections?.html#//apple_ref/doc/uid/TP40011210-CH7-SW1 for reference to values, for example.
- Is there something specific you wish to bring up from them related to "types" or official definitions of "value" or something? Otherwise, I don't know what you want me to do with those. Ask developers to switch to SmallTalk instead of Php because it allegedly has better docs?
- I mean only to show that good/bad documentation is orthogonal to the TypeSystem.
- I'm not sure if that's a thorough enough sample size in terms of both language and topic. Regardless, I've yet to see what I consider "good documentation" for type issues in dynamic languages. I didn't find any in your links, but admit I did not read every last page, using only the TOC to guess coverage.
- How do you judge writing based solely on the table of contents? A table of contents, after all, is hardly "writing" per se -- it's just chapter and section headings, at best.
- I meant using the TOC to sample parts of the actual text, generally relating to "types" or "values". Sorry, I wasn't clear about that. I saw nothing special or unique in the parts I did read. They also seem to be conflating "value" and "literal", or at least making no definitive attempt to separate the concepts in readers' minds.
- There isn't anything special or unique about the links I provided; they're simply examples of reasonable documentation. As for "value" and "literal", as I've pointed out repeatedly, a literal always denotes a value so it's reasonable to use the term "value" in place of "literal".
- So one could say that "expressions return literals"?
- No, a literal always denotes a value, but a value doesn't denote a literal.
- How does one empirically test that? Or, are you just processing fuzzy feelings/notions/habits?
- It is true by definition.
- Which one? And I mean a real one, not one you made up.
- What do you consider a "real" definition?
- Just make it clear where your definition comes from.
- The Wikipedia definition at http://en.wikipedia.org/wiki/Literal_(computer_programming) is as good as any: "In computer science, a literal is a notation for representing a fixed value in source code."
- I don't see how this answers the question, but it doesn't appear to be a pivotal issue such that I'll abandon this for now.
Semantics exists every time you, say, assign an expression to a variable. The variable exists, and the expression exists, both in the interpreter environment and the source code. They do something, with measurable results in the program operation. They aren't syntactic, because the syntax can vary from language to language, yet "assign an expression to a variable" exists in every popular imperative programming language. That is semantics.
Re: "yet 'assign an expression to a variable' exists in...programming languages" -- Again, interpreters don't think, and don't think in English. You again appear to be anthropomorphizing interpreters or mentally projecting (imagining) your thought patterns into them.
Interpreters don't have to "think" for 'assign an expression to a variable' to exist in programming languages. Do you know any popular imperative programming language that doesn't implement 'assign an expression to a variable'?
They don't "run" your English. It's a silly question. You again appear to be anthropomorphizing interpreters or mentally projecting (imagining) your thought patterns into them.
Of course they don't "run" English. "Assign an expression to a variable" is the English we use to describe the language semantics, but "assign", "expression" and "variable" are all real language constructs regardless what we call them.
You are describing syntax elements. Even a non-AI machine can identify such parts (AKA parser).
No, syntax only describes the above as something like "<sequence of characters> <symbol> <sequence of characters> ( <symbol> <sequence of characters> [ '(' <blah blah blah> ')' ] )*". Syntax defines allowable arrangements of symbols that form valid sentences in a language. What those sentences mean to us humans -- such as "assign an expression to a variable" -- and what that does in the machine in terms of language constructs, is semantics.
"Meaning" as it takes place in human heads is not directly measurable. Two interpreters having similar behavior (I/O profile) only tells us they have similar behavior. To say anything about some supernatural force called "semantics" is not useful because it's not scientifically analyzable (so far). It's useless to talk about such, it does not help communication. Please stop. I can say interpreters have a force called Zazzo in them. You can neither confirm nor deny it's existence in interpreters. "Semantics" is no more meaningful to me than Zazzo.
Meaning as it takes place in human heads is irrelevant for our purposes, and it only matters to programmers to the extent that they need to understand how programming languages work in order to use them. Our interest in language semantics -- as software engineers, computer scientists, or language designers -- ends long before we reach the point of considering a programmer's interpretation of language semantics. As a language designer, it is sufficient to document the intended semantics -- using English, formal notations, code examples, or a reference implementation -- and from that a compiler/interpreter author can create a compiler or interpreter that implements them.
Their "work" is defined in terms of behavior. And written descriptions sometimes employ UsefulLies, yes, but that does not make them universal truths.
What does this have to do with UsefulLies? Semantics defines behaviour; semantics also defines static structures, relationships between language components, and so on.
Semantics also scratch my itches while I'm asleep. Prove it doesn't. Enough of your SemanticsReligion?.
You're quibbling.
Quibbling over lack of science? Guilty!
You appear to be assuming the only science is observation-based natural science, ignoring the fact that mathematical disciplines (like ComputerScience) are even more rigorous.
Math is what we use to communicate and document models of reality. Ideally, all parts of models should be tested against reality to make sure there is not a problem somewhere with assumptions/givens or math/model derivation or computation mistakes. (In practice we spot-check instead of check everything.) However, I don't really see how it's relevant here since this is no mathematical model of semantics actually being used in these debates.
[That is one use to which we put it, but it's not the only one. And even if it were, it still wouldn't make applying natural science techniques appropriate. Your final point is also incorrect. Some of the semantics under discussion have been mathematical and the one on TypeSystemCategoriesInImperativeLanguages is a portion of a mathematical one presented informally. Other models have been physical, as in the ones implemented in compilers and interpreters.]
TypeSystemCategoriesInImperativeLanguages has models that may be influenced by semantics, but that's not the same as mathematically examining semantics, such as determining equivalency of semantics from one model to another or one language to another.
{Mathematically examining semantics can be done with DenotationalSemantics and other formalisms, but I don't think that's necessary in order to recognise the simple and inarguable fact that "a = foo() + b;" has the same semantics in every popular imperative programming language.}
Sorry, I have to disagree. There are multiple different mental models that can process or analyze such expressions similar to how there are different algorithms to process it. Again, you seem to be mistaking your personal preference or existing mental model for a universal truth.
{"Mental models" are irrelevant. However, even if we consider programmer's "mental models", it's highly unlikely that a programmer will have one mental model for "a = foo() + b;" in Python and a completely different mental model for "a = foo() + b;" in PHP. Do you have different mental models for "a = foo() + b;" in Python and PHP?}
But one can often just cross-translate one into the other, like I already described. One may be mentally syntactically translating PHP into VBS in their head if they are used to VBS and are a newbie at Php. Thus, it could be only a single "semantic" with mostly syntactical translation. Further, that says nothing about inter-mind semantics even IF an individual were using the "same semantics" for common dynamic languages. Studies on monkeys who have their arms chopped off and then have a prosthetic robot limb added shows they use the same "arm" portion of their brain (via scans) to successfully control the prosthetic limp. They don't have to grow a brand new "limb lobe", they reuse what's already there and just translate at a higher level. The monkeys are using reusing the same "arm semantics".
{The fact that you can "cross-translate" from one language to another based on common syntax is proof of identical semantics.}
In a specific head? Maybe, but that's not a useful fact for our purposes. It says nothing about a shared semantics among similar languages or among different heads. It can be "explained" by using a single instance of semantic, plus syntactical translation, to get by using a single semantic in an individual's head. There's no "common semantics" there's only ONE semantic. It's not "identical" (your word), it's the same instance. "Identical" implies copies that are equivalent. There's is no copy in this scenario. I suppose the same identical "thing" is by definition identical to itself, but that's a UselessTruth.
{No, how language semantics are interpreted by a "specific head" or "different heads" is irrelevant. The fact that a statement like "a = foo() + b;" will perform the same computations at run-time in all popular imperative programming languages (modulo those differences in TypeSystem behaviour documented on TypeSystemCategoriesInImperativeLanguages) is proof of identical semantics.}
Please use ItemizedClearLogic. You are not showing some steps to your (alleged) reasoning.
{1. Select a popular imperative programming language.}
{2. Start up the language's text editor, IDE, or interactive environment. Write a function called 'foo' that takes no parameters and returns 3.}
{3. Declare a variable 'b' and assign it 4. If necessary, declare variable 'a'.}
{4. Write "a = foo() + b;", or the equivalent in the language's syntax.}
{5. Write a statement to write out the value of variable 'a'.}
{6. Run the program. Note down what it writes out.}
{7. Repeat steps 2 through 6 on all popular imperative programming languages.}
{8. Observe that the result is 7 in every case. Therefore, the semantics of the above must be the same in every case.}
FacePalm. Okay, let's roll with it. Where does your "Therefore" association in step 8 come from? What logic rule are you applying?
{I'm using equality.}
Of what? You appear to be making up operators without citations to logic rules or the like. It seems an instance of ThenaMiracleOccurs.
{Of the sevens. You are aware that every 7 is the same 7, so they are "equal", yes?}
Are you saying that numerical equality is the same as semantics equality? Your "proof" needs more StepwiseRefinement, or it's logical equivalent.
{No. The fact that an example of almost identical syntax for a given statement -- run in all popular imperative programming languages -- results in the same run-time behaviour (as demonstrated by equal results) is evidence of the same semantics.}
That's a claim, not a proof. And "is evidence of" may be true as a necessary condition (aka, prerequisite, which I don't necessary dispute), but may not be a sufficient condition to say "semantics are same". You need to establish it as a sufficient condition.
{Yes, it's a claim because "Repeat steps 2 through 6 on all popular imperative programming languages" is not and cannot be a logical statement. However, it can be tested empirically. Try it and see.}
- No, I mean "is evidence of". That's a fuzz rule.
- {Sorry, not following you.}
- You are not clear on how it's "evidence of". That part needs clarification. It needs more specifics there.
- {Take (say) a Quicksort algorithm written in C, along with some test code. Verify that it works. Now port it to Java, C#, Perl, Python, Ruby, Objective-C, Visual Basic, C++ and PHP. You will note that you don't have to change the program much; just a few syntax tweaks in each case. This is evidence of very similar syntax and equivalent semantics across all of these popular imperative programming languages. For comparison's sake, port the program to Prolog and Haskell. Note that you have to change the program significantly, both in syntax and structure. This is evidence of different syntax and different semantics.}
- They are not minor changes though such that we can't rule out some other factor. You are downplaying the percentage of code that has to be changed (depending on the algorithms being tested). We have a "feeling" about the similarities, but so far that hasn't been "tamed" for rigorous analysis.
- {Actually, they are minor changes; the percentage of code change is negligible. Try it and see. I don't know what "other factor" you're suggesting there might be.}
- I can think of a code snippet with a C version and a Pascal version that are roughly 80% different character-wise. Granted, it's a somewhat extreme case, but demonstrates the point. We have human judgement intervention here to make the translations that makes the test less objective.
- {They differ strictly in syntax, not semantics. The semantics would be identical. Note that C's '=' and Pascal's ':=' -- the assignment operator -- have different syntax, but identical semantics. Changing from one to the other is a negligible syntax tweak, as is changing 'begin' and 'end' to '{' and '}', or vice versa.}
- Per human "notions", I agree. But that doesn't produce anything objective such that we don't have to rely on feelings and notions.
- {What feelings and notions? I don't "feel" anything about variable assignment in popular imperative programming languages, and yet it's as clear and straightforward as any elementary arithmetic operator, and obviously the same in every popular imperative programming language, in as straightforward and indubitable a manner as noting (continuing the "elementary arithmetic operator" theme, here) that adding 2 things to 3 things invariably results in 5 things.}
- A lot of things are "elementary" to humans, but that does not make them rigorous or clearly defined. Washing dishes is "elementary" to most adult humans, but is extremely difficult to automate well (describe in a rigorous way). Process X being quickly doable by most humans does not by itself make X simple.
- {So? Do we need to formalise "washing dishes" in order to discuss washing dishes, or understand what "washing dishes" means?}
- We do if minutia matters to both parties.
- {It seems to matter to you. In most discussions -- even about programming languages -- it isn't necessary. Many rigorous things do not require formal methods in order to be rigorously understood. A good example are the rules for chess, which can be played at an international competition level without recourse to formal notations. Programming language semantics are rather like chess, in that there are pieces -- functions, variables, values, expressions, literals, types, operators, etc. -- and rules -- syntax and semantics -- governing their interaction. Also like chess, we can discuss the "rules" in English (or whatever other human language we understand), supplementing them with examples in the programming language under discussion.}
- It was you guy(s) who insisted there was One Standard/Common/Canonical "semantics", but I am highly skeptical because semantics is human thoughts and different brains can process things differently (and still arrive at a similar or same answer). I'm asking you to demonstrate clearly that there really is One and Only One. That's not an unrealistic, silly, nor pedantic request. The burden of uniqueness is on you. -t
Further, it almost looks like you are using the I/O profile to measure equivalent semantics, but you have rejected that in the past.
{I don't recognise "I/O profile" as being meaningful, so I neither promote nor demote statements that perform I/O. I don't treat them as any different from any other statements, so I may include them or exclude them as I see fit.}
If you don't recognize it, what alternative do you use to compare and verify that one interpreter is equivalent to another (runs the same language)? Assume poorly written manuals for now.
{I don't preclude using I/O as part of empirical verification of semantics, but it's hardly the sole means for grasping language semantics, and I certainly don't regard I/O as any more or less significant than any other means. You can also read the documentation -- "poorly written" does not preclude understanding language semantics -- or examine the run-time behaviour of statements in a debugger.}
I consider the I/O profile the best arbiter of language and interpreter equivalency. There are indeed multiple ways to "learn about" languages, but they each have weak areas. English documentation can be vague in certain areas, and debuggers can "leak" implementation specifics, and may not represent "output" well and/or be different per language vendor, for example. But in this context, we are talking about proof, not about learning.
Syntax and semantics are clear to me. Here is some syntax in a dynamic, MultiValued language.
1. Customer.Id = Save.Attribute.Values("Customers", "Name", "", "ACME")
2. Name = Get.Attribute.Values("Customers", "Name", Customer.Id)
==> Name now contains "ACME"
The syntax is
ClearEncapsulation. The semantics -
- 1. Save the name of this new customer. Return to the caller the Id used to create this Customer.
- 2. Read the Customer whose Id is the returned one, and return the attribute whose name is Name.
--
ChaunceyGardiner
I'm not sure what your general point is. This is not about interpreting app code. -t
If an entry showing a (hopefully) simple example of a difference between syntax and semantics is inappropriate on a page called semantics discussion, then perhaps I am misinterpreting the name. I would probably grok it more quickly if it were called TopsSemanticsDiscussion?.
Why does everyone use English to represent semantics, and say "this is the semantics..."? It's your personal interpretation of semantics. What we are looking for is a more objective way to compare and contrast semantics. English conversion of mental semantics has left a lot to be desired in these debates.
[They don't. If we were two people who spoke only Russian, we would be using Russian instead of English. We're using English here because it's the language of choice here.]
I doubt using Russian would free it from similar problems. English, as usually used, is insufficiently rigorous for our needs, such as measuring semantic equality.
It's entirely possible to represent semantics without using human language. DenotationalSemantics is a good example.
Then use it to prove your similarity/equivalency claims. Plus, you haven't demonstrated that DS is capturing ONLY semantics and not something else, such as restated algorithms mislabeled as "semantics". We've been over this already. Do we really need to reinvent this fight here again?
What is a "restated algorithm mislabeled as 'semantics'"? Semantics refers to the meaning (in both human and computational terms) of language statements. How would a language statement be a "restated algorithm"?
How do we know that whatever notation "comes out of" DS represents/encodes "semantics" and not the other things mentioned?
A language consists only of syntax and semantics, so if what's being described isn't syntax -- for which we have EBNF and other formal notations -- then it must be semantics. Note also that DenotationalSemantics merely formalises what we can explain in English or any other informal (but humanly-understandable) language. I don't know of any programming language reference manual -- which is a description of language syntax and semantics -- that contains a "restated algorithm mislabelled as 'semantics'", so I don't know why DenotationalSemantics would somehow capture it.
Syntax or semantics might be true of the language(s) itself, but not necessarily of what DS generates. In other words, limits on what a language must be don't necessarily apply to DS results. You seem to be conflating them. It may be generating an algorithm, for example. And many language manuals do describe some statements/operations using algorithms. I'd even argue that's how the better manuals do it because it's often clearer that way. Plus, instructions normally don't classify themselves such that not seeing a mis-classification doesn't tell us much. A mute person rarely misspeaks.
I'm afraid I don't follow any of this, except for "And many language manuals do describe some statements/operations using algorithms." It is true that the semantics of some operators can be described algorithmically. DenotationalSemantics describes them formulaic-ally. How does that relate to a "restated algorithm mislabeled as 'semantics'"?
I don't know why you can't follow any of it. It's clear to me, upon review. I don't know where the communication breakdown is happening such that I cannot "fix it". How do we know that the formulas generated by DS are "semantics" and not just "algorithms" restated in another way? DS produces something, I'll call X. How do we know that X is semantics and not something else? Remember, I'm asking this about DS, not about "programming languages"; thus your statement "A language consists only of syntax and semantics, so if..." does NOT apply. I'm asking about characteristics of DS's output, not (directly) about programming languages at this point. (That's a later step.)
I don't know what the question "how do we know that the formulas generated by DS are 'semantics' and not just 'algorithms'?" means. It makes even less sense than "how do we know that elementary arithmetic expressions are 'simple mathematical formulae' and not just instructions for building a pocket calculator?" Do you understand what denotational semantics are?
I'm not sure, but my answer doesn't excuse you from proving that the output of DS is semantics and only semantics (or at least is free of algorithms). If you say the output of X only contains Y, then prove it only contains Y. Whether I understand X is irrelevant to your proof. Your proof wouldn't care if I was dumb.
I no more need to prove that "the output of DS is semantics" than I need to prove that "the output" of a blue-print is a floor-plan and free of circuit diagrams. I no more need to prove that "the output of DS is semantics" than I need to prove that the Python reference manual is about the Python programming language free of instructions on how to create French poetry.
That's a copout. Generally one can provide evidence that something is an X instead of Y if they are not bullshitting. Circuit diagrams have certain features that floor-plans lack and vice verse and one can catalog existing features and compare occurrences of such features with agreed-upon representative samples, etc. "Shut up and trust me" is not acceptable.
It's not a case of "shut up and trust me", it's a case of "why the bizarre demand?" It's like asking for proof that the source code for a Javascript program isn't a French poem encoded in JSON. I don't know how I'd prove that, either. Your demand for "proof" is so non-sequitur I don't even know where to start, other than to repeat my previous question: Do you understand what denotational semantics are? I suspect if you did, you wouldn't ask.
Sorry, I don't see it as "bizarre". It's a perfectly good question. If you cannot answer that, than admit it like an honest man rather than insult the request.
It's a peculiar question, at least. I find it as strange as showing a picture of a cat, and being asked to prove how I can tell it isn't a car.
Just because it looks like a cat to you does not mean it does to others. You seem to be mistaking your personal head model for some universal truth. "I know it when I see it, so shut up and trust me" is not good enough.
You're quibbling. Requiring that every formalism about <x> prove that it's actually about <x> is unreasonable, and unnecessary, as is requiring that every claim of writing about <x> demonstrate that it's actually about <x>. If a document purports to be about <x> but is actually about <y>, it will inevitably become clear, sooner or later.
What's this "every" stuff? I only requested it for one situation. You are drama-queening. I'm highly skeptical the claimed item is "pure semantics".
Given that DenotationalSemantics is merely one formalism among many -- possessing no special or distinguishing attributes -- I can only assume that if you insist that it be proven that DenotationalSemantics is about semantics, then you must insist that it be shown that every formalism about <x> is actually about <x>. Otherwise, why do you single out DenotationalSemantics for special scrutiny?
I don't see why that's a global requirement. As mentioned before, as long as two parties agree on a given base fact, there is no reason to argue or question it. There are plenty of NON-agreements to debate such that gumming up the works proving things both sides already agree on should be a low priority in comparison. If you personally want to prove everything under the sun, go for it, Sheldon.
That doesn't answer my question, and doesn't appear to be related to it.
- As far as I can tell, I addressed your question sufficiently. I reread them both and answered it to the best of my abilities. It appears to be wandering off topic anyhow and I'm not interested in widening it at the moment.
- My question was specifically, "why do you single out DenotationalSemantics for special scrutiny?" That does not appear to be answered.
- I happen to be curious about that topic at the moment. I'm not curious about floor plans today.
- It's an odd focus. How often in discussions about ExBase did you feel compelled to ask whether the ExBase documentation was actually about algorithms rather than the ExBase language?
- Rarely, if ever, because we were focused on getting work done, not classification of things. If it gave us the necessary info to answer a question, it was "good" (for that question), or it was "not good". And there are different ways to answer questions, or at least provide sufficient clues. An algorithm example or explanation sometimes did the job, and sometimes a description did the job.
What is "pure semantics"?
Semantics, or a representation of, lacking syntactic and algorithm information, at least.
Can you given an example of non-"pure semantics", particularly using DenotationalSemantics?
The example in that topic that has a rule that syntax in the form of the left side "means" an operation/function described on the right side:
[[A + B]] = plus([[A]], [[B]])
That is or can be viewed as a partial
algorithm that can be used for the purposes of interpreting/compiling language statements. True, one does not have to use it as an algorithm or part of an algorithm, but again "meaning" and "intention" happens in human heads and different heads may do different things with the same given info.
An algorithm is a set of steps to be followed to solve a problem. I see no steps, only an equivalence of a syntactic construct to a construct in some other (perhaps mathematical, or perhaps the implementation language) domain.
An algorithm does NOT have to be "steps". Functional and logical algorithms can lack explicit "steps", for example.
[The definition of "algorithm" is "a set of steps to be followed to solve a problem." (There's an alternate wording at http://en.wikipedia.org/wiki/Algorithm .) It immediately follows that algorithms have to be composed of steps.]
So a logic-constraint type of language, such as non-procedural queries, are not "algorithms"? I don't believe most would agree with that. Those definitions are probably colloquial definitions and not industry-vetted. And even if they were not, they are still not "semantics" any more than queries are "semantics". It appears to me that DS is merely producing alternative syntax for languages that perhaps may aid in analysis, but this is not necessary pure "meaning". It looks more like a half-ass interpreter meta language. It's similar to a device that builds an AbstractSyntaxTree. Would such a device be called a "semantics extractor"? Perhaps, perhaps not, but it's not necessarily isolating unique semantics, but merely one of multiple possible semantics.
[That is correct, the non-procedural queries would not be an algorithm. Those definitions are the ones provided by the industry, so they are industry-vetted. As for what appears to you, it would help if you opened your eyes. DenotationalSemantics are not half-ass, do tell you what meaning to assign to what language constructs (and is therefore semantics). I don't think anyone would call a device that builds AbstractSyntaxTrees a "semantics extractor". (Hint: It's not an abstract semantic tree.) The "pure" and "uniqueness" constraints are yours and yours alone and aren't necessary.]
- If logic languages don't encode algorithms, what are they encoding? What do we call it? Formulas? Perhaps, but formulas are not necessarily "semantics".
- [Logic languages are based on predicates.]
- Re: 'The "pure" and "uniqueness" constraints are yours and yours alone and aren't necessary.' - Unnecessary for what? Please elaborate.
- Unnecessary for anything.
Interpreters/compilers also tell the computer "what meaning to assign to what language constructs". Compilers describe such "meaning" in terms of machine code or machine code patterns and DS uses a kind of meta language. Machine code may not be very friendly to read, but that's a quality/target-audience question, not a definitional issue. Nor are the results unique. And I did not say the
AbstractSyntaxTree was the semantics extractor itself. I suggest you reread it.
- [This is, of course, what we've been telling you. An immediate consequence of this is that semantics are not in the head. About the AbstractSyntaxTree, I've changed my response to better reflect what you wrote. Notice that the hint has remained the same.]
- I should have said implementation, not "meaning" with regard to machine code. I quoted "meaning" to imply I didn't sign off on that usage. Meaning only happens in human heads, not CPU chips.
- Programming language semantics defines meaning in two ways: One is the human cognition that lets us understand programming language, the other is the "meaning" to the machine, i.e., the mechanical interpretation/compilation into run-time language behaviour. The fact that the two correspond is what allows us to write programs that do useful things.
- I see no common evidence of this two-way-ness. The machine side is called "implementation". You are inventing definitions out of the blue.
- An "implementation" is just a compiler or interpreter. It is specifically the fact that the semantics of the language are implemented in the interpreter or compiler that the meaning of the programming language to us becomes useful run-time action on a computer. For example, the semantics of a syntactic construct like "while (p) {x};" might be "execute code 'x' as long as boolean expression 'p' evaluates to 'true' and continue with subsequent statements when 'p' evaluates to 'false'". The fact that the interpreter or compiler has implemented these semantics is what makes it useful, by performing a loop contingent on the result of evaluating an expression -- exactly what the semantics described.
- I don't see how that contradicts anything I've said. I'm not questioning "utility". Except semantics don't "describe". Semantics don't talk. You guys keep implying semantics talk in the way you describe it.
- Semantics "describes" what a language does at run-time, the same way the instruction manual "describes" what the buttons do on your dishwasher.
- I'm not talking about semantics in general, but your specific way of describing what semantics do. Also I would note that some manuals inject imaginary middle-man processes or parts as part of their descriptions to make it more palatable to the reader. UsefulLies.
- You said you "see no common evidence of this two-way-ness" and claimed that I am "inventing definitions out of the blue". I have clarified the definition of "implementation" using familiar terminology (so I'm not "inventing definitions out of the blue"), and demonstrated that there is a tight coupling between semantics as humans interpret them and how semantics are implemented, such that the "two-way-ness" is self-evident.
- You gave your version of what it means using familiar terminology. There may be a tight coupling, but that's not the same as equivalence. (Note: I made some text changes above.)
- I gave the conventional version of what it means using familiar terminology. Anyone who disagrees with it would be wrong, and it most certainly is equivalence. If the compiler/interpreter for language <x> doesn't match the semantics for language <x>, it's a bug.
- You haven't found a way to clearly measure and present your evidence of "conventional". So far it's just anecdotes. Also note that due to the ambiguity of English, it's possible for multiple different interpretations to not be "wrong" as given. As far as measuring "semantics match", we've already been over that.
Such a meta language may be quite useful for a compiler designed for multiple hardware platforms (CPU chip instruction sets) so that we only have to build one "front end" compiler to do roughly half the work, and a meta-language-to-machine-language translator "back end" would be built for each chip type to translate the meta language to the target machine language. (This is somewhat like Microsoft's CLR.) But such a meta language is not "pure semantics". It's at least partially algorithmic information. Nor is it unique: there are multiple ways to define and build such meta languages. Thus, even if by some stretch we consider such meta language "semantics", it does not prove a unique or canonical semantics for a given language family. Perhaps we can force it to be the same for a target family, but this itself does not necessarily prove canonical-ness because we can't rule out the similarity being due to artificial decisions that have the intent/goal of forcing similarity. The existence of semantics was not our point of contention, but COMPARING semantics to objectively say the semantics of X are the same as the semantics for Y. That's our ultimate goal.
- [Such meta languages are used to rigorously (beyond what can be accomplished using natural language) define the semantics of programming languages. While one could write a compiler that understood DenotationalSemantics, it would essentially allow one to compile langauges that the author of the compiler didn't now about. That does not look very much like Microsoft's CLR, where all of the compilers only understand a fixed set of languages. The big difference for this discussion would be that the DenotationalSemantics wouldn't be used as a target language. It would tell the program how to translate from the source language to machine language. Once again, the "pure" and "uniqueness" constraints are unnecessary. As for comparing semantics objectively, you just compare what the computer does when it executes a given language statement. If, at the level of abstraction of interest, they do the same thing, they have the same semantics.]
- DS does not produce semantics, but rather converts syntax patterns to partly-digested implementations. Just because you have a rule that converts "+" into a meta function called "plus" and changes infix to pre-fix does not mean it's "representing meaning". That's representing implementation.
- As was explained before, it's mapping language statements to formal constructs in another domain, typically mathematical objects. The example did not define 'plus', though it would inevitably be formally defined elsewhere, and the change from infix to prefix is irrelevant.
- As was explained elsewhere, that is NOT semantics. If I map language statements to Prolog, that doesn't make the resulting Prolog code semantics and only semantics. It's just translating one language to another. DS just doesn't finish the job.
- The mappings themselves aren't semantics. The semantics are described by mathematical objects (typically) that formalise the semantics of the language in a rigorous manner that allows us to reason about the semantics. We normally can't reason effectively about imperative code because of the need to mentally keep track of state and side-effects. (Obviously, we can read imperative code, but mentally running code -- for anything more complex than toy programs -- is arduous.)
- It's encoding syntactical patterns and some degree of implementation as applied by a human user of the notation. For example, indicating that the expression syntax pattern "[a] + [b]" will be denoted "plus([a],[c])" is the DS user injecting an implementation (or part of an implementation) into the syntax pattern translation mechanism. It's a form of re-describing the language syntax in a form that's easier to apply notational analysis AND implementation analysis to (AKA math). It's encoding a mapping of syntax patterns to (partial) implementation patterns. I'm hesitant to call it "semantics" unless we end up agreeing that implementation is a sub-set of semantics. It's sort of like adding/integrating implementation hints into Backus–Naur Form. And I agree it can help one analyze implementation-related aspects of a programming language better than syntax alone, but that's not necessarily the same as semantics analysis. (I called this implementation aspect "algorithm" before, but I was using the term "algorithm" in too wide a fashion per usual industry usage, it appears.) -t
- What is does "injecting an implementation (or part of an implementation) into the syntax pattern translation mechanism" mean? There are certainly parser generators that allow us to associate statements in a host language (the language the interpreter or compiler is written in) with statements in the target language (the language being parsed, with a goal of being interpreted or compiled). This allows us to map target language statements to the host language in order to implement the semantics of the target language. However, that's not what DenotationalSemantics are used for. They're used to rigorously formalise descriptions of semantics, so we can reason logically about the semantics. In practice, DenotationalSemantics for a target language can be used to help the compiler/interpreter author decide how to implement the semantics, but DenotationalSemantics aren't implementation, they're description.
- Why does it matter what it's used for? The nature of the thing changes depending on what it's used for? That sometimes happens in physical life, granted, but it's odd here. And DS may indeed help provide some insight into semantics (or at least run-time "behavior"), but that's not the same as BEING semantics. What you call semantics in DS appears to me to be implementation hints. I say "hints" because they are not fully defined. I'm not sure what to call these kinds of hints, but I would not call them pure semantics. They are a partially digested implementation meal.
- I have no idea what a "partially digested implementation meal" means, but I suspect it derives from a misunderstanding of DenotationalSemantics. I suggest reading some texts on the subject.
- I'm not sure I care anymore what is and isn't "semantics". I forgot why it mattered. As I remember it, the issue was objectively proving that the semantics of two different languages were "equivalent". Even if DS produced "semantics", unless you prove that there is only one possible output string (from DS) for a given language and that output string is the same for both languages, you have not shown equivalent semantics between those two languages. It appears a human worker has to assign "meaning functions" (for lack of a better description) to produce the DS output. Thus, DS is not an objective system.
- Why would it matter whether "only one possible output string (from DS)" exists for a given language or not? DenotationalSemantics only formalises the semantics we can otherwise describe in some human language. Like English, DenotationalSemantics lets us describe the same semantics in different ways. However, if "while (p) {...}" has the same semantics in Java, C#, C, C++, PHP, and the same semantics as "while p do ... end" in Ruby and "while p: \n\t..." in Python, then it's the same semantics. We don't need DenotationalSemantics to prove the obvious.
- Just because they can be described in a very similar way does not by itself mean their semantics are the same/similar.
- Actually, it does.
- Let's say language 1 can be described using model B, C, F, and J. Language 2 can be described using model D, F, and K. They share model F in common, but that does not mean they fully behave the same way.
- In the languages I listed above, I don't know of any where the semantics of the "while" loop differ. In other words, they fully behave the same way.
- If they copy each other and have the same function in them, of course that function will act the same. Same with "while".
- Notion-wise, I agree they do, but I cannot rule out biases from other sources such as traditionally lumping them in the same family. Notion-y feelings are not good enough to make rigorous statements about them.
- True, we have to read the language documentation to make sure there aren't unanticipated semantics associated with apparently-familiar constructs.
- The final arbiter in practice is usually the behavior of the interpreter (IoProfile or an approximation of), not English descriptions of it. You seem to believe that regular developers care about the English side more than they actually do. We'll have to AgreeToDisagree on that. Another AnecdoteImpasse.
- I include source code examples as part of the language documentation, but obviously these are of negligible value unless (at least) commented. Thus, the language documentation is crucial. I don't know any programmer who uses your "IoProfile". Do you use it?
- Yes, I indeed do commonly learn using examples. And are we talking about learning, or verifying equivalency here?
DS doesn't produce a meta version of the app source code, but is more like a meta language for meta language producers. I'm not sure I'm saying that right. I'm lacking for a way to describe it well in English right now.
[You most certainly aren't.]
English Redux
a = b + c * d
Person
A: "Multiply c by d, and then add the result to b, and store that result in a".
Person B: "Push c and d onto the stack, apply multiplication reduction to the stack. Push b onto the stack and then apply addition reduction to the stack. Label the topmost element of the stack 'a'."
You seem to be calling descriptions similar to person A's description "semantics" and person B's description an "implementation suggestion" or an "algorithm".
However, I see no reason to make a classification distinction. A's description is also an algorithm. A's approach is generally how we learn to describe and process it in grade school and thus it's more entrenched human-wise. But it's just as arbitrary if we remove such upbringing influence. You can call both "semantics" if you want, but then you are agreeing that implementation and semantics are or can be the same thing, at least as English descriptions. (Notice how B does not really need a "store" step. Thus, "store" is not universal either.) -t
The above is a poor example, conflating the process of expression evaluation with the semantics which are simply, at a high level, "assign the result of evaluating an expression to 'a'".
- PageAnchor pattern-839
- That's not necessary semantics. It could be merely symbol substitution such that when somebody sees "assign the result of evaluating expression <expression> to 'x'" on paper one translates that to "x = <expression>" in their code editor. It's an alias. I remember in math class the teacher would show students how to literally take certain sentence patterns and translate it into math notation via "copy part A to part B" kind of things using arrows that mapped source to destination. It was brain-dead syntactical substitution, not necessarily "meaning". A non-English speaker could do it without even knowing what the words meant. (Well, I didn't know what they mean either because they were math-specific phrase conventions, not unlike "Find the Midenheimer Plex Transformation equivalent of X for the non-open set Y" or such. I just followed the substitution steps like a good little savant...sometimes.) As far as one can tell, the phrase you gave is simply a syntax convention that's equivalent or can be viewed as equivalent to the "code" version.
- You're again referring to interpretation, not specification. Semantics are specified, not inferred.
- What exactly is "specification"? I don't remember you using that word recently. And how does one know if they are looking at specification or implementation?
- A specification is a document. A language specification -- which is sometimes the same as a language reference manual, and sometimes different -- describes semantics and syntax of that language, hopefully in sufficient detail to make an implementation of it. An implementation (in the context used here) is software, a compiler or interpreter.
- If IBM came out with an alleged C-sharp compiler, most orgs would test it buy running their existing apps on a trial copy to make sure they work the same as they did under Microsoft's. They would not rely heavily on the IBM manual that came with it (even if it was well-written, which is uncommon) beyond looking for clues to any oddities encountered.
- You're describing compiler/interpreter validation, which is often done using validation suites by folks like Plumhall (see http://www.plumhall.com/products.html) I'm not sure what that has to do with the preceding discussion about specifications, semantics, and implementations. Validating compilers and interpreters is very different from what individuals do to learn languages.
- Few read the language's official documentation to learn. It's usually training-related materials that are used. Official documentation is mostly meant to describe the language to those who already know how to program, not to those starting from scratch.
- Training-related materials are fine; they're a reflection of the official documentation, invariably (aside from inadvertent error) reflecting the same syntax and semantics. As for starting programming from scratch, that's something else entirely.
- They are not necessarily a reflection of the "official" documentation for a given language. The author may choose different techniques. However, there are indeed common traditions in such writing such that everybody copies each other to some extent.
- Training-related materials that use semantics that don't reflect the "official" documentation for a given language would be pretty much useless. What good would be a training manual that claims "a = b;" means "shift left and dim the lights" instead of "assign the value of 'b' to variable 'a'"?
- If done well, it may work. I have yet to see a good example, but I cannot rule it out. Like I mentioned before, if one can "think in stacks" for expression evaluation, that's perfectly fine. He/she is not committing any sin. And "assign" is not necessarily "meaning". It's just a shared label we give to something.
A better example is the following. Imagine a language that has an operator 'sort' to sort a list or array. So, a statement like "a = sort b;" has the semantics "store the result of sorting 'b' in 'a'". That is quite distinct from the implementation and/or algorithm, which could be:
void Quicksort(IComparable[] elements, int left, int right)
{
int i = left, j = right;
IComparable pivot = elements[(left + right) / 2];
while (i <= j) {
while (elements[i].CompareTo(pivot) < 0) {i++;}
while (elements[j].CompareTo(pivot) > 0) {j--;}
if (i <= j) {
IComparable tmp = elements[i];
elements[i] = elements[j];
elements[j] = tmp;
i++;
j--;
}
}
if (left < j) {
Quicksort(elements, left, j);
}
if (i < right) {
Quicksort(elements, i, right);
}
}
IComparable[] tmp = (IComparable[])Expression.Evaluate('b');
Quicksort(tmp, 0, tmp.Length - 1);
Variable.Assign('a', tmp);
I agree they are very different, but that does not tell us precisely what the first thing is in terms of classification.
The first thing is an expression assigned to a variable. That's what it means, and therefore that is its semantics.
As described above near PageAnchor pattern-839, that could merely be a language pattern that is associated with a syntax pattern through habit or convention. It's not necessarily "meaning". Providing an alias is not necessarily meaning.
You're talking about how it might be inferred. Inference is irrelevant. I know of no popular imperative programming language where it would not have been specified as an expression assigned to a variable.
I'm not sure what you mean by "inferred" in this context. Manuals and training materials follow certain conventions of description, true, but that does not necessarily make those conventions "meaning". They can merely be conventions that are treated as aliases of the kind described near PageAnchor pattern-839. You see "foo is assigned to thing" and you can just mentally translate that to "thing = foo" out of tradition by studying word occurrence patterns in the books. Even a non-English speaker can do such because it's a pattern that can be learned without mentally associating meaning to each of the words or phrases. It's one of the reasons why foreign students often do so well in math in US universities despite flunking out of English 101. If you have a near-photographic memory, you must memorize word pattern usage in math books and plug in the "linguistic parameters" where appropriate. As long as the tests keep to the same conventions, the test taker can apply such linguistic substitution and get a good grade. -t
Again, you're making reference to inference rather than specification. Semantics are specified. Language statements mean what the language designer wants them to mean.
No, meaning is whatever anybody wants meaning to be. The language author cannot prevent me from using my favorite model etc. in my head to predict language behavior. Any documentation by the language author is a suggested model/description only. They are not God and their writing is not The Bible.
You're confusing "meaning" with "interpretation". Language statements mean what the language designer wants them to mean. How meaning is interpreted is up to each individual. Of course, when an individual is the author of a compiler or interpreter, hopefully there is a close concordance between the semantics intended by the language designer and the semantics implemented by the compiler/interpreter author.
You haven't demonstrated that they are fully distinct. One can use whatever model their head wants to analyze and predict source code. Nobody can stop them, not the language author and not you. -t
Well that has cleared that up. --AnonymousDonor
DecemberThirteen