Why are standard libraries not programming language primitives? [closed]












29















I was thinking why are there (in all programming languages I have learned, such as C++, Java, Python) standard libraries like stdlib, instead of having similar "functions" being a primitive of the language itself.










share|improve this question















closed as unclear what you're asking by gnat, Eric Lippert, BЈовић, jpmc26, BobDalgleish Jan 30 at 18:29


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.














  • 4





    What do you mean "why couldn't the compiler simply translate a function call into a set of instructions"? That's roughly what the compiler does, standard library or not (Ok, Python only partway and Java to JVM bytecode; similar concept). Standard libraries really don't have anything to do with the compilation of code -> instructions.

    – Delioth
    Jan 29 at 18:08






  • 24





    @Delioth I think Simone is asking why isn't everything in the standard library of language $LANG a primitive construct/function of that language instead. I'd say it's a reasonable question for anyone who is very new to programming languages :)

    – Andres F.
    Jan 29 at 18:24








  • 32





    The standard library generally fills the gap between a working programming language and a useful one that people will use.

    – Telastyn
    Jan 29 at 21:10






  • 6





    A significant part of Python's standard library is actually written in C and already compiled.

    – ElmoVanKielmo
    Jan 29 at 22:36






  • 1





    As a way of contrast, in most implementations of BASIC everything is part of the language and there are no libraries at all nor support for them (save, in several implementations, for the ability to call into machine language routines).

    – Euro Micelli
    Jan 30 at 0:40
















29















I was thinking why are there (in all programming languages I have learned, such as C++, Java, Python) standard libraries like stdlib, instead of having similar "functions" being a primitive of the language itself.










share|improve this question















closed as unclear what you're asking by gnat, Eric Lippert, BЈовић, jpmc26, BobDalgleish Jan 30 at 18:29


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.














  • 4





    What do you mean "why couldn't the compiler simply translate a function call into a set of instructions"? That's roughly what the compiler does, standard library or not (Ok, Python only partway and Java to JVM bytecode; similar concept). Standard libraries really don't have anything to do with the compilation of code -> instructions.

    – Delioth
    Jan 29 at 18:08






  • 24





    @Delioth I think Simone is asking why isn't everything in the standard library of language $LANG a primitive construct/function of that language instead. I'd say it's a reasonable question for anyone who is very new to programming languages :)

    – Andres F.
    Jan 29 at 18:24








  • 32





    The standard library generally fills the gap between a working programming language and a useful one that people will use.

    – Telastyn
    Jan 29 at 21:10






  • 6





    A significant part of Python's standard library is actually written in C and already compiled.

    – ElmoVanKielmo
    Jan 29 at 22:36






  • 1





    As a way of contrast, in most implementations of BASIC everything is part of the language and there are no libraries at all nor support for them (save, in several implementations, for the ability to call into machine language routines).

    – Euro Micelli
    Jan 30 at 0:40














29












29








29


6






I was thinking why are there (in all programming languages I have learned, such as C++, Java, Python) standard libraries like stdlib, instead of having similar "functions" being a primitive of the language itself.










share|improve this question
















I was thinking why are there (in all programming languages I have learned, such as C++, Java, Python) standard libraries like stdlib, instead of having similar "functions" being a primitive of the language itself.







programming-languages standard-library






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 30 at 1:43









Nicol Bolas

9,66742737




9,66742737










asked Jan 29 at 17:55









Simone BroiliSimone Broili

16026




16026




closed as unclear what you're asking by gnat, Eric Lippert, BЈовић, jpmc26, BobDalgleish Jan 30 at 18:29


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.









closed as unclear what you're asking by gnat, Eric Lippert, BЈовић, jpmc26, BobDalgleish Jan 30 at 18:29


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.










  • 4





    What do you mean "why couldn't the compiler simply translate a function call into a set of instructions"? That's roughly what the compiler does, standard library or not (Ok, Python only partway and Java to JVM bytecode; similar concept). Standard libraries really don't have anything to do with the compilation of code -> instructions.

    – Delioth
    Jan 29 at 18:08






  • 24





    @Delioth I think Simone is asking why isn't everything in the standard library of language $LANG a primitive construct/function of that language instead. I'd say it's a reasonable question for anyone who is very new to programming languages :)

    – Andres F.
    Jan 29 at 18:24








  • 32





    The standard library generally fills the gap between a working programming language and a useful one that people will use.

    – Telastyn
    Jan 29 at 21:10






  • 6





    A significant part of Python's standard library is actually written in C and already compiled.

    – ElmoVanKielmo
    Jan 29 at 22:36






  • 1





    As a way of contrast, in most implementations of BASIC everything is part of the language and there are no libraries at all nor support for them (save, in several implementations, for the ability to call into machine language routines).

    – Euro Micelli
    Jan 30 at 0:40














  • 4





    What do you mean "why couldn't the compiler simply translate a function call into a set of instructions"? That's roughly what the compiler does, standard library or not (Ok, Python only partway and Java to JVM bytecode; similar concept). Standard libraries really don't have anything to do with the compilation of code -> instructions.

    – Delioth
    Jan 29 at 18:08






  • 24





    @Delioth I think Simone is asking why isn't everything in the standard library of language $LANG a primitive construct/function of that language instead. I'd say it's a reasonable question for anyone who is very new to programming languages :)

    – Andres F.
    Jan 29 at 18:24








  • 32





    The standard library generally fills the gap between a working programming language and a useful one that people will use.

    – Telastyn
    Jan 29 at 21:10






  • 6





    A significant part of Python's standard library is actually written in C and already compiled.

    – ElmoVanKielmo
    Jan 29 at 22:36






  • 1





    As a way of contrast, in most implementations of BASIC everything is part of the language and there are no libraries at all nor support for them (save, in several implementations, for the ability to call into machine language routines).

    – Euro Micelli
    Jan 30 at 0:40








4




4





What do you mean "why couldn't the compiler simply translate a function call into a set of instructions"? That's roughly what the compiler does, standard library or not (Ok, Python only partway and Java to JVM bytecode; similar concept). Standard libraries really don't have anything to do with the compilation of code -> instructions.

– Delioth
Jan 29 at 18:08





What do you mean "why couldn't the compiler simply translate a function call into a set of instructions"? That's roughly what the compiler does, standard library or not (Ok, Python only partway and Java to JVM bytecode; similar concept). Standard libraries really don't have anything to do with the compilation of code -> instructions.

– Delioth
Jan 29 at 18:08




24




24





@Delioth I think Simone is asking why isn't everything in the standard library of language $LANG a primitive construct/function of that language instead. I'd say it's a reasonable question for anyone who is very new to programming languages :)

– Andres F.
Jan 29 at 18:24







@Delioth I think Simone is asking why isn't everything in the standard library of language $LANG a primitive construct/function of that language instead. I'd say it's a reasonable question for anyone who is very new to programming languages :)

– Andres F.
Jan 29 at 18:24






32




32





The standard library generally fills the gap between a working programming language and a useful one that people will use.

– Telastyn
Jan 29 at 21:10





The standard library generally fills the gap between a working programming language and a useful one that people will use.

– Telastyn
Jan 29 at 21:10




6




6





A significant part of Python's standard library is actually written in C and already compiled.

– ElmoVanKielmo
Jan 29 at 22:36





A significant part of Python's standard library is actually written in C and already compiled.

– ElmoVanKielmo
Jan 29 at 22:36




1




1





As a way of contrast, in most implementations of BASIC everything is part of the language and there are no libraries at all nor support for them (save, in several implementations, for the ability to call into machine language routines).

– Euro Micelli
Jan 30 at 0:40





As a way of contrast, in most implementations of BASIC everything is part of the language and there are no libraries at all nor support for them (save, in several implementations, for the ability to call into machine language routines).

– Euro Micelli
Jan 30 at 0:40










10 Answers
10






active

oldest

votes


















33














Allow me to expand somewhat on @Vincent's (+1) good answer:




Why couldn't the compiler simply translate a function call into a set of instructions?




It can, and does so via at least two mechanisms:




  • inlining a function call — during translation, the compiler can replace a source code call with its implementation directly inline instead of making an actual call to the function.  Still the function needs to have an implementation defined somewhere and that can be in the standard library.


  • intrinsic function — intrinsics are functions that the compiler has been informed of without necessarily finding the function in a library.  These are usually reserved for hardware features that are not practically accessible in any other way, being so simple that even the overhead of a call to assembly language library function is considered high.  (The compiler can generally only automatically inline source code in its language, but not assembly functions, which is where intrinsic mechanism comes in.)



Still these being said, the best option sometimes is for the compiler to translate a function call in the source language into a function call in the machine code.  Recursion, virtual methods, and sheer size are some reasons that inlining is not always possible/practical.  (Another reason is intent of the build, such as separate compilation (object modules), separate load units (e.g. DLLs)).



There's no real advantage to making most standard library functions intrisics either (that would hard code a lot more knowledge into the compiler for no real advantage), so a machine code call again is often most appropriate.



C is a notable language that arguably omitted other explicit language statements in favor standard library functions.  Though libraries pre-existed, this language made a shift to doing more work from standard library functions and less as explicit statements in the grammar of the language.  IO in other languages, for example, was frequently given its own syntax in the form of various statements, whereas the C grammar does not define any IO statements, simply instead deferring to its standard library to provide that, all accessible via function calls, which the compiler already knows how to do.






share|improve this answer





















  • 3





    Nice answer. One should add some words why this decision in C was made: if I remember correctly, the main reason was actually because it made it way easier to create C compilers for many different hardware architectures.

    – Doc Brown
    Jan 29 at 21:20






  • 10





    @DocBrown By 1975, there were enough examples in the area of the programming language development (ALGOL-68, anyone?) which showed that attempts to bake-in everything into the language directly led to considerable slow downs in both finsihing the language specifications and in producing language implementations.

    – Joker_vD
    Jan 29 at 21:27






  • 5





    A similar example is what Python did with print: In 2.x, it was a statement, with its own special grammar, but in 3.x, it became just another function call. See PEP 3105 for the official explanation.

    – dan04
    Jan 29 at 23:17






  • 1





    @DocBrown, portability was almost certainly not a reason. When Unix and C were created, they were designed and built for exactly one machine, a spare PDP-7, as Ken Thompson wondered what concepts could be salvaged from the failed Multics project. C was also created for one reason: to have a high level language in which to (re)implement Unix. They we’re basically an experiment in software design, not a serious attempt at a commercial multi-platform OS and language. See bell-labs.com/usr/dmr/www/chist.html for example.

    – Euro Micelli
    Jan 30 at 0:28











  • @EuroMicelli: I don't see there a contradiction. And your reference contains a lot of details about when portability became important, it was actually in the early years of the C and Unix development. I can only guess here, but if the C inventors would not have kept the language intentionally small, I think it would have been quite unlikely that they could have ported it so quickly and sucessfully to many different architectures.

    – Doc Brown
    Jan 30 at 6:36





















70














This is simply to keep the language itself as simple as possible. You need to distinguish between a feature of the language, such as a type of loop or ways to pass parameters to functions and so on, and common functionality that most applications need.



Libraries are functions that may be useful to many programmers so they are created as reusable code that can be shared. The standard libraries are designed to be very common functions that programmers typically need. This way the programming language is immediately useful to a wider range of programmers. The libraries can be updated and extended without changing the core features of the language itself.






share|improve this answer



















  • 3





    Not always. PHP as an example hardly makes any differences between its vast language functions and the language itself.

    – Vahid Amiri
    Jan 30 at 7:25






  • 15





    I wouldn't take PHP as an example of a simple language

    – DrBreakalot
    Jan 30 at 10:29






  • 3





    @DrBreakalot PHP's an extremely simple language. That's not to say that it has a consistent design, but that's another issue.

    – Lightness Races in Orbit
    Jan 30 at 11:44






  • 19





    @LightnessRacesinOrbit I wouldn't call PHP "simple" at all: it has a class-based object system, a separate set of 'primitive values', standalone functions, first-class closures built on the object system, a namespace mechanism, various notions called "static", statements as well as expressions, include, require and require_once, if/for/while (structured programming), exceptions, a separate system of 'error values', complicated weak typing rules, complicated operator precedence rules, and on and on. Compare this to the simplicity of, say, Smalltalk, Scheme, Prolog, Forth, etc. ;)

    – Warbo
    Jan 30 at 14:22








  • 3





    The main reason, which is hinted at but not explicitly stated in this answer, is that by keeping the language as simple as possible, it is much easier to implement on other platforms. Since the standard libraries are usually written in the language itself, they can be trivially ported.

    – BlueRaja - Danny Pflughoeft
    Jan 30 at 17:40





















33














In addition to what the other answers have already said, putting standard functions into a library is separation of concerns:




  • It's the compiler's job to parse the language and generate code for it. It's not the compiler's job to contain anything that can already be written in that language and provided as a library.


  • It's the standard library's (the one that's always implicitly available) job to provide core functionality that's needed by virtually all programs. It's not the standard library's job to contain all the functions that might be useful.


  • It's the job of optional standard libraries to provide auxiliary functionality that many programs can do without, but which are still quite basic and also essential for many applications to warrant shipping with standard environments. It's not the job of those optional libraries to contain all reusable code that's ever been written.


  • It's the job of user libraries to provide collections of useful reusable functions. It's not the job of user libraries to contain all the code that's ever been written.


  • It's the job of an application's source code to provide the remaining bits of code that are really only relevant to that one application.



If you want a one-size-fits-all software, you get something insanely complex. You need to modularize to get the complexity down to manageable levels. And you need to modularize to allow partial implementations:




  • The threading library is worthless on the single-core embedded controller. Allowing the language implementation for this embedded controller to just not include the pthread library is just the right thing to do.


  • The math library is worthless on the micro-controller that doesn't even have an FPU. Again, not being forced to provide functions like sin() makes life a whole lot easier for the implementators of your language for that micro-controller.


  • Even the core standard library is worthless when you are programming a kernel. You cannot implement write() without a syscall into the kernel, and you cannot implement printf() without write(). As a kernel programmer, it's your job to provide the write() syscall, you cannot just expect it to be there.



A language that does not allow for such omissions from the standard libraries is simply not suited for many tasks. If you want your language to be flexibly usable in uncommon environments, it must be flexible in what standard libraries are included. The more your language relies on standard libraries, the more assumptions it makes on its execution environment, and thus restricts its use to environments that provide these prerequisites.



Of course, high level languages like python and java can make a lot of assumptions on their environment. And they tend to include many, many things into their standard libraries. Lower level languages like C provide much less in their standard libraries, and keep the core standard library much smaller. That's why you find a working C compiler for virtually any architecture, but may not be able to run any python scripts on it.






share|improve this answer

































    16














    One big reason compilers and standard libraries are separate are because they serve two different purposes (even if they're both defined by the same language spec): the compiler translates higher-level code into machine instructions, and the standard library provides pre-tested implementations of commonly-needed functionality. Compiler writers value modularity just like other software developers do. In fact, some of the early C compilers further split the compiler into separate programs for pre-processing, compiling, and linking.



    This modularity gives you a bunch of advantages:




    • It minimizes the amount of work needed when supporting a new hardware platform, since most of the standard library code is hardware-agnostic can be re-used.

    • A standard library implementation can be optimized in different ways (for speed, for space, for resource usage, etc). Many early computing systems only had one compiler available, and having a separate standard library meant developers could swap implementations to suit their needs.

    • The standard library functionality doesn't even have to exist. When writing bare-metal C code for instance, you have a full-featured compiler but most of the standard library functionality isn't there and some things like file I/O aren't even possible. If the compiler was required to implement this functionality, then you couldn't have a standards-conforming C compiler on some of the platforms where you need it the most.

    • On early systems, compilers were frequently developed by the company that designed the hardware. Standard libraries were frequently provided by the OS vendor, since they often required access to functionality (like system calls) specific to that software platform. It was impractical for a compiler writer to have to support all of the different combinations of hardware and software (there used to be a whole lot more variety in both hardware architecture and software platform).

    • In high-level languages, a standard library can be implemented as a dynamically-loaded library. One standard library implementation can then be used by multiple compilers and/or programming languages.


    Historically speaking (at least from C's perspective), the original, pre-standardization versions of the language didn't have a standard library at all. OS vendors and third parties would often provide libraries full of commonly-used functionality, but different implementations included different things and they were largely incompatible with each other. When C was standardized, they defined a "standard library" in an attempt to harmonize these disparate implementations and improve portability. The C standard library developed separate from the language, like the Boost libraries have for C++, but were later integrated into the language spec.






    share|improve this answer































      6














      Additional corner-case answer: Intellectual property management



      Notable example is implementation of Math.Pow(double, double) in .NET Framework which was purchased by Microsoft from Intel and remains undisclosed even if the framework went open-source. (To be precise, in the above case it is an internal call rather than a library but the idea holds.) A library separated from the language itself (theoretically also a subset of standard libraries) can give the language backers more flexibility in drawing the line between what to keep transparent and what has to remain undisclosed (due to their contracts with 3rd parties or other IP-related reasons).






      share|improve this answer
























      • This is confusing. The page you link to about Math.Pow doesn't mention any purchase, or anything about Intel, and talks about people reading the source code of the implementation of the function.

        – Lightness Races in Orbit
        Jan 30 at 11:46











      • @LightnessRacesinOrbit – hm, I can still see it there (when searching for "intel"). You can also find the reference to recent source code (in the most recent comments) and also an alternative implementation (in the second answer) which is publicly available but complexity and commented inefficiency of which gives a hint why original implementation is still not disclosed. Truly efficient implementation might require in-depth knowledge of many details on CPU-level which are not necessarily available in public domain.

        – miroxlav
        Jan 30 at 13:38





















      5














      Bugs and debugging.



      Bugs:
      All software has bugs, your standard library has bugs and your compiler has bugs. As a user of the language it is much easier to find and workaround such bugs when they're in the standard library as opposed to in the compiler.



      Debugging:
      It's much easier for me to see a stack trace of a standard library and give me some sense of what might be going wrong. Because that stack trace has code I understand. Ofcourse you can do dig deeper and you can also trace your intrinsic functions, but it's a lot easier if it's in a language you use all the time from day to day.






      share|improve this answer































        5














        This is an excellent question!



        State of the Art



        The C++ Standard, for example, never specifies what should be implemented in the compiler or in the standard library: it just refers to the implementation. For example, reserved symbols are defined both by the compiler (as intrinsics) and by the standard library, interchangeably.



        Yet, all C++ implementations that I know of will have the minimum possible number of intrinsics provided by the compiler, and as much as possible provided by the standard library.



        Thus, while it is technically feasible to define the standard library as intrinsic functionality in the compiler, it seems rarely used in practice.



        Why?



        Let's consider the idea of moving some piece of functionality from the standard library to the compiler.



        Advantages:




        • Better diagnostics: intrinsics can be special-cased.

        • Better performance: intrinsics can be special-cased.


        Disadvantages:




        • Increased compiler mass: each special-case adds complexity to the compiler; complexity increases maintenance costs, and the likelihood of bugs.

        • Slower iteration: changing the implementation of the functionality requires changing the compiler itself, making it harder to create just a small library (outside of std) to experiment.

        • Higher bar to entry: the more expensive/more difficult it is to change something, the less people are likely to jump in.


        This means that moving something to the compiler is expensive, now and in the future, and therefore it requires a solid case. For some pieces of functionality, it is necessary (they cannot be written as regular code), however even then it pays to extract minimal and generic pieces to move to the compiler and build atop them in the standard library.






        share|improve this answer































          5














          As a language designer myself, I'd like to echo some of the other answers here, but provide it through the eyes of someone who is building a language.




          An API is not finished when you are done adding everything you can into it. An API is finished when you're done taking everything you can out of it.




          A programming language has to be specified using some language. You have to be able to convey the meaning behind any program written in your language. This language is very hard to write, and even harder to write well. In general, it tends to be a very precise and well structured form of English used to convey meaning not to the computer, but to other developers, especially those developers writing compilers or interpreters for your language. Here's an example from the C++11 spec, [intro.multithread/14]:




          The visible sequence of side effects on an atomic object M, with respect to a value computation B of M, is
          a maximal contiguous sub-sequence of side effects in the modification order of M, where the first side effect
          is visible with respect to B, and for every side effect, it is not the case that B happens before it. The value
          of an atomic object M, as determined by evaluation B, shall be the value stored by some operation in the
          visible sequence of M with respect to B. [ Note: It can be shown that the visible sequence of side effects of
          a value computation is unique given the coherence requirements below. —end note ]




          Blek! Anyone who has taken the plunge into understanding how C++11 handles multithreading can appreciate why the wording has to be so dang opaque, but that doesn't forgive the fact that it is... well... so opaque!



          Contrast that with the definition of std::shared_ptr<T>::reset, in the library section of the standard:




          template <class Y> void reset(Y* p);



          Effects: Equivalent to shared_ptr(p).swap(*this)




          So what's the difference? In the language definition part, the writers cannot assume that the reader understands the language primitives. Everything must be specified carefully in English prose. Once we get to the library definition part, we can use the language to specify the behavior. This is often far easier!



          In principle, one could have a smooth build up from primitives at the start of the spec document, all the way up through defining what we would think of as "standard library features", without having to draw a line between "language primitives" and "standard library" features. In practice, that line proves enormously valuable to draw because it lets you write some of the most complex parts of the language (such as those which must implement algorithms) using a language designed to express them.



          And we do indeed see some blurry lines:




          • In Java, java.lang.ref.Reference<T> may only be subclassed by the standard library classes java.lang.ref.WeakReference<T> java.lang.ref.SoftReference<T> and java.lang.ref.PhantomReference<T> because the behaviors of Reference are so deeply entwined with the Java language specification that they needed to put some restrictions into the portion of that process implemented as "standard library" classes.

          • In C#, there is a class, System.Delegate which encapsulates the concept of delegates. Despite its name, it is not a delegate. It is also an abstract class (cannot be instantiated) that you cannot create derived classes from. Only the system can do it through features written into the language specification.






          share|improve this answer































            2














            This is meant as an addition to the existing answers (and is too long for a comment).



            There are at least two other reasons for a standard library:



            Barrier to Entry



            If a particular language feature is in a library function and I want to know how it works, I can just read the source for that function. If I want to submit a bug report/patch/pull request, it's not generally too difficult to code a fix and test case(s). If it's in the compiler, I have to be able to dig into the internals. Even if it's in the same language (and it should be, any self-respecting compiler should be self-hosted) compiler code is nothing like application code. It may take forever to even find the correct files.



            You're cutting yourself off from a lot of potential contributors if you go that route.



            Hot code loading



            Many languages offer this feature to one degree or another, but it would be enormously complicated to hot reload the code that's doing the hot reloading. If the SL is separate from the runtime it can be reloaded.






            share|improve this answer



















            • 3





              "any self-respecting compiler should be self-hosted" - not at all. It would be pointless to have versions of say LLVM written in C, C++, Objective-C, Swift, Fortran and so on to compile all these languages.

              – gnasher729
              Jan 29 at 23:20











            • @gnasher729 isn't that a bit of a special case (along with other multilanguage targets like the CLR)?

              – Jared Smith
              Jan 30 at 0:45











            • @JaredSmith I would say it is now the general case, not special at all. Nobody writes "a compiler" as a monolithic application any more. They produce compiler systems instead. Most of the functionality of complete compiler is completely independent of the particular language that is being compiled, and much of the language-dependent part can be done by supplying different data defining the grammar of the language, not by writing different code for each language you want to compile.

              – alephzero
              Jan 30 at 1:01



















            2














            This is an interesting question but there are many good answers already given, so I won't attempt a complete one.



            However, two things that I don't think have gotten enough attention:



            First is that the whole thing is not super clear cut. It's a bit of a spectrum exactly because there are reasons to do things differently.
            As an example, compilers often know about standard libraries and their functions.
            Example of the example: C's "Hello World" function - printf - is the best one I can think of. It's a library function, it sort-of has to be, as it's very platform dependent. But it's behaviour (implementation defined) needs to be known by the compiler in order to warn the programmer about bad invocations. This isn't particularly neat, but was seen as a good compromise. Incidentally, this is the real answer to most of the "why this design" questions: a lot of compromise and "seemed like a good idea at the time". Not always the "this was the clear way to do it" or "look: an example from on of the far ends of the spectrum" as often given by the proponents of that choice. (Not that those answers are not relevant).



            Second is that it allows the standard library not to be all that standard. There a lot of situations that a language is desirable but the standard libraries that usually accompany them are not both practical and desirable. This is most commonly the case with systems programming languages like C, on non-standard platforms. For example, if you have a system without an OS or a scheduler: you aren't going to have threading.



            With a standard library model (and threading being supported in it) this can be handled cleanly: the compiler is pretty much the same, you can reuse the bits of the libraries that apply, and anything that doesn't you can remove. If this is baked into the compiler things start to get messy.



            For example:




            • You can't be a compliant compiler.


            • How would you indicate your deviation from the standard.
              Note there is usually some form of import/include syntax you can have fail i.e. pythons's import or C's include that easily points to the problem if there is anything missing in the standard library model.



            Also similar problems apply if you want to tweak or extend 'library' functionality. This is far more common than you might think. Just to stick with threading: windows, linux and some-exotic-network-processing-units all do threading quite differently. While the linux/windows bits might be fairly static and be able to use an identical API, the NPU stuff will change with the day of the week and the API with it. Compilers would quickly deviate as people decided which bits they need to support/could-do-with-out quite rapidly if there was no way to split this sort of thing out.






            share|improve this answer
































              10 Answers
              10






              active

              oldest

              votes








              10 Answers
              10






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              33














              Allow me to expand somewhat on @Vincent's (+1) good answer:




              Why couldn't the compiler simply translate a function call into a set of instructions?




              It can, and does so via at least two mechanisms:




              • inlining a function call — during translation, the compiler can replace a source code call with its implementation directly inline instead of making an actual call to the function.  Still the function needs to have an implementation defined somewhere and that can be in the standard library.


              • intrinsic function — intrinsics are functions that the compiler has been informed of without necessarily finding the function in a library.  These are usually reserved for hardware features that are not practically accessible in any other way, being so simple that even the overhead of a call to assembly language library function is considered high.  (The compiler can generally only automatically inline source code in its language, but not assembly functions, which is where intrinsic mechanism comes in.)



              Still these being said, the best option sometimes is for the compiler to translate a function call in the source language into a function call in the machine code.  Recursion, virtual methods, and sheer size are some reasons that inlining is not always possible/practical.  (Another reason is intent of the build, such as separate compilation (object modules), separate load units (e.g. DLLs)).



              There's no real advantage to making most standard library functions intrisics either (that would hard code a lot more knowledge into the compiler for no real advantage), so a machine code call again is often most appropriate.



              C is a notable language that arguably omitted other explicit language statements in favor standard library functions.  Though libraries pre-existed, this language made a shift to doing more work from standard library functions and less as explicit statements in the grammar of the language.  IO in other languages, for example, was frequently given its own syntax in the form of various statements, whereas the C grammar does not define any IO statements, simply instead deferring to its standard library to provide that, all accessible via function calls, which the compiler already knows how to do.






              share|improve this answer





















              • 3





                Nice answer. One should add some words why this decision in C was made: if I remember correctly, the main reason was actually because it made it way easier to create C compilers for many different hardware architectures.

                – Doc Brown
                Jan 29 at 21:20






              • 10





                @DocBrown By 1975, there were enough examples in the area of the programming language development (ALGOL-68, anyone?) which showed that attempts to bake-in everything into the language directly led to considerable slow downs in both finsihing the language specifications and in producing language implementations.

                – Joker_vD
                Jan 29 at 21:27






              • 5





                A similar example is what Python did with print: In 2.x, it was a statement, with its own special grammar, but in 3.x, it became just another function call. See PEP 3105 for the official explanation.

                – dan04
                Jan 29 at 23:17






              • 1





                @DocBrown, portability was almost certainly not a reason. When Unix and C were created, they were designed and built for exactly one machine, a spare PDP-7, as Ken Thompson wondered what concepts could be salvaged from the failed Multics project. C was also created for one reason: to have a high level language in which to (re)implement Unix. They we’re basically an experiment in software design, not a serious attempt at a commercial multi-platform OS and language. See bell-labs.com/usr/dmr/www/chist.html for example.

                – Euro Micelli
                Jan 30 at 0:28











              • @EuroMicelli: I don't see there a contradiction. And your reference contains a lot of details about when portability became important, it was actually in the early years of the C and Unix development. I can only guess here, but if the C inventors would not have kept the language intentionally small, I think it would have been quite unlikely that they could have ported it so quickly and sucessfully to many different architectures.

                – Doc Brown
                Jan 30 at 6:36


















              33














              Allow me to expand somewhat on @Vincent's (+1) good answer:




              Why couldn't the compiler simply translate a function call into a set of instructions?




              It can, and does so via at least two mechanisms:




              • inlining a function call — during translation, the compiler can replace a source code call with its implementation directly inline instead of making an actual call to the function.  Still the function needs to have an implementation defined somewhere and that can be in the standard library.


              • intrinsic function — intrinsics are functions that the compiler has been informed of without necessarily finding the function in a library.  These are usually reserved for hardware features that are not practically accessible in any other way, being so simple that even the overhead of a call to assembly language library function is considered high.  (The compiler can generally only automatically inline source code in its language, but not assembly functions, which is where intrinsic mechanism comes in.)



              Still these being said, the best option sometimes is for the compiler to translate a function call in the source language into a function call in the machine code.  Recursion, virtual methods, and sheer size are some reasons that inlining is not always possible/practical.  (Another reason is intent of the build, such as separate compilation (object modules), separate load units (e.g. DLLs)).



              There's no real advantage to making most standard library functions intrisics either (that would hard code a lot more knowledge into the compiler for no real advantage), so a machine code call again is often most appropriate.



              C is a notable language that arguably omitted other explicit language statements in favor standard library functions.  Though libraries pre-existed, this language made a shift to doing more work from standard library functions and less as explicit statements in the grammar of the language.  IO in other languages, for example, was frequently given its own syntax in the form of various statements, whereas the C grammar does not define any IO statements, simply instead deferring to its standard library to provide that, all accessible via function calls, which the compiler already knows how to do.






              share|improve this answer





















              • 3





                Nice answer. One should add some words why this decision in C was made: if I remember correctly, the main reason was actually because it made it way easier to create C compilers for many different hardware architectures.

                – Doc Brown
                Jan 29 at 21:20






              • 10





                @DocBrown By 1975, there were enough examples in the area of the programming language development (ALGOL-68, anyone?) which showed that attempts to bake-in everything into the language directly led to considerable slow downs in both finsihing the language specifications and in producing language implementations.

                – Joker_vD
                Jan 29 at 21:27






              • 5





                A similar example is what Python did with print: In 2.x, it was a statement, with its own special grammar, but in 3.x, it became just another function call. See PEP 3105 for the official explanation.

                – dan04
                Jan 29 at 23:17






              • 1





                @DocBrown, portability was almost certainly not a reason. When Unix and C were created, they were designed and built for exactly one machine, a spare PDP-7, as Ken Thompson wondered what concepts could be salvaged from the failed Multics project. C was also created for one reason: to have a high level language in which to (re)implement Unix. They we’re basically an experiment in software design, not a serious attempt at a commercial multi-platform OS and language. See bell-labs.com/usr/dmr/www/chist.html for example.

                – Euro Micelli
                Jan 30 at 0:28











              • @EuroMicelli: I don't see there a contradiction. And your reference contains a lot of details about when portability became important, it was actually in the early years of the C and Unix development. I can only guess here, but if the C inventors would not have kept the language intentionally small, I think it would have been quite unlikely that they could have ported it so quickly and sucessfully to many different architectures.

                – Doc Brown
                Jan 30 at 6:36
















              33












              33








              33







              Allow me to expand somewhat on @Vincent's (+1) good answer:




              Why couldn't the compiler simply translate a function call into a set of instructions?




              It can, and does so via at least two mechanisms:




              • inlining a function call — during translation, the compiler can replace a source code call with its implementation directly inline instead of making an actual call to the function.  Still the function needs to have an implementation defined somewhere and that can be in the standard library.


              • intrinsic function — intrinsics are functions that the compiler has been informed of without necessarily finding the function in a library.  These are usually reserved for hardware features that are not practically accessible in any other way, being so simple that even the overhead of a call to assembly language library function is considered high.  (The compiler can generally only automatically inline source code in its language, but not assembly functions, which is where intrinsic mechanism comes in.)



              Still these being said, the best option sometimes is for the compiler to translate a function call in the source language into a function call in the machine code.  Recursion, virtual methods, and sheer size are some reasons that inlining is not always possible/practical.  (Another reason is intent of the build, such as separate compilation (object modules), separate load units (e.g. DLLs)).



              There's no real advantage to making most standard library functions intrisics either (that would hard code a lot more knowledge into the compiler for no real advantage), so a machine code call again is often most appropriate.



              C is a notable language that arguably omitted other explicit language statements in favor standard library functions.  Though libraries pre-existed, this language made a shift to doing more work from standard library functions and less as explicit statements in the grammar of the language.  IO in other languages, for example, was frequently given its own syntax in the form of various statements, whereas the C grammar does not define any IO statements, simply instead deferring to its standard library to provide that, all accessible via function calls, which the compiler already knows how to do.






              share|improve this answer















              Allow me to expand somewhat on @Vincent's (+1) good answer:




              Why couldn't the compiler simply translate a function call into a set of instructions?




              It can, and does so via at least two mechanisms:




              • inlining a function call — during translation, the compiler can replace a source code call with its implementation directly inline instead of making an actual call to the function.  Still the function needs to have an implementation defined somewhere and that can be in the standard library.


              • intrinsic function — intrinsics are functions that the compiler has been informed of without necessarily finding the function in a library.  These are usually reserved for hardware features that are not practically accessible in any other way, being so simple that even the overhead of a call to assembly language library function is considered high.  (The compiler can generally only automatically inline source code in its language, but not assembly functions, which is where intrinsic mechanism comes in.)



              Still these being said, the best option sometimes is for the compiler to translate a function call in the source language into a function call in the machine code.  Recursion, virtual methods, and sheer size are some reasons that inlining is not always possible/practical.  (Another reason is intent of the build, such as separate compilation (object modules), separate load units (e.g. DLLs)).



              There's no real advantage to making most standard library functions intrisics either (that would hard code a lot more knowledge into the compiler for no real advantage), so a machine code call again is often most appropriate.



              C is a notable language that arguably omitted other explicit language statements in favor standard library functions.  Though libraries pre-existed, this language made a shift to doing more work from standard library functions and less as explicit statements in the grammar of the language.  IO in other languages, for example, was frequently given its own syntax in the form of various statements, whereas the C grammar does not define any IO statements, simply instead deferring to its standard library to provide that, all accessible via function calls, which the compiler already knows how to do.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 30 at 15:34









              costrom

              19816




              19816










              answered Jan 29 at 20:23









              Erik EidtErik Eidt

              24.4k43567




              24.4k43567








              • 3





                Nice answer. One should add some words why this decision in C was made: if I remember correctly, the main reason was actually because it made it way easier to create C compilers for many different hardware architectures.

                – Doc Brown
                Jan 29 at 21:20






              • 10





                @DocBrown By 1975, there were enough examples in the area of the programming language development (ALGOL-68, anyone?) which showed that attempts to bake-in everything into the language directly led to considerable slow downs in both finsihing the language specifications and in producing language implementations.

                – Joker_vD
                Jan 29 at 21:27






              • 5





                A similar example is what Python did with print: In 2.x, it was a statement, with its own special grammar, but in 3.x, it became just another function call. See PEP 3105 for the official explanation.

                – dan04
                Jan 29 at 23:17






              • 1





                @DocBrown, portability was almost certainly not a reason. When Unix and C were created, they were designed and built for exactly one machine, a spare PDP-7, as Ken Thompson wondered what concepts could be salvaged from the failed Multics project. C was also created for one reason: to have a high level language in which to (re)implement Unix. They we’re basically an experiment in software design, not a serious attempt at a commercial multi-platform OS and language. See bell-labs.com/usr/dmr/www/chist.html for example.

                – Euro Micelli
                Jan 30 at 0:28











              • @EuroMicelli: I don't see there a contradiction. And your reference contains a lot of details about when portability became important, it was actually in the early years of the C and Unix development. I can only guess here, but if the C inventors would not have kept the language intentionally small, I think it would have been quite unlikely that they could have ported it so quickly and sucessfully to many different architectures.

                – Doc Brown
                Jan 30 at 6:36
















              • 3





                Nice answer. One should add some words why this decision in C was made: if I remember correctly, the main reason was actually because it made it way easier to create C compilers for many different hardware architectures.

                – Doc Brown
                Jan 29 at 21:20






              • 10





                @DocBrown By 1975, there were enough examples in the area of the programming language development (ALGOL-68, anyone?) which showed that attempts to bake-in everything into the language directly led to considerable slow downs in both finsihing the language specifications and in producing language implementations.

                – Joker_vD
                Jan 29 at 21:27






              • 5





                A similar example is what Python did with print: In 2.x, it was a statement, with its own special grammar, but in 3.x, it became just another function call. See PEP 3105 for the official explanation.

                – dan04
                Jan 29 at 23:17






              • 1





                @DocBrown, portability was almost certainly not a reason. When Unix and C were created, they were designed and built for exactly one machine, a spare PDP-7, as Ken Thompson wondered what concepts could be salvaged from the failed Multics project. C was also created for one reason: to have a high level language in which to (re)implement Unix. They we’re basically an experiment in software design, not a serious attempt at a commercial multi-platform OS and language. See bell-labs.com/usr/dmr/www/chist.html for example.

                – Euro Micelli
                Jan 30 at 0:28











              • @EuroMicelli: I don't see there a contradiction. And your reference contains a lot of details about when portability became important, it was actually in the early years of the C and Unix development. I can only guess here, but if the C inventors would not have kept the language intentionally small, I think it would have been quite unlikely that they could have ported it so quickly and sucessfully to many different architectures.

                – Doc Brown
                Jan 30 at 6:36










              3




              3





              Nice answer. One should add some words why this decision in C was made: if I remember correctly, the main reason was actually because it made it way easier to create C compilers for many different hardware architectures.

              – Doc Brown
              Jan 29 at 21:20





              Nice answer. One should add some words why this decision in C was made: if I remember correctly, the main reason was actually because it made it way easier to create C compilers for many different hardware architectures.

              – Doc Brown
              Jan 29 at 21:20




              10




              10





              @DocBrown By 1975, there were enough examples in the area of the programming language development (ALGOL-68, anyone?) which showed that attempts to bake-in everything into the language directly led to considerable slow downs in both finsihing the language specifications and in producing language implementations.

              – Joker_vD
              Jan 29 at 21:27





              @DocBrown By 1975, there were enough examples in the area of the programming language development (ALGOL-68, anyone?) which showed that attempts to bake-in everything into the language directly led to considerable slow downs in both finsihing the language specifications and in producing language implementations.

              – Joker_vD
              Jan 29 at 21:27




              5




              5





              A similar example is what Python did with print: In 2.x, it was a statement, with its own special grammar, but in 3.x, it became just another function call. See PEP 3105 for the official explanation.

              – dan04
              Jan 29 at 23:17





              A similar example is what Python did with print: In 2.x, it was a statement, with its own special grammar, but in 3.x, it became just another function call. See PEP 3105 for the official explanation.

              – dan04
              Jan 29 at 23:17




              1




              1





              @DocBrown, portability was almost certainly not a reason. When Unix and C were created, they were designed and built for exactly one machine, a spare PDP-7, as Ken Thompson wondered what concepts could be salvaged from the failed Multics project. C was also created for one reason: to have a high level language in which to (re)implement Unix. They we’re basically an experiment in software design, not a serious attempt at a commercial multi-platform OS and language. See bell-labs.com/usr/dmr/www/chist.html for example.

              – Euro Micelli
              Jan 30 at 0:28





              @DocBrown, portability was almost certainly not a reason. When Unix and C were created, they were designed and built for exactly one machine, a spare PDP-7, as Ken Thompson wondered what concepts could be salvaged from the failed Multics project. C was also created for one reason: to have a high level language in which to (re)implement Unix. They we’re basically an experiment in software design, not a serious attempt at a commercial multi-platform OS and language. See bell-labs.com/usr/dmr/www/chist.html for example.

              – Euro Micelli
              Jan 30 at 0:28













              @EuroMicelli: I don't see there a contradiction. And your reference contains a lot of details about when portability became important, it was actually in the early years of the C and Unix development. I can only guess here, but if the C inventors would not have kept the language intentionally small, I think it would have been quite unlikely that they could have ported it so quickly and sucessfully to many different architectures.

              – Doc Brown
              Jan 30 at 6:36







              @EuroMicelli: I don't see there a contradiction. And your reference contains a lot of details about when portability became important, it was actually in the early years of the C and Unix development. I can only guess here, but if the C inventors would not have kept the language intentionally small, I think it would have been quite unlikely that they could have ported it so quickly and sucessfully to many different architectures.

              – Doc Brown
              Jan 30 at 6:36















              70














              This is simply to keep the language itself as simple as possible. You need to distinguish between a feature of the language, such as a type of loop or ways to pass parameters to functions and so on, and common functionality that most applications need.



              Libraries are functions that may be useful to many programmers so they are created as reusable code that can be shared. The standard libraries are designed to be very common functions that programmers typically need. This way the programming language is immediately useful to a wider range of programmers. The libraries can be updated and extended without changing the core features of the language itself.






              share|improve this answer



















              • 3





                Not always. PHP as an example hardly makes any differences between its vast language functions and the language itself.

                – Vahid Amiri
                Jan 30 at 7:25






              • 15





                I wouldn't take PHP as an example of a simple language

                – DrBreakalot
                Jan 30 at 10:29






              • 3





                @DrBreakalot PHP's an extremely simple language. That's not to say that it has a consistent design, but that's another issue.

                – Lightness Races in Orbit
                Jan 30 at 11:44






              • 19





                @LightnessRacesinOrbit I wouldn't call PHP "simple" at all: it has a class-based object system, a separate set of 'primitive values', standalone functions, first-class closures built on the object system, a namespace mechanism, various notions called "static", statements as well as expressions, include, require and require_once, if/for/while (structured programming), exceptions, a separate system of 'error values', complicated weak typing rules, complicated operator precedence rules, and on and on. Compare this to the simplicity of, say, Smalltalk, Scheme, Prolog, Forth, etc. ;)

                – Warbo
                Jan 30 at 14:22








              • 3





                The main reason, which is hinted at but not explicitly stated in this answer, is that by keeping the language as simple as possible, it is much easier to implement on other platforms. Since the standard libraries are usually written in the language itself, they can be trivially ported.

                – BlueRaja - Danny Pflughoeft
                Jan 30 at 17:40


















              70














              This is simply to keep the language itself as simple as possible. You need to distinguish between a feature of the language, such as a type of loop or ways to pass parameters to functions and so on, and common functionality that most applications need.



              Libraries are functions that may be useful to many programmers so they are created as reusable code that can be shared. The standard libraries are designed to be very common functions that programmers typically need. This way the programming language is immediately useful to a wider range of programmers. The libraries can be updated and extended without changing the core features of the language itself.






              share|improve this answer



















              • 3





                Not always. PHP as an example hardly makes any differences between its vast language functions and the language itself.

                – Vahid Amiri
                Jan 30 at 7:25






              • 15





                I wouldn't take PHP as an example of a simple language

                – DrBreakalot
                Jan 30 at 10:29






              • 3





                @DrBreakalot PHP's an extremely simple language. That's not to say that it has a consistent design, but that's another issue.

                – Lightness Races in Orbit
                Jan 30 at 11:44






              • 19





                @LightnessRacesinOrbit I wouldn't call PHP "simple" at all: it has a class-based object system, a separate set of 'primitive values', standalone functions, first-class closures built on the object system, a namespace mechanism, various notions called "static", statements as well as expressions, include, require and require_once, if/for/while (structured programming), exceptions, a separate system of 'error values', complicated weak typing rules, complicated operator precedence rules, and on and on. Compare this to the simplicity of, say, Smalltalk, Scheme, Prolog, Forth, etc. ;)

                – Warbo
                Jan 30 at 14:22








              • 3





                The main reason, which is hinted at but not explicitly stated in this answer, is that by keeping the language as simple as possible, it is much easier to implement on other platforms. Since the standard libraries are usually written in the language itself, they can be trivially ported.

                – BlueRaja - Danny Pflughoeft
                Jan 30 at 17:40
















              70












              70








              70







              This is simply to keep the language itself as simple as possible. You need to distinguish between a feature of the language, such as a type of loop or ways to pass parameters to functions and so on, and common functionality that most applications need.



              Libraries are functions that may be useful to many programmers so they are created as reusable code that can be shared. The standard libraries are designed to be very common functions that programmers typically need. This way the programming language is immediately useful to a wider range of programmers. The libraries can be updated and extended without changing the core features of the language itself.






              share|improve this answer













              This is simply to keep the language itself as simple as possible. You need to distinguish between a feature of the language, such as a type of loop or ways to pass parameters to functions and so on, and common functionality that most applications need.



              Libraries are functions that may be useful to many programmers so they are created as reusable code that can be shared. The standard libraries are designed to be very common functions that programmers typically need. This way the programming language is immediately useful to a wider range of programmers. The libraries can be updated and extended without changing the core features of the language itself.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jan 29 at 18:02









              Vincent RamdhanieVincent Ramdhanie

              704145




              704145








              • 3





                Not always. PHP as an example hardly makes any differences between its vast language functions and the language itself.

                – Vahid Amiri
                Jan 30 at 7:25






              • 15





                I wouldn't take PHP as an example of a simple language

                – DrBreakalot
                Jan 30 at 10:29






              • 3





                @DrBreakalot PHP's an extremely simple language. That's not to say that it has a consistent design, but that's another issue.

                – Lightness Races in Orbit
                Jan 30 at 11:44






              • 19





                @LightnessRacesinOrbit I wouldn't call PHP "simple" at all: it has a class-based object system, a separate set of 'primitive values', standalone functions, first-class closures built on the object system, a namespace mechanism, various notions called "static", statements as well as expressions, include, require and require_once, if/for/while (structured programming), exceptions, a separate system of 'error values', complicated weak typing rules, complicated operator precedence rules, and on and on. Compare this to the simplicity of, say, Smalltalk, Scheme, Prolog, Forth, etc. ;)

                – Warbo
                Jan 30 at 14:22








              • 3





                The main reason, which is hinted at but not explicitly stated in this answer, is that by keeping the language as simple as possible, it is much easier to implement on other platforms. Since the standard libraries are usually written in the language itself, they can be trivially ported.

                – BlueRaja - Danny Pflughoeft
                Jan 30 at 17:40
















              • 3





                Not always. PHP as an example hardly makes any differences between its vast language functions and the language itself.

                – Vahid Amiri
                Jan 30 at 7:25






              • 15





                I wouldn't take PHP as an example of a simple language

                – DrBreakalot
                Jan 30 at 10:29






              • 3





                @DrBreakalot PHP's an extremely simple language. That's not to say that it has a consistent design, but that's another issue.

                – Lightness Races in Orbit
                Jan 30 at 11:44






              • 19





                @LightnessRacesinOrbit I wouldn't call PHP "simple" at all: it has a class-based object system, a separate set of 'primitive values', standalone functions, first-class closures built on the object system, a namespace mechanism, various notions called "static", statements as well as expressions, include, require and require_once, if/for/while (structured programming), exceptions, a separate system of 'error values', complicated weak typing rules, complicated operator precedence rules, and on and on. Compare this to the simplicity of, say, Smalltalk, Scheme, Prolog, Forth, etc. ;)

                – Warbo
                Jan 30 at 14:22








              • 3





                The main reason, which is hinted at but not explicitly stated in this answer, is that by keeping the language as simple as possible, it is much easier to implement on other platforms. Since the standard libraries are usually written in the language itself, they can be trivially ported.

                – BlueRaja - Danny Pflughoeft
                Jan 30 at 17:40










              3




              3





              Not always. PHP as an example hardly makes any differences between its vast language functions and the language itself.

              – Vahid Amiri
              Jan 30 at 7:25





              Not always. PHP as an example hardly makes any differences between its vast language functions and the language itself.

              – Vahid Amiri
              Jan 30 at 7:25




              15




              15





              I wouldn't take PHP as an example of a simple language

              – DrBreakalot
              Jan 30 at 10:29





              I wouldn't take PHP as an example of a simple language

              – DrBreakalot
              Jan 30 at 10:29




              3




              3





              @DrBreakalot PHP's an extremely simple language. That's not to say that it has a consistent design, but that's another issue.

              – Lightness Races in Orbit
              Jan 30 at 11:44





              @DrBreakalot PHP's an extremely simple language. That's not to say that it has a consistent design, but that's another issue.

              – Lightness Races in Orbit
              Jan 30 at 11:44




              19




              19





              @LightnessRacesinOrbit I wouldn't call PHP "simple" at all: it has a class-based object system, a separate set of 'primitive values', standalone functions, first-class closures built on the object system, a namespace mechanism, various notions called "static", statements as well as expressions, include, require and require_once, if/for/while (structured programming), exceptions, a separate system of 'error values', complicated weak typing rules, complicated operator precedence rules, and on and on. Compare this to the simplicity of, say, Smalltalk, Scheme, Prolog, Forth, etc. ;)

              – Warbo
              Jan 30 at 14:22







              @LightnessRacesinOrbit I wouldn't call PHP "simple" at all: it has a class-based object system, a separate set of 'primitive values', standalone functions, first-class closures built on the object system, a namespace mechanism, various notions called "static", statements as well as expressions, include, require and require_once, if/for/while (structured programming), exceptions, a separate system of 'error values', complicated weak typing rules, complicated operator precedence rules, and on and on. Compare this to the simplicity of, say, Smalltalk, Scheme, Prolog, Forth, etc. ;)

              – Warbo
              Jan 30 at 14:22






              3




              3





              The main reason, which is hinted at but not explicitly stated in this answer, is that by keeping the language as simple as possible, it is much easier to implement on other platforms. Since the standard libraries are usually written in the language itself, they can be trivially ported.

              – BlueRaja - Danny Pflughoeft
              Jan 30 at 17:40







              The main reason, which is hinted at but not explicitly stated in this answer, is that by keeping the language as simple as possible, it is much easier to implement on other platforms. Since the standard libraries are usually written in the language itself, they can be trivially ported.

              – BlueRaja - Danny Pflughoeft
              Jan 30 at 17:40













              33














              In addition to what the other answers have already said, putting standard functions into a library is separation of concerns:




              • It's the compiler's job to parse the language and generate code for it. It's not the compiler's job to contain anything that can already be written in that language and provided as a library.


              • It's the standard library's (the one that's always implicitly available) job to provide core functionality that's needed by virtually all programs. It's not the standard library's job to contain all the functions that might be useful.


              • It's the job of optional standard libraries to provide auxiliary functionality that many programs can do without, but which are still quite basic and also essential for many applications to warrant shipping with standard environments. It's not the job of those optional libraries to contain all reusable code that's ever been written.


              • It's the job of user libraries to provide collections of useful reusable functions. It's not the job of user libraries to contain all the code that's ever been written.


              • It's the job of an application's source code to provide the remaining bits of code that are really only relevant to that one application.



              If you want a one-size-fits-all software, you get something insanely complex. You need to modularize to get the complexity down to manageable levels. And you need to modularize to allow partial implementations:




              • The threading library is worthless on the single-core embedded controller. Allowing the language implementation for this embedded controller to just not include the pthread library is just the right thing to do.


              • The math library is worthless on the micro-controller that doesn't even have an FPU. Again, not being forced to provide functions like sin() makes life a whole lot easier for the implementators of your language for that micro-controller.


              • Even the core standard library is worthless when you are programming a kernel. You cannot implement write() without a syscall into the kernel, and you cannot implement printf() without write(). As a kernel programmer, it's your job to provide the write() syscall, you cannot just expect it to be there.



              A language that does not allow for such omissions from the standard libraries is simply not suited for many tasks. If you want your language to be flexibly usable in uncommon environments, it must be flexible in what standard libraries are included. The more your language relies on standard libraries, the more assumptions it makes on its execution environment, and thus restricts its use to environments that provide these prerequisites.



              Of course, high level languages like python and java can make a lot of assumptions on their environment. And they tend to include many, many things into their standard libraries. Lower level languages like C provide much less in their standard libraries, and keep the core standard library much smaller. That's why you find a working C compiler for virtually any architecture, but may not be able to run any python scripts on it.






              share|improve this answer






























                33














                In addition to what the other answers have already said, putting standard functions into a library is separation of concerns:




                • It's the compiler's job to parse the language and generate code for it. It's not the compiler's job to contain anything that can already be written in that language and provided as a library.


                • It's the standard library's (the one that's always implicitly available) job to provide core functionality that's needed by virtually all programs. It's not the standard library's job to contain all the functions that might be useful.


                • It's the job of optional standard libraries to provide auxiliary functionality that many programs can do without, but which are still quite basic and also essential for many applications to warrant shipping with standard environments. It's not the job of those optional libraries to contain all reusable code that's ever been written.


                • It's the job of user libraries to provide collections of useful reusable functions. It's not the job of user libraries to contain all the code that's ever been written.


                • It's the job of an application's source code to provide the remaining bits of code that are really only relevant to that one application.



                If you want a one-size-fits-all software, you get something insanely complex. You need to modularize to get the complexity down to manageable levels. And you need to modularize to allow partial implementations:




                • The threading library is worthless on the single-core embedded controller. Allowing the language implementation for this embedded controller to just not include the pthread library is just the right thing to do.


                • The math library is worthless on the micro-controller that doesn't even have an FPU. Again, not being forced to provide functions like sin() makes life a whole lot easier for the implementators of your language for that micro-controller.


                • Even the core standard library is worthless when you are programming a kernel. You cannot implement write() without a syscall into the kernel, and you cannot implement printf() without write(). As a kernel programmer, it's your job to provide the write() syscall, you cannot just expect it to be there.



                A language that does not allow for such omissions from the standard libraries is simply not suited for many tasks. If you want your language to be flexibly usable in uncommon environments, it must be flexible in what standard libraries are included. The more your language relies on standard libraries, the more assumptions it makes on its execution environment, and thus restricts its use to environments that provide these prerequisites.



                Of course, high level languages like python and java can make a lot of assumptions on their environment. And they tend to include many, many things into their standard libraries. Lower level languages like C provide much less in their standard libraries, and keep the core standard library much smaller. That's why you find a working C compiler for virtually any architecture, but may not be able to run any python scripts on it.






                share|improve this answer




























                  33












                  33








                  33







                  In addition to what the other answers have already said, putting standard functions into a library is separation of concerns:




                  • It's the compiler's job to parse the language and generate code for it. It's not the compiler's job to contain anything that can already be written in that language and provided as a library.


                  • It's the standard library's (the one that's always implicitly available) job to provide core functionality that's needed by virtually all programs. It's not the standard library's job to contain all the functions that might be useful.


                  • It's the job of optional standard libraries to provide auxiliary functionality that many programs can do without, but which are still quite basic and also essential for many applications to warrant shipping with standard environments. It's not the job of those optional libraries to contain all reusable code that's ever been written.


                  • It's the job of user libraries to provide collections of useful reusable functions. It's not the job of user libraries to contain all the code that's ever been written.


                  • It's the job of an application's source code to provide the remaining bits of code that are really only relevant to that one application.



                  If you want a one-size-fits-all software, you get something insanely complex. You need to modularize to get the complexity down to manageable levels. And you need to modularize to allow partial implementations:




                  • The threading library is worthless on the single-core embedded controller. Allowing the language implementation for this embedded controller to just not include the pthread library is just the right thing to do.


                  • The math library is worthless on the micro-controller that doesn't even have an FPU. Again, not being forced to provide functions like sin() makes life a whole lot easier for the implementators of your language for that micro-controller.


                  • Even the core standard library is worthless when you are programming a kernel. You cannot implement write() without a syscall into the kernel, and you cannot implement printf() without write(). As a kernel programmer, it's your job to provide the write() syscall, you cannot just expect it to be there.



                  A language that does not allow for such omissions from the standard libraries is simply not suited for many tasks. If you want your language to be flexibly usable in uncommon environments, it must be flexible in what standard libraries are included. The more your language relies on standard libraries, the more assumptions it makes on its execution environment, and thus restricts its use to environments that provide these prerequisites.



                  Of course, high level languages like python and java can make a lot of assumptions on their environment. And they tend to include many, many things into their standard libraries. Lower level languages like C provide much less in their standard libraries, and keep the core standard library much smaller. That's why you find a working C compiler for virtually any architecture, but may not be able to run any python scripts on it.






                  share|improve this answer















                  In addition to what the other answers have already said, putting standard functions into a library is separation of concerns:




                  • It's the compiler's job to parse the language and generate code for it. It's not the compiler's job to contain anything that can already be written in that language and provided as a library.


                  • It's the standard library's (the one that's always implicitly available) job to provide core functionality that's needed by virtually all programs. It's not the standard library's job to contain all the functions that might be useful.


                  • It's the job of optional standard libraries to provide auxiliary functionality that many programs can do without, but which are still quite basic and also essential for many applications to warrant shipping with standard environments. It's not the job of those optional libraries to contain all reusable code that's ever been written.


                  • It's the job of user libraries to provide collections of useful reusable functions. It's not the job of user libraries to contain all the code that's ever been written.


                  • It's the job of an application's source code to provide the remaining bits of code that are really only relevant to that one application.



                  If you want a one-size-fits-all software, you get something insanely complex. You need to modularize to get the complexity down to manageable levels. And you need to modularize to allow partial implementations:




                  • The threading library is worthless on the single-core embedded controller. Allowing the language implementation for this embedded controller to just not include the pthread library is just the right thing to do.


                  • The math library is worthless on the micro-controller that doesn't even have an FPU. Again, not being forced to provide functions like sin() makes life a whole lot easier for the implementators of your language for that micro-controller.


                  • Even the core standard library is worthless when you are programming a kernel. You cannot implement write() without a syscall into the kernel, and you cannot implement printf() without write(). As a kernel programmer, it's your job to provide the write() syscall, you cannot just expect it to be there.



                  A language that does not allow for such omissions from the standard libraries is simply not suited for many tasks. If you want your language to be flexibly usable in uncommon environments, it must be flexible in what standard libraries are included. The more your language relies on standard libraries, the more assumptions it makes on its execution environment, and thus restricts its use to environments that provide these prerequisites.



                  Of course, high level languages like python and java can make a lot of assumptions on their environment. And they tend to include many, many things into their standard libraries. Lower level languages like C provide much less in their standard libraries, and keep the core standard library much smaller. That's why you find a working C compiler for virtually any architecture, but may not be able to run any python scripts on it.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 30 at 10:24









                  Michael Green

                  664413




                  664413










                  answered Jan 29 at 22:29









                  cmastercmaster

                  6,62811321




                  6,62811321























                      16














                      One big reason compilers and standard libraries are separate are because they serve two different purposes (even if they're both defined by the same language spec): the compiler translates higher-level code into machine instructions, and the standard library provides pre-tested implementations of commonly-needed functionality. Compiler writers value modularity just like other software developers do. In fact, some of the early C compilers further split the compiler into separate programs for pre-processing, compiling, and linking.



                      This modularity gives you a bunch of advantages:




                      • It minimizes the amount of work needed when supporting a new hardware platform, since most of the standard library code is hardware-agnostic can be re-used.

                      • A standard library implementation can be optimized in different ways (for speed, for space, for resource usage, etc). Many early computing systems only had one compiler available, and having a separate standard library meant developers could swap implementations to suit their needs.

                      • The standard library functionality doesn't even have to exist. When writing bare-metal C code for instance, you have a full-featured compiler but most of the standard library functionality isn't there and some things like file I/O aren't even possible. If the compiler was required to implement this functionality, then you couldn't have a standards-conforming C compiler on some of the platforms where you need it the most.

                      • On early systems, compilers were frequently developed by the company that designed the hardware. Standard libraries were frequently provided by the OS vendor, since they often required access to functionality (like system calls) specific to that software platform. It was impractical for a compiler writer to have to support all of the different combinations of hardware and software (there used to be a whole lot more variety in both hardware architecture and software platform).

                      • In high-level languages, a standard library can be implemented as a dynamically-loaded library. One standard library implementation can then be used by multiple compilers and/or programming languages.


                      Historically speaking (at least from C's perspective), the original, pre-standardization versions of the language didn't have a standard library at all. OS vendors and third parties would often provide libraries full of commonly-used functionality, but different implementations included different things and they were largely incompatible with each other. When C was standardized, they defined a "standard library" in an attempt to harmonize these disparate implementations and improve portability. The C standard library developed separate from the language, like the Boost libraries have for C++, but were later integrated into the language spec.






                      share|improve this answer




























                        16














                        One big reason compilers and standard libraries are separate are because they serve two different purposes (even if they're both defined by the same language spec): the compiler translates higher-level code into machine instructions, and the standard library provides pre-tested implementations of commonly-needed functionality. Compiler writers value modularity just like other software developers do. In fact, some of the early C compilers further split the compiler into separate programs for pre-processing, compiling, and linking.



                        This modularity gives you a bunch of advantages:




                        • It minimizes the amount of work needed when supporting a new hardware platform, since most of the standard library code is hardware-agnostic can be re-used.

                        • A standard library implementation can be optimized in different ways (for speed, for space, for resource usage, etc). Many early computing systems only had one compiler available, and having a separate standard library meant developers could swap implementations to suit their needs.

                        • The standard library functionality doesn't even have to exist. When writing bare-metal C code for instance, you have a full-featured compiler but most of the standard library functionality isn't there and some things like file I/O aren't even possible. If the compiler was required to implement this functionality, then you couldn't have a standards-conforming C compiler on some of the platforms where you need it the most.

                        • On early systems, compilers were frequently developed by the company that designed the hardware. Standard libraries were frequently provided by the OS vendor, since they often required access to functionality (like system calls) specific to that software platform. It was impractical for a compiler writer to have to support all of the different combinations of hardware and software (there used to be a whole lot more variety in both hardware architecture and software platform).

                        • In high-level languages, a standard library can be implemented as a dynamically-loaded library. One standard library implementation can then be used by multiple compilers and/or programming languages.


                        Historically speaking (at least from C's perspective), the original, pre-standardization versions of the language didn't have a standard library at all. OS vendors and third parties would often provide libraries full of commonly-used functionality, but different implementations included different things and they were largely incompatible with each other. When C was standardized, they defined a "standard library" in an attempt to harmonize these disparate implementations and improve portability. The C standard library developed separate from the language, like the Boost libraries have for C++, but were later integrated into the language spec.






                        share|improve this answer


























                          16












                          16








                          16







                          One big reason compilers and standard libraries are separate are because they serve two different purposes (even if they're both defined by the same language spec): the compiler translates higher-level code into machine instructions, and the standard library provides pre-tested implementations of commonly-needed functionality. Compiler writers value modularity just like other software developers do. In fact, some of the early C compilers further split the compiler into separate programs for pre-processing, compiling, and linking.



                          This modularity gives you a bunch of advantages:




                          • It minimizes the amount of work needed when supporting a new hardware platform, since most of the standard library code is hardware-agnostic can be re-used.

                          • A standard library implementation can be optimized in different ways (for speed, for space, for resource usage, etc). Many early computing systems only had one compiler available, and having a separate standard library meant developers could swap implementations to suit their needs.

                          • The standard library functionality doesn't even have to exist. When writing bare-metal C code for instance, you have a full-featured compiler but most of the standard library functionality isn't there and some things like file I/O aren't even possible. If the compiler was required to implement this functionality, then you couldn't have a standards-conforming C compiler on some of the platforms where you need it the most.

                          • On early systems, compilers were frequently developed by the company that designed the hardware. Standard libraries were frequently provided by the OS vendor, since they often required access to functionality (like system calls) specific to that software platform. It was impractical for a compiler writer to have to support all of the different combinations of hardware and software (there used to be a whole lot more variety in both hardware architecture and software platform).

                          • In high-level languages, a standard library can be implemented as a dynamically-loaded library. One standard library implementation can then be used by multiple compilers and/or programming languages.


                          Historically speaking (at least from C's perspective), the original, pre-standardization versions of the language didn't have a standard library at all. OS vendors and third parties would often provide libraries full of commonly-used functionality, but different implementations included different things and they were largely incompatible with each other. When C was standardized, they defined a "standard library" in an attempt to harmonize these disparate implementations and improve portability. The C standard library developed separate from the language, like the Boost libraries have for C++, but were later integrated into the language spec.






                          share|improve this answer













                          One big reason compilers and standard libraries are separate are because they serve two different purposes (even if they're both defined by the same language spec): the compiler translates higher-level code into machine instructions, and the standard library provides pre-tested implementations of commonly-needed functionality. Compiler writers value modularity just like other software developers do. In fact, some of the early C compilers further split the compiler into separate programs for pre-processing, compiling, and linking.



                          This modularity gives you a bunch of advantages:




                          • It minimizes the amount of work needed when supporting a new hardware platform, since most of the standard library code is hardware-agnostic can be re-used.

                          • A standard library implementation can be optimized in different ways (for speed, for space, for resource usage, etc). Many early computing systems only had one compiler available, and having a separate standard library meant developers could swap implementations to suit their needs.

                          • The standard library functionality doesn't even have to exist. When writing bare-metal C code for instance, you have a full-featured compiler but most of the standard library functionality isn't there and some things like file I/O aren't even possible. If the compiler was required to implement this functionality, then you couldn't have a standards-conforming C compiler on some of the platforms where you need it the most.

                          • On early systems, compilers were frequently developed by the company that designed the hardware. Standard libraries were frequently provided by the OS vendor, since they often required access to functionality (like system calls) specific to that software platform. It was impractical for a compiler writer to have to support all of the different combinations of hardware and software (there used to be a whole lot more variety in both hardware architecture and software platform).

                          • In high-level languages, a standard library can be implemented as a dynamically-loaded library. One standard library implementation can then be used by multiple compilers and/or programming languages.


                          Historically speaking (at least from C's perspective), the original, pre-standardization versions of the language didn't have a standard library at all. OS vendors and third parties would often provide libraries full of commonly-used functionality, but different implementations included different things and they were largely incompatible with each other. When C was standardized, they defined a "standard library" in an attempt to harmonize these disparate implementations and improve portability. The C standard library developed separate from the language, like the Boost libraries have for C++, but were later integrated into the language spec.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jan 29 at 23:00









                          btabta

                          64948




                          64948























                              6














                              Additional corner-case answer: Intellectual property management



                              Notable example is implementation of Math.Pow(double, double) in .NET Framework which was purchased by Microsoft from Intel and remains undisclosed even if the framework went open-source. (To be precise, in the above case it is an internal call rather than a library but the idea holds.) A library separated from the language itself (theoretically also a subset of standard libraries) can give the language backers more flexibility in drawing the line between what to keep transparent and what has to remain undisclosed (due to their contracts with 3rd parties or other IP-related reasons).






                              share|improve this answer
























                              • This is confusing. The page you link to about Math.Pow doesn't mention any purchase, or anything about Intel, and talks about people reading the source code of the implementation of the function.

                                – Lightness Races in Orbit
                                Jan 30 at 11:46











                              • @LightnessRacesinOrbit – hm, I can still see it there (when searching for "intel"). You can also find the reference to recent source code (in the most recent comments) and also an alternative implementation (in the second answer) which is publicly available but complexity and commented inefficiency of which gives a hint why original implementation is still not disclosed. Truly efficient implementation might require in-depth knowledge of many details on CPU-level which are not necessarily available in public domain.

                                – miroxlav
                                Jan 30 at 13:38


















                              6














                              Additional corner-case answer: Intellectual property management



                              Notable example is implementation of Math.Pow(double, double) in .NET Framework which was purchased by Microsoft from Intel and remains undisclosed even if the framework went open-source. (To be precise, in the above case it is an internal call rather than a library but the idea holds.) A library separated from the language itself (theoretically also a subset of standard libraries) can give the language backers more flexibility in drawing the line between what to keep transparent and what has to remain undisclosed (due to their contracts with 3rd parties or other IP-related reasons).






                              share|improve this answer
























                              • This is confusing. The page you link to about Math.Pow doesn't mention any purchase, or anything about Intel, and talks about people reading the source code of the implementation of the function.

                                – Lightness Races in Orbit
                                Jan 30 at 11:46











                              • @LightnessRacesinOrbit – hm, I can still see it there (when searching for "intel"). You can also find the reference to recent source code (in the most recent comments) and also an alternative implementation (in the second answer) which is publicly available but complexity and commented inefficiency of which gives a hint why original implementation is still not disclosed. Truly efficient implementation might require in-depth knowledge of many details on CPU-level which are not necessarily available in public domain.

                                – miroxlav
                                Jan 30 at 13:38
















                              6












                              6








                              6







                              Additional corner-case answer: Intellectual property management



                              Notable example is implementation of Math.Pow(double, double) in .NET Framework which was purchased by Microsoft from Intel and remains undisclosed even if the framework went open-source. (To be precise, in the above case it is an internal call rather than a library but the idea holds.) A library separated from the language itself (theoretically also a subset of standard libraries) can give the language backers more flexibility in drawing the line between what to keep transparent and what has to remain undisclosed (due to their contracts with 3rd parties or other IP-related reasons).






                              share|improve this answer













                              Additional corner-case answer: Intellectual property management



                              Notable example is implementation of Math.Pow(double, double) in .NET Framework which was purchased by Microsoft from Intel and remains undisclosed even if the framework went open-source. (To be precise, in the above case it is an internal call rather than a library but the idea holds.) A library separated from the language itself (theoretically also a subset of standard libraries) can give the language backers more flexibility in drawing the line between what to keep transparent and what has to remain undisclosed (due to their contracts with 3rd parties or other IP-related reasons).







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Jan 29 at 23:44









                              miroxlavmiroxlav

                              524211




                              524211













                              • This is confusing. The page you link to about Math.Pow doesn't mention any purchase, or anything about Intel, and talks about people reading the source code of the implementation of the function.

                                – Lightness Races in Orbit
                                Jan 30 at 11:46











                              • @LightnessRacesinOrbit – hm, I can still see it there (when searching for "intel"). You can also find the reference to recent source code (in the most recent comments) and also an alternative implementation (in the second answer) which is publicly available but complexity and commented inefficiency of which gives a hint why original implementation is still not disclosed. Truly efficient implementation might require in-depth knowledge of many details on CPU-level which are not necessarily available in public domain.

                                – miroxlav
                                Jan 30 at 13:38





















                              • This is confusing. The page you link to about Math.Pow doesn't mention any purchase, or anything about Intel, and talks about people reading the source code of the implementation of the function.

                                – Lightness Races in Orbit
                                Jan 30 at 11:46











                              • @LightnessRacesinOrbit – hm, I can still see it there (when searching for "intel"). You can also find the reference to recent source code (in the most recent comments) and also an alternative implementation (in the second answer) which is publicly available but complexity and commented inefficiency of which gives a hint why original implementation is still not disclosed. Truly efficient implementation might require in-depth knowledge of many details on CPU-level which are not necessarily available in public domain.

                                – miroxlav
                                Jan 30 at 13:38



















                              This is confusing. The page you link to about Math.Pow doesn't mention any purchase, or anything about Intel, and talks about people reading the source code of the implementation of the function.

                              – Lightness Races in Orbit
                              Jan 30 at 11:46





                              This is confusing. The page you link to about Math.Pow doesn't mention any purchase, or anything about Intel, and talks about people reading the source code of the implementation of the function.

                              – Lightness Races in Orbit
                              Jan 30 at 11:46













                              @LightnessRacesinOrbit – hm, I can still see it there (when searching for "intel"). You can also find the reference to recent source code (in the most recent comments) and also an alternative implementation (in the second answer) which is publicly available but complexity and commented inefficiency of which gives a hint why original implementation is still not disclosed. Truly efficient implementation might require in-depth knowledge of many details on CPU-level which are not necessarily available in public domain.

                              – miroxlav
                              Jan 30 at 13:38







                              @LightnessRacesinOrbit – hm, I can still see it there (when searching for "intel"). You can also find the reference to recent source code (in the most recent comments) and also an alternative implementation (in the second answer) which is publicly available but complexity and commented inefficiency of which gives a hint why original implementation is still not disclosed. Truly efficient implementation might require in-depth knowledge of many details on CPU-level which are not necessarily available in public domain.

                              – miroxlav
                              Jan 30 at 13:38













                              5














                              Bugs and debugging.



                              Bugs:
                              All software has bugs, your standard library has bugs and your compiler has bugs. As a user of the language it is much easier to find and workaround such bugs when they're in the standard library as opposed to in the compiler.



                              Debugging:
                              It's much easier for me to see a stack trace of a standard library and give me some sense of what might be going wrong. Because that stack trace has code I understand. Ofcourse you can do dig deeper and you can also trace your intrinsic functions, but it's a lot easier if it's in a language you use all the time from day to day.






                              share|improve this answer




























                                5














                                Bugs and debugging.



                                Bugs:
                                All software has bugs, your standard library has bugs and your compiler has bugs. As a user of the language it is much easier to find and workaround such bugs when they're in the standard library as opposed to in the compiler.



                                Debugging:
                                It's much easier for me to see a stack trace of a standard library and give me some sense of what might be going wrong. Because that stack trace has code I understand. Ofcourse you can do dig deeper and you can also trace your intrinsic functions, but it's a lot easier if it's in a language you use all the time from day to day.






                                share|improve this answer


























                                  5












                                  5








                                  5







                                  Bugs and debugging.



                                  Bugs:
                                  All software has bugs, your standard library has bugs and your compiler has bugs. As a user of the language it is much easier to find and workaround such bugs when they're in the standard library as opposed to in the compiler.



                                  Debugging:
                                  It's much easier for me to see a stack trace of a standard library and give me some sense of what might be going wrong. Because that stack trace has code I understand. Ofcourse you can do dig deeper and you can also trace your intrinsic functions, but it's a lot easier if it's in a language you use all the time from day to day.






                                  share|improve this answer













                                  Bugs and debugging.



                                  Bugs:
                                  All software has bugs, your standard library has bugs and your compiler has bugs. As a user of the language it is much easier to find and workaround such bugs when they're in the standard library as opposed to in the compiler.



                                  Debugging:
                                  It's much easier for me to see a stack trace of a standard library and give me some sense of what might be going wrong. Because that stack trace has code I understand. Ofcourse you can do dig deeper and you can also trace your intrinsic functions, but it's a lot easier if it's in a language you use all the time from day to day.







                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Jan 30 at 2:21









                                  Pieter BPieter B

                                  11k12661




                                  11k12661























                                      5














                                      This is an excellent question!



                                      State of the Art



                                      The C++ Standard, for example, never specifies what should be implemented in the compiler or in the standard library: it just refers to the implementation. For example, reserved symbols are defined both by the compiler (as intrinsics) and by the standard library, interchangeably.



                                      Yet, all C++ implementations that I know of will have the minimum possible number of intrinsics provided by the compiler, and as much as possible provided by the standard library.



                                      Thus, while it is technically feasible to define the standard library as intrinsic functionality in the compiler, it seems rarely used in practice.



                                      Why?



                                      Let's consider the idea of moving some piece of functionality from the standard library to the compiler.



                                      Advantages:




                                      • Better diagnostics: intrinsics can be special-cased.

                                      • Better performance: intrinsics can be special-cased.


                                      Disadvantages:




                                      • Increased compiler mass: each special-case adds complexity to the compiler; complexity increases maintenance costs, and the likelihood of bugs.

                                      • Slower iteration: changing the implementation of the functionality requires changing the compiler itself, making it harder to create just a small library (outside of std) to experiment.

                                      • Higher bar to entry: the more expensive/more difficult it is to change something, the less people are likely to jump in.


                                      This means that moving something to the compiler is expensive, now and in the future, and therefore it requires a solid case. For some pieces of functionality, it is necessary (they cannot be written as regular code), however even then it pays to extract minimal and generic pieces to move to the compiler and build atop them in the standard library.






                                      share|improve this answer




























                                        5














                                        This is an excellent question!



                                        State of the Art



                                        The C++ Standard, for example, never specifies what should be implemented in the compiler or in the standard library: it just refers to the implementation. For example, reserved symbols are defined both by the compiler (as intrinsics) and by the standard library, interchangeably.



                                        Yet, all C++ implementations that I know of will have the minimum possible number of intrinsics provided by the compiler, and as much as possible provided by the standard library.



                                        Thus, while it is technically feasible to define the standard library as intrinsic functionality in the compiler, it seems rarely used in practice.



                                        Why?



                                        Let's consider the idea of moving some piece of functionality from the standard library to the compiler.



                                        Advantages:




                                        • Better diagnostics: intrinsics can be special-cased.

                                        • Better performance: intrinsics can be special-cased.


                                        Disadvantages:




                                        • Increased compiler mass: each special-case adds complexity to the compiler; complexity increases maintenance costs, and the likelihood of bugs.

                                        • Slower iteration: changing the implementation of the functionality requires changing the compiler itself, making it harder to create just a small library (outside of std) to experiment.

                                        • Higher bar to entry: the more expensive/more difficult it is to change something, the less people are likely to jump in.


                                        This means that moving something to the compiler is expensive, now and in the future, and therefore it requires a solid case. For some pieces of functionality, it is necessary (they cannot be written as regular code), however even then it pays to extract minimal and generic pieces to move to the compiler and build atop them in the standard library.






                                        share|improve this answer


























                                          5












                                          5








                                          5







                                          This is an excellent question!



                                          State of the Art



                                          The C++ Standard, for example, never specifies what should be implemented in the compiler or in the standard library: it just refers to the implementation. For example, reserved symbols are defined both by the compiler (as intrinsics) and by the standard library, interchangeably.



                                          Yet, all C++ implementations that I know of will have the minimum possible number of intrinsics provided by the compiler, and as much as possible provided by the standard library.



                                          Thus, while it is technically feasible to define the standard library as intrinsic functionality in the compiler, it seems rarely used in practice.



                                          Why?



                                          Let's consider the idea of moving some piece of functionality from the standard library to the compiler.



                                          Advantages:




                                          • Better diagnostics: intrinsics can be special-cased.

                                          • Better performance: intrinsics can be special-cased.


                                          Disadvantages:




                                          • Increased compiler mass: each special-case adds complexity to the compiler; complexity increases maintenance costs, and the likelihood of bugs.

                                          • Slower iteration: changing the implementation of the functionality requires changing the compiler itself, making it harder to create just a small library (outside of std) to experiment.

                                          • Higher bar to entry: the more expensive/more difficult it is to change something, the less people are likely to jump in.


                                          This means that moving something to the compiler is expensive, now and in the future, and therefore it requires a solid case. For some pieces of functionality, it is necessary (they cannot be written as regular code), however even then it pays to extract minimal and generic pieces to move to the compiler and build atop them in the standard library.






                                          share|improve this answer













                                          This is an excellent question!



                                          State of the Art



                                          The C++ Standard, for example, never specifies what should be implemented in the compiler or in the standard library: it just refers to the implementation. For example, reserved symbols are defined both by the compiler (as intrinsics) and by the standard library, interchangeably.



                                          Yet, all C++ implementations that I know of will have the minimum possible number of intrinsics provided by the compiler, and as much as possible provided by the standard library.



                                          Thus, while it is technically feasible to define the standard library as intrinsic functionality in the compiler, it seems rarely used in practice.



                                          Why?



                                          Let's consider the idea of moving some piece of functionality from the standard library to the compiler.



                                          Advantages:




                                          • Better diagnostics: intrinsics can be special-cased.

                                          • Better performance: intrinsics can be special-cased.


                                          Disadvantages:




                                          • Increased compiler mass: each special-case adds complexity to the compiler; complexity increases maintenance costs, and the likelihood of bugs.

                                          • Slower iteration: changing the implementation of the functionality requires changing the compiler itself, making it harder to create just a small library (outside of std) to experiment.

                                          • Higher bar to entry: the more expensive/more difficult it is to change something, the less people are likely to jump in.


                                          This means that moving something to the compiler is expensive, now and in the future, and therefore it requires a solid case. For some pieces of functionality, it is necessary (they cannot be written as regular code), however even then it pays to extract minimal and generic pieces to move to the compiler and build atop them in the standard library.







                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Jan 30 at 10:30









                                          Matthieu M.Matthieu M.

                                          11.9k43755




                                          11.9k43755























                                              5














                                              As a language designer myself, I'd like to echo some of the other answers here, but provide it through the eyes of someone who is building a language.




                                              An API is not finished when you are done adding everything you can into it. An API is finished when you're done taking everything you can out of it.




                                              A programming language has to be specified using some language. You have to be able to convey the meaning behind any program written in your language. This language is very hard to write, and even harder to write well. In general, it tends to be a very precise and well structured form of English used to convey meaning not to the computer, but to other developers, especially those developers writing compilers or interpreters for your language. Here's an example from the C++11 spec, [intro.multithread/14]:




                                              The visible sequence of side effects on an atomic object M, with respect to a value computation B of M, is
                                              a maximal contiguous sub-sequence of side effects in the modification order of M, where the first side effect
                                              is visible with respect to B, and for every side effect, it is not the case that B happens before it. The value
                                              of an atomic object M, as determined by evaluation B, shall be the value stored by some operation in the
                                              visible sequence of M with respect to B. [ Note: It can be shown that the visible sequence of side effects of
                                              a value computation is unique given the coherence requirements below. —end note ]




                                              Blek! Anyone who has taken the plunge into understanding how C++11 handles multithreading can appreciate why the wording has to be so dang opaque, but that doesn't forgive the fact that it is... well... so opaque!



                                              Contrast that with the definition of std::shared_ptr<T>::reset, in the library section of the standard:




                                              template <class Y> void reset(Y* p);



                                              Effects: Equivalent to shared_ptr(p).swap(*this)




                                              So what's the difference? In the language definition part, the writers cannot assume that the reader understands the language primitives. Everything must be specified carefully in English prose. Once we get to the library definition part, we can use the language to specify the behavior. This is often far easier!



                                              In principle, one could have a smooth build up from primitives at the start of the spec document, all the way up through defining what we would think of as "standard library features", without having to draw a line between "language primitives" and "standard library" features. In practice, that line proves enormously valuable to draw because it lets you write some of the most complex parts of the language (such as those which must implement algorithms) using a language designed to express them.



                                              And we do indeed see some blurry lines:




                                              • In Java, java.lang.ref.Reference<T> may only be subclassed by the standard library classes java.lang.ref.WeakReference<T> java.lang.ref.SoftReference<T> and java.lang.ref.PhantomReference<T> because the behaviors of Reference are so deeply entwined with the Java language specification that they needed to put some restrictions into the portion of that process implemented as "standard library" classes.

                                              • In C#, there is a class, System.Delegate which encapsulates the concept of delegates. Despite its name, it is not a delegate. It is also an abstract class (cannot be instantiated) that you cannot create derived classes from. Only the system can do it through features written into the language specification.






                                              share|improve this answer




























                                                5














                                                As a language designer myself, I'd like to echo some of the other answers here, but provide it through the eyes of someone who is building a language.




                                                An API is not finished when you are done adding everything you can into it. An API is finished when you're done taking everything you can out of it.




                                                A programming language has to be specified using some language. You have to be able to convey the meaning behind any program written in your language. This language is very hard to write, and even harder to write well. In general, it tends to be a very precise and well structured form of English used to convey meaning not to the computer, but to other developers, especially those developers writing compilers or interpreters for your language. Here's an example from the C++11 spec, [intro.multithread/14]:




                                                The visible sequence of side effects on an atomic object M, with respect to a value computation B of M, is
                                                a maximal contiguous sub-sequence of side effects in the modification order of M, where the first side effect
                                                is visible with respect to B, and for every side effect, it is not the case that B happens before it. The value
                                                of an atomic object M, as determined by evaluation B, shall be the value stored by some operation in the
                                                visible sequence of M with respect to B. [ Note: It can be shown that the visible sequence of side effects of
                                                a value computation is unique given the coherence requirements below. —end note ]




                                                Blek! Anyone who has taken the plunge into understanding how C++11 handles multithreading can appreciate why the wording has to be so dang opaque, but that doesn't forgive the fact that it is... well... so opaque!



                                                Contrast that with the definition of std::shared_ptr<T>::reset, in the library section of the standard:




                                                template <class Y> void reset(Y* p);



                                                Effects: Equivalent to shared_ptr(p).swap(*this)




                                                So what's the difference? In the language definition part, the writers cannot assume that the reader understands the language primitives. Everything must be specified carefully in English prose. Once we get to the library definition part, we can use the language to specify the behavior. This is often far easier!



                                                In principle, one could have a smooth build up from primitives at the start of the spec document, all the way up through defining what we would think of as "standard library features", without having to draw a line between "language primitives" and "standard library" features. In practice, that line proves enormously valuable to draw because it lets you write some of the most complex parts of the language (such as those which must implement algorithms) using a language designed to express them.



                                                And we do indeed see some blurry lines:




                                                • In Java, java.lang.ref.Reference<T> may only be subclassed by the standard library classes java.lang.ref.WeakReference<T> java.lang.ref.SoftReference<T> and java.lang.ref.PhantomReference<T> because the behaviors of Reference are so deeply entwined with the Java language specification that they needed to put some restrictions into the portion of that process implemented as "standard library" classes.

                                                • In C#, there is a class, System.Delegate which encapsulates the concept of delegates. Despite its name, it is not a delegate. It is also an abstract class (cannot be instantiated) that you cannot create derived classes from. Only the system can do it through features written into the language specification.






                                                share|improve this answer


























                                                  5












                                                  5








                                                  5







                                                  As a language designer myself, I'd like to echo some of the other answers here, but provide it through the eyes of someone who is building a language.




                                                  An API is not finished when you are done adding everything you can into it. An API is finished when you're done taking everything you can out of it.




                                                  A programming language has to be specified using some language. You have to be able to convey the meaning behind any program written in your language. This language is very hard to write, and even harder to write well. In general, it tends to be a very precise and well structured form of English used to convey meaning not to the computer, but to other developers, especially those developers writing compilers or interpreters for your language. Here's an example from the C++11 spec, [intro.multithread/14]:




                                                  The visible sequence of side effects on an atomic object M, with respect to a value computation B of M, is
                                                  a maximal contiguous sub-sequence of side effects in the modification order of M, where the first side effect
                                                  is visible with respect to B, and for every side effect, it is not the case that B happens before it. The value
                                                  of an atomic object M, as determined by evaluation B, shall be the value stored by some operation in the
                                                  visible sequence of M with respect to B. [ Note: It can be shown that the visible sequence of side effects of
                                                  a value computation is unique given the coherence requirements below. —end note ]




                                                  Blek! Anyone who has taken the plunge into understanding how C++11 handles multithreading can appreciate why the wording has to be so dang opaque, but that doesn't forgive the fact that it is... well... so opaque!



                                                  Contrast that with the definition of std::shared_ptr<T>::reset, in the library section of the standard:




                                                  template <class Y> void reset(Y* p);



                                                  Effects: Equivalent to shared_ptr(p).swap(*this)




                                                  So what's the difference? In the language definition part, the writers cannot assume that the reader understands the language primitives. Everything must be specified carefully in English prose. Once we get to the library definition part, we can use the language to specify the behavior. This is often far easier!



                                                  In principle, one could have a smooth build up from primitives at the start of the spec document, all the way up through defining what we would think of as "standard library features", without having to draw a line between "language primitives" and "standard library" features. In practice, that line proves enormously valuable to draw because it lets you write some of the most complex parts of the language (such as those which must implement algorithms) using a language designed to express them.



                                                  And we do indeed see some blurry lines:




                                                  • In Java, java.lang.ref.Reference<T> may only be subclassed by the standard library classes java.lang.ref.WeakReference<T> java.lang.ref.SoftReference<T> and java.lang.ref.PhantomReference<T> because the behaviors of Reference are so deeply entwined with the Java language specification that they needed to put some restrictions into the portion of that process implemented as "standard library" classes.

                                                  • In C#, there is a class, System.Delegate which encapsulates the concept of delegates. Despite its name, it is not a delegate. It is also an abstract class (cannot be instantiated) that you cannot create derived classes from. Only the system can do it through features written into the language specification.






                                                  share|improve this answer













                                                  As a language designer myself, I'd like to echo some of the other answers here, but provide it through the eyes of someone who is building a language.




                                                  An API is not finished when you are done adding everything you can into it. An API is finished when you're done taking everything you can out of it.




                                                  A programming language has to be specified using some language. You have to be able to convey the meaning behind any program written in your language. This language is very hard to write, and even harder to write well. In general, it tends to be a very precise and well structured form of English used to convey meaning not to the computer, but to other developers, especially those developers writing compilers or interpreters for your language. Here's an example from the C++11 spec, [intro.multithread/14]:




                                                  The visible sequence of side effects on an atomic object M, with respect to a value computation B of M, is
                                                  a maximal contiguous sub-sequence of side effects in the modification order of M, where the first side effect
                                                  is visible with respect to B, and for every side effect, it is not the case that B happens before it. The value
                                                  of an atomic object M, as determined by evaluation B, shall be the value stored by some operation in the
                                                  visible sequence of M with respect to B. [ Note: It can be shown that the visible sequence of side effects of
                                                  a value computation is unique given the coherence requirements below. —end note ]




                                                  Blek! Anyone who has taken the plunge into understanding how C++11 handles multithreading can appreciate why the wording has to be so dang opaque, but that doesn't forgive the fact that it is... well... so opaque!



                                                  Contrast that with the definition of std::shared_ptr<T>::reset, in the library section of the standard:




                                                  template <class Y> void reset(Y* p);



                                                  Effects: Equivalent to shared_ptr(p).swap(*this)




                                                  So what's the difference? In the language definition part, the writers cannot assume that the reader understands the language primitives. Everything must be specified carefully in English prose. Once we get to the library definition part, we can use the language to specify the behavior. This is often far easier!



                                                  In principle, one could have a smooth build up from primitives at the start of the spec document, all the way up through defining what we would think of as "standard library features", without having to draw a line between "language primitives" and "standard library" features. In practice, that line proves enormously valuable to draw because it lets you write some of the most complex parts of the language (such as those which must implement algorithms) using a language designed to express them.



                                                  And we do indeed see some blurry lines:




                                                  • In Java, java.lang.ref.Reference<T> may only be subclassed by the standard library classes java.lang.ref.WeakReference<T> java.lang.ref.SoftReference<T> and java.lang.ref.PhantomReference<T> because the behaviors of Reference are so deeply entwined with the Java language specification that they needed to put some restrictions into the portion of that process implemented as "standard library" classes.

                                                  • In C#, there is a class, System.Delegate which encapsulates the concept of delegates. Despite its name, it is not a delegate. It is also an abstract class (cannot be instantiated) that you cannot create derived classes from. Only the system can do it through features written into the language specification.







                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Jan 30 at 17:16









                                                  Cort AmmonCort Ammon

                                                  9,68131830




                                                  9,68131830























                                                      2














                                                      This is meant as an addition to the existing answers (and is too long for a comment).



                                                      There are at least two other reasons for a standard library:



                                                      Barrier to Entry



                                                      If a particular language feature is in a library function and I want to know how it works, I can just read the source for that function. If I want to submit a bug report/patch/pull request, it's not generally too difficult to code a fix and test case(s). If it's in the compiler, I have to be able to dig into the internals. Even if it's in the same language (and it should be, any self-respecting compiler should be self-hosted) compiler code is nothing like application code. It may take forever to even find the correct files.



                                                      You're cutting yourself off from a lot of potential contributors if you go that route.



                                                      Hot code loading



                                                      Many languages offer this feature to one degree or another, but it would be enormously complicated to hot reload the code that's doing the hot reloading. If the SL is separate from the runtime it can be reloaded.






                                                      share|improve this answer



















                                                      • 3





                                                        "any self-respecting compiler should be self-hosted" - not at all. It would be pointless to have versions of say LLVM written in C, C++, Objective-C, Swift, Fortran and so on to compile all these languages.

                                                        – gnasher729
                                                        Jan 29 at 23:20











                                                      • @gnasher729 isn't that a bit of a special case (along with other multilanguage targets like the CLR)?

                                                        – Jared Smith
                                                        Jan 30 at 0:45











                                                      • @JaredSmith I would say it is now the general case, not special at all. Nobody writes "a compiler" as a monolithic application any more. They produce compiler systems instead. Most of the functionality of complete compiler is completely independent of the particular language that is being compiled, and much of the language-dependent part can be done by supplying different data defining the grammar of the language, not by writing different code for each language you want to compile.

                                                        – alephzero
                                                        Jan 30 at 1:01
















                                                      2














                                                      This is meant as an addition to the existing answers (and is too long for a comment).



                                                      There are at least two other reasons for a standard library:



                                                      Barrier to Entry



                                                      If a particular language feature is in a library function and I want to know how it works, I can just read the source for that function. If I want to submit a bug report/patch/pull request, it's not generally too difficult to code a fix and test case(s). If it's in the compiler, I have to be able to dig into the internals. Even if it's in the same language (and it should be, any self-respecting compiler should be self-hosted) compiler code is nothing like application code. It may take forever to even find the correct files.



                                                      You're cutting yourself off from a lot of potential contributors if you go that route.



                                                      Hot code loading



                                                      Many languages offer this feature to one degree or another, but it would be enormously complicated to hot reload the code that's doing the hot reloading. If the SL is separate from the runtime it can be reloaded.






                                                      share|improve this answer



















                                                      • 3





                                                        "any self-respecting compiler should be self-hosted" - not at all. It would be pointless to have versions of say LLVM written in C, C++, Objective-C, Swift, Fortran and so on to compile all these languages.

                                                        – gnasher729
                                                        Jan 29 at 23:20











                                                      • @gnasher729 isn't that a bit of a special case (along with other multilanguage targets like the CLR)?

                                                        – Jared Smith
                                                        Jan 30 at 0:45











                                                      • @JaredSmith I would say it is now the general case, not special at all. Nobody writes "a compiler" as a monolithic application any more. They produce compiler systems instead. Most of the functionality of complete compiler is completely independent of the particular language that is being compiled, and much of the language-dependent part can be done by supplying different data defining the grammar of the language, not by writing different code for each language you want to compile.

                                                        – alephzero
                                                        Jan 30 at 1:01














                                                      2












                                                      2








                                                      2







                                                      This is meant as an addition to the existing answers (and is too long for a comment).



                                                      There are at least two other reasons for a standard library:



                                                      Barrier to Entry



                                                      If a particular language feature is in a library function and I want to know how it works, I can just read the source for that function. If I want to submit a bug report/patch/pull request, it's not generally too difficult to code a fix and test case(s). If it's in the compiler, I have to be able to dig into the internals. Even if it's in the same language (and it should be, any self-respecting compiler should be self-hosted) compiler code is nothing like application code. It may take forever to even find the correct files.



                                                      You're cutting yourself off from a lot of potential contributors if you go that route.



                                                      Hot code loading



                                                      Many languages offer this feature to one degree or another, but it would be enormously complicated to hot reload the code that's doing the hot reloading. If the SL is separate from the runtime it can be reloaded.






                                                      share|improve this answer













                                                      This is meant as an addition to the existing answers (and is too long for a comment).



                                                      There are at least two other reasons for a standard library:



                                                      Barrier to Entry



                                                      If a particular language feature is in a library function and I want to know how it works, I can just read the source for that function. If I want to submit a bug report/patch/pull request, it's not generally too difficult to code a fix and test case(s). If it's in the compiler, I have to be able to dig into the internals. Even if it's in the same language (and it should be, any self-respecting compiler should be self-hosted) compiler code is nothing like application code. It may take forever to even find the correct files.



                                                      You're cutting yourself off from a lot of potential contributors if you go that route.



                                                      Hot code loading



                                                      Many languages offer this feature to one degree or another, but it would be enormously complicated to hot reload the code that's doing the hot reloading. If the SL is separate from the runtime it can be reloaded.







                                                      share|improve this answer












                                                      share|improve this answer



                                                      share|improve this answer










                                                      answered Jan 29 at 22:32









                                                      Jared SmithJared Smith

                                                      1,267517




                                                      1,267517








                                                      • 3





                                                        "any self-respecting compiler should be self-hosted" - not at all. It would be pointless to have versions of say LLVM written in C, C++, Objective-C, Swift, Fortran and so on to compile all these languages.

                                                        – gnasher729
                                                        Jan 29 at 23:20











                                                      • @gnasher729 isn't that a bit of a special case (along with other multilanguage targets like the CLR)?

                                                        – Jared Smith
                                                        Jan 30 at 0:45











                                                      • @JaredSmith I would say it is now the general case, not special at all. Nobody writes "a compiler" as a monolithic application any more. They produce compiler systems instead. Most of the functionality of complete compiler is completely independent of the particular language that is being compiled, and much of the language-dependent part can be done by supplying different data defining the grammar of the language, not by writing different code for each language you want to compile.

                                                        – alephzero
                                                        Jan 30 at 1:01














                                                      • 3





                                                        "any self-respecting compiler should be self-hosted" - not at all. It would be pointless to have versions of say LLVM written in C, C++, Objective-C, Swift, Fortran and so on to compile all these languages.

                                                        – gnasher729
                                                        Jan 29 at 23:20











                                                      • @gnasher729 isn't that a bit of a special case (along with other multilanguage targets like the CLR)?

                                                        – Jared Smith
                                                        Jan 30 at 0:45











                                                      • @JaredSmith I would say it is now the general case, not special at all. Nobody writes "a compiler" as a monolithic application any more. They produce compiler systems instead. Most of the functionality of complete compiler is completely independent of the particular language that is being compiled, and much of the language-dependent part can be done by supplying different data defining the grammar of the language, not by writing different code for each language you want to compile.

                                                        – alephzero
                                                        Jan 30 at 1:01








                                                      3




                                                      3





                                                      "any self-respecting compiler should be self-hosted" - not at all. It would be pointless to have versions of say LLVM written in C, C++, Objective-C, Swift, Fortran and so on to compile all these languages.

                                                      – gnasher729
                                                      Jan 29 at 23:20





                                                      "any self-respecting compiler should be self-hosted" - not at all. It would be pointless to have versions of say LLVM written in C, C++, Objective-C, Swift, Fortran and so on to compile all these languages.

                                                      – gnasher729
                                                      Jan 29 at 23:20













                                                      @gnasher729 isn't that a bit of a special case (along with other multilanguage targets like the CLR)?

                                                      – Jared Smith
                                                      Jan 30 at 0:45





                                                      @gnasher729 isn't that a bit of a special case (along with other multilanguage targets like the CLR)?

                                                      – Jared Smith
                                                      Jan 30 at 0:45













                                                      @JaredSmith I would say it is now the general case, not special at all. Nobody writes "a compiler" as a monolithic application any more. They produce compiler systems instead. Most of the functionality of complete compiler is completely independent of the particular language that is being compiled, and much of the language-dependent part can be done by supplying different data defining the grammar of the language, not by writing different code for each language you want to compile.

                                                      – alephzero
                                                      Jan 30 at 1:01





                                                      @JaredSmith I would say it is now the general case, not special at all. Nobody writes "a compiler" as a monolithic application any more. They produce compiler systems instead. Most of the functionality of complete compiler is completely independent of the particular language that is being compiled, and much of the language-dependent part can be done by supplying different data defining the grammar of the language, not by writing different code for each language you want to compile.

                                                      – alephzero
                                                      Jan 30 at 1:01











                                                      2














                                                      This is an interesting question but there are many good answers already given, so I won't attempt a complete one.



                                                      However, two things that I don't think have gotten enough attention:



                                                      First is that the whole thing is not super clear cut. It's a bit of a spectrum exactly because there are reasons to do things differently.
                                                      As an example, compilers often know about standard libraries and their functions.
                                                      Example of the example: C's "Hello World" function - printf - is the best one I can think of. It's a library function, it sort-of has to be, as it's very platform dependent. But it's behaviour (implementation defined) needs to be known by the compiler in order to warn the programmer about bad invocations. This isn't particularly neat, but was seen as a good compromise. Incidentally, this is the real answer to most of the "why this design" questions: a lot of compromise and "seemed like a good idea at the time". Not always the "this was the clear way to do it" or "look: an example from on of the far ends of the spectrum" as often given by the proponents of that choice. (Not that those answers are not relevant).



                                                      Second is that it allows the standard library not to be all that standard. There a lot of situations that a language is desirable but the standard libraries that usually accompany them are not both practical and desirable. This is most commonly the case with systems programming languages like C, on non-standard platforms. For example, if you have a system without an OS or a scheduler: you aren't going to have threading.



                                                      With a standard library model (and threading being supported in it) this can be handled cleanly: the compiler is pretty much the same, you can reuse the bits of the libraries that apply, and anything that doesn't you can remove. If this is baked into the compiler things start to get messy.



                                                      For example:




                                                      • You can't be a compliant compiler.


                                                      • How would you indicate your deviation from the standard.
                                                        Note there is usually some form of import/include syntax you can have fail i.e. pythons's import or C's include that easily points to the problem if there is anything missing in the standard library model.



                                                      Also similar problems apply if you want to tweak or extend 'library' functionality. This is far more common than you might think. Just to stick with threading: windows, linux and some-exotic-network-processing-units all do threading quite differently. While the linux/windows bits might be fairly static and be able to use an identical API, the NPU stuff will change with the day of the week and the API with it. Compilers would quickly deviate as people decided which bits they need to support/could-do-with-out quite rapidly if there was no way to split this sort of thing out.






                                                      share|improve this answer






























                                                        2














                                                        This is an interesting question but there are many good answers already given, so I won't attempt a complete one.



                                                        However, two things that I don't think have gotten enough attention:



                                                        First is that the whole thing is not super clear cut. It's a bit of a spectrum exactly because there are reasons to do things differently.
                                                        As an example, compilers often know about standard libraries and their functions.
                                                        Example of the example: C's "Hello World" function - printf - is the best one I can think of. It's a library function, it sort-of has to be, as it's very platform dependent. But it's behaviour (implementation defined) needs to be known by the compiler in order to warn the programmer about bad invocations. This isn't particularly neat, but was seen as a good compromise. Incidentally, this is the real answer to most of the "why this design" questions: a lot of compromise and "seemed like a good idea at the time". Not always the "this was the clear way to do it" or "look: an example from on of the far ends of the spectrum" as often given by the proponents of that choice. (Not that those answers are not relevant).



                                                        Second is that it allows the standard library not to be all that standard. There a lot of situations that a language is desirable but the standard libraries that usually accompany them are not both practical and desirable. This is most commonly the case with systems programming languages like C, on non-standard platforms. For example, if you have a system without an OS or a scheduler: you aren't going to have threading.



                                                        With a standard library model (and threading being supported in it) this can be handled cleanly: the compiler is pretty much the same, you can reuse the bits of the libraries that apply, and anything that doesn't you can remove. If this is baked into the compiler things start to get messy.



                                                        For example:




                                                        • You can't be a compliant compiler.


                                                        • How would you indicate your deviation from the standard.
                                                          Note there is usually some form of import/include syntax you can have fail i.e. pythons's import or C's include that easily points to the problem if there is anything missing in the standard library model.



                                                        Also similar problems apply if you want to tweak or extend 'library' functionality. This is far more common than you might think. Just to stick with threading: windows, linux and some-exotic-network-processing-units all do threading quite differently. While the linux/windows bits might be fairly static and be able to use an identical API, the NPU stuff will change with the day of the week and the API with it. Compilers would quickly deviate as people decided which bits they need to support/could-do-with-out quite rapidly if there was no way to split this sort of thing out.






                                                        share|improve this answer




























                                                          2












                                                          2








                                                          2







                                                          This is an interesting question but there are many good answers already given, so I won't attempt a complete one.



                                                          However, two things that I don't think have gotten enough attention:



                                                          First is that the whole thing is not super clear cut. It's a bit of a spectrum exactly because there are reasons to do things differently.
                                                          As an example, compilers often know about standard libraries and their functions.
                                                          Example of the example: C's "Hello World" function - printf - is the best one I can think of. It's a library function, it sort-of has to be, as it's very platform dependent. But it's behaviour (implementation defined) needs to be known by the compiler in order to warn the programmer about bad invocations. This isn't particularly neat, but was seen as a good compromise. Incidentally, this is the real answer to most of the "why this design" questions: a lot of compromise and "seemed like a good idea at the time". Not always the "this was the clear way to do it" or "look: an example from on of the far ends of the spectrum" as often given by the proponents of that choice. (Not that those answers are not relevant).



                                                          Second is that it allows the standard library not to be all that standard. There a lot of situations that a language is desirable but the standard libraries that usually accompany them are not both practical and desirable. This is most commonly the case with systems programming languages like C, on non-standard platforms. For example, if you have a system without an OS or a scheduler: you aren't going to have threading.



                                                          With a standard library model (and threading being supported in it) this can be handled cleanly: the compiler is pretty much the same, you can reuse the bits of the libraries that apply, and anything that doesn't you can remove. If this is baked into the compiler things start to get messy.



                                                          For example:




                                                          • You can't be a compliant compiler.


                                                          • How would you indicate your deviation from the standard.
                                                            Note there is usually some form of import/include syntax you can have fail i.e. pythons's import or C's include that easily points to the problem if there is anything missing in the standard library model.



                                                          Also similar problems apply if you want to tweak or extend 'library' functionality. This is far more common than you might think. Just to stick with threading: windows, linux and some-exotic-network-processing-units all do threading quite differently. While the linux/windows bits might be fairly static and be able to use an identical API, the NPU stuff will change with the day of the week and the API with it. Compilers would quickly deviate as people decided which bits they need to support/could-do-with-out quite rapidly if there was no way to split this sort of thing out.






                                                          share|improve this answer















                                                          This is an interesting question but there are many good answers already given, so I won't attempt a complete one.



                                                          However, two things that I don't think have gotten enough attention:



                                                          First is that the whole thing is not super clear cut. It's a bit of a spectrum exactly because there are reasons to do things differently.
                                                          As an example, compilers often know about standard libraries and their functions.
                                                          Example of the example: C's "Hello World" function - printf - is the best one I can think of. It's a library function, it sort-of has to be, as it's very platform dependent. But it's behaviour (implementation defined) needs to be known by the compiler in order to warn the programmer about bad invocations. This isn't particularly neat, but was seen as a good compromise. Incidentally, this is the real answer to most of the "why this design" questions: a lot of compromise and "seemed like a good idea at the time". Not always the "this was the clear way to do it" or "look: an example from on of the far ends of the spectrum" as often given by the proponents of that choice. (Not that those answers are not relevant).



                                                          Second is that it allows the standard library not to be all that standard. There a lot of situations that a language is desirable but the standard libraries that usually accompany them are not both practical and desirable. This is most commonly the case with systems programming languages like C, on non-standard platforms. For example, if you have a system without an OS or a scheduler: you aren't going to have threading.



                                                          With a standard library model (and threading being supported in it) this can be handled cleanly: the compiler is pretty much the same, you can reuse the bits of the libraries that apply, and anything that doesn't you can remove. If this is baked into the compiler things start to get messy.



                                                          For example:




                                                          • You can't be a compliant compiler.


                                                          • How would you indicate your deviation from the standard.
                                                            Note there is usually some form of import/include syntax you can have fail i.e. pythons's import or C's include that easily points to the problem if there is anything missing in the standard library model.



                                                          Also similar problems apply if you want to tweak or extend 'library' functionality. This is far more common than you might think. Just to stick with threading: windows, linux and some-exotic-network-processing-units all do threading quite differently. While the linux/windows bits might be fairly static and be able to use an identical API, the NPU stuff will change with the day of the week and the API with it. Compilers would quickly deviate as people decided which bits they need to support/could-do-with-out quite rapidly if there was no way to split this sort of thing out.







                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited Feb 1 at 0:08

























                                                          answered Jan 30 at 15:41









                                                          drjpizzledrjpizzle

                                                          1964




                                                          1964















                                                              Popular posts from this blog

                                                              Index of /

                                                              Tribalistas

                                                              Listed building